diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..29715f6 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,1709 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [0.5.18] - 2025-02-27 + +### Fixed + +- **🌐 Open WebUI Now Works Over LAN in Insecure Context**: Resolved an issue preventing Open WebUI from functioning when accessed over a local network in an insecure context, ensuring seamless connectivity. +- **🔄 UI Now Reflects Deleted Connections Instantly**: Fixed an issue where deleting a connection did not update the UI in real time, ensuring accurate system state visibility. +- **🛠️ Models Now Display Correctly with ENABLE_FORWARD_USER_INFO_HEADERS**: Addressed a bug where models were not visible when ENABLE_FORWARD_USER_INFO_HEADERS was set, restoring proper model listing. + +## [0.5.17] - 2025-02-27 + +### Added + +- **🚀 Instant Document Upload with Bypass Embedding & Retrieval**: Admins can now enable "Bypass Embedding & Retrieval" in Admin Settings > Documents, significantly speeding up document uploads and ensuring full document context is retained without chunking. +- **🔎 "Stream" Hook for Real-Time Filtering**: The new "stream" hook allows dynamic real-time message filtering. Learn more in our documentation (https://docs.openwebui.com/features/plugin/functions/filter). +- **☁️ OneDrive Integration**: Early support for OneDrive storage integration has been introduced, expanding file import options. +- **📈 Enhanced Logging with Loguru**: Backend logging has been improved with Loguru, making debugging and issue tracking far more efficient. +- **⚙️ General Stability Enhancements**: Backend and frontend refactoring improves performance, ensuring a smoother and more reliable user experience. +- **🌍 Updated Translations**: Refined multilingual support for better localization and accuracy across various languages. + +### Fixed + +- **🔄 Reliable Model Imports from the Community Platform**: Resolved import failures, allowing seamless integration of community-shared models without errors. +- **📊 OpenAI Usage Statistics Restored**: Fixed an issue where OpenAI usage metrics were not displaying correctly, ensuring accurate tracking of usage data. +- **🗂️ Deduplication for Retrieved Documents**: Documents retrieved during searches are now intelligently deduplicated, meaning no more redundant results—helping to keep information concise and relevant. + +### Changed + +- **📝 "Full Context Mode" Renamed for Clarity**: The "Full Context Mode" toggle in Web Search settings is now labeled "Bypass Embedding & Retrieval" for consistency across the UI. + +## [0.5.16] - 2025-02-20 + +### Fixed + +- **🔍 Web Search Retrieval Restored**: Resolved a critical issue that broke web search retrieval by reverting deduplication changes, ensuring complete and accurate search results once again. + +## [0.5.15] - 2025-02-20 + +### Added + +- **📄 Full Context Mode for Local Document Search (RAG)**: Toggle full context mode from Admin Settings > Documents to inject entire document content into context, improving accuracy for models with large context windows—ideal for deep context understanding. +- **🌍 Smarter Web Search with Agentic Workflows**: Web searches now intelligently gather and refine multiple relevant terms, similar to RAG handling, delivering significantly better search results for more accurate information retrieval. +- **🔎 Experimental Playwright Support for Web Loader**: Web content retrieval is taken to the next level with Playwright-powered scraping for enhanced accuracy in extracted web data. +- **☁️ Experimental Azure Storage Provider**: Early-stage support for Azure Storage allows more cloud storage flexibility directly within Open WebUI. +- **📊 Improved Jupyter Code Execution with Plots**: Interactive coding now properly displays inline plots, making data visualization more seamless inside chat interactions. +- **⏳ Adjustable Execution Timeout for Jupyter Interpreter**: Customize execution timeout (default: 60s) for Jupyter-based code execution, allowing longer or more constrained execution based on your needs. +- **▶️ "Running..." Indicator for Jupyter Code Execution**: A visual indicator now appears while code execution is in progress, providing real-time status updates on ongoing computations. +- **⚙️ General Backend & Frontend Stability Enhancements**: Extensive refactoring improves reliability, performance, and overall user experience for a more seamless Open WebUI. +- **🌍 Translation Updates**: Various international translation refinements ensure better localization and a more natural user interface experience. + +### Fixed + +- **📱 Mobile Hover Issue Resolved**: Users can now edit responses smoothly on mobile without interference, fixing a longstanding hover issue. +- **🔄 Temporary Chat Message Duplication Fixed**: Eliminated buggy behavior where messages were being unnecessarily repeated in temporary chat mode, ensuring a smooth and consistent conversation flow. + +## [0.5.14] - 2025-02-17 + +### Fixed + +- **🔧 Critical Import Error Resolved**: Fixed a circular import issue preventing 'override_static' from being correctly imported in 'open_webui.config', ensuring smooth system initialization and stability. + +## [0.5.13] - 2025-02-17 + +### Added + +- **🌐 Full Context Mode for Web Search**: Enable highly accurate web searches by utilizing full context mode—ideal for models with large context windows, ensuring more precise and insightful results. +- **⚡ Optimized Asynchronous Web Search**: Web searches now load significantly faster with optimized async support, providing users with quicker, more efficient information retrieval. +- **🔄 Auto Text Direction for RTL Languages**: Automatic text alignment based on language input, ensuring seamless conversation flow for Arabic, Hebrew, and other right-to-left scripts. +- **🚀 Jupyter Notebook Support for Code Execution**: The "Run" button in code blocks can now use Jupyter for execution, offering a powerful, dynamic coding experience directly in the chat. +- **🗑️ Message Delete Confirmation Dialog**: Prevent accidental deletions with a new confirmation prompt before removing messages, adding an additional layer of security to your chat history. +- **📥 Download Button for SVG Diagrams**: SVG diagrams generated within chat can now be downloaded instantly, making it easier to save and share complex visual data. +- **✨ General UI/UX Improvements and Backend Stability**: A refined interface with smoother interactions, improved layouts, and backend stability enhancements for a more reliable, polished experience. + +### Fixed + +- **🛠️ Temporary Chat Message Continue Button Fixed**: The "Continue Response" button for temporary chats now works as expected, ensuring an uninterrupted conversation flow. + +### Changed + +- **📝 Prompt Variable Update**: Deprecated square bracket '[]' indicators for prompt variables; now requires double curly brackets '{{}}' for consistency and clarity. +- **🔧 Stability Enhancements**: Error handling improved in chat history, ensuring smoother operations when reviewing previous messages. + +## [0.5.12] - 2025-02-13 + +### Added + +- **🛠️ Multiple Tool Calls Support for Native Function Mode**: Functions now can call multiple tools within a single response, unlocking better automation and workflow flexibility when using native function calling. + +### Fixed + +- **📝 Playground Text Completion Restored**: Addressed an issue where text completion in the Playground was not functioning. +- **🔗 Direct Connections Now Work for Regular Users**: Fixed a bug where users with the 'user' role couldn't establish direct API connections, enabling seamless model usage for all user tiers. +- **⚡ Landing Page Input No Longer Lags with Long Text**: Improved input responsiveness on the landing page, ensuring fast and smooth typing experiences even when entering long messages. +- **🔧 Parameter in Functions Fixed**: Fixed an issue where the reserved parameters wasn’t recognized within functions, restoring full functionality for advanced task-based automation. + +## [0.5.11] - 2025-02-13 + +### Added + +- **🎤 Kokoro-JS TTS Support**: A new on-device, high-quality text-to-speech engine has been integrated, vastly improving voice generation quality—everything runs directly in your browser. +- **🐍 Jupyter Notebook Support in Code Interpreter**: Now, you can configure Code Interpreter to run Python code not only via Pyodide but also through Jupyter, offering a more robust coding environment for AI-driven computations and analysis. +- **🔗 Direct API Connections for Private & Local Inference**: You can now connect Open WebUI to your private or localhost API inference endpoints. CORS must be enabled, but this unlocks direct, on-device AI infrastructure support. +- **🔍 Advanced Domain Filtering for Web Search**: You can now specify which domains should be included or excluded from web searches, refining results for more relevant information retrieval. +- **🚀 Improved Image Generation Metadata Handling**: Generated images now retain metadata for better organization and future retrieval. +- **📂 S3 Key Prefix Support**: Fine-grained control over S3 storage file structuring with configurable key prefixes. +- **📸 Support for Image-Only Messages**: Send messages containing only images, facilitating more visual-centric interactions. +- **🌍 Updated Translations**: German, Spanish, Traditional Chinese, and Catalan translations updated for better multilingual support. + +### Fixed + +- **🔧 OAuth Debug Logs & Username Claim Fixes**: Debug logs have been added for OAuth role and group management, with fixes ensuring proper OAuth username retrieval and claim handling. +- **📌 Citations Formatting & Toggle Fixes**: Inline citation toggles now function correctly, and citations with more than three sources are now fully visible when expanded. +- **📸 ComfyUI Maximum Seed Value Constraint Fixed**: The maximum allowed seed value for ComfyUI has been corrected, preventing unintended behavior. +- **🔑 Connection Settings Stability**: Addressed connection settings issues that were causing instability when saving configurations. +- **📂 GGUF Model Upload Stability**: Fixed upload inconsistencies for GGUF models, ensuring reliable local model handling. +- **🔧 Web Search Configuration Bug**: Fixed issues where web search filters and settings weren't correctly applied. +- **💾 User Settings Persistence Fix**: Ensured user-specific settings are correctly saved and applied across sessions. +- **🔄 OpenID Username Retrieval Enhancement**: Usernames are now correctly picked up and assigned for OpenID Connect (OIDC) logins. + +## [0.5.10] - 2025-02-05 + +### Fixed + +- **⚙️ System Prompts Now Properly Templated via API**: Resolved an issue where system prompts were not being correctly processed when used through the API, ensuring template variables now function as expected. +- **📝 '' Tag Display Issue Fixed**: Fixed a bug where the 'thinking' tag was disrupting content rendering, ensuring clean and accurate text display. +- **💻 Code Interpreter Stability with Custom Functions**: Addressed failures when using the Code Interpreter with certain custom functions like Anthropic, ensuring smoother execution and better compatibility. + +## [0.5.9] - 2025-02-05 + +### Fixed + +- **💡 "Think" Tag Display Issue**: Resolved a bug where the "Think" tag was not functioning correctly, ensuring proper visualization of the model's reasoning process before delivering responses. + +## [0.5.8] - 2025-02-05 + +### Added + +- **🖥️ Code Interpreter**: Models can now execute code in real time to refine their answers dynamically, running securely within a sandboxed browser environment using Pyodide. Perfect for calculations, data analysis, and AI-assisted coding tasks! +- **💬 Redesigned Chat Input UI**: Enjoy a sleeker and more intuitive message input with improved feature selection, making it easier than ever to toggle tools, enable search, and interact with AI seamlessly. +- **🛠️ Native Tool Calling Support (Experimental)**: Supported models can now call tools natively, reducing query latency and improving contextual responses. More enhancements coming soon! +- **🔗 Exa Search Engine Integration**: A new search provider has been added, allowing users to retrieve up-to-date and relevant information without leaving the chat interface. +- **🌍 Localized Dates & Times**: Date and time formats now match your system locale, ensuring a more natural, region-specific experience. +- **📎 User Headers for External Embedding APIs**: API calls to external embedding services now include user-related headers. +- **🌍 "Always On" Web Search Toggle**: A new option under Settings > Interface allows users to enable Web Search by default—transform Open WebUI into your go-to search engine, ensuring AI-powered results with every query. +- **🚀 General Performance & Stability**: Significant improvements across the platform for a faster, more reliable experience. +- **🖼️ UI/UX Enhancements**: Numerous design refinements improving readability, responsiveness, and accessibility. +- **🌍 Improved Translations**: Chinese, Korean, French, Ukrainian and Serbian translations have been updated with refined terminologies for better clarity. + +### Fixed + +- **🔄 OAuth Name Field Fallback**: Resolves OAuth login failures by using the email field as a fallback when a name is missing. +- **🔑 Google Drive Credentials Restriction**: Ensures only authenticated users can access Google Drive credentials for enhanced security. +- **🌐 DuckDuckGo Search Rate Limit Handling**: Fixes issues where users would encounter 202 errors due to rate limits when using DuckDuckGo for web search. +- **📁 File Upload Permission Indicator**: Users are now notified when they lack permission to upload files, improving clarity on system restrictions. +- **🔧 Max Tokens Issue**: Fixes cases where 'max_tokens' were not applied correctly, ensuring proper model behavior. +- **🔍 Validation for RAG Web Search URLs**: Filters out invalid or unsupported URLs when using web-based retrieval augmentation. +- **🖋️ Title Generation Bug**: Fixes inconsistencies in title generation, ensuring proper chat organization. + +### Removed + +- **⚡ Deprecated Non-Web Worker Pyodide Execution**: Moves entirely to browser sandboxing for better performance and security. + +## [0.5.7] - 2025-01-23 + +### Added + +- **🌍 Enhanced Internationalization (i18n)**: Refined and expanded translations for greater global accessibility and a smoother experience for international users. + +### Fixed + +- **🔗 Connection Model ID Resolution**: Resolved an issue preventing model IDs from registering in connections. +- **💡 Prefix ID for Ollama Connections**: Fixed a bug where prefix IDs in Ollama connections were non-functional. +- **🔧 Ollama Model Enable/Disable Functionality**: Addressed the issue of enable/disable toggles not working for Ollama base models. +- **🔒 RBAC Permissions for Tools and Models**: Corrected incorrect Role-Based Access Control (RBAC) permissions for tools and models, ensuring that users now only access features according to their assigned privileges, enhancing security and role clarity. + +## [0.5.6] - 2025-01-22 + +### Added + +- **🧠 Effortful Reasoning Control for OpenAI Models**: Introduced the reasoning_effort parameter in chat controls for supported OpenAI models, enabling users to fine-tune how much cognitive effort a model dedicates to its responses, offering greater customization for complex queries and reasoning tasks. + +### Fixed + +- **🔄 Chat Controls Loading UI Bug**: Resolved an issue where collapsible chat controls appeared as "loading," ensuring a smoother and more intuitive user experience for managing chat settings. + +### Changed + +- **🔧 Updated Ollama Model Creation**: Revamped the Ollama model creation method to align with their new JSON payload format, ensuring seamless compatibility and more efficient model setup workflows. + +## [0.5.5] - 2025-01-22 + +### Added + +- **🤔 Native 'Think' Tag Support**: Introduced the new 'think' tag support that visually displays how long the model is thinking, omitting the reasoning content itself until the next turn. Ideal for creating a more streamlined and focused interaction experience. +- **🖼️ Toggle Image Generation On/Off**: In the chat input menu, you can now easily toggle image generation before initiating chats, providing greater control and flexibility to suit your needs. +- **🔒 Chat Controls Permissions**: Admins can now disable chat controls access for users, offering tighter management and customization over user interactions. +- **🔍 Web Search & Image Generation Permissions**: Easily disable web search and image generation for specific users, improving workflow governance and security for certain environments. +- **🗂️ S3 and GCS Storage Provider Support**: Scaled deployments now benefit from expanded storage options with Amazon S3 and Google Cloud Storage seamlessly integrated as providers. +- **🎨 Enhanced Model Management**: Reintroduced the ability to download and delete models directly in the admin models settings page to minimize user confusion and aid efficient model management. +- **🔗 Improved Connection Handling**: Enhanced backend to smoothly handle multiple identical base URLs, allowing more flexible multi-instance configurations with fewer hiccups. +- **✨ General UI/UX Refinements**: Numerous tweaks across the WebUI make navigation and usability even more user-friendly and intuitive. +- **🌍 Translation Enhancements**: Various translation updates ensure smoother and more polished interactions for international users. + +### Fixed + +- **⚡ MPS Functionality for Mac Users**: Fixed MPS support, ensuring smooth performance and compatibility for Mac users leveraging MPS. +- **📡 Ollama Connection Management**: Resolved the issue where deleting all Ollama connections prevented adding new ones. + +### Changed + +- **⚙️ General Stability Refac**: Backend refactoring delivers a more stable, robust platform. +- **🖥️ Desktop App Preparations**: Ongoing work to support the upcoming Open WebUI desktop app. Follow our progress and updates here: https://github.com/open-webui/desktop + +## [0.5.4] - 2025-01-05 + +### Added + +- **🔄 Clone Shared Chats**: Effortlessly clone shared chats to save time and streamline collaboration, perfect for reusing insightful discussions or custom setups. +- **📣 Native Notifications for Channel Messages**: Stay informed with integrated desktop notifications for channel messages, ensuring you never miss important updates while multitasking. +- **🔥 Torch MPS Support**: MPS support for Mac users when Open WebUI is installed directly, offering better performance and compatibility for AI workloads. +- **🌍 Enhanced Translations**: Small improvements to various translations, ensuring a smoother global user experience. + +### Fixed + +- **🖼️ Image-Only Messages in Channels**: You can now send images without accompanying text or content in channels. +- **❌ Proper Exception Handling**: Enhanced error feedback by ensuring exceptions are raised clearly, reducing confusion and promoting smoother debugging. +- **🔍 RAG Query Generation Restored**: Fixed query generation issues for Retrieval-Augmented Generation, improving retrieval accuracy and ensuring seamless functionality. +- **📩 MOA Response Functionality Fixed**: Addressed an error with the MOA response generation feature. +- **💬 Channel Thread Loading with 50+ Messages**: Resolved an issue where channel threads stalled when exceeding 50 messages, ensuring smooth navigation in active discussions. +- **🔑 API Endpoint Restrictions Resolution**: Fixed a critical bug where the 'API_KEY_ALLOWED_ENDPOINTS' setting was not functioning as intended, ensuring API access is limited to specified endpoints for enhanced security. +- **🛠️ Action Functions Restored**: Corrected an issue preventing action functions from working, restoring their utility for customized automations and workflows. +- **📂 Temporary Chat JSON Export Fix**: Resolved a bug blocking temporary chats from being exported in JSON format, ensuring seamless data portability. + +### Changed + +- **🎛️ Sidebar UI Tweaks**: Chat folders, including pinned folders, now display below the Chats section for better organization; the "New Folder" button has been relocated to the Chats section for a more intuitive workflow. +- **🏗️ Real-Time Save Disabled by Default**: The 'ENABLE_REALTIME_CHAT_SAVE' setting is now off by default, boosting response speed for users who prioritize performance in high-paced workflows or less critical scenarios. +- **🎤 Audio Input Echo Cancellation**: Audio input now features echo cancellation enabled by default, reducing audio feedback for improved clarity during conversations or voice-based interactions. +- **🔧 General Reliability Improvements**: Numerous under-the-hood enhancements have been made to improve platform stability, boost overall performance, and ensure a more seamless, dependable experience across workflows. + +## [0.5.3] - 2024-12-31 + +### Added + +- **💬 Channel Reactions with Built-In Emoji Picker**: Easily express yourself in channel threads and messages with reactions, featuring an intuitive built-in emoji picker for seamless selection. +- **🧵 Threads for Channels**: Organize discussions within channels by creating threads, improving clarity and fostering focused conversations. +- **🔄 Reset Button for SVG Pan/Zoom**: Added a handy reset button to SVG Pan/Zoom, allowing users to quickly return diagrams or visuals to their default state without hassle. +- **⚡ Realtime Chat Save Environment Variable**: Introduced the ENABLE_REALTIME_CHAT_SAVE environment variable. Choose between faster responses by disabling realtime chat saving or ensuring chunk-by-chunk data persistency for critical operations. +- **🌍 Translation Enhancements**: Updated and refined translations across multiple languages, providing a smoother experience for international users. +- **📚 Improved Documentation**: Expanded documentation on functions, including clearer guidance on function plugins and detailed instructions for migrating to v0.5. This ensures users can adapt and harness new updates more effectively. (https://docs.openwebui.com/features/plugin/) + +### Fixed + +- **🛠️ Ollama Parameters Respected**: Resolved an issue where input parameters for Ollama were being ignored, ensuring precise and consistent model behavior. +- **🔧 Function Plugin Outlet Hook Reliability**: Fixed a bug causing issues with 'event_emitter' and outlet hooks in filter function plugins, guaranteeing smoother operation within custom extensions. +- **🖋️ Weird Custom Status Descriptions**: Adjusted the formatting and functionality for custom user statuses, ensuring they display correctly and intuitively. +- **🔗 Restored API Functionality**: Fixed a critical issue where APIs were not operational for certain configurations, ensuring uninterrupted access. +- **⏳ Custom Pipe Function Completion**: Resolved an issue where chats using specific custom pipe function plugins weren’t finishing properly, restoring consistent chat workflows. +- **✅ General Stability Enhancements**: Implemented various under-the-hood improvements to boost overall reliability, ensuring smoother and more consistent performance across the WebUI. + +## [0.5.2] - 2024-12-26 + +### Added + +- **🖊️ Typing Indicators in Channels**: Know exactly who’s typing in real-time within your channels, enhancing collaboration and keeping everyone engaged. +- **👤 User Status Indicators**: Quickly view a user’s status by clicking their profile image in channels for better coordination and availability insights. +- **🔒 Configurable API Key Authentication Restrictions**: Flexibly configure endpoint restrictions for API key authentication, now off by default for a smoother setup in trusted environments. + +### Fixed + +- **🔧 Playground Functionality Restored**: Resolved a critical issue where the playground wasn’t working, ensuring seamless experimentation and troubleshooting workflows. +- **📊 Corrected Ollama Usage Statistics**: Fixed a calculation error in Ollama’s usage statistics, providing more accurate tracking and insights for better resource management. +- **🔗 Pipelines Outlet Hook Registration**: Addressed an issue where outlet hooks for pipelines weren’t registered, restoring functionality and consistency in pipeline workflows. +- **🎨 Image Generation Error**: Resolved a persistent issue causing errors with 'get_automatic1111_api_auth()' to ensure smooth image generation workflows. +- **🎙️ Text-to-Speech Error**: Fixed the missing argument in Eleven Labs’ 'get_available_voices()', restoring full text-to-speech capabilities for uninterrupted voice interactions. +- **🖋️ Title Generation Issue**: Fixed a bug where title generation was not working in certain cases, ensuring consistent and reliable chat organization. + +## [0.5.1] - 2024-12-25 + +### Added + +- **🔕 Notification Sound Toggle**: Added a new setting under Settings > Interface to disable notification sounds, giving you greater control over your workspace environment and focus. + +### Fixed + +- **🔄 Non-Streaming Response Visibility**: Resolved an issue where non-streaming responses were not displayed, ensuring all responses are now reliably shown in your conversations. +- **🖋️ Title Generation with OpenAI APIs**: Fixed a bug preventing title generation when using OpenAI APIs, restoring the ability to automatically generate chat titles for smoother organization. +- **👥 Admin Panel User List**: Addressed the issue where only 50 users were visible in the admin panel. You can now manage and view all users without restrictions. +- **🖼️ Image Generation Error**: Fixed the issue causing 'get_automatic1111_api_auth()' errors in image generation, ensuring seamless creative workflows. +- **⚙️ Pipeline Settings Loading Issue**: Resolved a problem where pipeline settings were stuck at the loading screen, restoring full configurability in the admin panel. + +## [0.5.0] - 2024-12-25 + +### Added + +- **💬 True Asynchronous Chat Support**: Create chats, navigate away, and return anytime with responses ready. Ideal for reasoning models and multi-agent workflows, enhancing multitasking like never before. +- **🔔 Chat Completion Notifications**: Never miss a completed response. Receive instant in-UI notifications when a chat finishes in a non-active tab, keeping you updated while you work elsewhere. +- **🌐 Notification Webhook Integration**: Get alerts via webhooks even when your tab is closed! Configure your webhook URL in Settings > Account and receive timely updates for long-running chats or external integration needs. +- **📚 Channels (Beta)**: Explore Discord/Slack-style chat rooms designed for real-time collaboration between users and AIs. Build bots for channels and unlock asynchronous communication for proactive multi-agent workflows. Opt-in via Admin Settings > General. A Comprehensive Bot SDK tutorial (https://github.com/open-webui/bot) is incoming, so stay tuned! +- **🖼️ Client-Side Image Compression**: Now compress images before upload (Settings > Interface), saving bandwidth and improving performance seamlessly. +- **🛠️ OAuth Management for User Groups**: Enable group-level management via OAuth integration for enhanced control and scalability in collaborative environments. +- **✅ Structured Output for Ollama**: Pass structured data output directly to Ollama, unlocking new possibilities for streamlined automation and precise data handling. +- **📜 Offline Swagger Documentation**: Developer-friendly Swagger API docs are now available offline, ensuring full accessibility wherever you are. +- **📸 Quick Screen Capture Button**: Effortlessly capture your screen with a single click from the message input menu. +- **🌍 i18n Updates**: Improved and refined translations across several languages, including Ukrainian, German, Brazilian Portuguese, Catalan, and more, ensuring a seamless global user experience. + +### Fixed + +- **📋 Table Export to CSV**: Resolved issues with CSV export where headers were missing or errors occurred due to values with commas, ensuring smooth and reliable data handling. +- **🔓 BYPASS_MODEL_ACCESS_CONTROL**: Fixed an issue where users could see models but couldn’t use them with 'BYPASS_MODEL_ACCESS_CONTROL=True', restoring proper functionality for environments leveraging this setting. + +### Changed + +- **💡 API Key Authentication Restriction**: Narrowed API key auth permissions to '/api/models' and '/api/chat/completions' for enhanced security and better API governance. +- **⚙️ Backend Overhaul for Performance**: Major backend restructuring; a heads-up that some "Functions" using internal variables may face compatibility issues. Moving forward, websocket support is mandatory to ensure Open WebUI operates seamlessly. + +### Removed + +- **⚠️ Legacy Functionality Clean-Up**: Deprecated outdated backend systems that were non-essential or overlapped with newer implementations, allowing for a leaner, more efficient platform. + +## [0.4.8] - 2024-12-07 + +### Added + +- **🔓 Bypass Model Access Control**: Introduced the 'BYPASS_MODEL_ACCESS_CONTROL' environment variable. Easily bypass model access controls for user roles when access control isn't required, simplifying workflows for trusted environments. +- **📝 Markdown in Banners**: Now supports markdown for banners, enabling richer, more visually engaging announcements. +- **🌐 Internationalization Updates**: Enhanced translations across multiple languages, further improving accessibility and global user experience. +- **🎨 Styling Enhancements**: General UI style refinements for a cleaner and more polished interface. +- **📋 Rich Text Reliability**: Improved the reliability and stability of rich text input across chats for smoother interactions. + +### Fixed + +- **💡 Tailwind Build Issue**: Resolved a breaking bug caused by Tailwind, ensuring smoother builds and overall system reliability. +- **📚 Knowledge Collection Query Fix**: Addressed API endpoint issues with querying knowledge collections, ensuring accurate and reliable information retrieval. + +## [0.4.7] - 2024-12-01 + +### Added + +- **✨ Prompt Input Auto-Completion**: Type a prompt and let AI intelligently suggest and complete your inputs. Simply press 'Tab' or swipe right on mobile to confirm. Available only with Rich Text Input (default setting). Disable via Admin Settings for full control. +- **🌍 Improved Translations**: Enhanced localization for multiple languages, ensuring a more polished and accessible experience for international users. + +### Fixed + +- **🛠️ Tools Export Issue**: Resolved a critical issue where exporting tools wasn’t functioning, restoring seamless export capabilities. +- **🔗 Model ID Registration**: Fixed an issue where model IDs weren’t registering correctly in the model editor, ensuring reliable model setup and tracking. +- **🖋️ Textarea Auto-Expansion**: Corrected a bug where textareas didn’t expand automatically on certain browsers, improving usability for multi-line inputs. +- **🔧 Ollama Embed Endpoint**: Addressed the /ollama/embed endpoint malfunction, ensuring consistent performance and functionality. + +### Changed + +- **🎨 Knowledge Base Styling**: Refined knowledge base visuals for a cleaner, more modern look, laying the groundwork for further enhancements in upcoming releases. + +## [0.4.6] - 2024-11-26 + +### Added + +- **🌍 Enhanced Translations**: Various language translations improved to make the WebUI more accessible and user-friendly worldwide. + +### Fixed + +- **✏️ Textarea Shifting Bug**: Resolved the issue where the textarea shifted unexpectedly, ensuring a smoother typing experience. +- **⚙️ Model Configuration Modal**: Fixed the issue where the models configuration modal introduced in 0.4.5 wasn’t working for some users. +- **🔍 Legacy Query Support**: Restored functionality for custom query generation in RAG when using legacy prompts, ensuring both default and custom templates now work seamlessly. +- **⚡ Improved General Reliability**: Various minor fixes improve platform stability and ensure a smoother overall experience across workflows. + +## [0.4.5] - 2024-11-26 + +### Added + +- **🎨 Model Order/Defaults Reintroduced**: Brought back the ability to set model order and default models, now configurable via Admin Settings > Models > Configure (Gear Icon). + +### Fixed + +- **🔍 Query Generation Issue**: Resolved an error in web search query generation, enhancing search accuracy and ensuring smoother search workflows. +- **📏 Textarea Auto Height Bug**: Fixed a layout issue where textarea input height was shifting unpredictably, particularly when editing system prompts. +- **🔑 Ollama Authentication**: Corrected an issue with Ollama’s authorization headers, guaranteeing reliable authentication across all endpoints. +- **⚙️ Missing Min_P Save**: Resolved an issue where the 'min_p' parameter was not being saved in configurations. +- **🛠️ Tools Description**: Fixed a key issue that omitted tool descriptions in tools payload. + +## [0.4.4] - 2024-11-22 + +### Added + +- **🌐 Translation Updates**: Refreshed Catalan, Brazilian Portuguese, German, and Ukrainian translations, further enhancing the platform's accessibility and improving the experience for international users. + +### Fixed + +- **📱 Mobile Controls Visibility**: Resolved an issue where the controls button was not displaying on the new chats page for mobile users, ensuring smoother navigation and functionality on smaller screens. +- **📷 LDAP Profile Image Issue**: Fixed an LDAP integration bug related to profile images, ensuring seamless authentication and a reliable login experience for users. +- **⏳ RAG Query Generation Issue**: Addressed a significant problem where RAG query generation occurred unnecessarily without attached files, drastically improving speed and reducing delays during chat completions. + +### Changed + +- **⚙️ Legacy Event Emitter Support**: Reintroduced compatibility with legacy "citation" types for event emitters in tools and functions, providing smoother workflows and broader tool support for users. + +## [0.4.3] - 2024-11-21 + +### Added + +- **📚 Inline Citations for RAG Results**: Get seamless inline citations for Retrieval-Augmented Generation (RAG) responses using the default RAG prompt. Note: This feature only supports newly uploaded files, improving traceability and providing source clarity. +- **🎨 Better Rich Text Input Support**: Enjoy smoother and more reliable rich text formatting for chats, enhancing communication quality. +- **⚡ Faster Model Retrieval**: Implemented caching optimizations for faster model loading, providing a noticeable speed boost across workflows. Further improvements are on the way! + +### Fixed + +- **🔗 Pipelines Feature Restored**: Resolved a critical issue that previously prevented Pipelines from functioning, ensuring seamless workflows. +- **✏️ Missing Suffix Field in Ollama Form**: Added the missing "suffix" field to the Ollama generate form, enhancing customization options. + +### Changed + +- **🗂️ Renamed "Citations" to "Sources"**: Improved clarity and consistency by renaming the "citations" field to "sources" in messages. + +## [0.4.2] - 2024-11-20 + +### Fixed + +- **📁 Knowledge Files Visibility Issue**: Resolved the bug preventing individual files in knowledge collections from displaying when referenced with '#'. +- **🔗 OpenAI Endpoint Prefix**: Fixed the issue where certain OpenAI connections that deviate from the official API spec weren’t working correctly with prefixes. +- **⚔️ Arena Model Access Control**: Corrected an issue where arena model access control settings were not being saved. +- **🔧 Usage Capability Selector**: Fixed the broken usage capabilities selector in the model editor. + +## [0.4.1] - 2024-11-19 + +### Added + +- **📊 Enhanced Feedback System**: Introduced a detailed 1-10 rating scale for feedback alongside thumbs up/down, preparing for more precise model fine-tuning and improving feedback quality. +- **ℹ️ Tool Descriptions on Hover**: Easily access tool descriptions by hovering over the message input, providing a smoother workflow with more context when utilizing tools. + +### Fixed + +- **🗑️ Graceful Handling of Deleted Users**: Resolved an issue where deleted users caused workspace items (models, knowledge, prompts, tools) to fail, ensuring reliable workspace loading. +- **🔑 API Key Creation**: Fixed an issue preventing users from creating new API keys, restoring secure and seamless API management. +- **🔗 HTTPS Proxy Fix**: Corrected HTTPS proxy issues affecting the '/api/v1/models/' endpoint, ensuring smoother, uninterrupted model management. + +## [0.4.0] - 2024-11-19 + +### Added + +- **👥 User Groups**: You can now create and manage user groups, making user organization seamless. +- **🔐 Group-Based Access Control**: Set granular access to models, knowledge, prompts, and tools based on user groups, allowing for more controlled and secure environments. +- **🛠️ Group-Based User Permissions**: Easily manage workspace permissions. Grant users the ability to upload files, delete, edit, or create temporary chats, as well as define their ability to create models, knowledge, prompts, and tools. +- **🔑 LDAP Support**: Newly introduced LDAP authentication adds robust security and scalability to user management. +- **🌐 Enhanced OpenAI-Compatible Connections**: Added prefix ID support to avoid model ID clashes, with explicit model ID support for APIs lacking '/models' endpoint support, ensuring smooth operation with custom setups. +- **🔐 Ollama API Key Support**: Now manage credentials for Ollama when set behind proxies, including the option to utilize prefix ID for proper distinction across multiple Ollama instances. +- **🔄 Connection Enable/Disable Toggle**: Easily enable or disable individual OpenAI and Ollama connections as needed. +- **🎨 Redesigned Model Workspace**: Freshly redesigned to improve usability for managing models across users and groups. +- **🎨 Redesigned Prompt Workspace**: A fresh UI to conveniently organize and manage prompts. +- **🧩 Sorted Functions Workspace**: Functions are now automatically categorized by type (Action, Filter, Pipe), streamlining management. +- **💻 Redesigned Collaborative Workspace**: Enhanced support for multiple users contributing to models, knowledge, prompts, or tools, improving collaboration. +- **🔧 Auto-Selected Tools in Model Editor**: Tools enabled through the model editor are now automatically selected, whereas previously it only gave users the option to enable the tool, reducing manual steps and enhancing efficiency. +- **🔔 Web Search & Tools Indicator**: A clear indication now shows when web search or tools are active, reducing confusion. +- **🔑 Toggle API Key Auth**: Tighten security by easily enabling or disabling API key authentication option for Open WebUI. +- **🗂️ Agentic Retrieval**: Improve RAG accuracy via smart pre-processing of chat history to determine the best queries before retrieval. +- **📁 Large Text as File Option**: Optionally convert large pasted text into a file upload, keeping the chat interface cleaner. +- **🗂️ Toggle Citations for Models**: Ability to disable citations has been introduced in the model editor. +- **🔍 User Settings Search**: Quickly search for settings fields, improving ease of use and navigation. +- **🗣️ Experimental SpeechT5 TTS**: Local SpeechT5 support added for improved text-to-speech capabilities. +- **🔄 Unified Reset for Models**: A one-click option has been introduced to reset and remove all models from the Admin Settings. +- **🛠️ Initial Setup Wizard**: The setup process now explicitly informs users that they are creating an admin account during the first-time setup, ensuring clarity. Previously, users encountered the login page right away without this distinction. +- **🌐 Enhanced Translations**: Several language translations, including Ukrainian, Norwegian, and Brazilian Portuguese, were refined for better localization. + +### Fixed + +- **🎥 YouTube Video Attachments**: Fixed issues preventing proper loading and attachment of YouTube videos as files. +- **🔄 Shared Chat Update**: Corrected issues where shared chats were not updating, improving collaboration consistency. +- **🔍 DuckDuckGo Rate Limit Fix**: Addressed issues with DuckDuckGo search integration, enhancing search stability and performance when operating within rate limits. +- **🧾 Citations Relevance Fix**: Adjusted the relevance percentage calculation for citations, so that Open WebUI properly reflect the accuracy of a retrieved document in RAG, ensuring users get clearer insights into sources. +- **🔑 Jina Search API Key Requirement**: Added the option to input an API key for Jina Search, ensuring smooth functionality as keys are now mandatory. + +### Changed + +- **🛠️ Functions Moved to Admin Panel**: As Functions operate as advanced plugins, they are now accessible from the Admin Panel instead of the workspace. +- **🛠️ Manage Ollama Connections**: The "Models" section in Admin Settings has been relocated to Admin Settings > "Connections" > Ollama Connections. You can now manage Ollama instances via a dedicated "Manage Ollama" modal from "Connections", streamlining the setup and configuration of Ollama models. +- **📊 Base Models in Admin Settings**: Admins can now find all base models, both connections or functions, in the "Models" Admin setting. Global model accessibility can be enabled or disabled here. Models are private by default, requiring explicit permission assignment for user access. +- **📌 Sticky Model Selection for New Chats**: The model chosen from a previous chat now persists when creating a new chat. If you click "New Chat" again from the new chat page, it will revert to your default model. +- **🎨 Design Refactoring**: Overall design refinements across the platform have been made, providing a more cohesive and polished user experience. + +### Removed + +- **📂 Model List Reordering**: Temporarily removed and will be reintroduced in upcoming user group settings improvements. +- **⚙️ Default Model Setting**: Removed the ability to set a default model for users, will be reintroduced with user group settings in the future. + +## [0.3.35] - 2024-10-26 + +### Added + +- **🌐 Translation Update**: Added translation labels in the SearchInput and CreateCollection components and updated Brazilian Portuguese translation (pt-BR) +- **📁 Robust File Handling**: Enhanced file input handling for chat. If the content extraction fails or is empty, users will now receive a clear warning, preventing silent failures and ensuring you always know what's happening with your uploads. +- **🌍 New Language Support**: Introduced Hungarian translations and updated French translations, expanding the platform's language accessibility for a more global user base. + +### Fixed + +- **📚 Knowledge Base Loading Issue**: Resolved a critical bug where the Knowledge Base was not loading, ensuring smooth access to your stored documents and improving information retrieval in RAG-enhanced workflows. +- **🛠️ Tool Parameters Issue**: Fixed an error where tools were not functioning correctly when required parameters were missing, ensuring reliable tool performance and more efficient task completions. +- **🔗 Merged Response Loss in Multi-Model Chats**: Addressed an issue where responses in multi-model chat workflows were being deleted after follow-up queries, improving consistency and ensuring smoother interactions across models. + +## [0.3.34] - 2024-10-26 + +### Added + +- **🔧 Feedback Export Enhancements**: Feedback history data can now be exported to JSON, allowing for seamless integration in RLHF processing and further analysis. +- **🗂️ Embedding Model Lazy Loading**: Search functionality for leaderboard reranking is now more efficient, as embedding models are lazy-loaded only when needed, optimizing performance. +- **🎨 Rich Text Input Toggle**: Users can now switch back to legacy textarea input for chat if they prefer simpler text input, though rich text is still the default until deprecation. +- **🛠️ Improved Tool Calling Mechanism**: Enhanced method for parsing and calling tools, improving the reliability and robustness of tool function calls. +- **🌐 Globalization Enhancements**: Updates to internationalization (i18n) support, further refining multi-language compatibility and accuracy. + +### Fixed + +- **🖥️ Folder Rename Fix for Firefox**: Addressed a persistent issue where users could not rename folders by pressing enter in Firefox, now ensuring seamless folder management across browsers. +- **🔠 Tiktoken Model Text Splitter Issue**: Resolved an issue where the tiktoken text splitter wasn’t working in Docker installations, restoring full functionality for tokenized text editing. +- **💼 S3 File Upload Issue**: Fixed a problem affecting S3 file uploads, ensuring smooth operations for those who store files on cloud storage. +- **🔒 Strict-Transport-Security Crash**: Resolved a crash when setting the Strict-Transport-Security (HSTS) header, improving stability and security enhancements. +- **🚫 OIDC Boolean Access Fix**: Addressed an issue with boolean values not being accessed correctly during OIDC logins, ensuring login reliability. +- **⚙️ Rich Text Paste Behavior**: Refined paste behavior in rich text input to make it smoother and more intuitive when pasting various content types. +- **🔨 Model Exclusion for Arena Fix**: Corrected the filter function that was not properly excluding models from the arena, improving model management. +- **🏷️ "Tags Generation Prompt" Fix**: Addressed an issue preventing custom "tags generation prompts" from registering properly, ensuring custom prompt work seamlessly. + +## [0.3.33] - 2024-10-24 + +### Added + +- **🏆 Evaluation Leaderboard**: Easily track your performance through a new leaderboard system where your ratings contribute to a real-time ranking based on the Elo system. Sibling responses (regenerations, many model chats) are required for your ratings to count in the leaderboard. Additionally, you can opt-in to share your feedback history and be part of the community-wide leaderboard. Expect further improvements as we refine the algorithm—help us build the best community leaderboard! +- **⚔️ Arena Model Evaluation**: Enable blind A/B testing of models directly from Admin Settings > Evaluation for a true side-by-side comparison. Ideal for pinpointing the best model for your needs. +- **🎯 Topic-Based Leaderboard**: Discover more accurate rankings with experimental topic-based reranking, which adjusts leaderboard standings based on tag similarity in feedback. Get more relevant insights based on specific topics! +- **📁 Folders Support for Chats**: Organize your chats better by grouping them into folders. Drag and drop chats between folders and export them seamlessly for easy sharing or analysis. +- **📤 Easy Chat Import via Drag & Drop**: Save time by simply dragging and dropping chat exports (JSON) directly onto the sidebar to import them into your workspace—streamlined, efficient, and intuitive! +- **📚 Enhanced Knowledge Collection**: Now, you can reference individual files from a knowledge collection—ideal for more precise Retrieval-Augmented Generations (RAG) queries and document analysis. +- **🏷️ Enhanced Tagging System**: Tags now take up less space! Utilize the new 'tag:' query system to manage, search, and organize your conversations more effectively without cluttering the interface. +- **🧠 Auto-Tagging for Chats**: Your conversations are now automatically tagged for improved organization, mirroring the efficiency of auto-generated titles. +- **🔍 Backend Chat Query System**: Chat filtering has become more efficient, now handled through the backend\*\* instead of your browser, improving search performance and accuracy. +- **🎮 Revamped Playground**: Experience a refreshed and optimized Playground for smoother testing, tweaks, and experimentation of your models and tools. +- **🧩 Token-Based Text Splitter**: Introducing token-based text splitting (tiktoken), giving you more precise control over how text is processed. Previously, only character-based splitting was available. +- **🔢 Ollama Batch Embeddings**: Leverage new batch embedding support for improved efficiency and performance with Ollama embedding models. +- **🔍 Enhanced Add Text Content Modal**: Enjoy a cleaner, more intuitive workflow for adding and curating knowledge content with an upgraded input modal from our Knowledge workspace. +- **🖋️ Rich Text Input for Chats**: Make your chat inputs more dynamic with support for rich text formatting. Your conversations just got a lot more polished and professional. +- **⚡ Faster Whisper Model Configurability**: Customize your local faster whisper model directly from the WebUI. +- **☁️ Experimental S3 Support**: Enable stateless WebUI instances with S3 support, greatly enhancing scalability and balancing heavy workloads. +- **🔕 Disable Update Toast**: Now you can streamline your workspace even further—choose to disable update notifications for a more focused experience. +- **🌟 RAG Citation Relevance Percentage**: Easily assess citation accuracy with the addition of relevance percentages in RAG results. +- **⚙️ Mermaid Copy Button**: Mermaid diagrams now come with a handy copy button, simplifying the extraction and use of diagram contents directly in your workflow. +- **🎨 UI Redesign**: Major interface redesign that will make navigation smoother, keep your focus where it matters, and ensure a modern look. + +### Fixed + +- **🎙️ Voice Note Mic Stopping Issue**: Fixed the issue where the microphone stayed active after ending a voice note recording, ensuring your audio workflow runs smoothly. + +### Removed + +- **👋 Goodbye Sidebar Tags**: Sidebar tag clutter is gone. We’ve shifted tag buttons to more effective query-based tag filtering for a sleeker, more agile interface. + +## [0.3.32] - 2024-10-06 + +### Added + +- **🔢 Workspace Enhancements**: Added a display count for models, prompts, tools, and functions in the workspace, providing a clear overview and easier management. + +### Fixed + +- **🖥️ Web and YouTube Attachment Fix**: Resolved an issue where attaching web links and YouTube videos was malfunctioning, ensuring seamless integration and display within chats. +- **📞 Call Mode Activation on Landing Page**: Fixed a bug where call mode was not operational from the landing page. + +### Changed + +- **🔄 URL Parameter Refinement**: Updated the 'tool_ids' URL parameter to 'tools' or 'tool-ids' for more intuitive and consistent user experience. +- **🎨 Floating Buttons Styling Update**: Refactored the styling of floating buttons to intelligently adjust to the left side when there isn't enough room on the right, improving interface usability and aesthetic. +- **🔧 Enhanced Accessibility for Floating Buttons**: Implemented the ability to close floating buttons with the 'Esc' key, making workflow smoother and more efficient for users navigating via keyboard. +- **🖇️ Updated Information URL**: Information URLs now direct users to a general release page rather than a version-specific URL, ensuring access to the latest and relevant details all in one place. +- **📦 Library Dependencies Update**: Upgraded dependencies to ensure compatibility and performance optimization for pip installs. + +## [0.3.31] - 2024-10-06 + +### Added + +- **📚 Knowledge Feature**: Reimagined documents feature, now more performant with a better UI for enhanced organization; includes streamlined API integration for Retrieval-Augmented Generation (RAG). Detailed documentation forthcoming: https://docs.openwebui.com/ +- **🌐 New Landing Page**: Freshly designed landing page; toggle between the new UI and the classic chat UI from Settings > Interface for a personalized experience. +- **📁 Full Document Retrieval Mode**: Toggle between full document retrieval or traditional snippets by clicking on the file item. This mode enhances document capabilities and supports comprehensive tasks like summarization by utilizing the entire content instead of RAG. +- **📄 Extracted File Content Display**: View extracted content directly by clicking on the file item, simplifying file analysis. +- **🎨 Artifacts Feature**: Render web content and SVGs directly in the interface, supporting quick iterations and live changes. +- **🖊️ Editable Code Blocks**: Supercharged code blocks now allow live editing directly in the LLM response, with live reloads supported by artifacts. +- **🔧 Code Block Enhancements**: Introduced a floating copy button in code blocks to facilitate easier code copying without scrolling. +- **🔍 SVG Pan/Zoom**: Enhanced interaction with SVG images, including Mermaid diagrams, via new pan and zoom capabilities. +- **🔍 Text Select Quick Actions**: New floating buttons appear when text is highlighted in LLM responses, offering deeper interactions like "Ask a Question" or "Explain". +- **🗃️ Database Pool Configuration**: Enhanced database handling to support scalable user growth. +- **🔊 Experimental Audio Compression**: Compress audio files to navigate around the 25MB limit for OpenAI's speech-to-text processing. +- **🔍 Query Embedding**: Adjusted embedding behavior to enhance system performance by not repeating query embedding. +- **💾 Lazy Load Optimizations**: Implemented lazy loading of large dependencies to minimize initial memory usage, boosting performance. +- **🍏 Apple Touch Icon Support**: Optimizes the display of icons for web bookmarks on Apple mobile devices. +- **🔽 Expandable Content Markdown Support**: Introducing 'details', 'summary' tag support for creating expandable content sections in markdown, facilitating cleaner, organized documentation and interactive content display. + +### Fixed + +- **🔘 Action Button Issue**: Resolved a bug where action buttons were not functioning, enhancing UI reliability. +- **🔄 Multi-Model Chat Loop**: Fixed an infinite loop issue in multi-model chat environments, ensuring smoother chat operations. +- **📄 Chat PDF/TXT Export Issue**: Resolved problems with exporting chat logs to PDF and TXT formats. +- **🔊 Call to Text-to-Speech Issues**: Rectified problems with text-to-speech functions to improve audio interactions. + +### Changed + +- **⚙️ Endpoint Renaming**: Renamed 'rag' endpoints to 'retrieval' for clearer function description. +- **🎨 Styling and Interface Updates**: Multiple refinements across the platform to enhance visual appeal and user interaction. + +### Removed + +- **🗑️ Deprecated 'DOCS_DIR'**: Removed the outdated 'docs_dir' variable in favor of more direct file management solutions, with direct file directory syncing and API uploads for a more integrated experience. + +## [0.3.30] - 2024-09-26 + +### Fixed + +- **🍞 Update Available Toast Dismissal**: Enhanced user experience by ensuring that once the update available notification is dismissed, it won't reappear for 24 hours. +- **📋 Ollama /embed Form Data**: Adjusted the integration inaccuracies in the /embed form data to ensure it perfectly matches with Ollama's specifications. +- **🔧 O1 Max Completion Tokens Issue**: Resolved compatibility issues with OpenAI's o1 models max_completion_tokens param to ensure smooth operation. +- **🔄 Pip Install Database Issue**: Fixed a critical issue where database changes during pip installations were reverting and not saving chat logs, now ensuring data persistence and reliability in chat operations. +- **🏷️ Chat Rename Tab Update**: Fixed the functionality to change the web browser's tab title simultaneously when a chat is renamed, keeping tab titles consistent. + +## [0.3.29] - 2023-09-25 + +### Fixed + +- **🔧 KaTeX Rendering Improvement**: Resolved specific corner cases in KaTeX rendering to enhance the display of complex mathematical notation. +- **📞 'Call' URL Parameter Fix**: Corrected functionality for 'call' URL search parameter ensuring reliable activation of voice calls through URL triggers. +- **🔄 Configuration Reset Fix**: Fixed the RESET_CONFIG_ON_START to ensure settings revert to default correctly upon each startup, improving reliability in configuration management. +- **🌍 Filter Outlet Hook Fix**: Addressed issues in the filter outlet hook, ensuring all filter functions operate as intended. + +## [0.3.28] - 2024-09-24 + +### Fixed + +- **🔍 Web Search Functionality**: Corrected an issue where the web search option was not functioning properly. + +## [0.3.27] - 2024-09-24 + +### Fixed + +- **🔄 Periodic Cleanup Error Resolved**: Fixed a critical RuntimeError related to the 'periodic_usage_pool_cleanup' coroutine, ensuring smooth and efficient performance post-pip install, correcting a persisting issue from version 0.3.26. +- **📊 Enhanced LaTeX Rendering**: Improved rendering for LaTeX content, enhancing clarity and visual presentation in documents and mathematical models. + +## [0.3.26] - 2024-09-24 + +### Fixed + +- **🔄 Event Loop Error Resolution**: Addressed a critical error where a missing running event loop caused 'periodic_usage_pool_cleanup' to fail with pip installs. This fix ensures smoother and more reliable updates and installations, enhancing overall system stability. + +## [0.3.25] - 2024-09-24 + +### Fixed + +- **🖼️ Image Generation Functionality**: Resolved an issue where image generation was not functioning, restoring full capability for visual content creation. +- **⚖️ Rate Response Corrections**: Addressed a problem where rate responses were not working, ensuring reliable feedback mechanisms are operational. + +## [0.3.24] - 2024-09-24 + +### Added + +- **🚀 Rendering Optimization**: Significantly improved message rendering performance, enhancing user experience and webui responsiveness. +- **💖 Favorite Response Feature in Chat Overview**: Users can now mark responses as favorite directly from the chat overview, enhancing ease of retrieval and organization of preferred responses. +- **💬 Create Message Pairs with Shortcut**: Implemented creation of new message pairs using Cmd/Ctrl+Shift+Enter, making conversation editing faster and more intuitive. +- **🌍 Expanded User Prompt Variables**: Added weekday, timezone, and language information variables to user prompts to match system prompt variables. +- **🎵 Enhanced Audio Support**: Now includes support for 'audio/x-m4a' files, broadening compatibility with audio content within the platform. +- **🔏 Model URL Search Parameter**: Added an ability to select a model directly via URL parameters, streamlining navigation and model access. +- **📄 Enhanced PDF Citations**: PDF citations now open at the associated page, streamlining reference checks and document handling. +- **🔧Use of Redis in Sockets**: Enhanced socket implementation to fully support Redis, enabling effective stateless instances suitable for scalable load balancing. +- **🌍 Stream Individual Model Responses**: Allows specific models to have individualized streaming settings, enhancing performance and customization. +- **🕒 Display Model Hash and Last Modified Timestamp for Ollama Models**: Provides critical model details directly in the Models workspace for enhanced tracking. +- **❗ Update Info Notification for Admins**: Ensures administrators receive immediate updates upon login, keeping them informed of the latest changes and system statuses. + +### Fixed + +- **🗑️ Temporary File Handling On Windows**: Fixed an issue causing errors when accessing a temporary file being used by another process, Tools & Functions should now work as intended. +- **🔓 Authentication Toggle Issue**: Resolved the malfunction where setting 'WEBUI_AUTH=False' did not appropriately disable authentication, ensuring that user experience and system security settings function as configured. +- **🔧 Save As Copy Issue for Many Model Chats**: Resolved an error preventing users from save messages as copies in many model chats. +- **🔒 Sidebar Closure on Mobile**: Resolved an issue where the mobile sidebar remained open after menu engagement, improving user interface responsivity and comfort. +- **🛡️ Tooltip XSS Vulnerability**: Resolved a cross-site scripting (XSS) issue within tooltips, ensuring enhanced security and data integrity during user interactions. + +### Changed + +- **↩️ Deprecated Interface Stream Response Settings**: Moved to advanced parameters to streamline interface settings and enhance user clarity. +- **⚙️ Renamed 'speedRate' to 'playbackRate'**: Standardizes terminology, improving usability and understanding in media settings. + +## [0.3.23] - 2024-09-21 + +### Added + +- **🚀 WebSocket Redis Support**: Enhanced load balancing capabilities for multiple instance setups, promoting better performance and reliability in WebUI. +- **🔧 Adjustable Chat Controls**: Introduced width-adjustable chat controls, enabling a personalized and more comfortable user interface. +- **🌎 i18n Updates**: Improved and updated the Chinese translations. + +### Fixed + +- **🌐 Task Model Unloading Issue**: Modified task handling to use the Ollama /api/chat endpoint instead of OpenAI compatible endpoint, ensuring models stay loaded and ready with custom parameters, thus minimizing delays in task execution. +- **📝 Title Generation Fix for OpenAI Compatible APIs**: Resolved an issue preventing the generation of titles, enhancing consistency and reliability when using multiple API providers. +- **🗃️ RAG Duplicate Collection Issue**: Fixed a bug causing repeated processing of the same uploaded file. Now utilizes indexed files to prevent unnecessary duplications, optimizing resource usage. +- **🖼️ Image Generation Enhancement**: Refactored OpenAI image generation endpoint to be asynchronous, preventing the WebUI from becoming unresponsive during processing, thus enhancing user experience. +- **🔓 Downgrade Authlib**: Reverted Authlib to version 1.3.1 to address and resolve issues concerning OAuth functionality. + +### Changed + +- **🔍 Improved Message Interaction**: Enhanced the message node interface to allow for easier focus redirection with a simple click, streamlining user interaction. +- **✨ Styling Refactor**: Updated WebUI styling for a cleaner, more modern look, enhancing user experience across the platform. + +## [0.3.22] - 2024-09-19 + +### Added + +- **⭐ Chat Overview**: Introducing a node-based interactive messages diagram for improved visualization of conversation flows. +- **🔗 Multiple Vector DB Support**: Now supports multiple vector databases, including the newly added Milvus support. Community contributions for additional database support are highly encouraged! +- **📡 Experimental Non-Stream Chat Completion**: Experimental feature allowing the use of OpenAI o1 models, which do not support streaming, ensuring more versatile model deployment. +- **🔍 Experimental Colbert-AI Reranker Integration**: Added support for "jinaai/jina-colbert-v2" as a reranker, enhancing search relevance and accuracy. Note: it may not function at all on low-spec computers. +- **🕸️ ENABLE_WEBSOCKET_SUPPORT**: Added environment variable for instances to ignore websocket upgrades, stabilizing connections on platforms with websocket issues. +- **🔊 Azure Speech Service Integration**: Added support for Azure Speech services for Text-to-Speech (TTS). +- **🎚️ Customizable Playback Speed**: Playback speed control is now available in Call mode settings, allowing users to adjust audio playback speed to their preferences. +- **🧠 Enhanced Error Messaging**: System now displays helpful error messages directly to users during chat completion issues. +- **📂 Save Model as Transparent PNG**: Model profile images are now saved as PNGs, supporting transparency and improving visual integration. +- **📱 iPhone Compatibility Adjustments**: Added padding to accommodate the iPhone navigation bar, improving UI display on these devices. +- **🔗 Secure Response Headers**: Implemented security response headers, bolstering web application security. +- **🔧 Enhanced AUTOMATIC1111 Settings**: Users can now configure 'CFG Scale', 'Sampler', and 'Scheduler' parameters directly in the admin settings, enhancing workflow flexibility without source code modifications. +- **🌍 i18n Updates**: Enhanced translations for Chinese, Ukrainian, Russian, and French, fostering a better localized experience. + +### Fixed + +- **🛠️ Chat Message Deletion**: Resolved issues with chat message deletion, ensuring a smoother user interaction and system stability. +- **🔢 Ordered List Numbering**: Fixed the incorrect ordering in lists. + +### Changed + +- **🎨 Transparent Icon Handling**: Allowed model icons to be displayed on transparent backgrounds, improving UI aesthetics. +- **📝 Improved RAG Template**: Enhanced Retrieval-Augmented Generation template, optimizing context handling and error checking for more precise operation. + +## [0.3.21] - 2024-09-08 + +### Added + +- **📊 Document Count Display**: Now displays the total number of documents directly within the dashboard. +- **🚀 Ollama Embed API Endpoint**: Enabled /api/embed endpoint proxy support. + +### Fixed + +- **🐳 Docker Launch Issue**: Resolved the problem preventing Open-WebUI from launching correctly when using Docker. + +### Changed + +- **🔍 Enhanced Search Prompts**: Improved the search query generation prompts for better accuracy and user interaction, enhancing the overall search experience. + +## [0.3.20] - 2024-09-07 + +### Added + +- **🌐 Translation Update**: Updated Catalan translations to improve user experience for Catalan speakers. + +### Fixed + +- **📄 PDF Download**: Resolved a configuration issue with fonts directory, ensuring PDFs are now downloaded with the correct formatting. +- **🛠️ Installation of Tools & Functions Requirements**: Fixed a bug where necessary requirements for tools and functions were not properly installing. +- **🔗 Inline Image Link Rendering**: Enabled rendering of images directly from links in chat. +- **📞 Post-Call User Interface Cleanup**: Adjusted UI behavior to automatically close chat controls after a voice call ends, reducing screen clutter. +- **🎙️ Microphone Deactivation Post-Call**: Addressed an issue where the microphone remained active after calls. +- **✍️ Markdown Spacing Correction**: Corrected spacing in Markdown rendering, ensuring text appears neatly and as expected. +- **🔄 Message Re-rendering**: Fixed an issue causing all response messages to re-render with each new message, now improving chat performance. + +### Changed + +- **🌐 Refined Web Search Integration**: Deprecated the Search Query Generation Prompt threshold; introduced a toggle button for "Enable Web Search Query Generation" allowing users to opt-in to using web search more judiciously. +- **📝 Default Prompt Templates Update**: Emptied environment variable templates for search and title generation now default to the Open WebUI default prompt templates, simplifying configuration efforts. + +## [0.3.19] - 2024-09-05 + +### Added + +- **🌐 Translation Update**: Improved Chinese translations. + +### Fixed + +- **📂 DATA_DIR Overriding**: Fixed an issue to avoid overriding DATA_DIR, preventing errors when directories are set identically, ensuring smoother operation and data management. +- **🛠️ Frontmatter Extraction**: Fixed the extraction process for frontmatter in tools and functions. + +### Changed + +- **🎨 UI Styling**: Refined the user interface styling for enhanced visual coherence and user experience. + +## [0.3.18] - 2024-09-04 + +### Added + +- **🛠️ Direct Database Execution for Tools & Functions**: Enhanced the execution of Python files for tools and functions, now directly loading from the database for a more streamlined backend process. + +### Fixed + +- **🔄 Automatic Rewrite of Import Statements in Tools & Functions**: Tool and function scripts that import 'utils', 'apps', 'main', 'config' will now automatically rename these with 'open_webui.', ensuring compatibility and consistency across different modules. +- **🎨 Styling Adjustments**: Minor fixes in the visual styling to improve user experience and interface consistency. + +## [0.3.17] - 2024-09-04 + +### Added + +- **🔄 Import/Export Configuration**: Users can now import and export webui configurations from admin settings > Database, simplifying setup replication across systems. +- **🌍 Web Search via URL Parameter**: Added support for activating web search directly through URL by setting 'web-search=true'. +- **🌐 SearchApi Integration**: Added support for SearchApi as an alternative web search provider, enhancing search capabilities within the platform. +- **🔍 Literal Type Support in Tools**: Tools now support the Literal type. +- **🌍 Updated Translations**: Improved translations for Chinese, Ukrainian, and Catalan. + +### Fixed + +- **🔧 Pip Install Issue**: Resolved the issue where pip install failed due to missing 'alembic.ini', ensuring smoother installation processes. +- **🌃 Automatic Theme Update**: Fixed an issue where the color theme did not update dynamically with system changes. +- **🛠️ User Agent in ComfyUI**: Added default headers in ComfyUI to fix access issues, improving reliability in network communications. +- **🔄 Missing Chat Completion Response Headers**: Ensured proper return of proxied response headers during chat completion, improving API reliability. +- **🔗 Websocket Connection Prioritization**: Modified socket.io configuration to prefer websockets and more reliably fallback to polling, enhancing connection stability. +- **🎭 Accessibility Enhancements**: Added missing ARIA labels for buttons, improving accessibility for visually impaired users. +- **⚖️ Advanced Parameter**: Fixed an issue ensuring that advanced parameters are correctly applied in all scenarios, ensuring consistent behavior of user-defined settings. + +### Changed + +- **🔁 Namespace Reorganization**: Reorganized all Python files under the 'open_webui' namespace to streamline the project structure and improve maintainability. Tools and functions importing from 'utils' should now use 'open_webui.utils'. +- **🚧 Dependency Updates**: Updated several backend dependencies like 'aiohttp', 'authlib', 'duckduckgo-search', 'flask-cors', and 'langchain' to their latest versions, enhancing performance and security. + +## [0.3.16] - 2024-08-27 + +### Added + +- **🚀 Config DB Migration**: Migrated configuration handling from config.json to the database, enabling high-availability setups and load balancing across multiple Open WebUI instances. +- **🔗 Call Mode Activation via URL**: Added a 'call=true' URL search parameter enabling direct shortcuts to activate call mode, enhancing user interaction on mobile devices. +- **✨ TTS Content Control**: Added functionality to control how message content is segmented for Text-to-Speech (TTS) generation requests, allowing for more flexible speech output options. +- **😄 Show Knowledge Search Status**: Enhanced model usage transparency by displaying status when working with knowledge-augmented models, helping users understand the system's state during queries. +- **👆 Click-to-Copy for Codespan**: Enhanced interactive experience in the WebUI by allowing users to click to copy content from code spans directly. +- **🚫 API User Blocking via Model Filter**: Introduced the ability to block API users based on customized model filters, enhancing security and control over API access. +- **🎬 Call Overlay Styling**: Adjusted call overlay styling on large screens to not cover the entire interface, but only the chat control area, for a more unobtrusive interaction experience. + +### Fixed + +- **🔧 LaTeX Rendering Issue**: Addressed an issue that affected the correct rendering of LaTeX. +- **📁 File Leak Prevention**: Resolved the issue of uploaded files mistakenly being accessible across user chats. +- **🔧 Pipe Functions with '**files**' Param**: Fixed issues with '**files**' parameter not functioning correctly in pipe functions. +- **📝 Markdown Processing for RAG**: Fixed issues with processing Markdown in files. +- **🚫 Duplicate System Prompts**: Fixed bugs causing system prompts to duplicate. + +### Changed + +- **🔋 Wakelock Permission**: Optimized the activation of wakelock to only engage during call mode, conserving device resources and improving battery performance during idle periods. +- **🔍 Content-Type for Ollama Chats**: Added 'application/x-ndjson' content-type to '/api/chat' endpoint responses to match raw Ollama responses. +- **✋ Disable Signups Conditionally**: Implemented conditional logic to disable sign-ups when 'ENABLE_LOGIN_FORM' is set to false. + +## [0.3.15] - 2024-08-21 + +### Added + +- **🔗 Temporary Chat Activation**: Integrated a new URL parameter 'temporary-chat=true' to enable temporary chat sessions directly through the URL. +- **🌄 ComfyUI Seed Node Support**: Introduced seed node support in ComfyUI for image generation, allowing users to specify node IDs for randomized seed assignment. + +### Fixed + +- **🛠️ Tools and Functions**: Resolved a critical issue where Tools and Functions were not properly functioning, restoring full capability and reliability to these essential features. +- **🔘 Chat Action Button in Many Model Chat**: Fixed the malfunctioning of chat action buttons in many model chat environments, ensuring a smoother and more responsive user interaction. +- **⏪ Many Model Chat Compatibility**: Restored backward compatibility for many model chats. + +## [0.3.14] - 2024-08-21 + +### Added + +- **🛠️ Custom ComfyUI Workflow**: Deprecating several older environment variables, this enhancement introduces a new, customizable workflow for a more tailored user experience. +- **🔀 Merge Responses in Many Model Chat**: Enhances the dialogue by merging responses from multiple models into a single, coherent reply, improving the interaction quality in many model chats. +- **✅ Multiple Instances of Same Model in Chats**: Enhanced many model chat to support adding multiple instances of the same model. +- **🔧 Quick Actions in Model Workspace**: Enhanced Shift key quick actions for hiding/unhiding and deleting models, facilitating a smoother workflow. +- **🗨️ Markdown Rendering in User Messages**: User messages are now rendered in Markdown, enhancing readability and interaction. +- **💬 Temporary Chat Feature**: Introduced a temporary chat feature, deprecating the old chat history setting to enhance user interaction flexibility. +- **🖋️ User Message Editing**: Enhanced the user chat editing feature to allow saving changes without sending, providing more flexibility in message management. +- **🛡️ Security Enhancements**: Various security improvements implemented across the platform to ensure safer user experiences. +- **🌍 Updated Translations**: Enhanced translations for Chinese, Ukrainian, and Bahasa Malaysia, improving localization and user comprehension. + +### Fixed + +- **📑 Mermaid Rendering Issue**: Addressed issues with Mermaid chart rendering to ensure clean and clear visual data representation. +- **🎭 PWA Icon Maskability**: Fixed the Progressive Web App icon to be maskable, ensuring proper display on various device home screens. +- **🔀 Cloned Model Chat Freezing Issue**: Fixed a bug where cloning many model chats would cause freezing, enhancing stability and responsiveness. +- **🔍 Generic Error Handling and Refinements**: Various minor fixes and refinements to address previously untracked issues, ensuring smoother operations. + +### Changed + +- **🖼️ Image Generation Refactor**: Overhauled image generation processes for improved efficiency and quality. +- **🔨 Refactor Tool and Function Calling**: Refactored tool and function calling mechanisms for improved clarity and maintainability. +- **🌐 Backend Library Updates**: Updated critical backend libraries including SQLAlchemy, uvicorn[standard], faster-whisper, bcrypt, and boto3 for enhanced performance and security. + +### Removed + +- **🚫 Deprecated ComfyUI Environment Variables**: Removed several outdated environment variables related to ComfyUI settings, simplifying configuration management. + +## [0.3.13] - 2024-08-14 + +### Added + +- **🎨 Enhanced Markdown Rendering**: Significant improvements in rendering markdown, ensuring smooth and reliable display of LaTeX and Mermaid charts, enhancing user experience with more robust visual content. +- **🔄 Auto-Install Tools & Functions Python Dependencies**: For 'Tools' and 'Functions', Open WebUI now automatically install extra python requirements specified in the frontmatter, streamlining setup processes and customization. +- **🌀 OAuth Email Claim Customization**: Introduced an 'OAUTH_EMAIL_CLAIM' variable to allow customization of the default "email" claim within OAuth configurations, providing greater flexibility in authentication processes. +- **📶 Websocket Reconnection**: Enhanced reliability with the capability to automatically reconnect when a websocket is closed, ensuring consistent and stable communication. +- **🤳 Haptic Feedback on Support Devices**: Android devices now support haptic feedback for an immersive tactile experience during certain interactions. + +### Fixed + +- **🛠️ ComfyUI Performance Improvement**: Addressed an issue causing FastAPI to stall when ComfyUI image generation was active; now runs in a separate thread to prevent UI unresponsiveness. +- **🔀 Session Handling**: Fixed an issue mandating session_id on client-side to ensure smoother session management and transitions. +- **🖋️ Minor Bug Fixes and Format Corrections**: Various minor fixes including typo corrections, backend formatting improvements, and test amendments enhancing overall system stability and performance. + +### Changed + +- **🚀 Migration to SvelteKit 2**: Upgraded the underlying framework to SvelteKit version 2, offering enhanced speed, better code structure, and improved deployment capabilities. +- **🧹 General Cleanup and Refactoring**: Performed broad cleanup and refactoring across the platform, improving code efficiency and maintaining high standards of code health. +- **🚧 Integration Testing Improvements**: Modified how Cypress integration tests detect chat messages and updated sharing tests for better reliability and accuracy. +- **📁 Standardized '.safetensors' File Extension**: Renamed the '.sft' file extension to '.safetensors' for ComfyUI workflows, standardizing file formats across the platform. + +### Removed + +- **🗑️ Deprecated Frontend Functions**: Removed frontend functions that were migrated to backend to declutter the codebase and reduce redundancy. + +## [0.3.12] - 2024-08-07 + +### Added + +- **🔄 Sidebar Infinite Scroll**: Added an infinite scroll feature in the sidebar for more efficient chat navigation, reducing load times and enhancing user experience. +- **🚀 Enhanced Markdown Rendering**: Support for rendering all code blocks and making images clickable for preview; codespan styling is also enhanced to improve readability and user interaction. +- **🔒 Admin Shared Chat Visibility**: Admins no longer have default visibility over shared chats when ENABLE_ADMIN_CHAT_ACCESS is set to false, tightening security and privacy settings for users. +- **🌍 Language Updates**: Added Malay (Bahasa Malaysia) translation and updated Catalan and Traditional Chinese translations to improve accessibility for more users. + +### Fixed + +- **📊 Markdown Rendering Issues**: Resolved issues with markdown rendering to ensure consistent and correct display across components. +- **🛠️ Styling Issues**: Multiple fixes applied to styling throughout the application, improving the overall visual experience and interface consistency. +- **🗃️ Modal Handling**: Fixed an issue where modals were not closing correctly in various model chat scenarios, enhancing usability and interface reliability. +- **📄 Missing OpenAI Usage Information**: Resolved issues where usage statistics for OpenAI services were not being correctly displayed, ensuring users have access to crucial data for managing and monitoring their API consumption. +- **🔧 Non-Streaming Support for Functions Plugin**: Fixed a functionality issue with the Functions plugin where non-streaming operations were not functioning as intended, restoring full capabilities for async and sync integration within the platform. +- **🔄 Environment Variable Type Correction (COMFYUI_FLUX_FP8_CLIP)**: Corrected the data type of the 'COMFYUI_FLUX_FP8_CLIP' environment variable from string to boolean, ensuring environment settings apply correctly and enhance configuration management. + +### Changed + +- **🔧 Backend Dependency Updates**: Updated several backend dependencies such as boto3, pypdf, python-pptx, validators, and black, ensuring up-to-date security and performance optimizations. + +## [0.3.11] - 2024-08-02 + +### Added + +- **📊 Model Information Display**: Added visuals for model selection, including images next to model names for more intuitive navigation. +- **🗣 ElevenLabs Voice Adaptations**: Voice enhancements including support for ElevenLabs voice ID by name for personalized vocal interactions. +- **⌨️ Arrow Keys Model Selection**: Users can now use arrow keys for quicker model selection, enhancing accessibility. +- **🔍 Fuzzy Search in Model Selector**: Enhanced model selector with fuzzy search to locate models swiftly, including descriptions. +- **🕹️ ComfyUI Flux Image Generation**: Added support for the new Flux image gen model; introduces environment controls like weight precision and CLIP model options in Settings. +- **💾 Display File Size for Uploads**: Enhanced file interface now displays file size, preparing for upcoming upload restrictions. +- **🎚️ Advanced Params "Min P"**: Added 'Min P' parameter in the advanced settings for customized model precision control. +- **🔒 Enhanced OAuth**: Introduced custom redirect URI support for OAuth behind reverse proxies, enabling safer authentication processes. +- **🖥 Enhanced Latex Rendering**: Adjustments made to latex rendering processes, now accurately detecting and presenting latex inputs from text. +- **🌐 Internationalization**: Enhanced with new Romanian and updated Vietnamese and Ukrainian translations, helping broaden accessibility for international users. + +### Fixed + +- **🔧 Tags Handling in Document Upload**: Tags are now properly sent to the upload document handler, resolving issues with missing metadata. +- **🖥️ Sensitive Input Fields**: Corrected browser misinterpretation of secure input fields, preventing misclassification as password fields. +- **📂 Static Path Resolution in PDF Generation**: Fixed static paths that adjust dynamically to prevent issues across various environments. + +### Changed + +- **🎨 UI/UX Styling Enhancements**: Multiple minor styling updates for a cleaner and more intuitive user interface. +- **🚧 Refactoring Various Components**: Numerous refactoring changes across styling, file handling, and function simplifications for clarity and performance. +- **🎛️ User Valves Management**: Moved user valves from settings to direct chat controls for more user-friendly access during interactions. + +### Removed + +- **⚙️ Health Check Logging**: Removed verbose logging from the health checking processes to declutter logs and improve backend performance. + +## [0.3.10] - 2024-07-17 + +### Fixed + +- **🔄 Improved File Upload**: Addressed the issue where file uploads lacked animation. +- **💬 Chat Continuity**: Fixed a problem where existing chats were not functioning properly in some instances. +- **🗂️ Chat File Reset**: Resolved the issue of chat files not resetting for new conversations, now ensuring a clean slate for each chat session. +- **📁 Document Workspace Uploads**: Corrected the handling of document uploads in the workspace using the Files API. + +## [0.3.9] - 2024-07-17 + +### Added + +- **📁 Files Chat Controls**: We've reverted to the old file handling behavior where uploaded files are always included. You can now manage files directly within the chat controls section, giving you the ability to remove files as needed. +- **🔧 "Action" Function Support**: Introducing a new "Action" function to write custom buttons to the message toolbar. This feature enables more interactive messaging, with documentation coming soon. +- **📜 Citations Handling**: For newly uploaded files in documents workspace, citations will now display the actual filename. Additionally, you can click on these filenames to open the file in a new tab for easier access. +- **🛠️ Event Emitter and Call Updates**: Enhanced 'event_emitter' to allow message replacement and 'event_call' to support text input for Tools and Functions. Detailed documentation will be provided shortly. +- **🎨 Styling Refactor**: Various styling updates for a cleaner and more cohesive user interface. +- **🌐 Enhanced Translations**: Improved translations for Catalan, Ukrainian, and Brazilian Portuguese. + +### Fixed + +- **🔧 Chat Controls Priority**: Resolved an issue where Chat Controls values were being overridden by model information parameters. The priority is now Chat Controls, followed by Global Settings, then Model Settings. +- **🪲 Debug Logs**: Fixed an issue where debug logs were not being logged properly. +- **🔑 Automatic1111 Auth Key**: The auth key for Automatic1111 is no longer required. +- **📝 Title Generation**: Ensured that the title generation runs only once, even when multiple models are in a chat. +- **✅ Boolean Values in Params**: Added support for boolean values in parameters. +- **🖼️ Files Overlay Styling**: Fixed the styling issue with the files overlay. + +### Changed + +- **⬆️ Dependency Updates** + - Upgraded 'pydantic' from version 2.7.1 to 2.8.2. + - Upgraded 'sqlalchemy' from version 2.0.30 to 2.0.31. + - Upgraded 'unstructured' from version 0.14.9 to 0.14.10. + - Upgraded 'chromadb' from version 0.5.3 to 0.5.4. + +## [0.3.8] - 2024-07-09 + +### Added + +- **💬 Chat Controls**: Easily adjust parameters for each chat session, offering more precise control over your interactions. +- **📌 Pinned Chats**: Support for pinned chats, allowing you to keep important conversations easily accessible. +- **📄 Apache Tika Integration**: Added support for using Apache Tika as a document loader, enhancing document processing capabilities. +- **🛠️ Custom Environment for OpenID Claims**: Allows setting custom claims for OpenID, providing more flexibility in user authentication. +- **🔧 Enhanced Tools & Functions API**: Introduced 'event_emitter' and 'event_call', now you can also add citations for better documentation and tracking. Detailed documentation will be provided on our documentation website. +- **↔️ Sideways Scrolling in Settings**: Settings tabs container now supports horizontal scrolling for easier navigation. +- **🌑 Darker OLED Theme**: Includes a new, darker OLED theme and improved styling for the light theme, enhancing visual appeal. +- **🌐 Language Updates**: Updated translations for Indonesian, German, French, and Catalan languages, expanding accessibility. + +### Fixed + +- **⏰ OpenAI Streaming Timeout**: Resolved issues with OpenAI streaming response using the 'AIOHTTP_CLIENT_TIMEOUT' setting, ensuring reliable performance. +- **💡 User Valves**: Fixed malfunctioning user valves, ensuring proper functionality. +- **🔄 Collapsible Components**: Addressed issues with collapsible components not working, restoring expected behavior. + +### Changed + +- **🗃️ Database Backend**: Switched from Peewee to SQLAlchemy for improved concurrency support, enhancing database performance. +- **⬆️ ChromaDB Update**: Upgraded to version 0.5.3. Ensure your remote ChromaDB instance matches this version. +- **🔤 Primary Font Styling**: Updated primary font to Archivo for better visual consistency. +- **🔄 Font Change for Windows**: Replaced Arimo with Inter font for Windows users, improving readability. +- **🚀 Lazy Loading**: Implemented lazy loading for 'faster_whisper' and 'sentence_transformers' to reduce startup memory usage. +- **📋 Task Generation Payload**: Task generations now include only the "task" field in the body instead of "title". + +## [0.3.7] - 2024-06-29 + +### Added + +- **🌐 Enhanced Internationalization (i18n)**: Newly introduced Indonesian translation, and updated translations for Turkish, Chinese, and Catalan languages to improve user accessibility. + +### Fixed + +- **🕵️‍♂️ Browser Language Detection**: Corrected the issue where the application was not properly detecting and adapting to the browser's language settings. +- **🔐 OIDC Admin Role Assignment**: Fixed a bug where the admin role was not being assigned to the first user who signed up via OpenID Connect (OIDC). +- **💬 Chat/Completions Endpoint**: Resolved an issue where the chat/completions endpoint was non-functional when the stream option was set to False. +- **🚫 'WEBUI_AUTH' Configuration**: Addressed the problem where setting 'WEBUI_AUTH' to False was not being applied correctly. + +### Changed + +- **📦 Dependency Update**: Upgraded 'authlib' from version 1.3.0 to 1.3.1 to ensure better security and performance enhancements. + +## [0.3.6] - 2024-06-27 + +### Added + +- **✨ "Functions" Feature**: You can now utilize "Functions" like filters (middleware) and pipe (model) functions directly within the WebUI. While largely compatible with Pipelines, these native functions can be executed easily within Open WebUI. Example use cases for filter functions include usage monitoring, real-time translation, moderation, and automemory. For pipe functions, the scope ranges from Cohere and Anthropic integration directly within Open WebUI, enabling "Valves" for per-user OpenAI API key usage, and much more. If you encounter issues, SAFE_MODE has been introduced. +- **📁 Files API**: Compatible with OpenAI, this feature allows for custom Retrieval-Augmented Generation (RAG) in conjunction with the Filter Function. More examples will be shared on our community platform and official documentation website. +- **🛠️ Tool Enhancements**: Tools now support citations and "Valves". Documentation will be available shortly. +- **🔗 Iframe Support via Files API**: Enables rendering HTML directly into your chat interface using functions and tools. Use cases include playing games like DOOM and Snake, displaying a weather applet, and implementing Anthropic "artifacts"-like features. Stay tuned for updates on our community platform and documentation. +- **🔒 Experimental OAuth Support**: New experimental OAuth support. Check our documentation for more details. +- **🖼️ Custom Background Support**: Set a custom background from Settings > Interface to personalize your experience. +- **🔑 AUTOMATIC1111_API_AUTH Support**: Enhanced security for the AUTOMATIC1111 API. +- **🎨 Code Highlight Optimization**: Improved code highlighting features. +- **🎙️ Voice Interruption Feature**: Reintroduced and now toggleable from Settings > Interface. +- **💤 Wakelock API**: Now in use to prevent screen dimming during important tasks. +- **🔐 API Key Privacy**: All API keys are now hidden by default for better security. +- **🔍 New Web Search Provider**: Added jina_search as a new option. +- **🌐 Enhanced Internationalization (i18n)**: Improved Korean translation and updated Chinese and Ukrainian translations. + +### Fixed + +- **🔧 Conversation Mode Issue**: Fixed the issue where Conversation Mode remained active after being removed from settings. +- **📏 Scroll Button Obstruction**: Resolved the issue where the scrollToBottom button container obstructed clicks on buttons beneath it. + +### Changed + +- **⏲️ AIOHTTP_CLIENT_TIMEOUT**: Now set to 'None' by default for improved configuration flexibility. +- **📞 Voice Call Enhancements**: Improved by skipping code blocks and expressions during calls. +- **🚫 Error Message Handling**: Disabled the continuation of operations with error messages. +- **🗂️ Playground Relocation**: Moved the Playground from the workspace to the user menu for better user experience. + +## [0.3.5] - 2024-06-16 + +### Added + +- **📞 Enhanced Voice Call**: Text-to-speech (TTS) callback now operates in real-time for each sentence, reducing latency by not waiting for full completion. +- **👆 Tap to Interrupt**: During a call, you can now stop the assistant from speaking by simply tapping, instead of using voice. This resolves the issue of the speaker's voice being mistakenly registered as input. +- **😊 Emoji Call**: Toggle this feature on from the Settings > Interface, allowing LLMs to express emotions using emojis during voice calls for a more dynamic interaction. +- **🖱️ Quick Archive/Delete**: Use the Shift key + mouseover on the chat list to swiftly archive or delete items. +- **📝 Markdown Support in Model Descriptions**: You can now format model descriptions with markdown, enabling bold text, links, etc. +- **🧠 Editable Memories**: Adds the capability to modify memories. +- **📋 Admin Panel Sorting**: Introduces the ability to sort users/chats within the admin panel. +- **🌑 Dark Mode for Quick Selectors**: Dark mode now available for chat quick selectors (prompts, models, documents). +- **🔧 Advanced Parameters**: Adds 'num_keep' and 'num_batch' to advanced parameters for customization. +- **📅 Dynamic System Prompts**: New variables '{{CURRENT_DATETIME}}', '{{CURRENT_TIME}}', '{{USER_LOCATION}}' added for system prompts. Ensure '{{USER_LOCATION}}' is toggled on from Settings > Interface. +- **🌐 Tavily Web Search**: Includes Tavily as a web search provider option. +- **🖊️ Federated Auth Usernames**: Ability to set user names for federated authentication. +- **🔗 Auto Clean URLs**: When adding connection URLs, trailing slashes are now automatically removed. +- **🌐 Enhanced Translations**: Improved Chinese and Swedish translations. + +### Fixed + +- **⏳ AIOHTTP_CLIENT_TIMEOUT**: Introduced a new environment variable 'AIOHTTP_CLIENT_TIMEOUT' for requests to Ollama lasting longer than 5 minutes. Default is 300 seconds; set to blank ('') for no timeout. +- **❌ Message Delete Freeze**: Resolved an issue where message deletion would sometimes cause the web UI to freeze. + +## [0.3.4] - 2024-06-12 + +### Fixed + +- **🔒 Mixed Content with HTTPS Issue**: Resolved a problem where mixed content (HTTP and HTTPS) was causing security warnings and blocking resources on HTTPS sites. +- **🔍 Web Search Issue**: Addressed the problem where web search functionality was not working correctly. The 'ENABLE_RAG_LOCAL_WEB_FETCH' option has been reintroduced to restore proper web searching capabilities. +- **💾 RAG Template Not Being Saved**: Fixed an issue where the RAG template was not being saved correctly, ensuring your custom templates are now preserved as expected. + +## [0.3.3] - 2024-06-12 + +### Added + +- **🛠️ Native Python Function Calling**: Introducing native Python function calling within Open WebUI. We’ve also included a built-in code editor to seamlessly develop and integrate function code within the 'Tools' workspace. With this, you can significantly enhance your LLM’s capabilities by creating custom RAG pipelines, web search tools, and even agent-like features such as sending Discord messages. +- **🌐 DuckDuckGo Integration**: Added DuckDuckGo as a web search provider, giving you more search options. +- **🌏 Enhanced Translations**: Improved translations for Vietnamese and Chinese languages, making the interface more accessible. + +### Fixed + +- **🔗 Web Search URL Error Handling**: Fixed the issue where a single URL error would disrupt the data loading process in Web Search mode. Now, such errors will be handled gracefully to ensure uninterrupted data loading. +- **🖥️ Frontend Responsiveness**: Resolved the problem where the frontend would stop responding if the backend encounters an error while downloading a model. Improved error handling to maintain frontend stability. +- **🔧 Dependency Issues in pip**: Fixed issues related to pip installations, ensuring all dependencies are correctly managed to prevent installation errors. + +## [0.3.2] - 2024-06-10 + +### Added + +- **🔍 Web Search Query Status**: The web search query will now persist in the results section to aid in easier debugging and tracking of search queries. +- **🌐 New Web Search Provider**: We have added Serply as a new option for web search providers, giving you more choices for your search needs. +- **🌏 Improved Translations**: We've enhanced translations for Chinese and Portuguese. + +### Fixed + +- **🎤 Audio File Upload Issue**: The bug that prevented audio files from being uploaded in chat input has been fixed, ensuring smooth communication. +- **💬 Message Input Handling**: Improved the handling of message inputs by instantly clearing images and text after sending, along with immediate visual indications when a response message is loading, enhancing user feedback. +- **⚙️ Parameter Registration and Validation**: Fixed the issue where parameters were not registering in certain cases and addressed the problem where users were unable to save due to invalid input errors. + +## [0.3.1] - 2024-06-09 + +### Fixed + +- **💬 Chat Functionality**: Resolved the issue where chat functionality was not working for specific models. + +## [0.3.0] - 2024-06-09 + +### Added + +- **📚 Knowledge Support for Models**: Attach documents directly to models from the models workspace, enhancing the information available to each model. +- **🎙️ Hands-Free Voice Call Feature**: Initiate voice calls without needing to use your hands, making interactions more seamless. +- **📹 Video Call Feature**: Enable video calls with supported vision models like Llava and GPT-4o, adding a visual dimension to your communications. +- **🎛️ Enhanced UI for Voice Recording**: Improved user interface for the voice recording feature, making it more intuitive and user-friendly. +- **🌐 External STT Support**: Now support for external Speech-To-Text services, providing more flexibility in choosing your STT provider. +- **⚙️ Unified Settings**: Consolidated settings including document settings under a new admin settings section for easier management. +- **🌑 Dark Mode Splash Screen**: A new splash screen for dark mode, ensuring a consistent and visually appealing experience for dark mode users. +- **📥 Upload Pipeline**: Directly upload pipelines from the admin settings > pipelines section, streamlining the pipeline management process. +- **🌍 Improved Language Support**: Enhanced support for Chinese and Ukrainian languages, better catering to a global user base. + +### Fixed + +- **🛠️ Playground Issue**: Fixed the playground not functioning properly, ensuring a smoother user experience. +- **🔥 Temperature Parameter Issue**: Corrected the issue where the temperature value '0' was not being passed correctly. +- **📝 Prompt Input Clearing**: Resolved prompt input textarea not being cleared right away, ensuring a clean slate for new inputs. +- **✨ Various UI Styling Issues**: Fixed numerous user interface styling problems for a more cohesive look. +- **👥 Active Users Display**: Fixed active users showing active sessions instead of actual users, now reflecting accurate user activity. +- **🌐 Community Platform Compatibility**: The Community Platform is back online and fully compatible with Open WebUI. + +### Changed + +- **📝 RAG Implementation**: Updated the RAG (Retrieval-Augmented Generation) implementation to use a system prompt for context, instead of overriding the user's prompt. +- **🔄 Settings Relocation**: Moved Models, Connections, Audio, and Images settings to the admin settings for better organization. +- **✍️ Improved Title Generation**: Enhanced the default prompt for title generation, yielding better results. +- **🔧 Backend Task Management**: Tasks like title generation and search query generation are now managed on the backend side and controlled only by the admin. +- **🔍 Editable Search Query Prompt**: You can now edit the search query generation prompt, offering more control over how queries are generated. +- **📏 Prompt Length Threshold**: Set the prompt length threshold for search query generation from the admin settings, giving more customization options. +- **📣 Settings Consolidation**: Merged the Banners admin setting with the Interface admin setting for a more streamlined settings area. + +## [0.2.5] - 2024-06-05 + +### Added + +- **👥 Active Users Indicator**: Now you can see how many people are currently active and what they are running. This helps you gauge when performance might slow down due to a high number of users. +- **🗂️ Create Ollama Modelfile**: The option to create a modelfile for Ollama has been reintroduced in the Settings > Models section, making it easier to manage your models. +- **⚙️ Default Model Setting**: Added an option to set the default model from Settings > Interface. This feature is now easily accessible, especially convenient for mobile users as it was previously hidden. +- **🌐 Enhanced Translations**: We've improved the Chinese translations and added support for Turkmen and Norwegian languages to make the interface more accessible globally. + +### Fixed + +- **📱 Mobile View Improvements**: The UI now uses dvh (dynamic viewport height) instead of vh (viewport height), providing a better and more responsive experience for mobile users. + +## [0.2.4] - 2024-06-03 + +### Added + +- **👤 Improved Account Pending Page**: The account pending page now displays admin details by default to avoid confusion. You can disable this feature in the admin settings if needed. +- **🌐 HTTP Proxy Support**: We have enabled the use of the 'http_proxy' environment variable in OpenAI and Ollama API calls, making it easier to configure network settings. +- **❓ Quick Access to Documentation**: You can now easily access Open WebUI documents via a question mark button located at the bottom right corner of the screen (available on larger screens like PCs). +- **🌍 Enhanced Translation**: Improvements have been made to translations. + +### Fixed + +- **🔍 SearxNG Web Search**: Fixed the issue where the SearxNG web search functionality was not working properly. + +## [0.2.3] - 2024-06-03 + +### Added + +- **📁 Export Chat as JSON**: You can now export individual chats as JSON files from the navbar menu by navigating to 'Download > Export Chat'. This makes sharing specific conversations easier. +- **✏️ Edit Titles with Double Click**: Double-click on titles to rename them quickly and efficiently. +- **🧩 Batch Multiple Embeddings**: Introduced 'RAG_EMBEDDING_OPENAI_BATCH_SIZE' to process multiple embeddings in a batch, enhancing performance for large datasets. +- **🌍 Improved Translations**: Enhanced the translation quality across various languages for a better user experience. + +### Fixed + +- **🛠️ Modelfile Migration Script**: Fixed an issue where the modelfile migration script would fail if an invalid modelfile was encountered. +- **💬 Zhuyin Input Method on Mac**: Resolved an issue where using the Zhuyin input method in the Web UI on a Mac caused text to send immediately upon pressing the enter key, leading to incorrect input. +- **🔊 Local TTS Voice Selection**: Fixed the issue where the selected local Text-to-Speech (TTS) voice was not being displayed in settings. + +## [0.2.2] - 2024-06-02 + +### Added + +- **🌊 Mermaid Rendering Support**: We've included support for Mermaid rendering. This allows you to create beautiful diagrams and flowcharts directly within Open WebUI. +- **🔄 New Environment Variable 'RESET_CONFIG_ON_START'**: Introducing a new environment variable: 'RESET_CONFIG_ON_START'. Set this variable to reset your configuration settings upon starting the application, making it easier to revert to default settings. + +### Fixed + +- **🔧 Pipelines Filter Issue**: We've addressed an issue with the pipelines where filters were not functioning as expected. + +## [0.2.1] - 2024-06-02 + +### Added + +- **🖱️ Single Model Export Button**: Easily export models with just one click using the new single model export button. +- **🖥️ Advanced Parameters Support**: Added support for 'num_thread', 'use_mmap', and 'use_mlock' parameters for Ollama. +- **🌐 Improved Vietnamese Translation**: Enhanced Vietnamese language support for a better user experience for our Vietnamese-speaking community. + +### Fixed + +- **🔧 OpenAI URL API Save Issue**: Corrected a problem preventing the saving of OpenAI URL API settings. +- **🚫 Display Issue with Disabled Ollama API**: Fixed the display bug causing models to appear in settings when the Ollama API was disabled. + +### Changed + +- **💡 Versioning Update**: As a reminder from our previous update, version 0.2.y will focus primarily on bug fixes, while major updates will be designated as 0.x from now on for better version tracking. + +## [0.2.0] - 2024-06-01 + +### Added + +- **🔧 Pipelines Support**: Open WebUI now includes a plugin framework for enhanced customization and functionality (https://github.com/open-webui/pipelines). Easily add custom logic and integrate Python libraries, from AI agents to home automation APIs. +- **🔗 Function Calling via Pipelines**: Integrate function calling seamlessly through Pipelines. +- **⚖️ User Rate Limiting via Pipelines**: Implement user-specific rate limits to manage API usage efficiently. +- **📊 Usage Monitoring with Langfuse**: Track and analyze usage statistics with Langfuse integration through Pipelines. +- **🕒 Conversation Turn Limits**: Set limits on conversation turns to manage interactions better through Pipelines. +- **🛡️ Toxic Message Filtering**: Automatically filter out toxic messages to maintain a safe environment using Pipelines. +- **🔍 Web Search Support**: Introducing built-in web search capabilities via RAG API, allowing users to search using SearXNG, Google Programmatic Search Engine, Brave Search, serpstack, and serper. Activate it effortlessly by adding necessary variables from Document settings > Web Params. +- **🗂️ Models Workspace**: Create and manage model presets for both Ollama/OpenAI API. Note: The old Modelfiles workspace is deprecated. +- **🛠️ Model Builder Feature**: Build and edit all models with persistent builder mode. +- **🏷️ Model Tagging Support**: Organize models with tagging features in the models workspace. +- **📋 Model Ordering Support**: Effortlessly organize models by dragging and dropping them into the desired positions within the models workspace. +- **📈 OpenAI Generation Stats**: Access detailed generation statistics for OpenAI models. +- **📅 System Prompt Variables**: New variables added: '{{CURRENT_DATE}}' and '{{USER_NAME}}' for dynamic prompts. +- **📢 Global Banner Support**: Manage global banners from admin settings > banners. +- **🗃️ Enhanced Archived Chats Modal**: Search and export archived chats easily. +- **📂 Archive All Button**: Quickly archive all chats from settings > chats. +- **🌐 Improved Translations**: Added and improved translations for French, Croatian, Cebuano, and Vietnamese. + +### Fixed + +- **🔍 Archived Chats Visibility**: Resolved issue with archived chats not showing in the admin panel. +- **💬 Message Styling**: Fixed styling issues affecting message appearance. +- **🔗 Shared Chat Responses**: Corrected the issue where shared chat response messages were not readonly. +- **🖥️ UI Enhancement**: Fixed the scrollbar overlapping issue with the message box in the user interface. + +### Changed + +- **💾 User Settings Storage**: User settings are now saved on the backend, ensuring consistency across all devices. +- **📡 Unified API Requests**: The API request for getting models is now unified to '/api/models' for easier usage. +- **🔄 Versioning Update**: Our versioning will now follow the format 0.x for major updates and 0.x.y for patches. +- **📦 Export All Chats (All Users)**: Moved this functionality to the Admin Panel settings for better organization and accessibility. + +### Removed + +- **🚫 Bundled LiteLLM Support Deprecated**: Migrate your LiteLLM config.yaml to a self-hosted LiteLLM instance. LiteLLM can still be added via OpenAI Connections. Download the LiteLLM config.yaml from admin settings > database > export LiteLLM config.yaml. + +## [0.1.125] - 2024-05-19 + +### Added + +- **🔄 Updated UI**: Chat interface revamped with chat bubbles. Easily switch back to the old style via settings > interface > chat bubble UI. +- **📂 Enhanced Sidebar UI**: Model files, documents, prompts, and playground merged into Workspace for streamlined access. +- **🚀 Improved Many Model Interaction**: All responses now displayed simultaneously for a smoother experience. +- **🐍 Python Code Execution**: Execute Python code locally in the browser with libraries like 'requests', 'beautifulsoup4', 'numpy', 'pandas', 'seaborn', 'matplotlib', 'scikit-learn', 'scipy', 'regex'. +- **🧠 Experimental Memory Feature**: Manually input personal information you want LLMs to remember via settings > personalization > memory. +- **💾 Persistent Settings**: Settings now saved as config.json for convenience. +- **🩺 Health Check Endpoint**: Added for Docker deployment. +- **↕️ RTL Support**: Toggle chat direction via settings > interface > chat direction. +- **🖥️ PowerPoint Support**: RAG pipeline now supports PowerPoint documents. +- **🌐 Language Updates**: Ukrainian, Turkish, Arabic, Chinese, Serbian, Vietnamese updated; Punjabi added. + +### Changed + +- **👤 Shared Chat Update**: Shared chat now includes creator user information. + +## [0.1.124] - 2024-05-08 + +### Added + +- **🖼️ Improved Chat Sidebar**: Now conveniently displays time ranges and organizes chats by today, yesterday, and more. +- **📜 Citations in RAG Feature**: Easily track the context fed to the LLM with added citations in the RAG feature. +- **🔒 Auth Disable Option**: Introducing the ability to disable authentication. Set 'WEBUI_AUTH' to False to disable authentication. Note: Only applicable for fresh installations without existing users. +- **📹 Enhanced YouTube RAG Pipeline**: Now supports non-English videos for an enriched experience. +- **🔊 Specify OpenAI TTS Models**: Customize your TTS experience by specifying OpenAI TTS models. +- **🔧 Additional Environment Variables**: Discover more environment variables in our comprehensive documentation at Open WebUI Documentation (https://docs.openwebui.com). +- **🌐 Language Support**: Arabic, Finnish, and Hindi added; Improved support for German, Vietnamese, and Chinese. + +### Fixed + +- **🛠️ Model Selector Styling**: Addressed styling issues for improved user experience. +- **⚠️ Warning Messages**: Resolved backend warning messages. + +### Changed + +- **📝 Title Generation**: Limited output to 50 tokens. +- **📦 Helm Charts**: Removed Helm charts, now available in a separate repository (https://github.com/open-webui/helm-charts). + +## [0.1.123] - 2024-05-02 + +### Added + +- **🎨 New Landing Page Design**: Refreshed design for a more modern look and optimized use of screen space. +- **📹 Youtube RAG Pipeline**: Introduces dedicated RAG pipeline for Youtube videos, enabling interaction with video transcriptions directly. +- **🔧 Enhanced Admin Panel**: Streamlined user management with options to add users directly or in bulk via CSV import. +- **👥 '@' Model Integration**: Easily switch to specific models during conversations; old collaborative chat feature phased out. +- **🌐 Language Enhancements**: Swedish translation added, plus improvements to German, Spanish, and the addition of Doge translation. + +### Fixed + +- **🗑️ Delete Chat Shortcut**: Addressed issue where shortcut wasn't functioning. +- **🖼️ Modal Closing Bug**: Resolved unexpected closure of modal when dragging from within. +- **✏️ Edit Button Styling**: Fixed styling inconsistency with edit buttons. +- **🌐 Image Generation Compatibility Issue**: Rectified image generation compatibility issue with third-party APIs. +- **📱 iOS PWA Icon Fix**: Corrected iOS PWA home screen icon shape. +- **🔍 Scroll Gesture Bug**: Adjusted gesture sensitivity to prevent accidental activation when scrolling through code on mobile; now requires scrolling from the leftmost side to open the sidebar. + +### Changed + +- **🔄 Unlimited Context Length**: Advanced settings now allow unlimited max context length (previously limited to 16000). +- **👑 Super Admin Assignment**: The first signup is automatically assigned a super admin role, unchangeable by other admins. +- **🛡️ Admin User Restrictions**: User action buttons from the admin panel are now disabled for users with admin roles. +- **🔝 Default Model Selector**: Set as default model option now exclusively available on the landing page. + +## [0.1.122] - 2024-04-27 + +### Added + +- **🌟 Enhanced RAG Pipeline**: Now with hybrid searching via 'BM25', reranking powered by 'CrossEncoder', and configurable relevance score thresholds. +- **🛢️ External Database Support**: Seamlessly connect to custom SQLite or Postgres databases using the 'DATABASE_URL' environment variable. +- **🌐 Remote ChromaDB Support**: Introducing the capability to connect to remote ChromaDB servers. +- **👨‍💼 Improved Admin Panel**: Admins can now conveniently check users' chat lists and last active status directly from the admin panel. +- **🎨 Splash Screen**: Introducing a loading splash screen for a smoother user experience. +- **🌍 Language Support Expansion**: Added support for Bangla (bn-BD), along with enhancements to Chinese, Spanish, and Ukrainian translations. +- **💻 Improved LaTeX Rendering Performance**: Enjoy faster rendering times for LaTeX equations. +- **🔧 More Environment Variables**: Explore additional environment variables in our documentation (https://docs.openwebui.com), including the 'ENABLE_LITELLM' option to manage memory usage. + +### Fixed + +- **🔧 Ollama Compatibility**: Resolved errors occurring when Ollama server version isn't an integer, such as SHA builds or RCs. +- **🐛 Various OpenAI API Issues**: Addressed several issues related to the OpenAI API. +- **🛑 Stop Sequence Issue**: Fixed the problem where the stop sequence with a backslash '\' was not functioning. +- **🔤 Font Fallback**: Corrected font fallback issue. + +### Changed + +- **⌨️ Prompt Input Behavior on Mobile**: Enter key prompt submission disabled on mobile devices for improved user experience. + +## [0.1.121] - 2024-04-24 + +### Fixed + +- **🔧 Translation Issues**: Addressed various translation discrepancies. +- **🔒 LiteLLM Security Fix**: Updated LiteLLM version to resolve a security vulnerability. +- **🖥️ HTML Tag Display**: Rectified the issue where the '< br >' tag wasn't displaying correctly. +- **🔗 WebSocket Connection**: Resolved the failure of WebSocket connection under HTTPS security for ComfyUI server. +- **📜 FileReader Optimization**: Implemented FileReader initialization per image in multi-file drag & drop to ensure reusability. +- **🏷️ Tag Display**: Corrected tag display inconsistencies. +- **📦 Archived Chat Styling**: Fixed styling issues in archived chat. +- **🔖 Safari Copy Button Bug**: Addressed the bug where the copy button failed to copy links in Safari. + +## [0.1.120] - 2024-04-20 + +### Added + +- **📦 Archive Chat Feature**: Easily archive chats with a new sidebar button, and access archived chats via the profile button > archived chats. +- **🔊 Configurable Text-to-Speech Endpoint**: Customize your Text-to-Speech experience with configurable OpenAI endpoints. +- **🛠️ Improved Error Handling**: Enhanced error message handling for connection failures. +- **⌨️ Enhanced Shortcut**: When editing messages, use ctrl/cmd+enter to save and submit, and esc to close. +- **🌐 Language Support**: Added support for Georgian and enhanced translations for Portuguese and Vietnamese. + +### Fixed + +- **🔧 Model Selector**: Resolved issue where default model selection was not saving. +- **🔗 Share Link Copy Button**: Fixed bug where the copy button wasn't copying links in Safari. +- **🎨 Light Theme Styling**: Addressed styling issue with the light theme. + +## [0.1.119] - 2024-04-16 + +### Added + +- **🌟 Enhanced RAG Embedding Support**: Ollama, and OpenAI models can now be used for RAG embedding model. +- **🔄 Seamless Integration**: Copy 'ollama run ' directly from Ollama page to easily select and pull models. +- **🏷️ Tagging Feature**: Add tags to chats directly via the sidebar chat menu. +- **📱 Mobile Accessibility**: Swipe left and right on mobile to effortlessly open and close the sidebar. +- **🔍 Improved Navigation**: Admin panel now supports pagination for user list. +- **🌍 Additional Language Support**: Added Polish language support. + +### Fixed + +- **🌍 Language Enhancements**: Vietnamese and Spanish translations have been improved. +- **🔧 Helm Fixes**: Resolved issues with Helm trailing slash and manifest.json. + +### Changed + +- **🐳 Docker Optimization**: Updated docker image build process to utilize 'uv' for significantly faster builds compared to 'pip3'. + +## [0.1.118] - 2024-04-10 + +### Added + +- **🦙 Ollama and CUDA Images**: Added support for ':ollama' and ':cuda' tagged images. +- **👍 Enhanced Response Rating**: Now you can annotate your ratings for better feedback. +- **👤 User Initials Profile Photo**: User initials are now the default profile photo. +- **🔍 Update RAG Embedding Model**: Customize RAG embedding model directly in document settings. +- **🌍 Additional Language Support**: Added Turkish language support. + +### Fixed + +- **🔒 Share Chat Permission**: Resolved issue with chat sharing permissions. +- **🛠 Modal Close**: Modals can now be closed using the Esc key. + +### Changed + +- **🎨 Admin Panel Styling**: Refreshed styling for the admin panel. +- **🐳 Docker Image Build**: Updated docker image build process for improved efficiency. + +## [0.1.117] - 2024-04-03 + +### Added + +- 🗨️ **Local Chat Sharing**: Share chat links seamlessly between users. +- 🔑 **API Key Generation Support**: Generate secret keys to leverage Open WebUI with OpenAI libraries. +- 📄 **Chat Download as PDF**: Easily download chats in PDF format. +- 📝 **Improved Logging**: Enhancements to logging functionality. +- 📧 **Trusted Email Authentication**: Authenticate using a trusted email header. + +### Fixed + +- 🌷 **Enhanced Dutch Translation**: Improved translation for Dutch users. +- ⚪ **White Theme Styling**: Resolved styling issue with the white theme. +- 📜 **LaTeX Chat Screen Overflow**: Fixed screen overflow issue with LaTeX rendering. +- 🔒 **Security Patches**: Applied necessary security patches. + +## [0.1.116] - 2024-03-31 + +### Added + +- **🔄 Enhanced UI**: Model selector now conveniently located in the navbar, enabling seamless switching between multiple models during conversations. +- **🔍 Improved Model Selector**: Directly pull a model from the selector/Models now display detailed information for better understanding. +- **💬 Webhook Support**: Now compatible with Google Chat and Microsoft Teams. +- **🌐 Localization**: Korean translation (I18n) now available. +- **🌑 Dark Theme**: OLED dark theme introduced for reduced strain during prolonged usage. +- **🏷️ Tag Autocomplete**: Dropdown feature added for effortless chat tagging. + +### Fixed + +- **🔽 Auto-Scrolling**: Addressed OpenAI auto-scrolling issue. +- **🏷️ Tag Validation**: Implemented tag validation to prevent empty string tags. +- **🚫 Model Whitelisting**: Resolved LiteLLM model whitelisting issue. +- **✅ Spelling**: Corrected various spelling issues for improved readability. + +## [0.1.115] - 2024-03-24 + +### Added + +- **🔍 Custom Model Selector**: Easily find and select custom models with the new search filter feature. +- **🛑 Cancel Model Download**: Added the ability to cancel model downloads. +- **🎨 Image Generation ComfyUI**: Image generation now supports ComfyUI. +- **🌟 Updated Light Theme**: Updated the light theme for a fresh look. +- **🌍 Additional Language Support**: Now supporting Bulgarian, Italian, Portuguese, Japanese, and Dutch. + +### Fixed + +- **🔧 Fixed Broken Experimental GGUF Upload**: Resolved issues with experimental GGUF upload functionality. + +### Changed + +- **🔄 Vector Storage Reset Button**: Moved the reset vector storage button to document settings. + +## [0.1.114] - 2024-03-20 + +### Added + +- **🔗 Webhook Integration**: Now you can subscribe to new user sign-up events via webhook. Simply navigate to the admin panel > admin settings > webhook URL. +- **🛡️ Enhanced Model Filtering**: Alongside Ollama, OpenAI proxy model whitelisting, we've added model filtering functionality for LiteLLM proxy. +- **🌍 Expanded Language Support**: Spanish, Catalan, and Vietnamese languages are now available, with improvements made to others. + +### Fixed + +- **🔧 Input Field Spelling**: Resolved issue with spelling mistakes in input fields. +- **🖊️ Light Mode Styling**: Fixed styling issue with light mode in document adding. + +### Changed + +- **🔄 Language Sorting**: Languages are now sorted alphabetically by their code for improved organization. + +## [0.1.113] - 2024-03-18 + +### Added + +- 🌍 **Localization**: You can now change the UI language in Settings > General. We support Ukrainian, German, Farsi (Persian), Traditional and Simplified Chinese and French translations. You can help us to translate the UI into your language! More info in our [CONTRIBUTION.md](https://github.com/open-webui/open-webui/blob/main/docs/CONTRIBUTING.md#-translations-and-internationalization). +- 🎨 **System-wide Theme**: Introducing a new system-wide theme for enhanced visual experience. + +### Fixed + +- 🌑 **Dark Background on Select Fields**: Improved readability by adding a dark background to select fields, addressing issues on certain browsers/devices. +- **Multiple OPENAI_API_BASE_URLS Issue**: Resolved issue where multiple base URLs caused conflicts when one wasn't functioning. +- **RAG Encoding Issue**: Fixed encoding problem in RAG. +- **npm Audit Fix**: Addressed npm audit findings. +- **Reduced Scroll Threshold**: Improved auto-scroll experience by reducing the scroll threshold from 50px to 5px. + +### Changed + +- 🔄 **Sidebar UI Update**: Updated sidebar UI to feature a chat menu dropdown, replacing two icons for improved navigation. + +## [0.1.112] - 2024-03-15 + +### Fixed + +- 🗨️ Resolved chat malfunction after image generation. +- 🎨 Fixed various RAG issues. +- 🧪 Rectified experimental broken GGUF upload logic. + +## [0.1.111] - 2024-03-10 + +### Added + +- 🛡️ **Model Whitelisting**: Admins now have the ability to whitelist models for users with the 'user' role. +- 🔄 **Update All Models**: Added a convenient button to update all models at once. +- 📄 **Toggle PDF OCR**: Users can now toggle PDF OCR option for improved parsing performance. +- 🎨 **DALL-E Integration**: Introduced DALL-E integration for image generation alongside automatic1111. +- 🛠️ **RAG API Refactoring**: Refactored RAG logic and exposed its API, with additional documentation to follow. + +### Fixed + +- 🔒 **Max Token Settings**: Added max token settings for anthropic/claude-3-sonnet-20240229 (Issue #1094). +- 🔧 **Misalignment Issue**: Corrected misalignment of Edit and Delete Icons when Chat Title is Empty (Issue #1104). +- 🔄 **Context Loss Fix**: Resolved RAG losing context on model response regeneration with Groq models via API key (Issue #1105). +- 📁 **File Handling Bug**: Addressed File Not Found Notification when Dropping a Conversation Element (Issue #1098). +- 🖱️ **Dragged File Styling**: Fixed dragged file layover styling issue. + +## [0.1.110] - 2024-03-06 + +### Added + +- **🌐 Multiple OpenAI Servers Support**: Enjoy seamless integration with multiple OpenAI-compatible APIs, now supported natively. + +### Fixed + +- **🔍 OCR Issue**: Resolved PDF parsing issue caused by OCR malfunction. +- **🚫 RAG Issue**: Fixed the RAG functionality, ensuring it operates smoothly. +- **📄 "Add Docs" Model Button**: Addressed the non-functional behavior of the "Add Docs" model button. + +## [0.1.109] - 2024-03-06 + +### Added + +- **🔄 Multiple Ollama Servers Support**: Enjoy enhanced scalability and performance with support for multiple Ollama servers in a single WebUI. Load balancing features are now available, providing improved efficiency (#788, #278). +- **🔧 Support for Claude 3 and Gemini**: Responding to user requests, we've expanded our toolset to include Claude 3 and Gemini, offering a wider range of functionalities within our platform (#1064). +- **🔍 OCR Functionality for PDF Loader**: We've augmented our PDF loader with Optical Character Recognition (OCR) capabilities. Now, extract text from scanned documents and images within PDFs, broadening the scope of content processing (#1050). + +### Fixed + +- **🛠️ RAG Collection**: Implemented a dynamic mechanism to recreate RAG collections, ensuring users have up-to-date and accurate data (#1031). +- **📝 User Agent Headers**: Fixed issue of RAG web requests being sent with empty user_agent headers, reducing rejections from certain websites. Realistic headers are now utilized for these requests (#1024). +- **⏹️ Playground Cancel Functionality**: Introducing a new "Cancel" option for stopping Ollama generation in the Playground, enhancing user control and usability (#1006). +- **🔤 Typographical Error in 'ASSISTANT' Field**: Corrected a typographical error in the 'ASSISTANT' field within the GGUF model upload template for accuracy and consistency (#1061). + +### Changed + +- **🔄 Refactored Message Deletion Logic**: Streamlined message deletion process for improved efficiency and user experience, simplifying interactions within the platform (#1004). +- **⚠️ Deprecation of `OLLAMA_API_BASE_URL`**: Deprecated `OLLAMA_API_BASE_URL` environment variable; recommend using `OLLAMA_BASE_URL` instead. Refer to our documentation for further details. + +## [0.1.108] - 2024-03-02 + +### Added + +- **🎮 Playground Feature (Beta)**: Explore the full potential of the raw API through an intuitive UI with our new playground feature, accessible to admins. Simply click on the bottom name area of the sidebar to access it. The playground feature offers two modes text completion (notebook) and chat completion. As it's in beta, please report any issues you encounter. +- **🛠️ Direct Database Download for Admins**: Admins can now download the database directly from the WebUI via the admin settings. +- **🎨 Additional RAG Settings**: Customize your RAG process with the ability to edit the TOP K value. Navigate to Documents > Settings > General to make changes. +- **🖥️ UI Improvements**: Tooltips now available in the input area and sidebar handle. More tooltips will be added across other parts of the UI. + +### Fixed + +- Resolved input autofocus issue on mobile when the sidebar is open, making it easier to use. +- Corrected numbered list display issue in Safari (#963). +- Restricted user ability to delete chats without proper permissions (#993). + +### Changed + +- **Simplified Ollama Settings**: Ollama settings now don't require the `/api` suffix. You can now utilize the Ollama base URL directly, e.g., `http://localhost:11434`. Also, an `OLLAMA_BASE_URL` environment variable has been added. +- **Database Renaming**: Starting from this release, `ollama.db` will be automatically renamed to `webui.db`. + +## [0.1.107] - 2024-03-01 + +### Added + +- **🚀 Makefile and LLM Update Script**: Included Makefile and a script for LLM updates in the repository. + +### Fixed + +- Corrected issue where links in the settings modal didn't appear clickable (#960). +- Fixed problem with web UI port not taking effect due to incorrect environment variable name in run-compose.sh (#996). +- Enhanced user experience by displaying chat in browser title and enabling automatic scrolling to the bottom (#992). + +### Changed + +- Upgraded toast library from `svelte-french-toast` to `svelte-sonner` for a more polished UI. +- Enhanced accessibility with the addition of dark mode on the authentication page. + +## [0.1.106] - 2024-02-27 + +### Added + +- **🎯 Auto-focus Feature**: The input area now automatically focuses when initiating or opening a chat conversation. + +### Fixed + +- Corrected typo from "HuggingFace" to "Hugging Face" (Issue #924). +- Resolved bug causing errors in chat completion API calls to OpenAI due to missing "num_ctx" parameter (Issue #927). +- Fixed issues preventing text editing, selection, and cursor retention in the input field (Issue #940). +- Fixed a bug where defining an OpenAI-compatible API server using 'OPENAI_API_BASE_URL' containing 'openai' string resulted in hiding models not containing 'gpt' string from the model menu. (Issue #930) + +## [0.1.105] - 2024-02-25 + +### Added + +- **📄 Document Selection**: Now you can select and delete multiple documents at once for easier management. + +### Changed + +- **🏷️ Document Pre-tagging**: Simply click the "+" button at the top, enter tag names in the popup window, or select from a list of existing tags. Then, upload files with the added tags for streamlined organization. + +## [0.1.104] - 2024-02-25 + +### Added + +- **🔄 Check for Updates**: Keep your system current by checking for updates conveniently located in Settings > About. +- **🗑️ Automatic Tag Deletion**: Unused tags on the sidebar will now be deleted automatically with just a click. + +### Changed + +- **🎨 Modernized Styling**: Enjoy a refreshed look with updated styling for a more contemporary experience. + +## [0.1.103] - 2024-02-25 + +### Added + +- **🔗 Built-in LiteLLM Proxy**: Now includes LiteLLM proxy within Open WebUI for enhanced functionality. + + - Easily integrate existing LiteLLM configurations using `-v /path/to/config.yaml:/app/backend/data/litellm/config.yaml` flag. + - When utilizing Docker container to run Open WebUI, ensure connections to localhost use `host.docker.internal`. + +- **🖼️ Image Generation Enhancements**: Introducing Advanced Settings with Image Preview Feature. + - Customize image generation by setting the number of steps; defaults to A1111 value. + +### Fixed + +- Resolved issue with RAG scan halting document loading upon encountering unsupported MIME types or exceptions (Issue #866). + +### Changed + +- Ollama is no longer required to run Open WebUI. +- Access our comprehensive documentation at [Open WebUI Documentation](https://docs.openwebui.com/). + +## [0.1.102] - 2024-02-22 + +### Added + +- **🖼️ Image Generation**: Generate Images using the AUTOMATIC1111/stable-diffusion-webui API. You can set this up in Settings > Images. +- **📝 Change title generation prompt**: Change the prompt used to generate titles for your chats. You can set this up in the Settings > Interface. +- **🤖 Change embedding model**: Change the embedding model used to generate embeddings for your chats in the Dockerfile. Use any sentence transformer model from huggingface.co. +- **📢 CHANGELOG.md/Popup**: This popup will show you the latest changes. + +## [0.1.101] - 2024-02-22 + +### Fixed + +- LaTex output formatting issue (#828) + +### Changed + +- Instead of having the previous 1.0.0-alpha.101, we switched to semantic versioning as a way to respect global conventions. diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..eb54b48 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,99 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +As members, contributors, and leaders of this community, we pledge to make participation in our open-source project a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socioeconomic status, nationality, personal appearance, race, religion, or sexual identity and orientation. + +We are committed to creating and maintaining an open, respectful, and professional environment where positive contributions and meaningful discussions can flourish. By participating in this project, you agree to uphold these values and align your behavior to the standards outlined in this Code of Conduct. + +## Why These Standards Are Important + +Open-source projects rely on a community of volunteers dedicating their time, expertise, and effort toward a shared goal. These projects are inherently collaborative but also fragile, as the success of the project depends on the goodwill, energy, and productivity of those involved. + +Maintaining a positive and respectful environment is essential to safeguarding the integrity of this project and protecting contributors' efforts. Behavior that disrupts this atmosphere—whether through hostility, entitlement, or unprofessional conduct—can severely harm the morale and productivity of the community. **Strict enforcement of these standards ensures a safe and supportive space for meaningful collaboration.** + +This is a community where **respect and professionalism are mandatory.** Violations of these standards will result in **zero tolerance** and immediate enforcement to prevent disruption and ensure the well-being of all participants. + +## Our Standards + +Examples of behavior that contribute to a positive and professional community include: + +- **Respecting others.** Be considerate, listen actively, and engage with empathy toward others' viewpoints and experiences. +- **Constructive feedback.** Provide actionable, thoughtful, and respectful feedback that helps improve the project and encourages collaboration. Avoid unproductive negativity or hypercriticism. +- **Recognizing volunteer contributions.** Appreciate that contributors dedicate their free time and resources selflessly. Approach them with gratitude and patience. +- **Focusing on shared goals.** Collaborate in ways that prioritize the health, success, and sustainability of the community over individual agendas. + +Examples of unacceptable behavior include: + +- The use of discriminatory, demeaning, or sexualized language or behavior. +- Personal attacks, derogatory comments, trolling, or inflammatory political or ideological arguments. +- Harassment, intimidation, or any behavior intended to create a hostile, uncomfortable, or unsafe environment. +- Publishing others' private information (e.g., physical or email addresses) without explicit permission. +- **Entitlement, demand, or aggression toward contributors.** Volunteers are under no obligation to provide immediate or personalized support. Rude or dismissive behavior will not be tolerated. +- **Unproductive or destructive behavior.** This includes venting frustration as hostility ("tantrums"), hypercriticism, attention-seeking negativity, or anything that distracts from the project's goals. +- **Spamming and promotional exploitation.** Sharing irrelevant product promotions or self-promotion in the community is not allowed unless it directly contributes value to the discussion. + +### Feedback and Community Engagement + +- **Constructive feedback is encouraged, but hostile or entitled behavior will result in immediate action.** If you disagree with elements of the project, we encourage you to offer meaningful improvements or fork the project if necessary. Healthy discussions and technical disagreements are welcome only when handled with professionalism. +- **Respect contributors' time and efforts.** No one is entitled to personalized or on-demand assistance. This is a community built on collaboration and shared effort; demanding or demeaning behavior undermines that trust and will not be allowed. + +### Zero Tolerance: No Warnings, Immediate Action + +This community operates under a **zero-tolerance policy.** Any behavior deemed unacceptable under this Code of Conduct will result in **immediate enforcement, without prior warning.** + +We employ this approach to ensure that unproductive or disruptive behavior does not escalate further or cause unnecessary harm to other contributors. The standards are clear, and violations of any kind—whether mild or severe—will be addressed decisively to protect the community. + +## Enforcement Responsibilities + +Community leaders are responsible for upholding and enforcing these standards. They are empowered to take **immediate and appropriate action** to address any behaviors they deem unacceptable under this Code of Conduct. These actions are taken with the goal of protecting the community and preserving its safe, positive, and productive environment. + +## Scope + +This Code of Conduct applies to all community spaces, including forums, repositories, social media accounts, and in-person events. It also applies when an individual represents the community in public settings, such as conferences or official communications. + +Additionally, any behavior outside of these defined spaces that negatively impacts the community or its members may fall within the scope of this Code of Conduct. + +## Reporting Violations + +Instances of unacceptable behavior can be reported to the leadership team at **hello@openwebui.com**. Reports will be handled promptly, confidentially, and with consideration for the safety and well-being of the reporter. + +All community leaders are required to uphold confidentiality and impartiality when addressing reports of violations. + +## Enforcement Guidelines + +### Ban + +**Community Impact**: Community leaders will issue a ban to any participant whose behavior is deemed unacceptable according to this Code of Conduct. Bans are enforced immediately and without prior notice. + +A ban may be temporary or permanent, depending on the severity of the violation. This includes—but is not limited to—behavior such as: + +- Harassment or abusive behavior toward contributors. +- Persistent negativity or hostility that disrupts the collaborative environment. +- Disrespectful, demanding, or aggressive interactions with others. +- Attempts to cause harm or sabotage the community. + +**Consequence**: A banned individual is immediately removed from access to all community spaces, communication channels, and events. Community leaders reserve the right to enforce either a time-limited suspension or a permanent ban based on the specific circumstances of the violation. + +This approach ensures that disruptive behaviors are addressed swiftly and decisively in order to maintain the integrity and productivity of the community. + +## Why Zero Tolerance Is Necessary + +Open-source projects thrive on collaboration, goodwill, and mutual respect. Toxic behaviors—such as entitlement, hostility, or persistent negativity—threaten not just individual contributors but the health of the project as a whole. Allowing such behaviors to persist robs contributors of their time, energy, and enthusiasm for the work they do. + +By enforcing a zero-tolerance policy, we ensure that the community remains a safe, welcoming space for all participants. These measures are not about harshness—they are about protecting contributors and fostering a productive environment where innovation can thrive. + +Our expectations are clear, and our enforcement reflects our commitment to this project's long-term success. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/Caddyfile.localhost b/Caddyfile.localhost new file mode 100644 index 0000000..80728ee --- /dev/null +++ b/Caddyfile.localhost @@ -0,0 +1,64 @@ +# Run with +# caddy run --envfile ./example.env --config ./Caddyfile.localhost +# +# This is configured for +# - Automatic HTTPS (even for localhost) +# - Reverse Proxying to Ollama API Base URL (http://localhost:11434/api) +# - CORS +# - HTTP Basic Auth API Tokens (uncomment basicauth section) + + +# CORS Preflight (OPTIONS) + Request (GET, POST, PATCH, PUT, DELETE) +(cors-api) { + @match-cors-api-preflight method OPTIONS + handle @match-cors-api-preflight { + header { + Access-Control-Allow-Origin "{http.request.header.origin}" + Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE, OPTIONS" + Access-Control-Allow-Headers "Origin, Accept, Authorization, Content-Type, X-Requested-With" + Access-Control-Allow-Credentials "true" + Access-Control-Max-Age "3600" + defer + } + respond "" 204 + } + + @match-cors-api-request { + not { + header Origin "{http.request.scheme}://{http.request.host}" + } + header Origin "{http.request.header.origin}" + } + handle @match-cors-api-request { + header { + Access-Control-Allow-Origin "{http.request.header.origin}" + Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE, OPTIONS" + Access-Control-Allow-Headers "Origin, Accept, Authorization, Content-Type, X-Requested-With" + Access-Control-Allow-Credentials "true" + Access-Control-Max-Age "3600" + defer + } + } +} + +# replace localhost with example.com or whatever +localhost { + ## HTTP Basic Auth + ## (uncomment to enable) + # basicauth { + # # see .example.env for how to generate tokens + # {env.OLLAMA_API_ID} {env.OLLAMA_API_TOKEN_DIGEST} + # } + + handle /api/* { + # Comment to disable CORS + import cors-api + + reverse_proxy localhost:11434 + } + + # Same-Origin Static Web Server + file_server { + root ./build/ + } +} diff --git a/Dockerfile b/Dockerfile index 9e525e4..274e23d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,30 +1,176 @@ -# Użyj oficjalnego obrazu Python jako bazowego -FROM --platform=linux/amd64 python:3.9-slim +# syntax=docker/dockerfile:1 +# Initialize device type args +# use build args in the docker build command with --build-arg="BUILDARG=true" +ARG USE_CUDA=false +ARG USE_OLLAMA=false +# Tested with cu117 for CUDA 11 and cu121 for CUDA 12 (default) +ARG USE_CUDA_VER=cu121 +# any sentence transformer model; models to use can be found at https://huggingface.co/models?library=sentence-transformers +# Leaderboard: https://huggingface.co/spaces/mteb/leaderboard +# for better performance and multilangauge support use "intfloat/multilingual-e5-large" (~2.5GB) or "intfloat/multilingual-e5-base" (~1.5GB) +# IMPORTANT: If you change the embedding model (sentence-transformers/all-MiniLM-L6-v2) and vice versa, you aren't able to use RAG Chat with your previous documents loaded in the WebUI! You need to re-embed them. +ARG USE_EMBEDDING_MODEL=sentence-transformers/all-MiniLM-L6-v2 +ARG USE_RERANKING_MODEL="" + +# Tiktoken encoding name; models to use can be found at https://huggingface.co/models?library=tiktoken +ARG USE_TIKTOKEN_ENCODING_NAME="cl100k_base" + +ARG BUILD_HASH=dev-build +# Override at your own risk - non-root configurations are untested +ARG UID=0 +ARG GID=0 + +######## WebUI frontend ######## +FROM --platform=$BUILDPLATFORM node:22-alpine3.20 AS build +ARG BUILD_HASH -# Ustaw katalog roboczy w kontenerze WORKDIR /app -# Zainstaluj git -RUN apt-get update && apt-get install -y git nano wget curl iputils-ping +COPY package.json package-lock.json ./ +RUN npm ci -# Skopiuj pliki wymagań (jeśli istnieją) i zainstaluj zależności -COPY requirements.txt . -RUN pip install --no-cache-dir -r requirements.txt - -# Skopiuj plik requirements.txt do kontenera -COPY requirements.txt . - -# Zainstaluj zależności z pliku requirements.txt -RUN pip install --no-cache-dir -r requirements.txt - -# Zainstaluj Tesseract OCR -RUN apt-get install -y tesseract-ocr - -# Skopiuj kod źródłowy do kontenera COPY . . -COPY entrypoint.sh /entrypoint.sh +ENV APP_BUILD_HASH=${BUILD_HASH} +RUN npm run build -RUN chmod +x /entrypoint.sh +######## WebUI backend ######## +FROM python:3.11-slim-bookworm AS base -# Uruchom aplikację -ENTRYPOINT ["/entrypoint.sh"] +# Use args +ARG USE_CUDA +ARG USE_OLLAMA +ARG USE_CUDA_VER +ARG USE_EMBEDDING_MODEL +ARG USE_RERANKING_MODEL +ARG UID +ARG GID + +## Basis ## +ENV ENV=prod \ + PORT=8080 \ + # pass build args to the build + USE_OLLAMA_DOCKER=${USE_OLLAMA} \ + USE_CUDA_DOCKER=${USE_CUDA} \ + USE_CUDA_DOCKER_VER=${USE_CUDA_VER} \ + USE_EMBEDDING_MODEL_DOCKER=${USE_EMBEDDING_MODEL} \ + USE_RERANKING_MODEL_DOCKER=${USE_RERANKING_MODEL} + +## Basis URL Config ## +ENV OLLAMA_BASE_URL="/ollama" \ + OPENAI_API_BASE_URL="" + +## API Key and Security Config ## +ENV OPENAI_API_KEY="" \ + WEBUI_SECRET_KEY="" \ + SCARF_NO_ANALYTICS=true \ + DO_NOT_TRACK=true \ + ANONYMIZED_TELEMETRY=false + +#### Other models ######################################################### +## whisper TTS model settings ## +ENV WHISPER_MODEL="base" \ + WHISPER_MODEL_DIR="/app/backend/data/cache/whisper/models" + +## RAG Embedding model settings ## +ENV RAG_EMBEDDING_MODEL="$USE_EMBEDDING_MODEL_DOCKER" \ + RAG_RERANKING_MODEL="$USE_RERANKING_MODEL_DOCKER" \ + SENTENCE_TRANSFORMERS_HOME="/app/backend/data/cache/embedding/models" + +## Tiktoken model settings ## +ENV TIKTOKEN_ENCODING_NAME="cl100k_base" \ + TIKTOKEN_CACHE_DIR="/app/backend/data/cache/tiktoken" + +## Hugging Face download cache ## +ENV HF_HOME="/app/backend/data/cache/embedding/models" + +## Torch Extensions ## +# ENV TORCH_EXTENSIONS_DIR="/.cache/torch_extensions" + +#### Other models ########################################################## + +WORKDIR /app/backend + +ENV HOME=/root +# Create user and group if not root +RUN if [ $UID -ne 0 ]; then \ + if [ $GID -ne 0 ]; then \ + addgroup --gid $GID app; \ + fi; \ + adduser --uid $UID --gid $GID --home $HOME --disabled-password --no-create-home app; \ + fi + +RUN mkdir -p $HOME/.cache/chroma +RUN echo -n 00000000-0000-0000-0000-000000000000 > $HOME/.cache/chroma/telemetry_user_id + +# Make sure the user has access to the app and root directory +RUN chown -R $UID:$GID /app $HOME + +RUN if [ "$USE_OLLAMA" = "true" ]; then \ + apt-get update && \ + # Install pandoc and netcat + apt-get install -y --no-install-recommends git build-essential pandoc netcat-openbsd curl && \ + apt-get install -y --no-install-recommends gcc python3-dev && \ + # for RAG OCR + apt-get install -y --no-install-recommends ffmpeg libsm6 libxext6 && \ + # install helper tools + apt-get install -y --no-install-recommends curl jq && \ + # install ollama + curl -fsSL https://ollama.com/install.sh | sh && \ + # cleanup + rm -rf /var/lib/apt/lists/*; \ + else \ + apt-get update && \ + # Install pandoc, netcat and gcc + apt-get install -y --no-install-recommends git build-essential pandoc gcc netcat-openbsd curl jq && \ + apt-get install -y --no-install-recommends gcc python3-dev && \ + # for RAG OCR + apt-get install -y --no-install-recommends ffmpeg libsm6 libxext6 && \ + # cleanup + rm -rf /var/lib/apt/lists/*; \ + fi + +# install python dependencies +COPY --chown=$UID:$GID ./backend/requirements.txt ./requirements.txt + +RUN pip3 install uv && \ + if [ "$USE_CUDA" = "true" ]; then \ + # If you use CUDA the whisper and embedding model will be downloaded on first use + pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/$USE_CUDA_DOCKER_VER --no-cache-dir && \ + uv pip install --system -r requirements.txt --no-cache-dir && \ + python -c "import os; from sentence_transformers import SentenceTransformer; SentenceTransformer(os.environ['RAG_EMBEDDING_MODEL'], device='cpu')" && \ + python -c "import os; from faster_whisper import WhisperModel; WhisperModel(os.environ['WHISPER_MODEL'], device='cpu', compute_type='int8', download_root=os.environ['WHISPER_MODEL_DIR'])"; \ + python -c "import os; import tiktoken; tiktoken.get_encoding(os.environ['TIKTOKEN_ENCODING_NAME'])"; \ + else \ + pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu --no-cache-dir && \ + uv pip install --system -r requirements.txt --no-cache-dir && \ + python -c "import os; from sentence_transformers import SentenceTransformer; SentenceTransformer(os.environ['RAG_EMBEDDING_MODEL'], device='cpu')" && \ + python -c "import os; from faster_whisper import WhisperModel; WhisperModel(os.environ['WHISPER_MODEL'], device='cpu', compute_type='int8', download_root=os.environ['WHISPER_MODEL_DIR'])"; \ + python -c "import os; import tiktoken; tiktoken.get_encoding(os.environ['TIKTOKEN_ENCODING_NAME'])"; \ + fi; \ + chown -R $UID:$GID /app/backend/data/ + + + +# copy embedding weight from build +# RUN mkdir -p /root/.cache/chroma/onnx_models/all-MiniLM-L6-v2 +# COPY --from=build /app/onnx /root/.cache/chroma/onnx_models/all-MiniLM-L6-v2/onnx + +# copy built frontend files +COPY --chown=$UID:$GID --from=build /app/build /app/build +COPY --chown=$UID:$GID --from=build /app/CHANGELOG.md /app/CHANGELOG.md +COPY --chown=$UID:$GID --from=build /app/package.json /app/package.json + +# copy backend files +COPY --chown=$UID:$GID ./backend . + +EXPOSE 8080 + +HEALTHCHECK CMD curl --silent --fail http://localhost:${PORT:-8080}/health | jq -ne 'input.status == true' || exit 1 + +USER $UID:$GID + +ARG BUILD_HASH +ENV WEBUI_BUILD_VERSION=${BUILD_HASH} +ENV DOCKER=true + +CMD [ "bash", "start.sh"] diff --git a/INSTALLATION.md b/INSTALLATION.md new file mode 100644 index 0000000..4298b17 --- /dev/null +++ b/INSTALLATION.md @@ -0,0 +1,35 @@ +### Installing Both Ollama and Open WebUI Using Kustomize + +For cpu-only pod + +```bash +kubectl apply -f ./kubernetes/manifest/base +``` + +For gpu-enabled pod + +```bash +kubectl apply -k ./kubernetes/manifest +``` + +### Installing Both Ollama and Open WebUI Using Helm + +Package Helm file first + +```bash +helm package ./kubernetes/helm/ +``` + +For cpu-only pod + +```bash +helm install ollama-webui ./ollama-webui-*.tgz +``` + +For gpu-enabled pod + +```bash +helm install ollama-webui ./ollama-webui-*.tgz --set ollama.resources.limits.nvidia.com/gpu="1" +``` + +Check the `kubernetes/helm/values.yaml` file to know which parameters are available for customization diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..89109d7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2023-2025 Timothy Jaeryang Baek +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4b60b04 --- /dev/null +++ b/Makefile @@ -0,0 +1,33 @@ + +ifneq ($(shell which docker-compose 2>/dev/null),) + DOCKER_COMPOSE := docker-compose +else + DOCKER_COMPOSE := docker compose +endif + +install: + $(DOCKER_COMPOSE) up -d + +remove: + @chmod +x confirm_remove.sh + @./confirm_remove.sh + +start: + $(DOCKER_COMPOSE) start +startAndBuild: + $(DOCKER_COMPOSE) up -d --build + +stop: + $(DOCKER_COMPOSE) stop + +update: + # Calls the LLM update script + chmod +x update_ollama_models.sh + @./update_ollama_models.sh + @git pull + $(DOCKER_COMPOSE) down + # Make sure the ollama-webui container is stopped before rebuilding + @docker stop open-webui || true + $(DOCKER_COMPOSE) up --build -d + $(DOCKER_COMPOSE) start + diff --git a/TROUBLESHOOTING.md b/TROUBLESHOOTING.md new file mode 100644 index 0000000..83251a3 --- /dev/null +++ b/TROUBLESHOOTING.md @@ -0,0 +1,36 @@ +# Open WebUI Troubleshooting Guide + +## Understanding the Open WebUI Architecture + +The Open WebUI system is designed to streamline interactions between the client (your browser) and the Ollama API. At the heart of this design is a backend reverse proxy, enhancing security and resolving CORS issues. + +- **How it Works**: The Open WebUI is designed to interact with the Ollama API through a specific route. When a request is made from the WebUI to Ollama, it is not directly sent to the Ollama API. Initially, the request is sent to the Open WebUI backend via `/ollama` route. From there, the backend is responsible for forwarding the request to the Ollama API. This forwarding is accomplished by using the route specified in the `OLLAMA_BASE_URL` environment variable. Therefore, a request made to `/ollama` in the WebUI is effectively the same as making a request to `OLLAMA_BASE_URL` in the backend. For instance, a request to `/ollama/api/tags` in the WebUI is equivalent to `OLLAMA_BASE_URL/api/tags` in the backend. + +- **Security Benefits**: This design prevents direct exposure of the Ollama API to the frontend, safeguarding against potential CORS (Cross-Origin Resource Sharing) issues and unauthorized access. Requiring authentication to access the Ollama API further enhances this security layer. + +## Open WebUI: Server Connection Error + +If you're experiencing connection issues, it’s often due to the WebUI docker container not being able to reach the Ollama server at 127.0.0.1:11434 (host.docker.internal:11434) inside the container . Use the `--network=host` flag in your docker command to resolve this. Note that the port changes from 3000 to 8080, resulting in the link: `http://localhost:8080`. + +**Example Docker Command**: + +```bash +docker run -d --network=host -v open-webui:/app/backend/data -e OLLAMA_BASE_URL=http://127.0.0.1:11434 --name open-webui --restart always ghcr.io/open-webui/open-webui:main +``` + +### Error on Slow Responses for Ollama + +Open WebUI has a default timeout of 5 minutes for Ollama to finish generating the response. If needed, this can be adjusted via the environment variable AIOHTTP_CLIENT_TIMEOUT, which sets the timeout in seconds. + +### General Connection Errors + +**Ensure Ollama Version is Up-to-Date**: Always start by checking that you have the latest version of Ollama. Visit [Ollama's official site](https://ollama.com/) for the latest updates. + +**Troubleshooting Steps**: + +1. **Verify Ollama URL Format**: + - When running the Web UI container, ensure the `OLLAMA_BASE_URL` is correctly set. (e.g., `http://192.168.1.1:11434` for different host setups). + - In the Open WebUI, navigate to "Settings" > "General". + - Confirm that the Ollama Server URL is correctly set to `[OLLAMA URL]` (e.g., `http://localhost:11434`). + +By following these enhanced troubleshooting steps, connection issues should be effectively resolved. For further assistance or queries, feel free to reach out to us on our community Discord. diff --git a/allegro.py b/allegro.py deleted file mode 100644 index 978af6f..0000000 --- a/allegro.py +++ /dev/null @@ -1,120 +0,0 @@ -import os -os.environ["TOKENIZERS_PARALLELISM"] = "false" - -import torch -import numpy as np -from sentence_transformers import SentenceTransformer -from datasets import Dataset -from peft import LoraConfig, get_peft_model -from transformers import AutoModelForSeq2SeqLM, AutoTokenizer, TrainingArguments, Trainer, DataCollatorForSeq2Seq -import weaviate -from weaviate.client import WeaviateClient -from weaviate.connect import ConnectionParams - -# 1️⃣ Inicjalizacja modelu do embeddingów -embed_model = SentenceTransformer("all-MiniLM-L6-v2") - -# 2️⃣ Połączenie z Weaviate i pobranie dokumentów -client = WeaviateClient( - connection_params=ConnectionParams.from_params( - http_host="weaviate", - http_port=8080, - http_secure=False, - grpc_host="weaviate", - grpc_port=50051, - grpc_secure=False, - ) -) - -collection_name = "Document" # Zakładam, że to jest nazwa Twojej kolekcji -result = ( - client.query.get(collection_name, ["content"]) - .with_additional(["id"]) - .do() -) - -documents = [item['content'] for item in result['data']['Get'][collection_name]] - -# 3️⃣ Generowanie embeddingów -embeddings = embed_model.encode(documents) - -# 4️⃣ Przygotowanie danych treningowych -def create_training_data(): - data = { - "text": documents, - "embedding": embeddings.tolist() - } - return Dataset.from_dict(data) - -dataset = create_training_data() - -# Podział danych na treningowe i ewaluacyjne -split_dataset = dataset.train_test_split(test_size=0.25) -train_dataset = split_dataset["train"] -eval_dataset = split_dataset["test"] - -# 5️⃣ Ładowanie modelu allegro/multislav-5lang -device = "cuda" if torch.cuda.is_available() else "cpu" -model_name = "allegro/multislav-5lang" -model = AutoModelForSeq2SeqLM.from_pretrained(model_name).to(device) -tokenizer = AutoTokenizer.from_pretrained(model_name) - -# 6️⃣ Konfiguracja LoRA -lora_config = LoraConfig( - r=8, lora_alpha=32, lora_dropout=0.1, bias="none", task_type="SEQ_2_SEQ_LM" -) -model = get_peft_model(model, lora_config) - -# 7️⃣ Tokenizacja danych -max_length = 384 - -def tokenize_function(examples): - return tokenizer( - examples["text"], - padding="max_length", - truncation=True, - max_length=max_length - ) - -tokenized_train = train_dataset.map(tokenize_function, batched=True) -tokenized_eval = eval_dataset.map(tokenize_function, batched=True) - -# 8️⃣ Parametry treningu -training_args = TrainingArguments( - output_dir="./results", - eval_strategy="steps", - eval_steps=500, - save_strategy="steps", - save_steps=500, - learning_rate=1e-5, - per_device_train_batch_size=2, - per_device_eval_batch_size=2, - num_train_epochs=16, - weight_decay=0.01, - load_best_model_at_end=True, - metric_for_best_model="loss", - greater_is_better=False, -) - -# 9️⃣ Data Collator -data_collator = DataCollatorForSeq2Seq( - tokenizer=tokenizer, - model=model -) - -# 🔟 Trening modelu -trainer = Trainer( - model=model, - args=training_args, - train_dataset=tokenized_train, - eval_dataset=tokenized_eval, - data_collator=data_collator, -) - -trainer.train() - -# 1️⃣1️⃣ Zapis modelu -model.save_pretrained("./models/allegro") -tokenizer.save_pretrained("./models/allegro") - -print("✅ Model został wytrenowany i zapisany!") diff --git a/backend/.dockerignore b/backend/.dockerignore new file mode 100644 index 0000000..97ab328 --- /dev/null +++ b/backend/.dockerignore @@ -0,0 +1,14 @@ +__pycache__ +.env +_old +uploads +.ipynb_checkpoints +*.db +_test +!/data +/data/* +!/data/litellm +/data/litellm/* +!data/litellm/config.yaml + +!data/config.json \ No newline at end of file diff --git a/backend/.gitignore b/backend/.gitignore new file mode 100644 index 0000000..614a5f7 --- /dev/null +++ b/backend/.gitignore @@ -0,0 +1,12 @@ +__pycache__ +.env +_old +uploads +.ipynb_checkpoints +*.db +_test +Pipfile +!/data +/data/* +/open_webui/data/* +.webui_secret_key \ No newline at end of file diff --git a/backend/dev.sh b/backend/dev.sh new file mode 100755 index 0000000..5449ab7 --- /dev/null +++ b/backend/dev.sh @@ -0,0 +1,2 @@ +PORT="${PORT:-8080}" +uvicorn open_webui.main:app --port $PORT --host 0.0.0.0 --forwarded-allow-ips '*' --reload \ No newline at end of file diff --git a/backend/open_webui/__init__.py b/backend/open_webui/__init__.py new file mode 100644 index 0000000..d85be48 --- /dev/null +++ b/backend/open_webui/__init__.py @@ -0,0 +1,96 @@ +import base64 +import os +import random +from pathlib import Path + +import typer +import uvicorn +from typing import Optional +from typing_extensions import Annotated + +app = typer.Typer() + +KEY_FILE = Path.cwd() / ".webui_secret_key" + + +def version_callback(value: bool): + if value: + from open_webui.env import VERSION + + typer.echo(f"Open WebUI version: {VERSION}") + raise typer.Exit() + + +@app.command() +def main( + version: Annotated[ + Optional[bool], typer.Option("--version", callback=version_callback) + ] = None, +): + pass + + +@app.command() +def serve( + host: str = "0.0.0.0", + port: int = 8080, +): + os.environ["FROM_INIT_PY"] = "true" + if os.getenv("WEBUI_SECRET_KEY") is None: + typer.echo( + "Loading WEBUI_SECRET_KEY from file, not provided as an environment variable." + ) + if not KEY_FILE.exists(): + typer.echo(f"Generating a new secret key and saving it to {KEY_FILE}") + KEY_FILE.write_bytes(base64.b64encode(random.randbytes(12))) + typer.echo(f"Loading WEBUI_SECRET_KEY from {KEY_FILE}") + os.environ["WEBUI_SECRET_KEY"] = KEY_FILE.read_text() + + if os.getenv("USE_CUDA_DOCKER", "false") == "true": + typer.echo( + "CUDA is enabled, appending LD_LIBRARY_PATH to include torch/cudnn & cublas libraries." + ) + LD_LIBRARY_PATH = os.getenv("LD_LIBRARY_PATH", "").split(":") + os.environ["LD_LIBRARY_PATH"] = ":".join( + LD_LIBRARY_PATH + + [ + "/usr/local/lib/python3.11/site-packages/torch/lib", + "/usr/local/lib/python3.11/site-packages/nvidia/cudnn/lib", + ] + ) + try: + import torch + + assert torch.cuda.is_available(), "CUDA not available" + typer.echo("CUDA seems to be working") + except Exception as e: + typer.echo( + "Error when testing CUDA but USE_CUDA_DOCKER is true. " + "Resetting USE_CUDA_DOCKER to false and removing " + f"LD_LIBRARY_PATH modifications: {e}" + ) + os.environ["USE_CUDA_DOCKER"] = "false" + os.environ["LD_LIBRARY_PATH"] = ":".join(LD_LIBRARY_PATH) + + import open_webui.main # we need set environment variables before importing main + + uvicorn.run(open_webui.main.app, host=host, port=port, forwarded_allow_ips="*") + + +@app.command() +def dev( + host: str = "0.0.0.0", + port: int = 8080, + reload: bool = True, +): + uvicorn.run( + "open_webui.main:app", + host=host, + port=port, + reload=reload, + forwarded_allow_ips="*", + ) + + +if __name__ == "__main__": + app() diff --git a/backend/open_webui/alembic.ini b/backend/open_webui/alembic.ini new file mode 100644 index 0000000..4eff85f --- /dev/null +++ b/backend/open_webui/alembic.ini @@ -0,0 +1,114 @@ +# A generic, single database configuration. + +[alembic] +# path to migration scripts +script_location = migrations + +# template used to generate migration file names; The default value is %%(rev)s_%%(slug)s +# Uncomment the line below if you want the files to be prepended with date and time +# file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s + +# sys.path path, will be prepended to sys.path if present. +# defaults to the current working directory. +prepend_sys_path = . + +# timezone to use when rendering the date within the migration file +# as well as the filename. +# If specified, requires the python>=3.9 or backports.zoneinfo library. +# Any required deps can installed by adding `alembic[tz]` to the pip requirements +# string value is passed to ZoneInfo() +# leave blank for localtime +# timezone = + +# max length of characters to apply to the +# "slug" field +# truncate_slug_length = 40 + +# set to 'true' to run the environment during +# the 'revision' command, regardless of autogenerate +# revision_environment = false + +# set to 'true' to allow .pyc and .pyo files without +# a source .py file to be detected as revisions in the +# versions/ directory +# sourceless = false + +# version location specification; This defaults +# to migrations/versions. When using multiple version +# directories, initial revisions must be specified with --version-path. +# The path separator used here should be the separator specified by "version_path_separator" below. +# version_locations = %(here)s/bar:%(here)s/bat:migrations/versions + +# version path separator; As mentioned above, this is the character used to split +# version_locations. The default within new alembic.ini files is "os", which uses os.pathsep. +# If this key is omitted entirely, it falls back to the legacy behavior of splitting on spaces and/or commas. +# Valid values for version_path_separator are: +# +# version_path_separator = : +# version_path_separator = ; +# version_path_separator = space +version_path_separator = os # Use os.pathsep. Default configuration used for new projects. + +# set to 'true' to search source files recursively +# in each "version_locations" directory +# new in Alembic version 1.10 +# recursive_version_locations = false + +# the output encoding used when revision files +# are written from script.py.mako +# output_encoding = utf-8 + +# sqlalchemy.url = REPLACE_WITH_DATABASE_URL + + +[post_write_hooks] +# post_write_hooks defines scripts or Python functions that are run +# on newly generated revision scripts. See the documentation for further +# detail and examples + +# format using "black" - use the console_scripts runner, against the "black" entrypoint +# hooks = black +# black.type = console_scripts +# black.entrypoint = black +# black.options = -l 79 REVISION_SCRIPT_FILENAME + +# lint with attempts to fix using "ruff" - use the exec runner, execute a binary +# hooks = ruff +# ruff.type = exec +# ruff.executable = %(here)s/.venv/bin/ruff +# ruff.options = --fix REVISION_SCRIPT_FILENAME + +# Logging configuration +[loggers] +keys = root,sqlalchemy,alembic + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = WARN +handlers = console +qualname = + +[logger_sqlalchemy] +level = WARN +handlers = +qualname = sqlalchemy.engine + +[logger_alembic] +level = INFO +handlers = +qualname = alembic + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(levelname)-5.5s [%(name)s] %(message)s +datefmt = %H:%M:%S diff --git a/backend/open_webui/config.py b/backend/open_webui/config.py new file mode 100644 index 0000000..19abbf1 --- /dev/null +++ b/backend/open_webui/config.py @@ -0,0 +1,2436 @@ +import json +import logging +import os +import shutil +import base64 + +from datetime import datetime +from pathlib import Path +from typing import Generic, Optional, TypeVar +from urllib.parse import urlparse + +import requests +from pydantic import BaseModel +from sqlalchemy import JSON, Column, DateTime, Integer, func + +from open_webui.env import ( + DATA_DIR, + DATABASE_URL, + ENV, + FRONTEND_BUILD_DIR, + OFFLINE_MODE, + OPEN_WEBUI_DIR, + WEBUI_AUTH, + WEBUI_FAVICON_URL, + WEBUI_NAME, + log, +) +from open_webui.internal.db import Base, get_db + + +class EndpointFilter(logging.Filter): + def filter(self, record: logging.LogRecord) -> bool: + return record.getMessage().find("/health") == -1 + + +# Filter out /endpoint +logging.getLogger("uvicorn.access").addFilter(EndpointFilter()) + +#################################### +# Config helpers +#################################### + + +# Function to run the alembic migrations +def run_migrations(): + log.info("Running migrations") + try: + from alembic import command + from alembic.config import Config + + alembic_cfg = Config(OPEN_WEBUI_DIR / "alembic.ini") + + # Set the script location dynamically + migrations_path = OPEN_WEBUI_DIR / "migrations" + alembic_cfg.set_main_option("script_location", str(migrations_path)) + + command.upgrade(alembic_cfg, "head") + except Exception as e: + log.exception(f"Error running migrations: {e}") + + +run_migrations() + + +class Config(Base): + __tablename__ = "config" + + id = Column(Integer, primary_key=True) + data = Column(JSON, nullable=False) + version = Column(Integer, nullable=False, default=0) + created_at = Column(DateTime, nullable=False, server_default=func.now()) + updated_at = Column(DateTime, nullable=True, onupdate=func.now()) + + +def load_json_config(): + with open(f"{DATA_DIR}/config.json", "r") as file: + return json.load(file) + + +def save_to_db(data): + with get_db() as db: + existing_config = db.query(Config).first() + if not existing_config: + new_config = Config(data=data, version=0) + db.add(new_config) + else: + existing_config.data = data + existing_config.updated_at = datetime.now() + db.add(existing_config) + db.commit() + + +def reset_config(): + with get_db() as db: + db.query(Config).delete() + db.commit() + + +# When initializing, check if config.json exists and migrate it to the database +if os.path.exists(f"{DATA_DIR}/config.json"): + data = load_json_config() + save_to_db(data) + os.rename(f"{DATA_DIR}/config.json", f"{DATA_DIR}/old_config.json") + +DEFAULT_CONFIG = { + "version": 0, + "ui": { + "default_locale": "", + "prompt_suggestions": [ + { + "title": [ + "Help me study", + "vocabulary for a college entrance exam", + ], + "content": "Help me study vocabulary: write a sentence for me to fill in the blank, and I'll try to pick the correct option.", + }, + { + "title": [ + "Give me ideas", + "for what to do with my kids' art", + ], + "content": "What are 5 creative things I could do with my kids' art? I don't want to throw them away, but it's also so much clutter.", + }, + { + "title": ["Tell me a fun fact", "about the Roman Empire"], + "content": "Tell me a random fun fact about the Roman Empire", + }, + { + "title": [ + "Show me a code snippet", + "of a website's sticky header", + ], + "content": "Show me a code snippet of a website's sticky header in CSS and JavaScript.", + }, + { + "title": [ + "Explain options trading", + "if I'm familiar with buying and selling stocks", + ], + "content": "Explain options trading in simple terms if I'm familiar with buying and selling stocks.", + }, + { + "title": ["Overcome procrastination", "give me tips"], + "content": "Could you start by asking me about instances when I procrastinate the most and then give me some suggestions to overcome it?", + }, + { + "title": [ + "Grammar check", + "rewrite it for better readability ", + ], + "content": 'Check the following sentence for grammar and clarity: "[sentence]". Rewrite it for better readability while maintaining its original meaning.', + }, + ], + }, +} + + +def get_config(): + with get_db() as db: + config_entry = db.query(Config).order_by(Config.id.desc()).first() + return config_entry.data if config_entry else DEFAULT_CONFIG + + +CONFIG_DATA = get_config() + + +def get_config_value(config_path: str): + path_parts = config_path.split(".") + cur_config = CONFIG_DATA + for key in path_parts: + if key in cur_config: + cur_config = cur_config[key] + else: + return None + return cur_config + + +PERSISTENT_CONFIG_REGISTRY = [] + + +def save_config(config): + global CONFIG_DATA + global PERSISTENT_CONFIG_REGISTRY + try: + save_to_db(config) + CONFIG_DATA = config + + # Trigger updates on all registered PersistentConfig entries + for config_item in PERSISTENT_CONFIG_REGISTRY: + config_item.update() + except Exception as e: + log.exception(e) + return False + return True + + +T = TypeVar("T") + + +class PersistentConfig(Generic[T]): + def __init__(self, env_name: str, config_path: str, env_value: T): + self.env_name = env_name + self.config_path = config_path + self.env_value = env_value + self.config_value = get_config_value(config_path) + if self.config_value is not None: + log.info(f"'{env_name}' loaded from the latest database entry") + self.value = self.config_value + else: + self.value = env_value + + PERSISTENT_CONFIG_REGISTRY.append(self) + + def __str__(self): + return str(self.value) + + @property + def __dict__(self): + raise TypeError( + "PersistentConfig object cannot be converted to dict, use config_get or .value instead." + ) + + def __getattribute__(self, item): + if item == "__dict__": + raise TypeError( + "PersistentConfig object cannot be converted to dict, use config_get or .value instead." + ) + return super().__getattribute__(item) + + def update(self): + new_value = get_config_value(self.config_path) + if new_value is not None: + self.value = new_value + log.info(f"Updated {self.env_name} to new value {self.value}") + + def save(self): + log.info(f"Saving '{self.env_name}' to the database") + path_parts = self.config_path.split(".") + sub_config = CONFIG_DATA + for key in path_parts[:-1]: + if key not in sub_config: + sub_config[key] = {} + sub_config = sub_config[key] + sub_config[path_parts[-1]] = self.value + save_to_db(CONFIG_DATA) + self.config_value = self.value + + +class AppConfig: + _state: dict[str, PersistentConfig] + + def __init__(self): + super().__setattr__("_state", {}) + + def __setattr__(self, key, value): + if isinstance(value, PersistentConfig): + self._state[key] = value + else: + self._state[key].value = value + self._state[key].save() + + def __getattr__(self, key): + return self._state[key].value + + +#################################### +# WEBUI_AUTH (Required for security) +#################################### + +ENABLE_API_KEY = PersistentConfig( + "ENABLE_API_KEY", + "auth.api_key.enable", + os.environ.get("ENABLE_API_KEY", "True").lower() == "true", +) + +ENABLE_API_KEY_ENDPOINT_RESTRICTIONS = PersistentConfig( + "ENABLE_API_KEY_ENDPOINT_RESTRICTIONS", + "auth.api_key.endpoint_restrictions", + os.environ.get("ENABLE_API_KEY_ENDPOINT_RESTRICTIONS", "False").lower() == "true", +) + +API_KEY_ALLOWED_ENDPOINTS = PersistentConfig( + "API_KEY_ALLOWED_ENDPOINTS", + "auth.api_key.allowed_endpoints", + os.environ.get("API_KEY_ALLOWED_ENDPOINTS", ""), +) + + +JWT_EXPIRES_IN = PersistentConfig( + "JWT_EXPIRES_IN", "auth.jwt_expiry", os.environ.get("JWT_EXPIRES_IN", "-1") +) + +#################################### +# OAuth config +#################################### + +ENABLE_OAUTH_SIGNUP = PersistentConfig( + "ENABLE_OAUTH_SIGNUP", + "oauth.enable_signup", + os.environ.get("ENABLE_OAUTH_SIGNUP", "False").lower() == "true", +) + +OAUTH_MERGE_ACCOUNTS_BY_EMAIL = PersistentConfig( + "OAUTH_MERGE_ACCOUNTS_BY_EMAIL", + "oauth.merge_accounts_by_email", + os.environ.get("OAUTH_MERGE_ACCOUNTS_BY_EMAIL", "False").lower() == "true", +) + +OAUTH_PROVIDERS = {} + +GOOGLE_CLIENT_ID = PersistentConfig( + "GOOGLE_CLIENT_ID", + "oauth.google.client_id", + os.environ.get("GOOGLE_CLIENT_ID", ""), +) + +GOOGLE_CLIENT_SECRET = PersistentConfig( + "GOOGLE_CLIENT_SECRET", + "oauth.google.client_secret", + os.environ.get("GOOGLE_CLIENT_SECRET", ""), +) + + +GOOGLE_OAUTH_SCOPE = PersistentConfig( + "GOOGLE_OAUTH_SCOPE", + "oauth.google.scope", + os.environ.get("GOOGLE_OAUTH_SCOPE", "openid email profile"), +) + +GOOGLE_REDIRECT_URI = PersistentConfig( + "GOOGLE_REDIRECT_URI", + "oauth.google.redirect_uri", + os.environ.get("GOOGLE_REDIRECT_URI", ""), +) + +MICROSOFT_CLIENT_ID = PersistentConfig( + "MICROSOFT_CLIENT_ID", + "oauth.microsoft.client_id", + os.environ.get("MICROSOFT_CLIENT_ID", ""), +) + +MICROSOFT_CLIENT_SECRET = PersistentConfig( + "MICROSOFT_CLIENT_SECRET", + "oauth.microsoft.client_secret", + os.environ.get("MICROSOFT_CLIENT_SECRET", ""), +) + +MICROSOFT_CLIENT_TENANT_ID = PersistentConfig( + "MICROSOFT_CLIENT_TENANT_ID", + "oauth.microsoft.tenant_id", + os.environ.get("MICROSOFT_CLIENT_TENANT_ID", ""), +) + +MICROSOFT_OAUTH_SCOPE = PersistentConfig( + "MICROSOFT_OAUTH_SCOPE", + "oauth.microsoft.scope", + os.environ.get("MICROSOFT_OAUTH_SCOPE", "openid email profile"), +) + +MICROSOFT_REDIRECT_URI = PersistentConfig( + "MICROSOFT_REDIRECT_URI", + "oauth.microsoft.redirect_uri", + os.environ.get("MICROSOFT_REDIRECT_URI", ""), +) + +GITHUB_CLIENT_ID = PersistentConfig( + "GITHUB_CLIENT_ID", + "oauth.github.client_id", + os.environ.get("GITHUB_CLIENT_ID", ""), +) + +GITHUB_CLIENT_SECRET = PersistentConfig( + "GITHUB_CLIENT_SECRET", + "oauth.github.client_secret", + os.environ.get("GITHUB_CLIENT_SECRET", ""), +) + +GITHUB_CLIENT_SCOPE = PersistentConfig( + "GITHUB_CLIENT_SCOPE", + "oauth.github.scope", + os.environ.get("GITHUB_CLIENT_SCOPE", "user:email"), +) + +GITHUB_CLIENT_REDIRECT_URI = PersistentConfig( + "GITHUB_CLIENT_REDIRECT_URI", + "oauth.github.redirect_uri", + os.environ.get("GITHUB_CLIENT_REDIRECT_URI", ""), +) + +OAUTH_CLIENT_ID = PersistentConfig( + "OAUTH_CLIENT_ID", + "oauth.oidc.client_id", + os.environ.get("OAUTH_CLIENT_ID", ""), +) + +OAUTH_CLIENT_SECRET = PersistentConfig( + "OAUTH_CLIENT_SECRET", + "oauth.oidc.client_secret", + os.environ.get("OAUTH_CLIENT_SECRET", ""), +) + +OPENID_PROVIDER_URL = PersistentConfig( + "OPENID_PROVIDER_URL", + "oauth.oidc.provider_url", + os.environ.get("OPENID_PROVIDER_URL", ""), +) + +OPENID_REDIRECT_URI = PersistentConfig( + "OPENID_REDIRECT_URI", + "oauth.oidc.redirect_uri", + os.environ.get("OPENID_REDIRECT_URI", ""), +) + +OAUTH_SCOPES = PersistentConfig( + "OAUTH_SCOPES", + "oauth.oidc.scopes", + os.environ.get("OAUTH_SCOPES", "openid email profile"), +) + +OAUTH_PROVIDER_NAME = PersistentConfig( + "OAUTH_PROVIDER_NAME", + "oauth.oidc.provider_name", + os.environ.get("OAUTH_PROVIDER_NAME", "SSO"), +) + +OAUTH_USERNAME_CLAIM = PersistentConfig( + "OAUTH_USERNAME_CLAIM", + "oauth.oidc.username_claim", + os.environ.get("OAUTH_USERNAME_CLAIM", "name"), +) + +OAUTH_PICTURE_CLAIM = PersistentConfig( + "OAUTH_PICTURE_CLAIM", + "oauth.oidc.avatar_claim", + os.environ.get("OAUTH_PICTURE_CLAIM", "picture"), +) + +OAUTH_EMAIL_CLAIM = PersistentConfig( + "OAUTH_EMAIL_CLAIM", + "oauth.oidc.email_claim", + os.environ.get("OAUTH_EMAIL_CLAIM", "email"), +) + +OAUTH_GROUPS_CLAIM = PersistentConfig( + "OAUTH_GROUPS_CLAIM", + "oauth.oidc.group_claim", + os.environ.get("OAUTH_GROUP_CLAIM", "groups"), +) + +ENABLE_OAUTH_ROLE_MANAGEMENT = PersistentConfig( + "ENABLE_OAUTH_ROLE_MANAGEMENT", + "oauth.enable_role_mapping", + os.environ.get("ENABLE_OAUTH_ROLE_MANAGEMENT", "False").lower() == "true", +) + +ENABLE_OAUTH_GROUP_MANAGEMENT = PersistentConfig( + "ENABLE_OAUTH_GROUP_MANAGEMENT", + "oauth.enable_group_mapping", + os.environ.get("ENABLE_OAUTH_GROUP_MANAGEMENT", "False").lower() == "true", +) + +OAUTH_ROLES_CLAIM = PersistentConfig( + "OAUTH_ROLES_CLAIM", + "oauth.roles_claim", + os.environ.get("OAUTH_ROLES_CLAIM", "roles"), +) + +OAUTH_ALLOWED_ROLES = PersistentConfig( + "OAUTH_ALLOWED_ROLES", + "oauth.allowed_roles", + [ + role.strip() + for role in os.environ.get("OAUTH_ALLOWED_ROLES", "user,admin").split(",") + ], +) + +OAUTH_ADMIN_ROLES = PersistentConfig( + "OAUTH_ADMIN_ROLES", + "oauth.admin_roles", + [role.strip() for role in os.environ.get("OAUTH_ADMIN_ROLES", "admin").split(",")], +) + +OAUTH_ALLOWED_DOMAINS = PersistentConfig( + "OAUTH_ALLOWED_DOMAINS", + "oauth.allowed_domains", + [ + domain.strip() + for domain in os.environ.get("OAUTH_ALLOWED_DOMAINS", "*").split(",") + ], +) + + +def load_oauth_providers(): + OAUTH_PROVIDERS.clear() + if GOOGLE_CLIENT_ID.value and GOOGLE_CLIENT_SECRET.value: + + def google_oauth_register(client): + client.register( + name="google", + client_id=GOOGLE_CLIENT_ID.value, + client_secret=GOOGLE_CLIENT_SECRET.value, + server_metadata_url="https://accounts.google.com/.well-known/openid-configuration", + client_kwargs={"scope": GOOGLE_OAUTH_SCOPE.value}, + redirect_uri=GOOGLE_REDIRECT_URI.value, + ) + + OAUTH_PROVIDERS["google"] = { + "redirect_uri": GOOGLE_REDIRECT_URI.value, + "register": google_oauth_register, + } + + if ( + MICROSOFT_CLIENT_ID.value + and MICROSOFT_CLIENT_SECRET.value + and MICROSOFT_CLIENT_TENANT_ID.value + ): + + def microsoft_oauth_register(client): + client.register( + name="microsoft", + client_id=MICROSOFT_CLIENT_ID.value, + client_secret=MICROSOFT_CLIENT_SECRET.value, + server_metadata_url=f"https://login.microsoftonline.com/{MICROSOFT_CLIENT_TENANT_ID.value}/v2.0/.well-known/openid-configuration", + client_kwargs={ + "scope": MICROSOFT_OAUTH_SCOPE.value, + }, + redirect_uri=MICROSOFT_REDIRECT_URI.value, + ) + + OAUTH_PROVIDERS["microsoft"] = { + "redirect_uri": MICROSOFT_REDIRECT_URI.value, + "picture_url": "https://graph.microsoft.com/v1.0/me/photo/$value", + "register": microsoft_oauth_register, + } + + if GITHUB_CLIENT_ID.value and GITHUB_CLIENT_SECRET.value: + + def github_oauth_register(client): + client.register( + name="github", + client_id=GITHUB_CLIENT_ID.value, + client_secret=GITHUB_CLIENT_SECRET.value, + access_token_url="https://github.com/login/oauth/access_token", + authorize_url="https://github.com/login/oauth/authorize", + api_base_url="https://api.github.com", + userinfo_endpoint="https://api.github.com/user", + client_kwargs={"scope": GITHUB_CLIENT_SCOPE.value}, + redirect_uri=GITHUB_CLIENT_REDIRECT_URI.value, + ) + + OAUTH_PROVIDERS["github"] = { + "redirect_uri": GITHUB_CLIENT_REDIRECT_URI.value, + "register": github_oauth_register, + "sub_claim": "id", + } + + if ( + OAUTH_CLIENT_ID.value + and OAUTH_CLIENT_SECRET.value + and OPENID_PROVIDER_URL.value + ): + + def oidc_oauth_register(client): + client.register( + name="oidc", + client_id=OAUTH_CLIENT_ID.value, + client_secret=OAUTH_CLIENT_SECRET.value, + server_metadata_url=OPENID_PROVIDER_URL.value, + client_kwargs={ + "scope": OAUTH_SCOPES.value, + }, + redirect_uri=OPENID_REDIRECT_URI.value, + ) + + OAUTH_PROVIDERS["oidc"] = { + "name": OAUTH_PROVIDER_NAME.value, + "redirect_uri": OPENID_REDIRECT_URI.value, + "register": oidc_oauth_register, + } + + +load_oauth_providers() + +#################################### +# Static DIR +#################################### + +STATIC_DIR = Path(os.getenv("STATIC_DIR", OPEN_WEBUI_DIR / "static")).resolve() + +frontend_favicon = FRONTEND_BUILD_DIR / "static" / "favicon.png" + +if frontend_favicon.exists(): + try: + shutil.copyfile(frontend_favicon, STATIC_DIR / "favicon.png") + except Exception as e: + logging.error(f"An error occurred: {e}") + +frontend_splash = FRONTEND_BUILD_DIR / "static" / "splash.png" + +if frontend_splash.exists(): + try: + shutil.copyfile(frontend_splash, STATIC_DIR / "splash.png") + except Exception as e: + logging.error(f"An error occurred: {e}") + +frontend_loader = FRONTEND_BUILD_DIR / "static" / "loader.js" + +if frontend_loader.exists(): + try: + shutil.copyfile(frontend_loader, STATIC_DIR / "loader.js") + except Exception as e: + logging.error(f"An error occurred: {e}") + + +#################################### +# CUSTOM_NAME (Legacy) +#################################### + +CUSTOM_NAME = os.environ.get("CUSTOM_NAME", "") + +if CUSTOM_NAME: + try: + r = requests.get(f"https://api.openwebui.com/api/v1/custom/{CUSTOM_NAME}") + data = r.json() + if r.ok: + if "logo" in data: + WEBUI_FAVICON_URL = url = ( + f"https://api.openwebui.com{data['logo']}" + if data["logo"][0] == "/" + else data["logo"] + ) + + r = requests.get(url, stream=True) + if r.status_code == 200: + with open(f"{STATIC_DIR}/favicon.png", "wb") as f: + r.raw.decode_content = True + shutil.copyfileobj(r.raw, f) + + if "splash" in data: + url = ( + f"https://api.openwebui.com{data['splash']}" + if data["splash"][0] == "/" + else data["splash"] + ) + + r = requests.get(url, stream=True) + if r.status_code == 200: + with open(f"{STATIC_DIR}/splash.png", "wb") as f: + r.raw.decode_content = True + shutil.copyfileobj(r.raw, f) + + WEBUI_NAME = data["name"] + except Exception as e: + log.exception(e) + pass + + +#################################### +# LICENSE_KEY +#################################### + +LICENSE_KEY = PersistentConfig( + "LICENSE_KEY", + "license.key", + os.environ.get("LICENSE_KEY", ""), +) + +#################################### +# STORAGE PROVIDER +#################################### + +STORAGE_PROVIDER = os.environ.get("STORAGE_PROVIDER", "local") # defaults to local, s3 + +S3_ACCESS_KEY_ID = os.environ.get("S3_ACCESS_KEY_ID", None) +S3_SECRET_ACCESS_KEY = os.environ.get("S3_SECRET_ACCESS_KEY", None) +S3_REGION_NAME = os.environ.get("S3_REGION_NAME", None) +S3_BUCKET_NAME = os.environ.get("S3_BUCKET_NAME", None) +S3_KEY_PREFIX = os.environ.get("S3_KEY_PREFIX", None) +S3_ENDPOINT_URL = os.environ.get("S3_ENDPOINT_URL", None) +S3_USE_ACCELERATE_ENDPOINT = ( + os.environ.get("S3_USE_ACCELERATE_ENDPOINT", "False").lower() == "true" +) +S3_ADDRESSING_STYLE = os.environ.get("S3_ADDRESSING_STYLE", None) + +GCS_BUCKET_NAME = os.environ.get("GCS_BUCKET_NAME", None) +GOOGLE_APPLICATION_CREDENTIALS_JSON = os.environ.get( + "GOOGLE_APPLICATION_CREDENTIALS_JSON", None +) + +AZURE_STORAGE_ENDPOINT = os.environ.get("AZURE_STORAGE_ENDPOINT", None) +AZURE_STORAGE_CONTAINER_NAME = os.environ.get("AZURE_STORAGE_CONTAINER_NAME", None) +AZURE_STORAGE_KEY = os.environ.get("AZURE_STORAGE_KEY", None) + +#################################### +# File Upload DIR +#################################### + +UPLOAD_DIR = f"{DATA_DIR}/uploads" +Path(UPLOAD_DIR).mkdir(parents=True, exist_ok=True) + + +#################################### +# Cache DIR +#################################### + +CACHE_DIR = f"{DATA_DIR}/cache" +Path(CACHE_DIR).mkdir(parents=True, exist_ok=True) + + +#################################### +# DIRECT CONNECTIONS +#################################### + +ENABLE_DIRECT_CONNECTIONS = PersistentConfig( + "ENABLE_DIRECT_CONNECTIONS", + "direct.enable", + os.environ.get("ENABLE_DIRECT_CONNECTIONS", "True").lower() == "true", +) + +#################################### +# OLLAMA_BASE_URL +#################################### + +ENABLE_OLLAMA_API = PersistentConfig( + "ENABLE_OLLAMA_API", + "ollama.enable", + os.environ.get("ENABLE_OLLAMA_API", "True").lower() == "true", +) + +OLLAMA_API_BASE_URL = os.environ.get( + "OLLAMA_API_BASE_URL", "http://localhost:11434/api" +) + +OLLAMA_BASE_URL = os.environ.get("OLLAMA_BASE_URL", "") +if OLLAMA_BASE_URL: + # Remove trailing slash + OLLAMA_BASE_URL = ( + OLLAMA_BASE_URL[:-1] if OLLAMA_BASE_URL.endswith("/") else OLLAMA_BASE_URL + ) + + +K8S_FLAG = os.environ.get("K8S_FLAG", "") +USE_OLLAMA_DOCKER = os.environ.get("USE_OLLAMA_DOCKER", "false") + +if OLLAMA_BASE_URL == "" and OLLAMA_API_BASE_URL != "": + OLLAMA_BASE_URL = ( + OLLAMA_API_BASE_URL[:-4] + if OLLAMA_API_BASE_URL.endswith("/api") + else OLLAMA_API_BASE_URL + ) + +if ENV == "prod": + if OLLAMA_BASE_URL == "/ollama" and not K8S_FLAG: + if USE_OLLAMA_DOCKER.lower() == "true": + # if you use all-in-one docker container (Open WebUI + Ollama) + # with the docker build arg USE_OLLAMA=true (--build-arg="USE_OLLAMA=true") this only works with http://localhost:11434 + OLLAMA_BASE_URL = "http://localhost:11434" + else: + OLLAMA_BASE_URL = "http://host.docker.internal:11434" + elif K8S_FLAG: + OLLAMA_BASE_URL = "http://ollama-service.open-webui.svc.cluster.local:11434" + + +OLLAMA_BASE_URLS = os.environ.get("OLLAMA_BASE_URLS", "") +OLLAMA_BASE_URLS = OLLAMA_BASE_URLS if OLLAMA_BASE_URLS != "" else OLLAMA_BASE_URL + +OLLAMA_BASE_URLS = [url.strip() for url in OLLAMA_BASE_URLS.split(";")] +OLLAMA_BASE_URLS = PersistentConfig( + "OLLAMA_BASE_URLS", "ollama.base_urls", OLLAMA_BASE_URLS +) + +OLLAMA_API_CONFIGS = PersistentConfig( + "OLLAMA_API_CONFIGS", + "ollama.api_configs", + {}, +) + +#################################### +# OPENAI_API +#################################### + + +ENABLE_OPENAI_API = PersistentConfig( + "ENABLE_OPENAI_API", + "openai.enable", + os.environ.get("ENABLE_OPENAI_API", "True").lower() == "true", +) + + +OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY", "") +OPENAI_API_BASE_URL = os.environ.get("OPENAI_API_BASE_URL", "") + +GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY", "") +GEMINI_API_BASE_URL = os.environ.get("GEMINI_API_BASE_URL", "") + + +if OPENAI_API_BASE_URL == "": + OPENAI_API_BASE_URL = "https://api.openai.com/v1" + +OPENAI_API_KEYS = os.environ.get("OPENAI_API_KEYS", "") +OPENAI_API_KEYS = OPENAI_API_KEYS if OPENAI_API_KEYS != "" else OPENAI_API_KEY + +OPENAI_API_KEYS = [url.strip() for url in OPENAI_API_KEYS.split(";")] +OPENAI_API_KEYS = PersistentConfig( + "OPENAI_API_KEYS", "openai.api_keys", OPENAI_API_KEYS +) + +OPENAI_API_BASE_URLS = os.environ.get("OPENAI_API_BASE_URLS", "") +OPENAI_API_BASE_URLS = ( + OPENAI_API_BASE_URLS if OPENAI_API_BASE_URLS != "" else OPENAI_API_BASE_URL +) + +OPENAI_API_BASE_URLS = [ + url.strip() if url != "" else "https://api.openai.com/v1" + for url in OPENAI_API_BASE_URLS.split(";") +] +OPENAI_API_BASE_URLS = PersistentConfig( + "OPENAI_API_BASE_URLS", "openai.api_base_urls", OPENAI_API_BASE_URLS +) + +OPENAI_API_CONFIGS = PersistentConfig( + "OPENAI_API_CONFIGS", + "openai.api_configs", + {}, +) + +# Get the actual OpenAI API key based on the base URL +OPENAI_API_KEY = "" +try: + OPENAI_API_KEY = OPENAI_API_KEYS.value[ + OPENAI_API_BASE_URLS.value.index("https://api.openai.com/v1") + ] +except Exception: + pass +OPENAI_API_BASE_URL = "https://api.openai.com/v1" + +#################################### +# WEBUI +#################################### + + +WEBUI_URL = PersistentConfig( + "WEBUI_URL", "webui.url", os.environ.get("WEBUI_URL", "http://localhost:3000") +) + + +ENABLE_SIGNUP = PersistentConfig( + "ENABLE_SIGNUP", + "ui.enable_signup", + ( + False + if not WEBUI_AUTH + else os.environ.get("ENABLE_SIGNUP", "True").lower() == "true" + ), +) + +ENABLE_LOGIN_FORM = PersistentConfig( + "ENABLE_LOGIN_FORM", + "ui.ENABLE_LOGIN_FORM", + os.environ.get("ENABLE_LOGIN_FORM", "True").lower() == "true", +) + + +DEFAULT_LOCALE = PersistentConfig( + "DEFAULT_LOCALE", + "ui.default_locale", + os.environ.get("DEFAULT_LOCALE", ""), +) + +DEFAULT_MODELS = PersistentConfig( + "DEFAULT_MODELS", "ui.default_models", os.environ.get("DEFAULT_MODELS", None) +) + +DEFAULT_PROMPT_SUGGESTIONS = PersistentConfig( + "DEFAULT_PROMPT_SUGGESTIONS", + "ui.prompt_suggestions", + [ + { + "title": ["Help me study", "vocabulary for a college entrance exam"], + "content": "Help me study vocabulary: write a sentence for me to fill in the blank, and I'll try to pick the correct option.", + }, + { + "title": ["Give me ideas", "for what to do with my kids' art"], + "content": "What are 5 creative things I could do with my kids' art? I don't want to throw them away, but it's also so much clutter.", + }, + { + "title": ["Tell me a fun fact", "about the Roman Empire"], + "content": "Tell me a random fun fact about the Roman Empire", + }, + { + "title": ["Show me a code snippet", "of a website's sticky header"], + "content": "Show me a code snippet of a website's sticky header in CSS and JavaScript.", + }, + { + "title": [ + "Explain options trading", + "if I'm familiar with buying and selling stocks", + ], + "content": "Explain options trading in simple terms if I'm familiar with buying and selling stocks.", + }, + { + "title": ["Overcome procrastination", "give me tips"], + "content": "Could you start by asking me about instances when I procrastinate the most and then give me some suggestions to overcome it?", + }, + ], +) + +MODEL_ORDER_LIST = PersistentConfig( + "MODEL_ORDER_LIST", + "ui.model_order_list", + [], +) + +DEFAULT_USER_ROLE = PersistentConfig( + "DEFAULT_USER_ROLE", + "ui.default_user_role", + os.getenv("DEFAULT_USER_ROLE", "pending"), +) + +USER_PERMISSIONS_WORKSPACE_MODELS_ACCESS = ( + os.environ.get("USER_PERMISSIONS_WORKSPACE_MODELS_ACCESS", "False").lower() + == "true" +) + +USER_PERMISSIONS_WORKSPACE_KNOWLEDGE_ACCESS = ( + os.environ.get("USER_PERMISSIONS_WORKSPACE_KNOWLEDGE_ACCESS", "False").lower() + == "true" +) + +USER_PERMISSIONS_WORKSPACE_PROMPTS_ACCESS = ( + os.environ.get("USER_PERMISSIONS_WORKSPACE_PROMPTS_ACCESS", "False").lower() + == "true" +) + +USER_PERMISSIONS_WORKSPACE_TOOLS_ACCESS = ( + os.environ.get("USER_PERMISSIONS_WORKSPACE_TOOLS_ACCESS", "False").lower() == "true" +) + +USER_PERMISSIONS_CHAT_CONTROLS = ( + os.environ.get("USER_PERMISSIONS_CHAT_CONTROLS", "True").lower() == "true" +) + +USER_PERMISSIONS_CHAT_FILE_UPLOAD = ( + os.environ.get("USER_PERMISSIONS_CHAT_FILE_UPLOAD", "True").lower() == "true" +) + +USER_PERMISSIONS_CHAT_DELETE = ( + os.environ.get("USER_PERMISSIONS_CHAT_DELETE", "True").lower() == "true" +) + +USER_PERMISSIONS_CHAT_EDIT = ( + os.environ.get("USER_PERMISSIONS_CHAT_EDIT", "True").lower() == "true" +) + +USER_PERMISSIONS_CHAT_TEMPORARY = ( + os.environ.get("USER_PERMISSIONS_CHAT_TEMPORARY", "True").lower() == "true" +) + +USER_PERMISSIONS_FEATURES_WEB_SEARCH = ( + os.environ.get("USER_PERMISSIONS_FEATURES_WEB_SEARCH", "True").lower() == "true" +) + +USER_PERMISSIONS_FEATURES_IMAGE_GENERATION = ( + os.environ.get("USER_PERMISSIONS_FEATURES_IMAGE_GENERATION", "True").lower() + == "true" +) + +USER_PERMISSIONS_FEATURES_CODE_INTERPRETER = ( + os.environ.get("USER_PERMISSIONS_FEATURES_CODE_INTERPRETER", "True").lower() + == "true" +) + + +DEFAULT_USER_PERMISSIONS = { + "workspace": { + "models": USER_PERMISSIONS_WORKSPACE_MODELS_ACCESS, + "knowledge": USER_PERMISSIONS_WORKSPACE_KNOWLEDGE_ACCESS, + "prompts": USER_PERMISSIONS_WORKSPACE_PROMPTS_ACCESS, + "tools": USER_PERMISSIONS_WORKSPACE_TOOLS_ACCESS, + }, + "chat": { + "controls": USER_PERMISSIONS_CHAT_CONTROLS, + "file_upload": USER_PERMISSIONS_CHAT_FILE_UPLOAD, + "delete": USER_PERMISSIONS_CHAT_DELETE, + "edit": USER_PERMISSIONS_CHAT_EDIT, + "temporary": USER_PERMISSIONS_CHAT_TEMPORARY, + }, + "features": { + "web_search": USER_PERMISSIONS_FEATURES_WEB_SEARCH, + "image_generation": USER_PERMISSIONS_FEATURES_IMAGE_GENERATION, + "code_interpreter": USER_PERMISSIONS_FEATURES_CODE_INTERPRETER, + }, +} + +USER_PERMISSIONS = PersistentConfig( + "USER_PERMISSIONS", + "user.permissions", + DEFAULT_USER_PERMISSIONS, +) + +ENABLE_CHANNELS = PersistentConfig( + "ENABLE_CHANNELS", + "channels.enable", + os.environ.get("ENABLE_CHANNELS", "False").lower() == "true", +) + + +ENABLE_EVALUATION_ARENA_MODELS = PersistentConfig( + "ENABLE_EVALUATION_ARENA_MODELS", + "evaluation.arena.enable", + os.environ.get("ENABLE_EVALUATION_ARENA_MODELS", "True").lower() == "true", +) +EVALUATION_ARENA_MODELS = PersistentConfig( + "EVALUATION_ARENA_MODELS", + "evaluation.arena.models", + [], +) + +DEFAULT_ARENA_MODEL = { + "id": "arena-model", + "name": "Arena Model", + "meta": { + "profile_image_url": "/favicon.png", + "description": "Submit your questions to anonymous AI chatbots and vote on the best response.", + "model_ids": None, + }, +} + +WEBHOOK_URL = PersistentConfig( + "WEBHOOK_URL", "webhook_url", os.environ.get("WEBHOOK_URL", "") +) + +ENABLE_ADMIN_EXPORT = os.environ.get("ENABLE_ADMIN_EXPORT", "True").lower() == "true" + +ENABLE_ADMIN_CHAT_ACCESS = ( + os.environ.get("ENABLE_ADMIN_CHAT_ACCESS", "True").lower() == "true" +) + +ENABLE_COMMUNITY_SHARING = PersistentConfig( + "ENABLE_COMMUNITY_SHARING", + "ui.enable_community_sharing", + os.environ.get("ENABLE_COMMUNITY_SHARING", "True").lower() == "true", +) + +ENABLE_MESSAGE_RATING = PersistentConfig( + "ENABLE_MESSAGE_RATING", + "ui.enable_message_rating", + os.environ.get("ENABLE_MESSAGE_RATING", "True").lower() == "true", +) + + +def validate_cors_origins(origins): + for origin in origins: + if origin != "*": + validate_cors_origin(origin) + + +def validate_cors_origin(origin): + parsed_url = urlparse(origin) + + # Check if the scheme is either http or https + if parsed_url.scheme not in ["http", "https"]: + raise ValueError( + f"Invalid scheme in CORS_ALLOW_ORIGIN: '{origin}'. Only 'http' and 'https' are allowed." + ) + + # Ensure that the netloc (domain + port) is present, indicating it's a valid URL + if not parsed_url.netloc: + raise ValueError(f"Invalid URL structure in CORS_ALLOW_ORIGIN: '{origin}'.") + + +# For production, you should only need one host as +# fastapi serves the svelte-kit built frontend and backend from the same host and port. +# To test CORS_ALLOW_ORIGIN locally, you can set something like +# CORS_ALLOW_ORIGIN=http://localhost:5173;http://localhost:8080 +# in your .env file depending on your frontend port, 5173 in this case. +CORS_ALLOW_ORIGIN = os.environ.get("CORS_ALLOW_ORIGIN", "*").split(";") + +if "*" in CORS_ALLOW_ORIGIN: + log.warning( + "\n\nWARNING: CORS_ALLOW_ORIGIN IS SET TO '*' - NOT RECOMMENDED FOR PRODUCTION DEPLOYMENTS.\n" + ) + +validate_cors_origins(CORS_ALLOW_ORIGIN) + + +class BannerModel(BaseModel): + id: str + type: str + title: Optional[str] = None + content: str + dismissible: bool + timestamp: int + + +try: + banners = json.loads(os.environ.get("WEBUI_BANNERS", "[]")) + banners = [BannerModel(**banner) for banner in banners] +except Exception as e: + log.exception(f"Error loading WEBUI_BANNERS: {e}") + banners = [] + +WEBUI_BANNERS = PersistentConfig("WEBUI_BANNERS", "ui.banners", banners) + + +SHOW_ADMIN_DETAILS = PersistentConfig( + "SHOW_ADMIN_DETAILS", + "auth.admin.show", + os.environ.get("SHOW_ADMIN_DETAILS", "true").lower() == "true", +) + +ADMIN_EMAIL = PersistentConfig( + "ADMIN_EMAIL", + "auth.admin.email", + os.environ.get("ADMIN_EMAIL", None), +) + + +#################################### +# TASKS +#################################### + + +TASK_MODEL = PersistentConfig( + "TASK_MODEL", + "task.model.default", + os.environ.get("TASK_MODEL", ""), +) + +TASK_MODEL_EXTERNAL = PersistentConfig( + "TASK_MODEL_EXTERNAL", + "task.model.external", + os.environ.get("TASK_MODEL_EXTERNAL", ""), +) + +TITLE_GENERATION_PROMPT_TEMPLATE = PersistentConfig( + "TITLE_GENERATION_PROMPT_TEMPLATE", + "task.title.prompt_template", + os.environ.get("TITLE_GENERATION_PROMPT_TEMPLATE", ""), +) + +DEFAULT_TITLE_GENERATION_PROMPT_TEMPLATE = """### Task: +Generate a concise, 3-5 word title with an emoji summarizing the chat history. +### Guidelines: +- The title should clearly represent the main theme or subject of the conversation. +- Use emojis that enhance understanding of the topic, but avoid quotation marks or special formatting. +- Write the title in the chat's primary language; default to English if multilingual. +- Prioritize accuracy over excessive creativity; keep it clear and simple. +### Output: +JSON format: { "title": "your concise title here" } +### Examples: +- { "title": "📉 Stock Market Trends" }, +- { "title": "🍪 Perfect Chocolate Chip Recipe" }, +- { "title": "Evolution of Music Streaming" }, +- { "title": "Remote Work Productivity Tips" }, +- { "title": "Artificial Intelligence in Healthcare" }, +- { "title": "🎮 Video Game Development Insights" } +### Chat History: + +{{MESSAGES:END:2}} +""" + +TAGS_GENERATION_PROMPT_TEMPLATE = PersistentConfig( + "TAGS_GENERATION_PROMPT_TEMPLATE", + "task.tags.prompt_template", + os.environ.get("TAGS_GENERATION_PROMPT_TEMPLATE", ""), +) + +DEFAULT_TAGS_GENERATION_PROMPT_TEMPLATE = """### Task: +Generate 1-3 broad tags categorizing the main themes of the chat history, along with 1-3 more specific subtopic tags. + +### Guidelines: +- Start with high-level domains (e.g. Science, Technology, Philosophy, Arts, Politics, Business, Health, Sports, Entertainment, Education) +- Consider including relevant subfields/subdomains if they are strongly represented throughout the conversation +- If content is too short (less than 3 messages) or too diverse, use only ["General"] +- Use the chat's primary language; default to English if multilingual +- Prioritize accuracy over specificity + +### Output: +JSON format: { "tags": ["tag1", "tag2", "tag3"] } + +### Chat History: + +{{MESSAGES:END:6}} +""" + +IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE = PersistentConfig( + "IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE", + "task.image.prompt_template", + os.environ.get("IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE", ""), +) + +DEFAULT_IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE = """### Task: +Generate a detailed prompt for am image generation task based on the given language and context. Describe the image as if you were explaining it to someone who cannot see it. Include relevant details, colors, shapes, and any other important elements. + +### Guidelines: +- Be descriptive and detailed, focusing on the most important aspects of the image. +- Avoid making assumptions or adding information not present in the image. +- Use the chat's primary language; default to English if multilingual. +- If the image is too complex, focus on the most prominent elements. + +### Output: +Strictly return in JSON format: +{ + "prompt": "Your detailed description here." +} + +### Chat History: + +{{MESSAGES:END:6}} +""" + +ENABLE_TAGS_GENERATION = PersistentConfig( + "ENABLE_TAGS_GENERATION", + "task.tags.enable", + os.environ.get("ENABLE_TAGS_GENERATION", "True").lower() == "true", +) + +ENABLE_TITLE_GENERATION = PersistentConfig( + "ENABLE_TITLE_GENERATION", + "task.title.enable", + os.environ.get("ENABLE_TITLE_GENERATION", "True").lower() == "true", +) + + +ENABLE_SEARCH_QUERY_GENERATION = PersistentConfig( + "ENABLE_SEARCH_QUERY_GENERATION", + "task.query.search.enable", + os.environ.get("ENABLE_SEARCH_QUERY_GENERATION", "True").lower() == "true", +) + +ENABLE_RETRIEVAL_QUERY_GENERATION = PersistentConfig( + "ENABLE_RETRIEVAL_QUERY_GENERATION", + "task.query.retrieval.enable", + os.environ.get("ENABLE_RETRIEVAL_QUERY_GENERATION", "True").lower() == "true", +) + + +QUERY_GENERATION_PROMPT_TEMPLATE = PersistentConfig( + "QUERY_GENERATION_PROMPT_TEMPLATE", + "task.query.prompt_template", + os.environ.get("QUERY_GENERATION_PROMPT_TEMPLATE", ""), +) + +DEFAULT_QUERY_GENERATION_PROMPT_TEMPLATE = """### Task: +Analyze the chat history to determine the necessity of generating search queries, in the given language. By default, **prioritize generating 1-3 broad and relevant search queries** unless it is absolutely certain that no additional information is required. The aim is to retrieve comprehensive, updated, and valuable information even with minimal uncertainty. If no search is unequivocally needed, return an empty list. + +### Guidelines: +- Respond **EXCLUSIVELY** with a JSON object. Any form of extra commentary, explanation, or additional text is strictly prohibited. +- When generating search queries, respond in the format: { "queries": ["query1", "query2"] }, ensuring each query is distinct, concise, and relevant to the topic. +- If and only if it is entirely certain that no useful results can be retrieved by a search, return: { "queries": [] }. +- Err on the side of suggesting search queries if there is **any chance** they might provide useful or updated information. +- Be concise and focused on composing high-quality search queries, avoiding unnecessary elaboration, commentary, or assumptions. +- Today's date is: {{CURRENT_DATE}}. +- Always prioritize providing actionable and broad queries that maximize informational coverage. + +### Output: +Strictly return in JSON format: +{ + "queries": ["query1", "query2"] +} + +### Chat History: + +{{MESSAGES:END:6}} + +""" + +ENABLE_AUTOCOMPLETE_GENERATION = PersistentConfig( + "ENABLE_AUTOCOMPLETE_GENERATION", + "task.autocomplete.enable", + os.environ.get("ENABLE_AUTOCOMPLETE_GENERATION", "True").lower() == "true", +) + +AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH = PersistentConfig( + "AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH", + "task.autocomplete.input_max_length", + int(os.environ.get("AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH", "-1")), +) + +AUTOCOMPLETE_GENERATION_PROMPT_TEMPLATE = PersistentConfig( + "AUTOCOMPLETE_GENERATION_PROMPT_TEMPLATE", + "task.autocomplete.prompt_template", + os.environ.get("AUTOCOMPLETE_GENERATION_PROMPT_TEMPLATE", ""), +) + + +DEFAULT_AUTOCOMPLETE_GENERATION_PROMPT_TEMPLATE = """### Task: +You are an autocompletion system. Continue the text in `` based on the **completion type** in `` and the given language. + +### **Instructions**: +1. Analyze `` for context and meaning. +2. Use `` to guide your output: + - **General**: Provide a natural, concise continuation. + - **Search Query**: Complete as if generating a realistic search query. +3. Start as if you are directly continuing ``. Do **not** repeat, paraphrase, or respond as a model. Simply complete the text. +4. Ensure the continuation: + - Flows naturally from ``. + - Avoids repetition, overexplaining, or unrelated ideas. +5. If unsure, return: `{ "text": "" }`. + +### **Output Rules**: +- Respond only in JSON format: `{ "text": "" }`. + +### **Examples**: +#### Example 1: +Input: +General +The sun was setting over the horizon, painting the sky +Output: +{ "text": "with vibrant shades of orange and pink." } + +#### Example 2: +Input: +Search Query +Top-rated restaurants in +Output: +{ "text": "New York City for Italian cuisine." } + +--- +### Context: + +{{MESSAGES:END:6}} + +{{TYPE}} +{{PROMPT}} +#### Output: +""" + +TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE = PersistentConfig( + "TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE", + "task.tools.prompt_template", + os.environ.get("TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE", ""), +) + + +DEFAULT_TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE = """Available Tools: {{TOOLS}} + +Your task is to choose and return the correct tool(s) from the list of available tools based on the query. Follow these guidelines: + +- Return only the JSON object, without any additional text or explanation. + +- If no tools match the query, return an empty array: + { + "tool_calls": [] + } + +- If one or more tools match the query, construct a JSON response containing a "tool_calls" array with objects that include: + - "name": The tool's name. + - "parameters": A dictionary of required parameters and their corresponding values. + +The format for the JSON response is strictly: +{ + "tool_calls": [ + {"name": "toolName1", "parameters": {"key1": "value1"}}, + {"name": "toolName2", "parameters": {"key2": "value2"}} + ] +}""" + + +DEFAULT_EMOJI_GENERATION_PROMPT_TEMPLATE = """Your task is to reflect the speaker's likely facial expression through a fitting emoji. Interpret emotions from the message and reflect their facial expression using fitting, diverse emojis (e.g., 😊, 😢, 😡, 😱). + +Message: ```{{prompt}}```""" + +DEFAULT_MOA_GENERATION_PROMPT_TEMPLATE = """You have been provided with a set of responses from various models to the latest user query: "{{prompt}}" + +Your task is to synthesize these responses into a single, high-quality response. It is crucial to critically evaluate the information provided in these responses, recognizing that some of it may be biased or incorrect. Your response should not simply replicate the given answers but should offer a refined, accurate, and comprehensive reply to the instruction. Ensure your response is well-structured, coherent, and adheres to the highest standards of accuracy and reliability. + +Responses from models: {{responses}}""" + + +#################################### +# Code Interpreter +#################################### + + +CODE_EXECUTION_ENGINE = PersistentConfig( + "CODE_EXECUTION_ENGINE", + "code_execution.engine", + os.environ.get("CODE_EXECUTION_ENGINE", "pyodide"), +) + +CODE_EXECUTION_JUPYTER_URL = PersistentConfig( + "CODE_EXECUTION_JUPYTER_URL", + "code_execution.jupyter.url", + os.environ.get("CODE_EXECUTION_JUPYTER_URL", ""), +) + +CODE_EXECUTION_JUPYTER_AUTH = PersistentConfig( + "CODE_EXECUTION_JUPYTER_AUTH", + "code_execution.jupyter.auth", + os.environ.get("CODE_EXECUTION_JUPYTER_AUTH", ""), +) + +CODE_EXECUTION_JUPYTER_AUTH_TOKEN = PersistentConfig( + "CODE_EXECUTION_JUPYTER_AUTH_TOKEN", + "code_execution.jupyter.auth_token", + os.environ.get("CODE_EXECUTION_JUPYTER_AUTH_TOKEN", ""), +) + + +CODE_EXECUTION_JUPYTER_AUTH_PASSWORD = PersistentConfig( + "CODE_EXECUTION_JUPYTER_AUTH_PASSWORD", + "code_execution.jupyter.auth_password", + os.environ.get("CODE_EXECUTION_JUPYTER_AUTH_PASSWORD", ""), +) + +CODE_EXECUTION_JUPYTER_TIMEOUT = PersistentConfig( + "CODE_EXECUTION_JUPYTER_TIMEOUT", + "code_execution.jupyter.timeout", + int(os.environ.get("CODE_EXECUTION_JUPYTER_TIMEOUT", "60")), +) + +ENABLE_CODE_INTERPRETER = PersistentConfig( + "ENABLE_CODE_INTERPRETER", + "code_interpreter.enable", + os.environ.get("ENABLE_CODE_INTERPRETER", "True").lower() == "true", +) + +CODE_INTERPRETER_ENGINE = PersistentConfig( + "CODE_INTERPRETER_ENGINE", + "code_interpreter.engine", + os.environ.get("CODE_INTERPRETER_ENGINE", "pyodide"), +) + +CODE_INTERPRETER_PROMPT_TEMPLATE = PersistentConfig( + "CODE_INTERPRETER_PROMPT_TEMPLATE", + "code_interpreter.prompt_template", + os.environ.get("CODE_INTERPRETER_PROMPT_TEMPLATE", ""), +) + +CODE_INTERPRETER_JUPYTER_URL = PersistentConfig( + "CODE_INTERPRETER_JUPYTER_URL", + "code_interpreter.jupyter.url", + os.environ.get( + "CODE_INTERPRETER_JUPYTER_URL", os.environ.get("CODE_EXECUTION_JUPYTER_URL", "") + ), +) + +CODE_INTERPRETER_JUPYTER_AUTH = PersistentConfig( + "CODE_INTERPRETER_JUPYTER_AUTH", + "code_interpreter.jupyter.auth", + os.environ.get( + "CODE_INTERPRETER_JUPYTER_AUTH", + os.environ.get("CODE_EXECUTION_JUPYTER_AUTH", ""), + ), +) + +CODE_INTERPRETER_JUPYTER_AUTH_TOKEN = PersistentConfig( + "CODE_INTERPRETER_JUPYTER_AUTH_TOKEN", + "code_interpreter.jupyter.auth_token", + os.environ.get( + "CODE_INTERPRETER_JUPYTER_AUTH_TOKEN", + os.environ.get("CODE_EXECUTION_JUPYTER_AUTH_TOKEN", ""), + ), +) + + +CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD = PersistentConfig( + "CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD", + "code_interpreter.jupyter.auth_password", + os.environ.get( + "CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD", + os.environ.get("CODE_EXECUTION_JUPYTER_AUTH_PASSWORD", ""), + ), +) + +CODE_INTERPRETER_JUPYTER_TIMEOUT = PersistentConfig( + "CODE_INTERPRETER_JUPYTER_TIMEOUT", + "code_interpreter.jupyter.timeout", + int( + os.environ.get( + "CODE_INTERPRETER_JUPYTER_TIMEOUT", + os.environ.get("CODE_EXECUTION_JUPYTER_TIMEOUT", "60"), + ) + ), +) + + +DEFAULT_CODE_INTERPRETER_PROMPT = """ +#### Tools Available + +1. **Code Interpreter**: `` + - You have access to a Python shell that runs directly in the user's browser, enabling fast execution of code for analysis, calculations, or problem-solving. Use it in this response. + - The Python code you write can incorporate a wide array of libraries, handle data manipulation or visualization, perform API calls for web-related tasks, or tackle virtually any computational challenge. Use this flexibility to **think outside the box, craft elegant solutions, and harness Python's full potential**. + - To use it, **you must enclose your code within `` XML tags** and stop right away. If you don't, the code won't execute. Do NOT use triple backticks. + - When coding, **always aim to print meaningful outputs** (e.g., results, tables, summaries, or visuals) to better interpret and verify the findings. Avoid relying on implicit outputs; prioritize explicit and clear print statements so the results are effectively communicated to the user. + - After obtaining the printed output, **always provide a concise analysis, interpretation, or next steps to help the user understand the findings or refine the outcome further.** + - If the results are unclear, unexpected, or require validation, refine the code and execute it again as needed. Always aim to deliver meaningful insights from the results, iterating if necessary. + - **If a link to an image, audio, or any file is provided in markdown format in the output, ALWAYS regurgitate word for word, explicitly display it as part of the response to ensure the user can access it easily, do NOT change the link.** + - All responses should be communicated in the chat's primary language, ensuring seamless understanding. If the chat is multilingual, default to English for clarity. + +Ensure that the tools are effectively utilized to achieve the highest-quality analysis for the user.""" + + +#################################### +# Vector Database +#################################### + +VECTOR_DB = os.environ.get("VECTOR_DB", "chroma") + +# Chroma +CHROMA_DATA_PATH = f"{DATA_DIR}/vector_db" + +if VECTOR_DB == "chroma": + import chromadb + + CHROMA_TENANT = os.environ.get("CHROMA_TENANT", chromadb.DEFAULT_TENANT) + CHROMA_DATABASE = os.environ.get("CHROMA_DATABASE", chromadb.DEFAULT_DATABASE) + CHROMA_HTTP_HOST = os.environ.get("CHROMA_HTTP_HOST", "") + CHROMA_HTTP_PORT = int(os.environ.get("CHROMA_HTTP_PORT", "8000")) + CHROMA_CLIENT_AUTH_PROVIDER = os.environ.get("CHROMA_CLIENT_AUTH_PROVIDER", "") + CHROMA_CLIENT_AUTH_CREDENTIALS = os.environ.get( + "CHROMA_CLIENT_AUTH_CREDENTIALS", "" + ) + # Comma-separated list of header=value pairs + CHROMA_HTTP_HEADERS = os.environ.get("CHROMA_HTTP_HEADERS", "") + if CHROMA_HTTP_HEADERS: + CHROMA_HTTP_HEADERS = dict( + [pair.split("=") for pair in CHROMA_HTTP_HEADERS.split(",")] + ) + else: + CHROMA_HTTP_HEADERS = None + CHROMA_HTTP_SSL = os.environ.get("CHROMA_HTTP_SSL", "false").lower() == "true" +# this uses the model defined in the Dockerfile ENV variable. If you dont use docker or docker based deployments such as k8s, the default embedding model will be used (sentence-transformers/all-MiniLM-L6-v2) + +# Milvus + +MILVUS_URI = os.environ.get("MILVUS_URI", f"{DATA_DIR}/vector_db/milvus.db") +MILVUS_DB = os.environ.get("MILVUS_DB", "default") +MILVUS_TOKEN = os.environ.get("MILVUS_TOKEN", None) + +# Qdrant +QDRANT_URI = os.environ.get("QDRANT_URI", None) +QDRANT_API_KEY = os.environ.get("QDRANT_API_KEY", None) + +# OpenSearch +OPENSEARCH_URI = os.environ.get("OPENSEARCH_URI", "https://localhost:9200") +OPENSEARCH_SSL = os.environ.get("OPENSEARCH_SSL", True) +OPENSEARCH_CERT_VERIFY = os.environ.get("OPENSEARCH_CERT_VERIFY", False) +OPENSEARCH_USERNAME = os.environ.get("OPENSEARCH_USERNAME", None) +OPENSEARCH_PASSWORD = os.environ.get("OPENSEARCH_PASSWORD", None) + +# Pgvector +PGVECTOR_DB_URL = os.environ.get("PGVECTOR_DB_URL", DATABASE_URL) +if VECTOR_DB == "pgvector" and not PGVECTOR_DB_URL.startswith("postgres"): + raise ValueError( + "Pgvector requires setting PGVECTOR_DB_URL or using Postgres with vector extension as the primary database." + ) +PGVECTOR_INITIALIZE_MAX_VECTOR_LENGTH = int( + os.environ.get("PGVECTOR_INITIALIZE_MAX_VECTOR_LENGTH", "1536") +) + +#################################### +# Information Retrieval (RAG) +#################################### + + +# If configured, Google Drive will be available as an upload option. +ENABLE_GOOGLE_DRIVE_INTEGRATION = PersistentConfig( + "ENABLE_GOOGLE_DRIVE_INTEGRATION", + "google_drive.enable", + os.getenv("ENABLE_GOOGLE_DRIVE_INTEGRATION", "False").lower() == "true", +) + +GOOGLE_DRIVE_CLIENT_ID = PersistentConfig( + "GOOGLE_DRIVE_CLIENT_ID", + "google_drive.client_id", + os.environ.get("GOOGLE_DRIVE_CLIENT_ID", ""), +) + +GOOGLE_DRIVE_API_KEY = PersistentConfig( + "GOOGLE_DRIVE_API_KEY", + "google_drive.api_key", + os.environ.get("GOOGLE_DRIVE_API_KEY", ""), +) + +ENABLE_ONEDRIVE_INTEGRATION = PersistentConfig( + "ENABLE_ONEDRIVE_INTEGRATION", + "onedrive.enable", + os.getenv("ENABLE_ONEDRIVE_INTEGRATION", "False").lower() == "true", +) + +ONEDRIVE_CLIENT_ID = PersistentConfig( + "ONEDRIVE_CLIENT_ID", + "onedrive.client_id", + os.environ.get("ONEDRIVE_CLIENT_ID", ""), +) + +# RAG Content Extraction +CONTENT_EXTRACTION_ENGINE = PersistentConfig( + "CONTENT_EXTRACTION_ENGINE", + "rag.CONTENT_EXTRACTION_ENGINE", + os.environ.get("CONTENT_EXTRACTION_ENGINE", "").lower(), +) + +TIKA_SERVER_URL = PersistentConfig( + "TIKA_SERVER_URL", + "rag.tika_server_url", + os.getenv("TIKA_SERVER_URL", "http://tika:9998"), # Default for sidecar deployment +) + +DOCUMENT_INTELLIGENCE_ENDPOINT = PersistentConfig( + "DOCUMENT_INTELLIGENCE_ENDPOINT", + "rag.document_intelligence_endpoint", + os.getenv("DOCUMENT_INTELLIGENCE_ENDPOINT", ""), +) + +DOCUMENT_INTELLIGENCE_KEY = PersistentConfig( + "DOCUMENT_INTELLIGENCE_KEY", + "rag.document_intelligence_key", + os.getenv("DOCUMENT_INTELLIGENCE_KEY", ""), +) + + +BYPASS_EMBEDDING_AND_RETRIEVAL = PersistentConfig( + "BYPASS_EMBEDDING_AND_RETRIEVAL", + "rag.bypass_embedding_and_retrieval", + os.environ.get("BYPASS_EMBEDDING_AND_RETRIEVAL", "False").lower() == "true", +) + + +RAG_TOP_K = PersistentConfig( + "RAG_TOP_K", "rag.top_k", int(os.environ.get("RAG_TOP_K", "3")) +) +RAG_RELEVANCE_THRESHOLD = PersistentConfig( + "RAG_RELEVANCE_THRESHOLD", + "rag.relevance_threshold", + float(os.environ.get("RAG_RELEVANCE_THRESHOLD", "0.0")), +) + +ENABLE_RAG_HYBRID_SEARCH = PersistentConfig( + "ENABLE_RAG_HYBRID_SEARCH", + "rag.enable_hybrid_search", + os.environ.get("ENABLE_RAG_HYBRID_SEARCH", "").lower() == "true", +) + +RAG_FULL_CONTEXT = PersistentConfig( + "RAG_FULL_CONTEXT", + "rag.full_context", + os.getenv("RAG_FULL_CONTEXT", "False").lower() == "true", +) + +RAG_FILE_MAX_COUNT = PersistentConfig( + "RAG_FILE_MAX_COUNT", + "rag.file.max_count", + ( + int(os.environ.get("RAG_FILE_MAX_COUNT")) + if os.environ.get("RAG_FILE_MAX_COUNT") + else None + ), +) + +RAG_FILE_MAX_SIZE = PersistentConfig( + "RAG_FILE_MAX_SIZE", + "rag.file.max_size", + ( + int(os.environ.get("RAG_FILE_MAX_SIZE")) + if os.environ.get("RAG_FILE_MAX_SIZE") + else None + ), +) + +ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION = PersistentConfig( + "ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION", + "rag.enable_web_loader_ssl_verification", + os.environ.get("ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION", "True").lower() == "true", +) + +RAG_EMBEDDING_ENGINE = PersistentConfig( + "RAG_EMBEDDING_ENGINE", + "rag.embedding_engine", + os.environ.get("RAG_EMBEDDING_ENGINE", ""), +) + +PDF_EXTRACT_IMAGES = PersistentConfig( + "PDF_EXTRACT_IMAGES", + "rag.pdf_extract_images", + os.environ.get("PDF_EXTRACT_IMAGES", "False").lower() == "true", +) + +RAG_EMBEDDING_MODEL = PersistentConfig( + "RAG_EMBEDDING_MODEL", + "rag.embedding_model", + os.environ.get("RAG_EMBEDDING_MODEL", "sentence-transformers/all-MiniLM-L6-v2"), +) +log.info(f"Embedding model set: {RAG_EMBEDDING_MODEL.value}") + +RAG_EMBEDDING_MODEL_AUTO_UPDATE = ( + not OFFLINE_MODE + and os.environ.get("RAG_EMBEDDING_MODEL_AUTO_UPDATE", "True").lower() == "true" +) + +RAG_EMBEDDING_MODEL_TRUST_REMOTE_CODE = ( + os.environ.get("RAG_EMBEDDING_MODEL_TRUST_REMOTE_CODE", "True").lower() == "true" +) + +RAG_EMBEDDING_BATCH_SIZE = PersistentConfig( + "RAG_EMBEDDING_BATCH_SIZE", + "rag.embedding_batch_size", + int( + os.environ.get("RAG_EMBEDDING_BATCH_SIZE") + or os.environ.get("RAG_EMBEDDING_OPENAI_BATCH_SIZE", "1") + ), +) + +RAG_RERANKING_MODEL = PersistentConfig( + "RAG_RERANKING_MODEL", + "rag.reranking_model", + os.environ.get("RAG_RERANKING_MODEL", ""), +) +if RAG_RERANKING_MODEL.value != "": + log.info(f"Reranking model set: {RAG_RERANKING_MODEL.value}") + +RAG_RERANKING_MODEL_AUTO_UPDATE = ( + not OFFLINE_MODE + and os.environ.get("RAG_RERANKING_MODEL_AUTO_UPDATE", "True").lower() == "true" +) + +RAG_RERANKING_MODEL_TRUST_REMOTE_CODE = ( + os.environ.get("RAG_RERANKING_MODEL_TRUST_REMOTE_CODE", "True").lower() == "true" +) + + +RAG_TEXT_SPLITTER = PersistentConfig( + "RAG_TEXT_SPLITTER", + "rag.text_splitter", + os.environ.get("RAG_TEXT_SPLITTER", ""), +) + + +TIKTOKEN_CACHE_DIR = os.environ.get("TIKTOKEN_CACHE_DIR", f"{CACHE_DIR}/tiktoken") +TIKTOKEN_ENCODING_NAME = PersistentConfig( + "TIKTOKEN_ENCODING_NAME", + "rag.tiktoken_encoding_name", + os.environ.get("TIKTOKEN_ENCODING_NAME", "cl100k_base"), +) + + +CHUNK_SIZE = PersistentConfig( + "CHUNK_SIZE", "rag.chunk_size", int(os.environ.get("CHUNK_SIZE", "1000")) +) +CHUNK_OVERLAP = PersistentConfig( + "CHUNK_OVERLAP", + "rag.chunk_overlap", + int(os.environ.get("CHUNK_OVERLAP", "100")), +) + +DEFAULT_RAG_TEMPLATE = """### Task: +Respond to the user query using the provided context, incorporating inline citations in the format [source_id] **only when the tag is explicitly provided** in the context. + +### Guidelines: +- If you don't know the answer, clearly state that. +- If uncertain, ask the user for clarification. +- Respond in the same language as the user's query. +- If the context is unreadable or of poor quality, inform the user and provide the best possible answer. +- If the answer isn't present in the context but you possess the knowledge, explain this to the user and provide the answer using your own understanding. +- **Only include inline citations using [source_id] (e.g., [1], [2]) when a `` tag is explicitly provided in the context.** +- Do not cite if the tag is not provided in the context. +- Do not use XML tags in your response. +- Ensure citations are concise and directly related to the information provided. + +### Example of Citation: +If the user asks about a specific topic and the information is found in "whitepaper.pdf" with a provided , the response should include the citation like so: +* "According to the study, the proposed method increases efficiency by 20% [whitepaper.pdf]." +If no is present, the response should omit the citation. + +### Output: +Provide a clear and direct response to the user's query, including inline citations in the format [source_id] only when the tag is present in the context. + + +{{CONTEXT}} + + + +{{QUERY}} + +""" + +RAG_TEMPLATE = PersistentConfig( + "RAG_TEMPLATE", + "rag.template", + os.environ.get("RAG_TEMPLATE", DEFAULT_RAG_TEMPLATE), +) + +RAG_OPENAI_API_BASE_URL = PersistentConfig( + "RAG_OPENAI_API_BASE_URL", + "rag.openai_api_base_url", + os.getenv("RAG_OPENAI_API_BASE_URL", OPENAI_API_BASE_URL), +) +RAG_OPENAI_API_KEY = PersistentConfig( + "RAG_OPENAI_API_KEY", + "rag.openai_api_key", + os.getenv("RAG_OPENAI_API_KEY", OPENAI_API_KEY), +) + +RAG_OLLAMA_BASE_URL = PersistentConfig( + "RAG_OLLAMA_BASE_URL", + "rag.ollama.url", + os.getenv("RAG_OLLAMA_BASE_URL", OLLAMA_BASE_URL), +) + +RAG_OLLAMA_API_KEY = PersistentConfig( + "RAG_OLLAMA_API_KEY", + "rag.ollama.key", + os.getenv("RAG_OLLAMA_API_KEY", ""), +) + + +ENABLE_RAG_LOCAL_WEB_FETCH = ( + os.getenv("ENABLE_RAG_LOCAL_WEB_FETCH", "False").lower() == "true" +) + +YOUTUBE_LOADER_LANGUAGE = PersistentConfig( + "YOUTUBE_LOADER_LANGUAGE", + "rag.youtube_loader_language", + os.getenv("YOUTUBE_LOADER_LANGUAGE", "en").split(","), +) + +YOUTUBE_LOADER_PROXY_URL = PersistentConfig( + "YOUTUBE_LOADER_PROXY_URL", + "rag.youtube_loader_proxy_url", + os.getenv("YOUTUBE_LOADER_PROXY_URL", ""), +) + + +ENABLE_RAG_WEB_SEARCH = PersistentConfig( + "ENABLE_RAG_WEB_SEARCH", + "rag.web.search.enable", + os.getenv("ENABLE_RAG_WEB_SEARCH", "False").lower() == "true", +) + +RAG_WEB_SEARCH_ENGINE = PersistentConfig( + "RAG_WEB_SEARCH_ENGINE", + "rag.web.search.engine", + os.getenv("RAG_WEB_SEARCH_ENGINE", ""), +) + +BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL = PersistentConfig( + "BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL", + "rag.web.search.bypass_embedding_and_retrieval", + os.getenv("BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL", "False").lower() == "true", +) + +# You can provide a list of your own websites to filter after performing a web search. +# This ensures the highest level of safety and reliability of the information sources. +RAG_WEB_SEARCH_DOMAIN_FILTER_LIST = PersistentConfig( + "RAG_WEB_SEARCH_DOMAIN_FILTER_LIST", + "rag.web.search.domain.filter_list", + [ + # "wikipedia.com", + # "wikimedia.org", + # "wikidata.org", + ], +) + + +SEARXNG_QUERY_URL = PersistentConfig( + "SEARXNG_QUERY_URL", + "rag.web.search.searxng_query_url", + os.getenv("SEARXNG_QUERY_URL", ""), +) + +GOOGLE_PSE_API_KEY = PersistentConfig( + "GOOGLE_PSE_API_KEY", + "rag.web.search.google_pse_api_key", + os.getenv("GOOGLE_PSE_API_KEY", ""), +) + +GOOGLE_PSE_ENGINE_ID = PersistentConfig( + "GOOGLE_PSE_ENGINE_ID", + "rag.web.search.google_pse_engine_id", + os.getenv("GOOGLE_PSE_ENGINE_ID", ""), +) + +BRAVE_SEARCH_API_KEY = PersistentConfig( + "BRAVE_SEARCH_API_KEY", + "rag.web.search.brave_search_api_key", + os.getenv("BRAVE_SEARCH_API_KEY", ""), +) + +KAGI_SEARCH_API_KEY = PersistentConfig( + "KAGI_SEARCH_API_KEY", + "rag.web.search.kagi_search_api_key", + os.getenv("KAGI_SEARCH_API_KEY", ""), +) + +MOJEEK_SEARCH_API_KEY = PersistentConfig( + "MOJEEK_SEARCH_API_KEY", + "rag.web.search.mojeek_search_api_key", + os.getenv("MOJEEK_SEARCH_API_KEY", ""), +) + +BOCHA_SEARCH_API_KEY = PersistentConfig( + "BOCHA_SEARCH_API_KEY", + "rag.web.search.bocha_search_api_key", + os.getenv("BOCHA_SEARCH_API_KEY", ""), +) + +SERPSTACK_API_KEY = PersistentConfig( + "SERPSTACK_API_KEY", + "rag.web.search.serpstack_api_key", + os.getenv("SERPSTACK_API_KEY", ""), +) + +SERPSTACK_HTTPS = PersistentConfig( + "SERPSTACK_HTTPS", + "rag.web.search.serpstack_https", + os.getenv("SERPSTACK_HTTPS", "True").lower() == "true", +) + +SERPER_API_KEY = PersistentConfig( + "SERPER_API_KEY", + "rag.web.search.serper_api_key", + os.getenv("SERPER_API_KEY", ""), +) + +SERPLY_API_KEY = PersistentConfig( + "SERPLY_API_KEY", + "rag.web.search.serply_api_key", + os.getenv("SERPLY_API_KEY", ""), +) + +TAVILY_API_KEY = PersistentConfig( + "TAVILY_API_KEY", + "rag.web.search.tavily_api_key", + os.getenv("TAVILY_API_KEY", ""), +) + +JINA_API_KEY = PersistentConfig( + "JINA_API_KEY", + "rag.web.search.jina_api_key", + os.getenv("JINA_API_KEY", ""), +) + +SEARCHAPI_API_KEY = PersistentConfig( + "SEARCHAPI_API_KEY", + "rag.web.search.searchapi_api_key", + os.getenv("SEARCHAPI_API_KEY", ""), +) + +SEARCHAPI_ENGINE = PersistentConfig( + "SEARCHAPI_ENGINE", + "rag.web.search.searchapi_engine", + os.getenv("SEARCHAPI_ENGINE", ""), +) + +SERPAPI_API_KEY = PersistentConfig( + "SERPAPI_API_KEY", + "rag.web.search.serpapi_api_key", + os.getenv("SERPAPI_API_KEY", ""), +) + +SERPAPI_ENGINE = PersistentConfig( + "SERPAPI_ENGINE", + "rag.web.search.serpapi_engine", + os.getenv("SERPAPI_ENGINE", ""), +) + +BING_SEARCH_V7_ENDPOINT = PersistentConfig( + "BING_SEARCH_V7_ENDPOINT", + "rag.web.search.bing_search_v7_endpoint", + os.environ.get( + "BING_SEARCH_V7_ENDPOINT", "https://api.bing.microsoft.com/v7.0/search" + ), +) + +BING_SEARCH_V7_SUBSCRIPTION_KEY = PersistentConfig( + "BING_SEARCH_V7_SUBSCRIPTION_KEY", + "rag.web.search.bing_search_v7_subscription_key", + os.environ.get("BING_SEARCH_V7_SUBSCRIPTION_KEY", ""), +) + +EXA_API_KEY = PersistentConfig( + "EXA_API_KEY", + "rag.web.search.exa_api_key", + os.getenv("EXA_API_KEY", ""), +) + +RAG_WEB_SEARCH_RESULT_COUNT = PersistentConfig( + "RAG_WEB_SEARCH_RESULT_COUNT", + "rag.web.search.result_count", + int(os.getenv("RAG_WEB_SEARCH_RESULT_COUNT", "3")), +) + +RAG_WEB_SEARCH_CONCURRENT_REQUESTS = PersistentConfig( + "RAG_WEB_SEARCH_CONCURRENT_REQUESTS", + "rag.web.search.concurrent_requests", + int(os.getenv("RAG_WEB_SEARCH_CONCURRENT_REQUESTS", "10")), +) + +RAG_WEB_LOADER_ENGINE = PersistentConfig( + "RAG_WEB_LOADER_ENGINE", + "rag.web.loader.engine", + os.environ.get("RAG_WEB_LOADER_ENGINE", "safe_web"), +) + +RAG_WEB_SEARCH_TRUST_ENV = PersistentConfig( + "RAG_WEB_SEARCH_TRUST_ENV", + "rag.web.search.trust_env", + os.getenv("RAG_WEB_SEARCH_TRUST_ENV", "False").lower() == "true", +) + +PLAYWRIGHT_WS_URI = PersistentConfig( + "PLAYWRIGHT_WS_URI", + "rag.web.loader.engine.playwright.ws.uri", + os.environ.get("PLAYWRIGHT_WS_URI", None), +) + +FIRECRAWL_API_KEY = PersistentConfig( + "FIRECRAWL_API_KEY", + "firecrawl.api_key", + os.environ.get("FIRECRAWL_API_KEY", ""), +) + +FIRECRAWL_API_BASE_URL = PersistentConfig( + "FIRECRAWL_API_BASE_URL", + "firecrawl.api_url", + os.environ.get("FIRECRAWL_API_BASE_URL", "https://api.firecrawl.dev"), +) + +#################################### +# Images +#################################### + +IMAGE_GENERATION_ENGINE = PersistentConfig( + "IMAGE_GENERATION_ENGINE", + "image_generation.engine", + os.getenv("IMAGE_GENERATION_ENGINE", "openai"), +) + +ENABLE_IMAGE_GENERATION = PersistentConfig( + "ENABLE_IMAGE_GENERATION", + "image_generation.enable", + os.environ.get("ENABLE_IMAGE_GENERATION", "").lower() == "true", +) + +ENABLE_IMAGE_PROMPT_GENERATION = PersistentConfig( + "ENABLE_IMAGE_PROMPT_GENERATION", + "image_generation.prompt.enable", + os.environ.get("ENABLE_IMAGE_PROMPT_GENERATION", "true").lower() == "true", +) + +AUTOMATIC1111_BASE_URL = PersistentConfig( + "AUTOMATIC1111_BASE_URL", + "image_generation.automatic1111.base_url", + os.getenv("AUTOMATIC1111_BASE_URL", ""), +) +AUTOMATIC1111_API_AUTH = PersistentConfig( + "AUTOMATIC1111_API_AUTH", + "image_generation.automatic1111.api_auth", + os.getenv("AUTOMATIC1111_API_AUTH", ""), +) + +AUTOMATIC1111_CFG_SCALE = PersistentConfig( + "AUTOMATIC1111_CFG_SCALE", + "image_generation.automatic1111.cfg_scale", + ( + float(os.environ.get("AUTOMATIC1111_CFG_SCALE")) + if os.environ.get("AUTOMATIC1111_CFG_SCALE") + else None + ), +) + + +AUTOMATIC1111_SAMPLER = PersistentConfig( + "AUTOMATIC1111_SAMPLER", + "image_generation.automatic1111.sampler", + ( + os.environ.get("AUTOMATIC1111_SAMPLER") + if os.environ.get("AUTOMATIC1111_SAMPLER") + else None + ), +) + +AUTOMATIC1111_SCHEDULER = PersistentConfig( + "AUTOMATIC1111_SCHEDULER", + "image_generation.automatic1111.scheduler", + ( + os.environ.get("AUTOMATIC1111_SCHEDULER") + if os.environ.get("AUTOMATIC1111_SCHEDULER") + else None + ), +) + +COMFYUI_BASE_URL = PersistentConfig( + "COMFYUI_BASE_URL", + "image_generation.comfyui.base_url", + os.getenv("COMFYUI_BASE_URL", ""), +) + +COMFYUI_API_KEY = PersistentConfig( + "COMFYUI_API_KEY", + "image_generation.comfyui.api_key", + os.getenv("COMFYUI_API_KEY", ""), +) + +COMFYUI_DEFAULT_WORKFLOW = """ +{ + "3": { + "inputs": { + "seed": 0, + "steps": 20, + "cfg": 8, + "sampler_name": "euler", + "scheduler": "normal", + "denoise": 1, + "model": [ + "4", + 0 + ], + "positive": [ + "6", + 0 + ], + "negative": [ + "7", + 0 + ], + "latent_image": [ + "5", + 0 + ] + }, + "class_type": "KSampler", + "_meta": { + "title": "KSampler" + } + }, + "4": { + "inputs": { + "ckpt_name": "model.safetensors" + }, + "class_type": "CheckpointLoaderSimple", + "_meta": { + "title": "Load Checkpoint" + } + }, + "5": { + "inputs": { + "width": 512, + "height": 512, + "batch_size": 1 + }, + "class_type": "EmptyLatentImage", + "_meta": { + "title": "Empty Latent Image" + } + }, + "6": { + "inputs": { + "text": "Prompt", + "clip": [ + "4", + 1 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Prompt)" + } + }, + "7": { + "inputs": { + "text": "", + "clip": [ + "4", + 1 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Prompt)" + } + }, + "8": { + "inputs": { + "samples": [ + "3", + 0 + ], + "vae": [ + "4", + 2 + ] + }, + "class_type": "VAEDecode", + "_meta": { + "title": "VAE Decode" + } + }, + "9": { + "inputs": { + "filename_prefix": "ComfyUI", + "images": [ + "8", + 0 + ] + }, + "class_type": "SaveImage", + "_meta": { + "title": "Save Image" + } + } +} +""" + + +COMFYUI_WORKFLOW = PersistentConfig( + "COMFYUI_WORKFLOW", + "image_generation.comfyui.workflow", + os.getenv("COMFYUI_WORKFLOW", COMFYUI_DEFAULT_WORKFLOW), +) + +COMFYUI_WORKFLOW_NODES = PersistentConfig( + "COMFYUI_WORKFLOW", + "image_generation.comfyui.nodes", + [], +) + +IMAGES_OPENAI_API_BASE_URL = PersistentConfig( + "IMAGES_OPENAI_API_BASE_URL", + "image_generation.openai.api_base_url", + os.getenv("IMAGES_OPENAI_API_BASE_URL", OPENAI_API_BASE_URL), +) +IMAGES_OPENAI_API_KEY = PersistentConfig( + "IMAGES_OPENAI_API_KEY", + "image_generation.openai.api_key", + os.getenv("IMAGES_OPENAI_API_KEY", OPENAI_API_KEY), +) + +IMAGES_GEMINI_API_BASE_URL = PersistentConfig( + "IMAGES_GEMINI_API_BASE_URL", + "image_generation.gemini.api_base_url", + os.getenv("IMAGES_GEMINI_API_BASE_URL", GEMINI_API_BASE_URL), +) +IMAGES_GEMINI_API_KEY = PersistentConfig( + "IMAGES_GEMINI_API_KEY", + "image_generation.gemini.api_key", + os.getenv("IMAGES_GEMINI_API_KEY", GEMINI_API_KEY), +) + +IMAGE_SIZE = PersistentConfig( + "IMAGE_SIZE", "image_generation.size", os.getenv("IMAGE_SIZE", "512x512") +) + +IMAGE_STEPS = PersistentConfig( + "IMAGE_STEPS", "image_generation.steps", int(os.getenv("IMAGE_STEPS", 50)) +) + +IMAGE_GENERATION_MODEL = PersistentConfig( + "IMAGE_GENERATION_MODEL", + "image_generation.model", + os.getenv("IMAGE_GENERATION_MODEL", ""), +) + +#################################### +# Audio +#################################### + +# Transcription +WHISPER_MODEL = PersistentConfig( + "WHISPER_MODEL", + "audio.stt.whisper_model", + os.getenv("WHISPER_MODEL", "base"), +) + +WHISPER_MODEL_DIR = os.getenv("WHISPER_MODEL_DIR", f"{CACHE_DIR}/whisper/models") +WHISPER_MODEL_AUTO_UPDATE = ( + not OFFLINE_MODE + and os.environ.get("WHISPER_MODEL_AUTO_UPDATE", "").lower() == "true" +) + +# Add Deepgram configuration +DEEPGRAM_API_KEY = PersistentConfig( + "DEEPGRAM_API_KEY", + "audio.stt.deepgram.api_key", + os.getenv("DEEPGRAM_API_KEY", ""), +) + +AUDIO_STT_OPENAI_API_BASE_URL = PersistentConfig( + "AUDIO_STT_OPENAI_API_BASE_URL", + "audio.stt.openai.api_base_url", + os.getenv("AUDIO_STT_OPENAI_API_BASE_URL", OPENAI_API_BASE_URL), +) + +AUDIO_STT_OPENAI_API_KEY = PersistentConfig( + "AUDIO_STT_OPENAI_API_KEY", + "audio.stt.openai.api_key", + os.getenv("AUDIO_STT_OPENAI_API_KEY", OPENAI_API_KEY), +) + +AUDIO_STT_ENGINE = PersistentConfig( + "AUDIO_STT_ENGINE", + "audio.stt.engine", + os.getenv("AUDIO_STT_ENGINE", ""), +) + +AUDIO_STT_MODEL = PersistentConfig( + "AUDIO_STT_MODEL", + "audio.stt.model", + os.getenv("AUDIO_STT_MODEL", ""), +) + +AUDIO_TTS_OPENAI_API_BASE_URL = PersistentConfig( + "AUDIO_TTS_OPENAI_API_BASE_URL", + "audio.tts.openai.api_base_url", + os.getenv("AUDIO_TTS_OPENAI_API_BASE_URL", OPENAI_API_BASE_URL), +) +AUDIO_TTS_OPENAI_API_KEY = PersistentConfig( + "AUDIO_TTS_OPENAI_API_KEY", + "audio.tts.openai.api_key", + os.getenv("AUDIO_TTS_OPENAI_API_KEY", OPENAI_API_KEY), +) + +AUDIO_TTS_API_KEY = PersistentConfig( + "AUDIO_TTS_API_KEY", + "audio.tts.api_key", + os.getenv("AUDIO_TTS_API_KEY", ""), +) + +AUDIO_TTS_ENGINE = PersistentConfig( + "AUDIO_TTS_ENGINE", + "audio.tts.engine", + os.getenv("AUDIO_TTS_ENGINE", ""), +) + + +AUDIO_TTS_MODEL = PersistentConfig( + "AUDIO_TTS_MODEL", + "audio.tts.model", + os.getenv("AUDIO_TTS_MODEL", "tts-1"), # OpenAI default model +) + +AUDIO_TTS_VOICE = PersistentConfig( + "AUDIO_TTS_VOICE", + "audio.tts.voice", + os.getenv("AUDIO_TTS_VOICE", "alloy"), # OpenAI default voice +) + +AUDIO_TTS_SPLIT_ON = PersistentConfig( + "AUDIO_TTS_SPLIT_ON", + "audio.tts.split_on", + os.getenv("AUDIO_TTS_SPLIT_ON", "punctuation"), +) + +AUDIO_TTS_AZURE_SPEECH_REGION = PersistentConfig( + "AUDIO_TTS_AZURE_SPEECH_REGION", + "audio.tts.azure.speech_region", + os.getenv("AUDIO_TTS_AZURE_SPEECH_REGION", "eastus"), +) + +AUDIO_TTS_AZURE_SPEECH_OUTPUT_FORMAT = PersistentConfig( + "AUDIO_TTS_AZURE_SPEECH_OUTPUT_FORMAT", + "audio.tts.azure.speech_output_format", + os.getenv( + "AUDIO_TTS_AZURE_SPEECH_OUTPUT_FORMAT", "audio-24khz-160kbitrate-mono-mp3" + ), +) + + +#################################### +# LDAP +#################################### + +ENABLE_LDAP = PersistentConfig( + "ENABLE_LDAP", + "ldap.enable", + os.environ.get("ENABLE_LDAP", "false").lower() == "true", +) + +LDAP_SERVER_LABEL = PersistentConfig( + "LDAP_SERVER_LABEL", + "ldap.server.label", + os.environ.get("LDAP_SERVER_LABEL", "LDAP Server"), +) + +LDAP_SERVER_HOST = PersistentConfig( + "LDAP_SERVER_HOST", + "ldap.server.host", + os.environ.get("LDAP_SERVER_HOST", "localhost"), +) + +LDAP_SERVER_PORT = PersistentConfig( + "LDAP_SERVER_PORT", + "ldap.server.port", + int(os.environ.get("LDAP_SERVER_PORT", "389")), +) + +LDAP_ATTRIBUTE_FOR_MAIL = PersistentConfig( + "LDAP_ATTRIBUTE_FOR_MAIL", + "ldap.server.attribute_for_mail", + os.environ.get("LDAP_ATTRIBUTE_FOR_MAIL", "mail"), +) + +LDAP_ATTRIBUTE_FOR_USERNAME = PersistentConfig( + "LDAP_ATTRIBUTE_FOR_USERNAME", + "ldap.server.attribute_for_username", + os.environ.get("LDAP_ATTRIBUTE_FOR_USERNAME", "uid"), +) + +LDAP_APP_DN = PersistentConfig( + "LDAP_APP_DN", "ldap.server.app_dn", os.environ.get("LDAP_APP_DN", "") +) + +LDAP_APP_PASSWORD = PersistentConfig( + "LDAP_APP_PASSWORD", + "ldap.server.app_password", + os.environ.get("LDAP_APP_PASSWORD", ""), +) + +LDAP_SEARCH_BASE = PersistentConfig( + "LDAP_SEARCH_BASE", "ldap.server.users_dn", os.environ.get("LDAP_SEARCH_BASE", "") +) + +LDAP_SEARCH_FILTERS = PersistentConfig( + "LDAP_SEARCH_FILTER", + "ldap.server.search_filter", + os.environ.get("LDAP_SEARCH_FILTER", os.environ.get("LDAP_SEARCH_FILTERS", "")), +) + +LDAP_USE_TLS = PersistentConfig( + "LDAP_USE_TLS", + "ldap.server.use_tls", + os.environ.get("LDAP_USE_TLS", "True").lower() == "true", +) + +LDAP_CA_CERT_FILE = PersistentConfig( + "LDAP_CA_CERT_FILE", + "ldap.server.ca_cert_file", + os.environ.get("LDAP_CA_CERT_FILE", ""), +) + +LDAP_CIPHERS = PersistentConfig( + "LDAP_CIPHERS", "ldap.server.ciphers", os.environ.get("LDAP_CIPHERS", "ALL") +) diff --git a/backend/open_webui/constants.py b/backend/open_webui/constants.py new file mode 100644 index 0000000..86d87a2 --- /dev/null +++ b/backend/open_webui/constants.py @@ -0,0 +1,119 @@ +from enum import Enum + + +class MESSAGES(str, Enum): + DEFAULT = lambda msg="": f"{msg if msg else ''}" + MODEL_ADDED = lambda model="": f"The model '{model}' has been added successfully." + MODEL_DELETED = ( + lambda model="": f"The model '{model}' has been deleted successfully." + ) + + +class WEBHOOK_MESSAGES(str, Enum): + DEFAULT = lambda msg="": f"{msg if msg else ''}" + USER_SIGNUP = lambda username="": ( + f"New user signed up: {username}" if username else "New user signed up" + ) + + +class ERROR_MESSAGES(str, Enum): + def __str__(self) -> str: + return super().__str__() + + DEFAULT = ( + lambda err="": f'{"Something went wrong :/" if err == "" else "[ERROR: " + str(err) + "]"}' + ) + ENV_VAR_NOT_FOUND = "Required environment variable not found. Terminating now." + CREATE_USER_ERROR = "Oops! Something went wrong while creating your account. Please try again later. If the issue persists, contact support for assistance." + DELETE_USER_ERROR = "Oops! Something went wrong. We encountered an issue while trying to delete the user. Please give it another shot." + EMAIL_MISMATCH = "Uh-oh! This email does not match the email your provider is registered with. Please check your email and try again." + EMAIL_TAKEN = "Uh-oh! This email is already registered. Sign in with your existing account or choose another email to start anew." + USERNAME_TAKEN = ( + "Uh-oh! This username is already registered. Please choose another username." + ) + COMMAND_TAKEN = "Uh-oh! This command is already registered. Please choose another command string." + FILE_EXISTS = "Uh-oh! This file is already registered. Please choose another file." + + ID_TAKEN = "Uh-oh! This id is already registered. Please choose another id string." + MODEL_ID_TAKEN = "Uh-oh! This model id is already registered. Please choose another model id string." + NAME_TAG_TAKEN = "Uh-oh! This name tag is already registered. Please choose another name tag string." + + INVALID_TOKEN = ( + "Your session has expired or the token is invalid. Please sign in again." + ) + INVALID_CRED = "The email or password provided is incorrect. Please check for typos and try logging in again." + INVALID_EMAIL_FORMAT = "The email format you entered is invalid. Please double-check and make sure you're using a valid email address (e.g., yourname@example.com)." + INVALID_PASSWORD = ( + "The password provided is incorrect. Please check for typos and try again." + ) + INVALID_TRUSTED_HEADER = "Your provider has not provided a trusted header. Please contact your administrator for assistance." + + EXISTING_USERS = "You can't turn off authentication because there are existing users. If you want to disable WEBUI_AUTH, make sure your web interface doesn't have any existing users and is a fresh installation." + + UNAUTHORIZED = "401 Unauthorized" + ACCESS_PROHIBITED = "You do not have permission to access this resource. Please contact your administrator for assistance." + ACTION_PROHIBITED = ( + "The requested action has been restricted as a security measure." + ) + + FILE_NOT_SENT = "FILE_NOT_SENT" + FILE_NOT_SUPPORTED = "Oops! It seems like the file format you're trying to upload is not supported. Please upload a file with a supported format and try again." + + NOT_FOUND = "We could not find what you're looking for :/" + USER_NOT_FOUND = "We could not find what you're looking for :/" + API_KEY_NOT_FOUND = "Oops! It looks like there's a hiccup. The API key is missing. Please make sure to provide a valid API key to access this feature." + API_KEY_NOT_ALLOWED = "Use of API key is not enabled in the environment." + + MALICIOUS = "Unusual activities detected, please try again in a few minutes." + + PANDOC_NOT_INSTALLED = "Pandoc is not installed on the server. Please contact your administrator for assistance." + INCORRECT_FORMAT = ( + lambda err="": f"Invalid format. Please use the correct format{err}" + ) + RATE_LIMIT_EXCEEDED = "API rate limit exceeded" + + MODEL_NOT_FOUND = lambda name="": f"Model '{name}' was not found" + OPENAI_NOT_FOUND = lambda name="": "OpenAI API was not found" + OLLAMA_NOT_FOUND = "WebUI could not connect to Ollama" + CREATE_API_KEY_ERROR = "Oops! Something went wrong while creating your API key. Please try again later. If the issue persists, contact support for assistance." + API_KEY_CREATION_NOT_ALLOWED = "API key creation is not allowed in the environment." + + EMPTY_CONTENT = "The content provided is empty. Please ensure that there is text or data present before proceeding." + + DB_NOT_SQLITE = "This feature is only available when running with SQLite databases." + + INVALID_URL = ( + "Oops! The URL you provided is invalid. Please double-check and try again." + ) + + WEB_SEARCH_ERROR = ( + lambda err="": f"{err if err else 'Oops! Something went wrong while searching the web.'}" + ) + + OLLAMA_API_DISABLED = ( + "The Ollama API is disabled. Please enable it to use this feature." + ) + + FILE_TOO_LARGE = ( + lambda size="": f"Oops! The file you're trying to upload is too large. Please upload a file that is less than {size}." + ) + + DUPLICATE_CONTENT = ( + "Duplicate content detected. Please provide unique content to proceed." + ) + FILE_NOT_PROCESSED = "Extracted content is not available for this file. Please ensure that the file is processed before proceeding." + + +class TASKS(str, Enum): + def __str__(self) -> str: + return super().__str__() + + DEFAULT = lambda task="": f"{task if task else 'generation'}" + TITLE_GENERATION = "title_generation" + TAGS_GENERATION = "tags_generation" + EMOJI_GENERATION = "emoji_generation" + QUERY_GENERATION = "query_generation" + IMAGE_PROMPT_GENERATION = "image_prompt_generation" + AUTOCOMPLETE_GENERATION = "autocomplete_generation" + FUNCTION_CALLING = "function_calling" + MOA_RESPONSE_GENERATION = "moa_response_generation" diff --git a/backend/open_webui/env.py b/backend/open_webui/env.py new file mode 100644 index 0000000..ba546a2 --- /dev/null +++ b/backend/open_webui/env.py @@ -0,0 +1,443 @@ +import importlib.metadata +import json +import logging +import os +import pkgutil +import sys +import shutil +from pathlib import Path + +import markdown +from bs4 import BeautifulSoup +from open_webui.constants import ERROR_MESSAGES + +#################################### +# Load .env file +#################################### + +OPEN_WEBUI_DIR = Path(__file__).parent # the path containing this file +print(OPEN_WEBUI_DIR) + +BACKEND_DIR = OPEN_WEBUI_DIR.parent # the path containing this file +BASE_DIR = BACKEND_DIR.parent # the path containing the backend/ + +print(BACKEND_DIR) +print(BASE_DIR) + +try: + from dotenv import find_dotenv, load_dotenv + + load_dotenv(find_dotenv(str(BASE_DIR / ".env"))) +except ImportError: + print("dotenv not installed, skipping...") + +DOCKER = os.environ.get("DOCKER", "False").lower() == "true" + +# device type embedding models - "cpu" (default), "cuda" (nvidia gpu required) or "mps" (apple silicon) - choosing this right can lead to better performance +USE_CUDA = os.environ.get("USE_CUDA_DOCKER", "false") + +if USE_CUDA.lower() == "true": + try: + import torch + + assert torch.cuda.is_available(), "CUDA not available" + DEVICE_TYPE = "cuda" + except Exception as e: + cuda_error = ( + "Error when testing CUDA but USE_CUDA_DOCKER is true. " + f"Resetting USE_CUDA_DOCKER to false: {e}" + ) + os.environ["USE_CUDA_DOCKER"] = "false" + USE_CUDA = "false" + DEVICE_TYPE = "cpu" +else: + DEVICE_TYPE = "cpu" + +try: + import torch + + if torch.backends.mps.is_available() and torch.backends.mps.is_built(): + DEVICE_TYPE = "mps" +except Exception: + pass + +#################################### +# LOGGING +#################################### + +log_levels = ["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"] + +GLOBAL_LOG_LEVEL = os.environ.get("GLOBAL_LOG_LEVEL", "").upper() +if GLOBAL_LOG_LEVEL in log_levels: + logging.basicConfig(stream=sys.stdout, level=GLOBAL_LOG_LEVEL, force=True) +else: + GLOBAL_LOG_LEVEL = "INFO" + +log = logging.getLogger(__name__) +log.info(f"GLOBAL_LOG_LEVEL: {GLOBAL_LOG_LEVEL}") + +if "cuda_error" in locals(): + log.exception(cuda_error) + +log_sources = [ + "AUDIO", + "COMFYUI", + "CONFIG", + "DB", + "IMAGES", + "MAIN", + "MODELS", + "OLLAMA", + "OPENAI", + "RAG", + "WEBHOOK", + "SOCKET", + "OAUTH", +] + +SRC_LOG_LEVELS = {} + +for source in log_sources: + log_env_var = source + "_LOG_LEVEL" + SRC_LOG_LEVELS[source] = os.environ.get(log_env_var, "").upper() + if SRC_LOG_LEVELS[source] not in log_levels: + SRC_LOG_LEVELS[source] = GLOBAL_LOG_LEVEL + log.info(f"{log_env_var}: {SRC_LOG_LEVELS[source]}") + +log.setLevel(SRC_LOG_LEVELS["CONFIG"]) + + +WEBUI_NAME = os.environ.get("WEBUI_NAME", "Open WebUI") +if WEBUI_NAME != "Open WebUI": + WEBUI_NAME += " (Open WebUI)" + +WEBUI_FAVICON_URL = "https://openwebui.com/favicon.png" + +TRUSTED_SIGNATURE_KEY = os.environ.get("TRUSTED_SIGNATURE_KEY", "") + +#################################### +# ENV (dev,test,prod) +#################################### + +ENV = os.environ.get("ENV", "dev") + +FROM_INIT_PY = os.environ.get("FROM_INIT_PY", "False").lower() == "true" + +if FROM_INIT_PY: + PACKAGE_DATA = {"version": importlib.metadata.version("open-webui")} +else: + try: + PACKAGE_DATA = json.loads((BASE_DIR / "package.json").read_text()) + except Exception: + PACKAGE_DATA = {"version": "0.0.0"} + + +VERSION = PACKAGE_DATA["version"] + + +# Function to parse each section +def parse_section(section): + items = [] + for li in section.find_all("li"): + # Extract raw HTML string + raw_html = str(li) + + # Extract text without HTML tags + text = li.get_text(separator=" ", strip=True) + + # Split into title and content + parts = text.split(": ", 1) + title = parts[0].strip() if len(parts) > 1 else "" + content = parts[1].strip() if len(parts) > 1 else text + + items.append({"title": title, "content": content, "raw": raw_html}) + return items + + +try: + changelog_path = BASE_DIR / "CHANGELOG.md" + with open(str(changelog_path.absolute()), "r", encoding="utf8") as file: + changelog_content = file.read() + +except Exception: + changelog_content = (pkgutil.get_data("open_webui", "CHANGELOG.md") or b"").decode() + + +# Convert markdown content to HTML +html_content = markdown.markdown(changelog_content) + +# Parse the HTML content +soup = BeautifulSoup(html_content, "html.parser") + +# Initialize JSON structure +changelog_json = {} + +# Iterate over each version +for version in soup.find_all("h2"): + version_number = version.get_text().strip().split(" - ")[0][1:-1] # Remove brackets + date = version.get_text().strip().split(" - ")[1] + + version_data = {"date": date} + + # Find the next sibling that is a h3 tag (section title) + current = version.find_next_sibling() + + while current and current.name != "h2": + if current.name == "h3": + section_title = current.get_text().lower() # e.g., "added", "fixed" + section_items = parse_section(current.find_next_sibling("ul")) + version_data[section_title] = section_items + + # Move to the next element + current = current.find_next_sibling() + + changelog_json[version_number] = version_data + + +CHANGELOG = changelog_json + +#################################### +# SAFE_MODE +#################################### + +SAFE_MODE = os.environ.get("SAFE_MODE", "false").lower() == "true" + +#################################### +# ENABLE_FORWARD_USER_INFO_HEADERS +#################################### + +ENABLE_FORWARD_USER_INFO_HEADERS = ( + os.environ.get("ENABLE_FORWARD_USER_INFO_HEADERS", "False").lower() == "true" +) + + +#################################### +# WEBUI_BUILD_HASH +#################################### + +WEBUI_BUILD_HASH = os.environ.get("WEBUI_BUILD_HASH", "dev-build") + +#################################### +# DATA/FRONTEND BUILD DIR +#################################### + +DATA_DIR = Path(os.getenv("DATA_DIR", BACKEND_DIR / "data")).resolve() + +if FROM_INIT_PY: + NEW_DATA_DIR = Path(os.getenv("DATA_DIR", OPEN_WEBUI_DIR / "data")).resolve() + NEW_DATA_DIR.mkdir(parents=True, exist_ok=True) + + # Check if the data directory exists in the package directory + if DATA_DIR.exists() and DATA_DIR != NEW_DATA_DIR: + log.info(f"Moving {DATA_DIR} to {NEW_DATA_DIR}") + for item in DATA_DIR.iterdir(): + dest = NEW_DATA_DIR / item.name + if item.is_dir(): + shutil.copytree(item, dest, dirs_exist_ok=True) + else: + shutil.copy2(item, dest) + + # Zip the data directory + shutil.make_archive(DATA_DIR.parent / "open_webui_data", "zip", DATA_DIR) + + # Remove the old data directory + shutil.rmtree(DATA_DIR) + + DATA_DIR = Path(os.getenv("DATA_DIR", OPEN_WEBUI_DIR / "data")) + + +STATIC_DIR = Path(os.getenv("STATIC_DIR", OPEN_WEBUI_DIR / "static")) + +FONTS_DIR = Path(os.getenv("FONTS_DIR", OPEN_WEBUI_DIR / "static" / "fonts")) + +FRONTEND_BUILD_DIR = Path(os.getenv("FRONTEND_BUILD_DIR", BASE_DIR / "build")).resolve() + +if FROM_INIT_PY: + FRONTEND_BUILD_DIR = Path( + os.getenv("FRONTEND_BUILD_DIR", OPEN_WEBUI_DIR / "frontend") + ).resolve() + + +#################################### +# Database +#################################### + +# Check if the file exists +if os.path.exists(f"{DATA_DIR}/ollama.db"): + # Rename the file + os.rename(f"{DATA_DIR}/ollama.db", f"{DATA_DIR}/webui.db") + log.info("Database migrated from Ollama-WebUI successfully.") +else: + pass + +DATABASE_URL = os.environ.get("DATABASE_URL", f"sqlite:///{DATA_DIR}/webui.db") + +# Replace the postgres:// with postgresql:// +if "postgres://" in DATABASE_URL: + DATABASE_URL = DATABASE_URL.replace("postgres://", "postgresql://") + +DATABASE_SCHEMA = os.environ.get("DATABASE_SCHEMA", None) + +DATABASE_POOL_SIZE = os.environ.get("DATABASE_POOL_SIZE", 0) + +if DATABASE_POOL_SIZE == "": + DATABASE_POOL_SIZE = 0 +else: + try: + DATABASE_POOL_SIZE = int(DATABASE_POOL_SIZE) + except Exception: + DATABASE_POOL_SIZE = 0 + +DATABASE_POOL_MAX_OVERFLOW = os.environ.get("DATABASE_POOL_MAX_OVERFLOW", 0) + +if DATABASE_POOL_MAX_OVERFLOW == "": + DATABASE_POOL_MAX_OVERFLOW = 0 +else: + try: + DATABASE_POOL_MAX_OVERFLOW = int(DATABASE_POOL_MAX_OVERFLOW) + except Exception: + DATABASE_POOL_MAX_OVERFLOW = 0 + +DATABASE_POOL_TIMEOUT = os.environ.get("DATABASE_POOL_TIMEOUT", 30) + +if DATABASE_POOL_TIMEOUT == "": + DATABASE_POOL_TIMEOUT = 30 +else: + try: + DATABASE_POOL_TIMEOUT = int(DATABASE_POOL_TIMEOUT) + except Exception: + DATABASE_POOL_TIMEOUT = 30 + +DATABASE_POOL_RECYCLE = os.environ.get("DATABASE_POOL_RECYCLE", 3600) + +if DATABASE_POOL_RECYCLE == "": + DATABASE_POOL_RECYCLE = 3600 +else: + try: + DATABASE_POOL_RECYCLE = int(DATABASE_POOL_RECYCLE) + except Exception: + DATABASE_POOL_RECYCLE = 3600 + +RESET_CONFIG_ON_START = ( + os.environ.get("RESET_CONFIG_ON_START", "False").lower() == "true" +) + + +ENABLE_REALTIME_CHAT_SAVE = ( + os.environ.get("ENABLE_REALTIME_CHAT_SAVE", "False").lower() == "true" +) + +#################################### +# REDIS +#################################### + +REDIS_URL = os.environ.get("REDIS_URL", "redis://localhost:6379/0") + +#################################### +# WEBUI_AUTH (Required for security) +#################################### + +WEBUI_AUTH = os.environ.get("WEBUI_AUTH", "True").lower() == "true" +WEBUI_AUTH_TRUSTED_EMAIL_HEADER = os.environ.get( + "WEBUI_AUTH_TRUSTED_EMAIL_HEADER", None +) +WEBUI_AUTH_TRUSTED_NAME_HEADER = os.environ.get("WEBUI_AUTH_TRUSTED_NAME_HEADER", None) + +BYPASS_MODEL_ACCESS_CONTROL = ( + os.environ.get("BYPASS_MODEL_ACCESS_CONTROL", "False").lower() == "true" +) + +#################################### +# WEBUI_SECRET_KEY +#################################### + +WEBUI_SECRET_KEY = os.environ.get( + "WEBUI_SECRET_KEY", + os.environ.get( + "WEBUI_JWT_SECRET_KEY", "t0p-s3cr3t" + ), # DEPRECATED: remove at next major version +) + +WEBUI_SESSION_COOKIE_SAME_SITE = os.environ.get("WEBUI_SESSION_COOKIE_SAME_SITE", "lax") + +WEBUI_SESSION_COOKIE_SECURE = ( + os.environ.get("WEBUI_SESSION_COOKIE_SECURE", "false").lower() == "true" +) + +WEBUI_AUTH_COOKIE_SAME_SITE = os.environ.get( + "WEBUI_AUTH_COOKIE_SAME_SITE", WEBUI_SESSION_COOKIE_SAME_SITE +) + +WEBUI_AUTH_COOKIE_SECURE = ( + os.environ.get( + "WEBUI_AUTH_COOKIE_SECURE", + os.environ.get("WEBUI_SESSION_COOKIE_SECURE", "false"), + ).lower() + == "true" +) + +if WEBUI_AUTH and WEBUI_SECRET_KEY == "": + raise ValueError(ERROR_MESSAGES.ENV_VAR_NOT_FOUND) + +ENABLE_WEBSOCKET_SUPPORT = ( + os.environ.get("ENABLE_WEBSOCKET_SUPPORT", "True").lower() == "true" +) + +WEBSOCKET_MANAGER = os.environ.get("WEBSOCKET_MANAGER", "") + +WEBSOCKET_REDIS_URL = os.environ.get("WEBSOCKET_REDIS_URL", REDIS_URL) + +AIOHTTP_CLIENT_TIMEOUT = os.environ.get("AIOHTTP_CLIENT_TIMEOUT", "") + +if AIOHTTP_CLIENT_TIMEOUT == "": + AIOHTTP_CLIENT_TIMEOUT = None +else: + try: + AIOHTTP_CLIENT_TIMEOUT = int(AIOHTTP_CLIENT_TIMEOUT) + except Exception: + AIOHTTP_CLIENT_TIMEOUT = 300 + +AIOHTTP_CLIENT_TIMEOUT_OPENAI_MODEL_LIST = os.environ.get( + "AIOHTTP_CLIENT_TIMEOUT_OPENAI_MODEL_LIST", "" +) + +if AIOHTTP_CLIENT_TIMEOUT_OPENAI_MODEL_LIST == "": + AIOHTTP_CLIENT_TIMEOUT_OPENAI_MODEL_LIST = None +else: + try: + AIOHTTP_CLIENT_TIMEOUT_OPENAI_MODEL_LIST = int( + AIOHTTP_CLIENT_TIMEOUT_OPENAI_MODEL_LIST + ) + except Exception: + AIOHTTP_CLIENT_TIMEOUT_OPENAI_MODEL_LIST = 5 + +#################################### +# OFFLINE_MODE +#################################### + +OFFLINE_MODE = os.environ.get("OFFLINE_MODE", "false").lower() == "true" + +if OFFLINE_MODE: + os.environ["HF_HUB_OFFLINE"] = "1" + +#################################### +# AUDIT LOGGING +#################################### +ENABLE_AUDIT_LOGS = os.getenv("ENABLE_AUDIT_LOGS", "false").lower() == "true" +# Where to store log file +AUDIT_LOGS_FILE_PATH = f"{DATA_DIR}/audit.log" +# Maximum size of a file before rotating into a new log file +AUDIT_LOG_FILE_ROTATION_SIZE = os.getenv("AUDIT_LOG_FILE_ROTATION_SIZE", "10MB") +# METADATA | REQUEST | REQUEST_RESPONSE +AUDIT_LOG_LEVEL = os.getenv("AUDIT_LOG_LEVEL", "REQUEST_RESPONSE").upper() +try: + MAX_BODY_LOG_SIZE = int(os.environ.get("MAX_BODY_LOG_SIZE") or 2048) +except ValueError: + MAX_BODY_LOG_SIZE = 2048 + +# Comma separated list for urls to exclude from audit +AUDIT_EXCLUDED_PATHS = os.getenv("AUDIT_EXCLUDED_PATHS", "/chats,/chat,/folders").split( + "," +) +AUDIT_EXCLUDED_PATHS = [path.strip() for path in AUDIT_EXCLUDED_PATHS] +AUDIT_EXCLUDED_PATHS = [path.lstrip("/") for path in AUDIT_EXCLUDED_PATHS] diff --git a/backend/open_webui/functions.py b/backend/open_webui/functions.py new file mode 100644 index 0000000..2f94f70 --- /dev/null +++ b/backend/open_webui/functions.py @@ -0,0 +1,319 @@ +import logging +import sys +import inspect +import json +import asyncio + +from pydantic import BaseModel +from typing import AsyncGenerator, Generator, Iterator +from fastapi import ( + Depends, + FastAPI, + File, + Form, + HTTPException, + Request, + UploadFile, + status, +) +from starlette.responses import Response, StreamingResponse + + +from open_webui.socket.main import ( + get_event_call, + get_event_emitter, +) + + +from open_webui.models.functions import Functions +from open_webui.models.models import Models + +from open_webui.utils.plugin import load_function_module_by_id +from open_webui.utils.tools import get_tools +from open_webui.utils.access_control import has_access + +from open_webui.env import SRC_LOG_LEVELS, GLOBAL_LOG_LEVEL + +from open_webui.utils.misc import ( + add_or_update_system_message, + get_last_user_message, + prepend_to_first_user_message_content, + openai_chat_chunk_message_template, + openai_chat_completion_message_template, +) +from open_webui.utils.payload import ( + apply_model_params_to_body_openai, + apply_model_system_prompt_to_body, +) + + +logging.basicConfig(stream=sys.stdout, level=GLOBAL_LOG_LEVEL) +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MAIN"]) + + +def get_function_module_by_id(request: Request, pipe_id: str): + # Check if function is already loaded + if pipe_id not in request.app.state.FUNCTIONS: + function_module, _, _ = load_function_module_by_id(pipe_id) + request.app.state.FUNCTIONS[pipe_id] = function_module + else: + function_module = request.app.state.FUNCTIONS[pipe_id] + + if hasattr(function_module, "valves") and hasattr(function_module, "Valves"): + valves = Functions.get_function_valves_by_id(pipe_id) + function_module.valves = function_module.Valves(**(valves if valves else {})) + return function_module + + +async def get_function_models(request): + pipes = Functions.get_functions_by_type("pipe", active_only=True) + pipe_models = [] + + for pipe in pipes: + function_module = get_function_module_by_id(request, pipe.id) + + # Check if function is a manifold + if hasattr(function_module, "pipes"): + sub_pipes = [] + + # Handle pipes being a list, sync function, or async function + try: + if callable(function_module.pipes): + if asyncio.iscoroutinefunction(function_module.pipes): + sub_pipes = await function_module.pipes() + else: + sub_pipes = function_module.pipes() + else: + sub_pipes = function_module.pipes + except Exception as e: + log.exception(e) + sub_pipes = [] + + log.debug( + f"get_function_models: function '{pipe.id}' is a manifold of {sub_pipes}" + ) + + for p in sub_pipes: + sub_pipe_id = f'{pipe.id}.{p["id"]}' + sub_pipe_name = p["name"] + + if hasattr(function_module, "name"): + sub_pipe_name = f"{function_module.name}{sub_pipe_name}" + + pipe_flag = {"type": pipe.type} + + pipe_models.append( + { + "id": sub_pipe_id, + "name": sub_pipe_name, + "object": "model", + "created": pipe.created_at, + "owned_by": "openai", + "pipe": pipe_flag, + } + ) + else: + pipe_flag = {"type": "pipe"} + + log.debug( + f"get_function_models: function '{pipe.id}' is a single pipe {{ 'id': {pipe.id}, 'name': {pipe.name} }}" + ) + + pipe_models.append( + { + "id": pipe.id, + "name": pipe.name, + "object": "model", + "created": pipe.created_at, + "owned_by": "openai", + "pipe": pipe_flag, + } + ) + + return pipe_models + + +async def generate_function_chat_completion( + request, form_data, user, models: dict = {} +): + async def execute_pipe(pipe, params): + if inspect.iscoroutinefunction(pipe): + return await pipe(**params) + else: + return pipe(**params) + + async def get_message_content(res: str | Generator | AsyncGenerator) -> str: + if isinstance(res, str): + return res + if isinstance(res, Generator): + return "".join(map(str, res)) + if isinstance(res, AsyncGenerator): + return "".join([str(stream) async for stream in res]) + + def process_line(form_data: dict, line): + if isinstance(line, BaseModel): + line = line.model_dump_json() + line = f"data: {line}" + if isinstance(line, dict): + line = f"data: {json.dumps(line)}" + + try: + line = line.decode("utf-8") + except Exception: + pass + + if line.startswith("data:"): + return f"{line}\n\n" + else: + line = openai_chat_chunk_message_template(form_data["model"], line) + return f"data: {json.dumps(line)}\n\n" + + def get_pipe_id(form_data: dict) -> str: + pipe_id = form_data["model"] + if "." in pipe_id: + pipe_id, _ = pipe_id.split(".", 1) + return pipe_id + + def get_function_params(function_module, form_data, user, extra_params=None): + if extra_params is None: + extra_params = {} + + pipe_id = get_pipe_id(form_data) + + # Get the signature of the function + sig = inspect.signature(function_module.pipe) + params = {"body": form_data} | { + k: v for k, v in extra_params.items() if k in sig.parameters + } + + if "__user__" in params and hasattr(function_module, "UserValves"): + user_valves = Functions.get_user_valves_by_id_and_user_id(pipe_id, user.id) + try: + params["__user__"]["valves"] = function_module.UserValves(**user_valves) + except Exception as e: + log.exception(e) + params["__user__"]["valves"] = function_module.UserValves() + + return params + + model_id = form_data.get("model") + model_info = Models.get_model_by_id(model_id) + + metadata = form_data.pop("metadata", {}) + + files = metadata.get("files", []) + tool_ids = metadata.get("tool_ids", []) + # Check if tool_ids is None + if tool_ids is None: + tool_ids = [] + + __event_emitter__ = None + __event_call__ = None + __task__ = None + __task_body__ = None + + if metadata: + if all(k in metadata for k in ("session_id", "chat_id", "message_id")): + __event_emitter__ = get_event_emitter(metadata) + __event_call__ = get_event_call(metadata) + __task__ = metadata.get("task", None) + __task_body__ = metadata.get("task_body", None) + + extra_params = { + "__event_emitter__": __event_emitter__, + "__event_call__": __event_call__, + "__task__": __task__, + "__task_body__": __task_body__, + "__files__": files, + "__user__": { + "id": user.id, + "email": user.email, + "name": user.name, + "role": user.role, + }, + "__metadata__": metadata, + "__request__": request, + } + extra_params["__tools__"] = get_tools( + request, + tool_ids, + user, + { + **extra_params, + "__model__": models.get(form_data["model"], None), + "__messages__": form_data["messages"], + "__files__": files, + }, + ) + + if model_info: + if model_info.base_model_id: + form_data["model"] = model_info.base_model_id + + params = model_info.params.model_dump() + form_data = apply_model_params_to_body_openai(params, form_data) + form_data = apply_model_system_prompt_to_body(params, form_data, metadata, user) + + pipe_id = get_pipe_id(form_data) + function_module = get_function_module_by_id(request, pipe_id) + + pipe = function_module.pipe + params = get_function_params(function_module, form_data, user, extra_params) + + if form_data.get("stream", False): + + async def stream_content(): + try: + res = await execute_pipe(pipe, params) + + # Directly return if the response is a StreamingResponse + if isinstance(res, StreamingResponse): + async for data in res.body_iterator: + yield data + return + if isinstance(res, dict): + yield f"data: {json.dumps(res)}\n\n" + return + + except Exception as e: + log.error(f"Error: {e}") + yield f"data: {json.dumps({'error': {'detail':str(e)}})}\n\n" + return + + if isinstance(res, str): + message = openai_chat_chunk_message_template(form_data["model"], res) + yield f"data: {json.dumps(message)}\n\n" + + if isinstance(res, Iterator): + for line in res: + yield process_line(form_data, line) + + if isinstance(res, AsyncGenerator): + async for line in res: + yield process_line(form_data, line) + + if isinstance(res, str) or isinstance(res, Generator): + finish_message = openai_chat_chunk_message_template( + form_data["model"], "" + ) + finish_message["choices"][0]["finish_reason"] = "stop" + yield f"data: {json.dumps(finish_message)}\n\n" + yield "data: [DONE]" + + return StreamingResponse(stream_content(), media_type="text/event-stream") + else: + try: + res = await execute_pipe(pipe, params) + + except Exception as e: + log.error(f"Error: {e}") + return {"error": {"detail": str(e)}} + + if isinstance(res, StreamingResponse) or isinstance(res, dict): + return res + if isinstance(res, BaseModel): + return res.model_dump() + + message = await get_message_content(res) + return openai_chat_completion_message_template(form_data["model"], message) diff --git a/backend/open_webui/internal/db.py b/backend/open_webui/internal/db.py new file mode 100644 index 0000000..840f571 --- /dev/null +++ b/backend/open_webui/internal/db.py @@ -0,0 +1,116 @@ +import json +import logging +from contextlib import contextmanager +from typing import Any, Optional + +from open_webui.internal.wrappers import register_connection +from open_webui.env import ( + OPEN_WEBUI_DIR, + DATABASE_URL, + DATABASE_SCHEMA, + SRC_LOG_LEVELS, + DATABASE_POOL_MAX_OVERFLOW, + DATABASE_POOL_RECYCLE, + DATABASE_POOL_SIZE, + DATABASE_POOL_TIMEOUT, +) +from peewee_migrate import Router +from sqlalchemy import Dialect, create_engine, MetaData, types +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import scoped_session, sessionmaker +from sqlalchemy.pool import QueuePool, NullPool +from sqlalchemy.sql.type_api import _T +from typing_extensions import Self + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["DB"]) + + +class JSONField(types.TypeDecorator): + impl = types.Text + cache_ok = True + + def process_bind_param(self, value: Optional[_T], dialect: Dialect) -> Any: + return json.dumps(value) + + def process_result_value(self, value: Optional[_T], dialect: Dialect) -> Any: + if value is not None: + return json.loads(value) + + def copy(self, **kw: Any) -> Self: + return JSONField(self.impl.length) + + def db_value(self, value): + return json.dumps(value) + + def python_value(self, value): + if value is not None: + return json.loads(value) + + +# Workaround to handle the peewee migration +# This is required to ensure the peewee migration is handled before the alembic migration +def handle_peewee_migration(DATABASE_URL): + # db = None + try: + # Replace the postgresql:// with postgres:// to handle the peewee migration + db = register_connection(DATABASE_URL.replace("postgresql://", "postgres://")) + migrate_dir = OPEN_WEBUI_DIR / "internal" / "migrations" + router = Router(db, logger=log, migrate_dir=migrate_dir) + router.run() + db.close() + + except Exception as e: + log.error(f"Failed to initialize the database connection: {e}") + raise + finally: + # Properly closing the database connection + if db and not db.is_closed(): + db.close() + + # Assert if db connection has been closed + assert db.is_closed(), "Database connection is still open." + + +handle_peewee_migration(DATABASE_URL) + + +SQLALCHEMY_DATABASE_URL = DATABASE_URL +if "sqlite" in SQLALCHEMY_DATABASE_URL: + engine = create_engine( + SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False} + ) +else: + if DATABASE_POOL_SIZE > 0: + engine = create_engine( + SQLALCHEMY_DATABASE_URL, + pool_size=DATABASE_POOL_SIZE, + max_overflow=DATABASE_POOL_MAX_OVERFLOW, + pool_timeout=DATABASE_POOL_TIMEOUT, + pool_recycle=DATABASE_POOL_RECYCLE, + pool_pre_ping=True, + poolclass=QueuePool, + ) + else: + engine = create_engine( + SQLALCHEMY_DATABASE_URL, pool_pre_ping=True, poolclass=NullPool + ) + + +SessionLocal = sessionmaker( + autocommit=False, autoflush=False, bind=engine, expire_on_commit=False +) +metadata_obj = MetaData(schema=DATABASE_SCHEMA) +Base = declarative_base(metadata=metadata_obj) +Session = scoped_session(SessionLocal) + + +def get_session(): + db = SessionLocal() + try: + yield db + finally: + db.close() + + +get_db = contextmanager(get_session) diff --git a/backend/open_webui/internal/migrations/001_initial_schema.py b/backend/open_webui/internal/migrations/001_initial_schema.py new file mode 100644 index 0000000..93f278f --- /dev/null +++ b/backend/open_webui/internal/migrations/001_initial_schema.py @@ -0,0 +1,254 @@ +"""Peewee migrations -- 001_initial_schema.py. + +Some examples (model - class or model name):: + + > Model = migrator.orm['table_name'] # Return model in current state by name + > Model = migrator.ModelClass # Return model in current state by name + + > migrator.sql(sql) # Run custom SQL + > migrator.run(func, *args, **kwargs) # Run python function with the given args + > migrator.create_model(Model) # Create a model (could be used as decorator) + > migrator.remove_model(model, cascade=True) # Remove a model + > migrator.add_fields(model, **fields) # Add fields to a model + > migrator.change_fields(model, **fields) # Change fields + > migrator.remove_fields(model, *field_names, cascade=True) + > migrator.rename_field(model, old_field_name, new_field_name) + > migrator.rename_table(model, new_table_name) + > migrator.add_index(model, *col_names, unique=False) + > migrator.add_not_null(model, *field_names) + > migrator.add_default(model, field_name, default) + > migrator.add_constraint(model, name, sql) + > migrator.drop_index(model, *col_names) + > migrator.drop_not_null(model, *field_names) + > migrator.drop_constraints(model, *constraints) + +""" + +from contextlib import suppress + +import peewee as pw +from peewee_migrate import Migrator + + +with suppress(ImportError): + import playhouse.postgres_ext as pw_pext + + +def migrate(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your migrations here.""" + + # We perform different migrations for SQLite and other databases + # This is because SQLite is very loose with enforcing its schema, and trying to migrate other databases like SQLite + # will require per-database SQL queries. + # Instead, we assume that because external DB support was added at a later date, it is safe to assume a newer base + # schema instead of trying to migrate from an older schema. + if isinstance(database, pw.SqliteDatabase): + migrate_sqlite(migrator, database, fake=fake) + else: + migrate_external(migrator, database, fake=fake) + + +def migrate_sqlite(migrator: Migrator, database: pw.Database, *, fake=False): + @migrator.create_model + class Auth(pw.Model): + id = pw.CharField(max_length=255, unique=True) + email = pw.CharField(max_length=255) + password = pw.CharField(max_length=255) + active = pw.BooleanField() + + class Meta: + table_name = "auth" + + @migrator.create_model + class Chat(pw.Model): + id = pw.CharField(max_length=255, unique=True) + user_id = pw.CharField(max_length=255) + title = pw.CharField() + chat = pw.TextField() + timestamp = pw.BigIntegerField() + + class Meta: + table_name = "chat" + + @migrator.create_model + class ChatIdTag(pw.Model): + id = pw.CharField(max_length=255, unique=True) + tag_name = pw.CharField(max_length=255) + chat_id = pw.CharField(max_length=255) + user_id = pw.CharField(max_length=255) + timestamp = pw.BigIntegerField() + + class Meta: + table_name = "chatidtag" + + @migrator.create_model + class Document(pw.Model): + id = pw.AutoField() + collection_name = pw.CharField(max_length=255, unique=True) + name = pw.CharField(max_length=255, unique=True) + title = pw.CharField() + filename = pw.CharField() + content = pw.TextField(null=True) + user_id = pw.CharField(max_length=255) + timestamp = pw.BigIntegerField() + + class Meta: + table_name = "document" + + @migrator.create_model + class Modelfile(pw.Model): + id = pw.AutoField() + tag_name = pw.CharField(max_length=255, unique=True) + user_id = pw.CharField(max_length=255) + modelfile = pw.TextField() + timestamp = pw.BigIntegerField() + + class Meta: + table_name = "modelfile" + + @migrator.create_model + class Prompt(pw.Model): + id = pw.AutoField() + command = pw.CharField(max_length=255, unique=True) + user_id = pw.CharField(max_length=255) + title = pw.CharField() + content = pw.TextField() + timestamp = pw.BigIntegerField() + + class Meta: + table_name = "prompt" + + @migrator.create_model + class Tag(pw.Model): + id = pw.CharField(max_length=255, unique=True) + name = pw.CharField(max_length=255) + user_id = pw.CharField(max_length=255) + data = pw.TextField(null=True) + + class Meta: + table_name = "tag" + + @migrator.create_model + class User(pw.Model): + id = pw.CharField(max_length=255, unique=True) + name = pw.CharField(max_length=255) + email = pw.CharField(max_length=255) + role = pw.CharField(max_length=255) + profile_image_url = pw.CharField(max_length=255) + timestamp = pw.BigIntegerField() + + class Meta: + table_name = "user" + + +def migrate_external(migrator: Migrator, database: pw.Database, *, fake=False): + @migrator.create_model + class Auth(pw.Model): + id = pw.CharField(max_length=255, unique=True) + email = pw.CharField(max_length=255) + password = pw.TextField() + active = pw.BooleanField() + + class Meta: + table_name = "auth" + + @migrator.create_model + class Chat(pw.Model): + id = pw.CharField(max_length=255, unique=True) + user_id = pw.CharField(max_length=255) + title = pw.TextField() + chat = pw.TextField() + timestamp = pw.BigIntegerField() + + class Meta: + table_name = "chat" + + @migrator.create_model + class ChatIdTag(pw.Model): + id = pw.CharField(max_length=255, unique=True) + tag_name = pw.CharField(max_length=255) + chat_id = pw.CharField(max_length=255) + user_id = pw.CharField(max_length=255) + timestamp = pw.BigIntegerField() + + class Meta: + table_name = "chatidtag" + + @migrator.create_model + class Document(pw.Model): + id = pw.AutoField() + collection_name = pw.CharField(max_length=255, unique=True) + name = pw.CharField(max_length=255, unique=True) + title = pw.TextField() + filename = pw.TextField() + content = pw.TextField(null=True) + user_id = pw.CharField(max_length=255) + timestamp = pw.BigIntegerField() + + class Meta: + table_name = "document" + + @migrator.create_model + class Modelfile(pw.Model): + id = pw.AutoField() + tag_name = pw.CharField(max_length=255, unique=True) + user_id = pw.CharField(max_length=255) + modelfile = pw.TextField() + timestamp = pw.BigIntegerField() + + class Meta: + table_name = "modelfile" + + @migrator.create_model + class Prompt(pw.Model): + id = pw.AutoField() + command = pw.CharField(max_length=255, unique=True) + user_id = pw.CharField(max_length=255) + title = pw.TextField() + content = pw.TextField() + timestamp = pw.BigIntegerField() + + class Meta: + table_name = "prompt" + + @migrator.create_model + class Tag(pw.Model): + id = pw.CharField(max_length=255, unique=True) + name = pw.CharField(max_length=255) + user_id = pw.CharField(max_length=255) + data = pw.TextField(null=True) + + class Meta: + table_name = "tag" + + @migrator.create_model + class User(pw.Model): + id = pw.CharField(max_length=255, unique=True) + name = pw.CharField(max_length=255) + email = pw.CharField(max_length=255) + role = pw.CharField(max_length=255) + profile_image_url = pw.TextField() + timestamp = pw.BigIntegerField() + + class Meta: + table_name = "user" + + +def rollback(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your rollback migrations here.""" + + migrator.remove_model("user") + + migrator.remove_model("tag") + + migrator.remove_model("prompt") + + migrator.remove_model("modelfile") + + migrator.remove_model("document") + + migrator.remove_model("chatidtag") + + migrator.remove_model("chat") + + migrator.remove_model("auth") diff --git a/backend/open_webui/internal/migrations/002_add_local_sharing.py b/backend/open_webui/internal/migrations/002_add_local_sharing.py new file mode 100644 index 0000000..e93501a --- /dev/null +++ b/backend/open_webui/internal/migrations/002_add_local_sharing.py @@ -0,0 +1,48 @@ +"""Peewee migrations -- 002_add_local_sharing.py. + +Some examples (model - class or model name):: + + > Model = migrator.orm['table_name'] # Return model in current state by name + > Model = migrator.ModelClass # Return model in current state by name + + > migrator.sql(sql) # Run custom SQL + > migrator.run(func, *args, **kwargs) # Run python function with the given args + > migrator.create_model(Model) # Create a model (could be used as decorator) + > migrator.remove_model(model, cascade=True) # Remove a model + > migrator.add_fields(model, **fields) # Add fields to a model + > migrator.change_fields(model, **fields) # Change fields + > migrator.remove_fields(model, *field_names, cascade=True) + > migrator.rename_field(model, old_field_name, new_field_name) + > migrator.rename_table(model, new_table_name) + > migrator.add_index(model, *col_names, unique=False) + > migrator.add_not_null(model, *field_names) + > migrator.add_default(model, field_name, default) + > migrator.add_constraint(model, name, sql) + > migrator.drop_index(model, *col_names) + > migrator.drop_not_null(model, *field_names) + > migrator.drop_constraints(model, *constraints) + +""" + +from contextlib import suppress + +import peewee as pw +from peewee_migrate import Migrator + + +with suppress(ImportError): + import playhouse.postgres_ext as pw_pext + + +def migrate(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your migrations here.""" + + migrator.add_fields( + "chat", share_id=pw.CharField(max_length=255, null=True, unique=True) + ) + + +def rollback(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your rollback migrations here.""" + + migrator.remove_fields("chat", "share_id") diff --git a/backend/open_webui/internal/migrations/003_add_auth_api_key.py b/backend/open_webui/internal/migrations/003_add_auth_api_key.py new file mode 100644 index 0000000..07144f3 --- /dev/null +++ b/backend/open_webui/internal/migrations/003_add_auth_api_key.py @@ -0,0 +1,48 @@ +"""Peewee migrations -- 002_add_local_sharing.py. + +Some examples (model - class or model name):: + + > Model = migrator.orm['table_name'] # Return model in current state by name + > Model = migrator.ModelClass # Return model in current state by name + + > migrator.sql(sql) # Run custom SQL + > migrator.run(func, *args, **kwargs) # Run python function with the given args + > migrator.create_model(Model) # Create a model (could be used as decorator) + > migrator.remove_model(model, cascade=True) # Remove a model + > migrator.add_fields(model, **fields) # Add fields to a model + > migrator.change_fields(model, **fields) # Change fields + > migrator.remove_fields(model, *field_names, cascade=True) + > migrator.rename_field(model, old_field_name, new_field_name) + > migrator.rename_table(model, new_table_name) + > migrator.add_index(model, *col_names, unique=False) + > migrator.add_not_null(model, *field_names) + > migrator.add_default(model, field_name, default) + > migrator.add_constraint(model, name, sql) + > migrator.drop_index(model, *col_names) + > migrator.drop_not_null(model, *field_names) + > migrator.drop_constraints(model, *constraints) + +""" + +from contextlib import suppress + +import peewee as pw +from peewee_migrate import Migrator + + +with suppress(ImportError): + import playhouse.postgres_ext as pw_pext + + +def migrate(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your migrations here.""" + + migrator.add_fields( + "user", api_key=pw.CharField(max_length=255, null=True, unique=True) + ) + + +def rollback(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your rollback migrations here.""" + + migrator.remove_fields("user", "api_key") diff --git a/backend/open_webui/internal/migrations/004_add_archived.py b/backend/open_webui/internal/migrations/004_add_archived.py new file mode 100644 index 0000000..d01c06b --- /dev/null +++ b/backend/open_webui/internal/migrations/004_add_archived.py @@ -0,0 +1,46 @@ +"""Peewee migrations -- 002_add_local_sharing.py. + +Some examples (model - class or model name):: + + > Model = migrator.orm['table_name'] # Return model in current state by name + > Model = migrator.ModelClass # Return model in current state by name + + > migrator.sql(sql) # Run custom SQL + > migrator.run(func, *args, **kwargs) # Run python function with the given args + > migrator.create_model(Model) # Create a model (could be used as decorator) + > migrator.remove_model(model, cascade=True) # Remove a model + > migrator.add_fields(model, **fields) # Add fields to a model + > migrator.change_fields(model, **fields) # Change fields + > migrator.remove_fields(model, *field_names, cascade=True) + > migrator.rename_field(model, old_field_name, new_field_name) + > migrator.rename_table(model, new_table_name) + > migrator.add_index(model, *col_names, unique=False) + > migrator.add_not_null(model, *field_names) + > migrator.add_default(model, field_name, default) + > migrator.add_constraint(model, name, sql) + > migrator.drop_index(model, *col_names) + > migrator.drop_not_null(model, *field_names) + > migrator.drop_constraints(model, *constraints) + +""" + +from contextlib import suppress + +import peewee as pw +from peewee_migrate import Migrator + + +with suppress(ImportError): + import playhouse.postgres_ext as pw_pext + + +def migrate(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your migrations here.""" + + migrator.add_fields("chat", archived=pw.BooleanField(default=False)) + + +def rollback(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your rollback migrations here.""" + + migrator.remove_fields("chat", "archived") diff --git a/backend/open_webui/internal/migrations/005_add_updated_at.py b/backend/open_webui/internal/migrations/005_add_updated_at.py new file mode 100644 index 0000000..950866e --- /dev/null +++ b/backend/open_webui/internal/migrations/005_add_updated_at.py @@ -0,0 +1,130 @@ +"""Peewee migrations -- 002_add_local_sharing.py. + +Some examples (model - class or model name):: + + > Model = migrator.orm['table_name'] # Return model in current state by name + > Model = migrator.ModelClass # Return model in current state by name + + > migrator.sql(sql) # Run custom SQL + > migrator.run(func, *args, **kwargs) # Run python function with the given args + > migrator.create_model(Model) # Create a model (could be used as decorator) + > migrator.remove_model(model, cascade=True) # Remove a model + > migrator.add_fields(model, **fields) # Add fields to a model + > migrator.change_fields(model, **fields) # Change fields + > migrator.remove_fields(model, *field_names, cascade=True) + > migrator.rename_field(model, old_field_name, new_field_name) + > migrator.rename_table(model, new_table_name) + > migrator.add_index(model, *col_names, unique=False) + > migrator.add_not_null(model, *field_names) + > migrator.add_default(model, field_name, default) + > migrator.add_constraint(model, name, sql) + > migrator.drop_index(model, *col_names) + > migrator.drop_not_null(model, *field_names) + > migrator.drop_constraints(model, *constraints) + +""" + +from contextlib import suppress + +import peewee as pw +from peewee_migrate import Migrator + + +with suppress(ImportError): + import playhouse.postgres_ext as pw_pext + + +def migrate(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your migrations here.""" + + if isinstance(database, pw.SqliteDatabase): + migrate_sqlite(migrator, database, fake=fake) + else: + migrate_external(migrator, database, fake=fake) + + +def migrate_sqlite(migrator: Migrator, database: pw.Database, *, fake=False): + # Adding fields created_at and updated_at to the 'chat' table + migrator.add_fields( + "chat", + created_at=pw.DateTimeField(null=True), # Allow null for transition + updated_at=pw.DateTimeField(null=True), # Allow null for transition + ) + + # Populate the new fields from an existing 'timestamp' field + migrator.sql( + "UPDATE chat SET created_at = timestamp, updated_at = timestamp WHERE timestamp IS NOT NULL" + ) + + # Now that the data has been copied, remove the original 'timestamp' field + migrator.remove_fields("chat", "timestamp") + + # Update the fields to be not null now that they are populated + migrator.change_fields( + "chat", + created_at=pw.DateTimeField(null=False), + updated_at=pw.DateTimeField(null=False), + ) + + +def migrate_external(migrator: Migrator, database: pw.Database, *, fake=False): + # Adding fields created_at and updated_at to the 'chat' table + migrator.add_fields( + "chat", + created_at=pw.BigIntegerField(null=True), # Allow null for transition + updated_at=pw.BigIntegerField(null=True), # Allow null for transition + ) + + # Populate the new fields from an existing 'timestamp' field + migrator.sql( + "UPDATE chat SET created_at = timestamp, updated_at = timestamp WHERE timestamp IS NOT NULL" + ) + + # Now that the data has been copied, remove the original 'timestamp' field + migrator.remove_fields("chat", "timestamp") + + # Update the fields to be not null now that they are populated + migrator.change_fields( + "chat", + created_at=pw.BigIntegerField(null=False), + updated_at=pw.BigIntegerField(null=False), + ) + + +def rollback(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your rollback migrations here.""" + + if isinstance(database, pw.SqliteDatabase): + rollback_sqlite(migrator, database, fake=fake) + else: + rollback_external(migrator, database, fake=fake) + + +def rollback_sqlite(migrator: Migrator, database: pw.Database, *, fake=False): + # Recreate the timestamp field initially allowing null values for safe transition + migrator.add_fields("chat", timestamp=pw.DateTimeField(null=True)) + + # Copy the earliest created_at date back into the new timestamp field + # This assumes created_at was originally a copy of timestamp + migrator.sql("UPDATE chat SET timestamp = created_at") + + # Remove the created_at and updated_at fields + migrator.remove_fields("chat", "created_at", "updated_at") + + # Finally, alter the timestamp field to not allow nulls if that was the original setting + migrator.change_fields("chat", timestamp=pw.DateTimeField(null=False)) + + +def rollback_external(migrator: Migrator, database: pw.Database, *, fake=False): + # Recreate the timestamp field initially allowing null values for safe transition + migrator.add_fields("chat", timestamp=pw.BigIntegerField(null=True)) + + # Copy the earliest created_at date back into the new timestamp field + # This assumes created_at was originally a copy of timestamp + migrator.sql("UPDATE chat SET timestamp = created_at") + + # Remove the created_at and updated_at fields + migrator.remove_fields("chat", "created_at", "updated_at") + + # Finally, alter the timestamp field to not allow nulls if that was the original setting + migrator.change_fields("chat", timestamp=pw.BigIntegerField(null=False)) diff --git a/backend/open_webui/internal/migrations/006_migrate_timestamps_and_charfields.py b/backend/open_webui/internal/migrations/006_migrate_timestamps_and_charfields.py new file mode 100644 index 0000000..caca14d --- /dev/null +++ b/backend/open_webui/internal/migrations/006_migrate_timestamps_and_charfields.py @@ -0,0 +1,130 @@ +"""Peewee migrations -- 006_migrate_timestamps_and_charfields.py. + +Some examples (model - class or model name):: + + > Model = migrator.orm['table_name'] # Return model in current state by name + > Model = migrator.ModelClass # Return model in current state by name + + > migrator.sql(sql) # Run custom SQL + > migrator.run(func, *args, **kwargs) # Run python function with the given args + > migrator.create_model(Model) # Create a model (could be used as decorator) + > migrator.remove_model(model, cascade=True) # Remove a model + > migrator.add_fields(model, **fields) # Add fields to a model + > migrator.change_fields(model, **fields) # Change fields + > migrator.remove_fields(model, *field_names, cascade=True) + > migrator.rename_field(model, old_field_name, new_field_name) + > migrator.rename_table(model, new_table_name) + > migrator.add_index(model, *col_names, unique=False) + > migrator.add_not_null(model, *field_names) + > migrator.add_default(model, field_name, default) + > migrator.add_constraint(model, name, sql) + > migrator.drop_index(model, *col_names) + > migrator.drop_not_null(model, *field_names) + > migrator.drop_constraints(model, *constraints) + +""" + +from contextlib import suppress + +import peewee as pw +from peewee_migrate import Migrator + + +with suppress(ImportError): + import playhouse.postgres_ext as pw_pext + + +def migrate(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your migrations here.""" + + # Alter the tables with timestamps + migrator.change_fields( + "chatidtag", + timestamp=pw.BigIntegerField(), + ) + migrator.change_fields( + "document", + timestamp=pw.BigIntegerField(), + ) + migrator.change_fields( + "modelfile", + timestamp=pw.BigIntegerField(), + ) + migrator.change_fields( + "prompt", + timestamp=pw.BigIntegerField(), + ) + migrator.change_fields( + "user", + timestamp=pw.BigIntegerField(), + ) + # Alter the tables with varchar to text where necessary + migrator.change_fields( + "auth", + password=pw.TextField(), + ) + migrator.change_fields( + "chat", + title=pw.TextField(), + ) + migrator.change_fields( + "document", + title=pw.TextField(), + filename=pw.TextField(), + ) + migrator.change_fields( + "prompt", + title=pw.TextField(), + ) + migrator.change_fields( + "user", + profile_image_url=pw.TextField(), + ) + + +def rollback(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your rollback migrations here.""" + + if isinstance(database, pw.SqliteDatabase): + # Alter the tables with timestamps + migrator.change_fields( + "chatidtag", + timestamp=pw.DateField(), + ) + migrator.change_fields( + "document", + timestamp=pw.DateField(), + ) + migrator.change_fields( + "modelfile", + timestamp=pw.DateField(), + ) + migrator.change_fields( + "prompt", + timestamp=pw.DateField(), + ) + migrator.change_fields( + "user", + timestamp=pw.DateField(), + ) + migrator.change_fields( + "auth", + password=pw.CharField(max_length=255), + ) + migrator.change_fields( + "chat", + title=pw.CharField(), + ) + migrator.change_fields( + "document", + title=pw.CharField(), + filename=pw.CharField(), + ) + migrator.change_fields( + "prompt", + title=pw.CharField(), + ) + migrator.change_fields( + "user", + profile_image_url=pw.CharField(), + ) diff --git a/backend/open_webui/internal/migrations/007_add_user_last_active_at.py b/backend/open_webui/internal/migrations/007_add_user_last_active_at.py new file mode 100644 index 0000000..dd176ba --- /dev/null +++ b/backend/open_webui/internal/migrations/007_add_user_last_active_at.py @@ -0,0 +1,79 @@ +"""Peewee migrations -- 002_add_local_sharing.py. + +Some examples (model - class or model name):: + + > Model = migrator.orm['table_name'] # Return model in current state by name + > Model = migrator.ModelClass # Return model in current state by name + + > migrator.sql(sql) # Run custom SQL + > migrator.run(func, *args, **kwargs) # Run python function with the given args + > migrator.create_model(Model) # Create a model (could be used as decorator) + > migrator.remove_model(model, cascade=True) # Remove a model + > migrator.add_fields(model, **fields) # Add fields to a model + > migrator.change_fields(model, **fields) # Change fields + > migrator.remove_fields(model, *field_names, cascade=True) + > migrator.rename_field(model, old_field_name, new_field_name) + > migrator.rename_table(model, new_table_name) + > migrator.add_index(model, *col_names, unique=False) + > migrator.add_not_null(model, *field_names) + > migrator.add_default(model, field_name, default) + > migrator.add_constraint(model, name, sql) + > migrator.drop_index(model, *col_names) + > migrator.drop_not_null(model, *field_names) + > migrator.drop_constraints(model, *constraints) + +""" + +from contextlib import suppress + +import peewee as pw +from peewee_migrate import Migrator + + +with suppress(ImportError): + import playhouse.postgres_ext as pw_pext + + +def migrate(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your migrations here.""" + + # Adding fields created_at and updated_at to the 'user' table + migrator.add_fields( + "user", + created_at=pw.BigIntegerField(null=True), # Allow null for transition + updated_at=pw.BigIntegerField(null=True), # Allow null for transition + last_active_at=pw.BigIntegerField(null=True), # Allow null for transition + ) + + # Populate the new fields from an existing 'timestamp' field + migrator.sql( + 'UPDATE "user" SET created_at = timestamp, updated_at = timestamp, last_active_at = timestamp WHERE timestamp IS NOT NULL' + ) + + # Now that the data has been copied, remove the original 'timestamp' field + migrator.remove_fields("user", "timestamp") + + # Update the fields to be not null now that they are populated + migrator.change_fields( + "user", + created_at=pw.BigIntegerField(null=False), + updated_at=pw.BigIntegerField(null=False), + last_active_at=pw.BigIntegerField(null=False), + ) + + +def rollback(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your rollback migrations here.""" + + # Recreate the timestamp field initially allowing null values for safe transition + migrator.add_fields("user", timestamp=pw.BigIntegerField(null=True)) + + # Copy the earliest created_at date back into the new timestamp field + # This assumes created_at was originally a copy of timestamp + migrator.sql('UPDATE "user" SET timestamp = created_at') + + # Remove the created_at and updated_at fields + migrator.remove_fields("user", "created_at", "updated_at", "last_active_at") + + # Finally, alter the timestamp field to not allow nulls if that was the original setting + migrator.change_fields("user", timestamp=pw.BigIntegerField(null=False)) diff --git a/backend/open_webui/internal/migrations/008_add_memory.py b/backend/open_webui/internal/migrations/008_add_memory.py new file mode 100644 index 0000000..9307aa4 --- /dev/null +++ b/backend/open_webui/internal/migrations/008_add_memory.py @@ -0,0 +1,53 @@ +"""Peewee migrations -- 002_add_local_sharing.py. + +Some examples (model - class or model name):: + + > Model = migrator.orm['table_name'] # Return model in current state by name + > Model = migrator.ModelClass # Return model in current state by name + + > migrator.sql(sql) # Run custom SQL + > migrator.run(func, *args, **kwargs) # Run python function with the given args + > migrator.create_model(Model) # Create a model (could be used as decorator) + > migrator.remove_model(model, cascade=True) # Remove a model + > migrator.add_fields(model, **fields) # Add fields to a model + > migrator.change_fields(model, **fields) # Change fields + > migrator.remove_fields(model, *field_names, cascade=True) + > migrator.rename_field(model, old_field_name, new_field_name) + > migrator.rename_table(model, new_table_name) + > migrator.add_index(model, *col_names, unique=False) + > migrator.add_not_null(model, *field_names) + > migrator.add_default(model, field_name, default) + > migrator.add_constraint(model, name, sql) + > migrator.drop_index(model, *col_names) + > migrator.drop_not_null(model, *field_names) + > migrator.drop_constraints(model, *constraints) + +""" + +from contextlib import suppress + +import peewee as pw +from peewee_migrate import Migrator + + +with suppress(ImportError): + import playhouse.postgres_ext as pw_pext + + +def migrate(migrator: Migrator, database: pw.Database, *, fake=False): + @migrator.create_model + class Memory(pw.Model): + id = pw.CharField(max_length=255, unique=True) + user_id = pw.CharField(max_length=255) + content = pw.TextField(null=False) + updated_at = pw.BigIntegerField(null=False) + created_at = pw.BigIntegerField(null=False) + + class Meta: + table_name = "memory" + + +def rollback(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your rollback migrations here.""" + + migrator.remove_model("memory") diff --git a/backend/open_webui/internal/migrations/009_add_models.py b/backend/open_webui/internal/migrations/009_add_models.py new file mode 100644 index 0000000..548ec7c --- /dev/null +++ b/backend/open_webui/internal/migrations/009_add_models.py @@ -0,0 +1,61 @@ +"""Peewee migrations -- 009_add_models.py. + +Some examples (model - class or model name):: + + > Model = migrator.orm['table_name'] # Return model in current state by name + > Model = migrator.ModelClass # Return model in current state by name + + > migrator.sql(sql) # Run custom SQL + > migrator.run(func, *args, **kwargs) # Run python function with the given args + > migrator.create_model(Model) # Create a model (could be used as decorator) + > migrator.remove_model(model, cascade=True) # Remove a model + > migrator.add_fields(model, **fields) # Add fields to a model + > migrator.change_fields(model, **fields) # Change fields + > migrator.remove_fields(model, *field_names, cascade=True) + > migrator.rename_field(model, old_field_name, new_field_name) + > migrator.rename_table(model, new_table_name) + > migrator.add_index(model, *col_names, unique=False) + > migrator.add_not_null(model, *field_names) + > migrator.add_default(model, field_name, default) + > migrator.add_constraint(model, name, sql) + > migrator.drop_index(model, *col_names) + > migrator.drop_not_null(model, *field_names) + > migrator.drop_constraints(model, *constraints) + +""" + +from contextlib import suppress + +import peewee as pw +from peewee_migrate import Migrator + + +with suppress(ImportError): + import playhouse.postgres_ext as pw_pext + + +def migrate(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your migrations here.""" + + @migrator.create_model + class Model(pw.Model): + id = pw.TextField(unique=True) + user_id = pw.TextField() + base_model_id = pw.TextField(null=True) + + name = pw.TextField() + + meta = pw.TextField() + params = pw.TextField() + + created_at = pw.BigIntegerField(null=False) + updated_at = pw.BigIntegerField(null=False) + + class Meta: + table_name = "model" + + +def rollback(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your rollback migrations here.""" + + migrator.remove_model("model") diff --git a/backend/open_webui/internal/migrations/010_migrate_modelfiles_to_models.py b/backend/open_webui/internal/migrations/010_migrate_modelfiles_to_models.py new file mode 100644 index 0000000..322ddd4 --- /dev/null +++ b/backend/open_webui/internal/migrations/010_migrate_modelfiles_to_models.py @@ -0,0 +1,130 @@ +"""Peewee migrations -- 009_add_models.py. + +Some examples (model - class or model name):: + + > Model = migrator.orm['table_name'] # Return model in current state by name + > Model = migrator.ModelClass # Return model in current state by name + + > migrator.sql(sql) # Run custom SQL + > migrator.run(func, *args, **kwargs) # Run python function with the given args + > migrator.create_model(Model) # Create a model (could be used as decorator) + > migrator.remove_model(model, cascade=True) # Remove a model + > migrator.add_fields(model, **fields) # Add fields to a model + > migrator.change_fields(model, **fields) # Change fields + > migrator.remove_fields(model, *field_names, cascade=True) + > migrator.rename_field(model, old_field_name, new_field_name) + > migrator.rename_table(model, new_table_name) + > migrator.add_index(model, *col_names, unique=False) + > migrator.add_not_null(model, *field_names) + > migrator.add_default(model, field_name, default) + > migrator.add_constraint(model, name, sql) + > migrator.drop_index(model, *col_names) + > migrator.drop_not_null(model, *field_names) + > migrator.drop_constraints(model, *constraints) + +""" + +from contextlib import suppress + +import peewee as pw +from peewee_migrate import Migrator +import json + +from open_webui.utils.misc import parse_ollama_modelfile + +with suppress(ImportError): + import playhouse.postgres_ext as pw_pext + + +def migrate(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your migrations here.""" + + # Fetch data from 'modelfile' table and insert into 'model' table + migrate_modelfile_to_model(migrator, database) + # Drop the 'modelfile' table + migrator.remove_model("modelfile") + + +def migrate_modelfile_to_model(migrator: Migrator, database: pw.Database): + ModelFile = migrator.orm["modelfile"] + Model = migrator.orm["model"] + + modelfiles = ModelFile.select() + + for modelfile in modelfiles: + # Extract and transform data in Python + + modelfile.modelfile = json.loads(modelfile.modelfile) + meta = json.dumps( + { + "description": modelfile.modelfile.get("desc"), + "profile_image_url": modelfile.modelfile.get("imageUrl"), + "ollama": {"modelfile": modelfile.modelfile.get("content")}, + "suggestion_prompts": modelfile.modelfile.get("suggestionPrompts"), + "categories": modelfile.modelfile.get("categories"), + "user": {**modelfile.modelfile.get("user", {}), "community": True}, + } + ) + + info = parse_ollama_modelfile(modelfile.modelfile.get("content")) + + # Insert the processed data into the 'model' table + Model.create( + id=f"ollama-{modelfile.tag_name}", + user_id=modelfile.user_id, + base_model_id=info.get("base_model_id"), + name=modelfile.modelfile.get("title"), + meta=meta, + params=json.dumps(info.get("params", {})), + created_at=modelfile.timestamp, + updated_at=modelfile.timestamp, + ) + + +def rollback(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your rollback migrations here.""" + + recreate_modelfile_table(migrator, database) + move_data_back_to_modelfile(migrator, database) + migrator.remove_model("model") + + +def recreate_modelfile_table(migrator: Migrator, database: pw.Database): + query = """ + CREATE TABLE IF NOT EXISTS modelfile ( + user_id TEXT, + tag_name TEXT, + modelfile JSON, + timestamp BIGINT + ) + """ + migrator.sql(query) + + +def move_data_back_to_modelfile(migrator: Migrator, database: pw.Database): + Model = migrator.orm["model"] + Modelfile = migrator.orm["modelfile"] + + models = Model.select() + + for model in models: + # Extract and transform data in Python + meta = json.loads(model.meta) + + modelfile_data = { + "title": model.name, + "desc": meta.get("description"), + "imageUrl": meta.get("profile_image_url"), + "content": meta.get("ollama", {}).get("modelfile"), + "suggestionPrompts": meta.get("suggestion_prompts"), + "categories": meta.get("categories"), + "user": {k: v for k, v in meta.get("user", {}).items() if k != "community"}, + } + + # Insert the processed data back into the 'modelfile' table + Modelfile.create( + user_id=model.user_id, + tag_name=model.id, + modelfile=modelfile_data, + timestamp=model.created_at, + ) diff --git a/backend/open_webui/internal/migrations/011_add_user_settings.py b/backend/open_webui/internal/migrations/011_add_user_settings.py new file mode 100644 index 0000000..a1620dc --- /dev/null +++ b/backend/open_webui/internal/migrations/011_add_user_settings.py @@ -0,0 +1,48 @@ +"""Peewee migrations -- 002_add_local_sharing.py. + +Some examples (model - class or model name):: + + > Model = migrator.orm['table_name'] # Return model in current state by name + > Model = migrator.ModelClass # Return model in current state by name + + > migrator.sql(sql) # Run custom SQL + > migrator.run(func, *args, **kwargs) # Run python function with the given args + > migrator.create_model(Model) # Create a model (could be used as decorator) + > migrator.remove_model(model, cascade=True) # Remove a model + > migrator.add_fields(model, **fields) # Add fields to a model + > migrator.change_fields(model, **fields) # Change fields + > migrator.remove_fields(model, *field_names, cascade=True) + > migrator.rename_field(model, old_field_name, new_field_name) + > migrator.rename_table(model, new_table_name) + > migrator.add_index(model, *col_names, unique=False) + > migrator.add_not_null(model, *field_names) + > migrator.add_default(model, field_name, default) + > migrator.add_constraint(model, name, sql) + > migrator.drop_index(model, *col_names) + > migrator.drop_not_null(model, *field_names) + > migrator.drop_constraints(model, *constraints) + +""" + +from contextlib import suppress + +import peewee as pw +from peewee_migrate import Migrator + + +with suppress(ImportError): + import playhouse.postgres_ext as pw_pext + + +def migrate(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your migrations here.""" + + # Adding fields settings to the 'user' table + migrator.add_fields("user", settings=pw.TextField(null=True)) + + +def rollback(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your rollback migrations here.""" + + # Remove the settings field + migrator.remove_fields("user", "settings") diff --git a/backend/open_webui/internal/migrations/012_add_tools.py b/backend/open_webui/internal/migrations/012_add_tools.py new file mode 100644 index 0000000..4a68eea --- /dev/null +++ b/backend/open_webui/internal/migrations/012_add_tools.py @@ -0,0 +1,61 @@ +"""Peewee migrations -- 009_add_models.py. + +Some examples (model - class or model name):: + + > Model = migrator.orm['table_name'] # Return model in current state by name + > Model = migrator.ModelClass # Return model in current state by name + + > migrator.sql(sql) # Run custom SQL + > migrator.run(func, *args, **kwargs) # Run python function with the given args + > migrator.create_model(Model) # Create a model (could be used as decorator) + > migrator.remove_model(model, cascade=True) # Remove a model + > migrator.add_fields(model, **fields) # Add fields to a model + > migrator.change_fields(model, **fields) # Change fields + > migrator.remove_fields(model, *field_names, cascade=True) + > migrator.rename_field(model, old_field_name, new_field_name) + > migrator.rename_table(model, new_table_name) + > migrator.add_index(model, *col_names, unique=False) + > migrator.add_not_null(model, *field_names) + > migrator.add_default(model, field_name, default) + > migrator.add_constraint(model, name, sql) + > migrator.drop_index(model, *col_names) + > migrator.drop_not_null(model, *field_names) + > migrator.drop_constraints(model, *constraints) + +""" + +from contextlib import suppress + +import peewee as pw +from peewee_migrate import Migrator + + +with suppress(ImportError): + import playhouse.postgres_ext as pw_pext + + +def migrate(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your migrations here.""" + + @migrator.create_model + class Tool(pw.Model): + id = pw.TextField(unique=True) + user_id = pw.TextField() + + name = pw.TextField() + content = pw.TextField() + specs = pw.TextField() + + meta = pw.TextField() + + created_at = pw.BigIntegerField(null=False) + updated_at = pw.BigIntegerField(null=False) + + class Meta: + table_name = "tool" + + +def rollback(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your rollback migrations here.""" + + migrator.remove_model("tool") diff --git a/backend/open_webui/internal/migrations/013_add_user_info.py b/backend/open_webui/internal/migrations/013_add_user_info.py new file mode 100644 index 0000000..0f68669 --- /dev/null +++ b/backend/open_webui/internal/migrations/013_add_user_info.py @@ -0,0 +1,48 @@ +"""Peewee migrations -- 002_add_local_sharing.py. + +Some examples (model - class or model name):: + + > Model = migrator.orm['table_name'] # Return model in current state by name + > Model = migrator.ModelClass # Return model in current state by name + + > migrator.sql(sql) # Run custom SQL + > migrator.run(func, *args, **kwargs) # Run python function with the given args + > migrator.create_model(Model) # Create a model (could be used as decorator) + > migrator.remove_model(model, cascade=True) # Remove a model + > migrator.add_fields(model, **fields) # Add fields to a model + > migrator.change_fields(model, **fields) # Change fields + > migrator.remove_fields(model, *field_names, cascade=True) + > migrator.rename_field(model, old_field_name, new_field_name) + > migrator.rename_table(model, new_table_name) + > migrator.add_index(model, *col_names, unique=False) + > migrator.add_not_null(model, *field_names) + > migrator.add_default(model, field_name, default) + > migrator.add_constraint(model, name, sql) + > migrator.drop_index(model, *col_names) + > migrator.drop_not_null(model, *field_names) + > migrator.drop_constraints(model, *constraints) + +""" + +from contextlib import suppress + +import peewee as pw +from peewee_migrate import Migrator + + +with suppress(ImportError): + import playhouse.postgres_ext as pw_pext + + +def migrate(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your migrations here.""" + + # Adding fields info to the 'user' table + migrator.add_fields("user", info=pw.TextField(null=True)) + + +def rollback(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your rollback migrations here.""" + + # Remove the settings field + migrator.remove_fields("user", "info") diff --git a/backend/open_webui/internal/migrations/014_add_files.py b/backend/open_webui/internal/migrations/014_add_files.py new file mode 100644 index 0000000..5e1acf0 --- /dev/null +++ b/backend/open_webui/internal/migrations/014_add_files.py @@ -0,0 +1,55 @@ +"""Peewee migrations -- 009_add_models.py. + +Some examples (model - class or model name):: + + > Model = migrator.orm['table_name'] # Return model in current state by name + > Model = migrator.ModelClass # Return model in current state by name + + > migrator.sql(sql) # Run custom SQL + > migrator.run(func, *args, **kwargs) # Run python function with the given args + > migrator.create_model(Model) # Create a model (could be used as decorator) + > migrator.remove_model(model, cascade=True) # Remove a model + > migrator.add_fields(model, **fields) # Add fields to a model + > migrator.change_fields(model, **fields) # Change fields + > migrator.remove_fields(model, *field_names, cascade=True) + > migrator.rename_field(model, old_field_name, new_field_name) + > migrator.rename_table(model, new_table_name) + > migrator.add_index(model, *col_names, unique=False) + > migrator.add_not_null(model, *field_names) + > migrator.add_default(model, field_name, default) + > migrator.add_constraint(model, name, sql) + > migrator.drop_index(model, *col_names) + > migrator.drop_not_null(model, *field_names) + > migrator.drop_constraints(model, *constraints) + +""" + +from contextlib import suppress + +import peewee as pw +from peewee_migrate import Migrator + + +with suppress(ImportError): + import playhouse.postgres_ext as pw_pext + + +def migrate(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your migrations here.""" + + @migrator.create_model + class File(pw.Model): + id = pw.TextField(unique=True) + user_id = pw.TextField() + filename = pw.TextField() + meta = pw.TextField() + created_at = pw.BigIntegerField(null=False) + + class Meta: + table_name = "file" + + +def rollback(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your rollback migrations here.""" + + migrator.remove_model("file") diff --git a/backend/open_webui/internal/migrations/015_add_functions.py b/backend/open_webui/internal/migrations/015_add_functions.py new file mode 100644 index 0000000..8316a93 --- /dev/null +++ b/backend/open_webui/internal/migrations/015_add_functions.py @@ -0,0 +1,61 @@ +"""Peewee migrations -- 009_add_models.py. + +Some examples (model - class or model name):: + + > Model = migrator.orm['table_name'] # Return model in current state by name + > Model = migrator.ModelClass # Return model in current state by name + + > migrator.sql(sql) # Run custom SQL + > migrator.run(func, *args, **kwargs) # Run python function with the given args + > migrator.create_model(Model) # Create a model (could be used as decorator) + > migrator.remove_model(model, cascade=True) # Remove a model + > migrator.add_fields(model, **fields) # Add fields to a model + > migrator.change_fields(model, **fields) # Change fields + > migrator.remove_fields(model, *field_names, cascade=True) + > migrator.rename_field(model, old_field_name, new_field_name) + > migrator.rename_table(model, new_table_name) + > migrator.add_index(model, *col_names, unique=False) + > migrator.add_not_null(model, *field_names) + > migrator.add_default(model, field_name, default) + > migrator.add_constraint(model, name, sql) + > migrator.drop_index(model, *col_names) + > migrator.drop_not_null(model, *field_names) + > migrator.drop_constraints(model, *constraints) + +""" + +from contextlib import suppress + +import peewee as pw +from peewee_migrate import Migrator + + +with suppress(ImportError): + import playhouse.postgres_ext as pw_pext + + +def migrate(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your migrations here.""" + + @migrator.create_model + class Function(pw.Model): + id = pw.TextField(unique=True) + user_id = pw.TextField() + + name = pw.TextField() + type = pw.TextField() + + content = pw.TextField() + meta = pw.TextField() + + created_at = pw.BigIntegerField(null=False) + updated_at = pw.BigIntegerField(null=False) + + class Meta: + table_name = "function" + + +def rollback(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your rollback migrations here.""" + + migrator.remove_model("function") diff --git a/backend/open_webui/internal/migrations/016_add_valves_and_is_active.py b/backend/open_webui/internal/migrations/016_add_valves_and_is_active.py new file mode 100644 index 0000000..e3af521 --- /dev/null +++ b/backend/open_webui/internal/migrations/016_add_valves_and_is_active.py @@ -0,0 +1,50 @@ +"""Peewee migrations -- 009_add_models.py. + +Some examples (model - class or model name):: + + > Model = migrator.orm['table_name'] # Return model in current state by name + > Model = migrator.ModelClass # Return model in current state by name + + > migrator.sql(sql) # Run custom SQL + > migrator.run(func, *args, **kwargs) # Run python function with the given args + > migrator.create_model(Model) # Create a model (could be used as decorator) + > migrator.remove_model(model, cascade=True) # Remove a model + > migrator.add_fields(model, **fields) # Add fields to a model + > migrator.change_fields(model, **fields) # Change fields + > migrator.remove_fields(model, *field_names, cascade=True) + > migrator.rename_field(model, old_field_name, new_field_name) + > migrator.rename_table(model, new_table_name) + > migrator.add_index(model, *col_names, unique=False) + > migrator.add_not_null(model, *field_names) + > migrator.add_default(model, field_name, default) + > migrator.add_constraint(model, name, sql) + > migrator.drop_index(model, *col_names) + > migrator.drop_not_null(model, *field_names) + > migrator.drop_constraints(model, *constraints) + +""" + +from contextlib import suppress + +import peewee as pw +from peewee_migrate import Migrator + + +with suppress(ImportError): + import playhouse.postgres_ext as pw_pext + + +def migrate(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your migrations here.""" + + migrator.add_fields("tool", valves=pw.TextField(null=True)) + migrator.add_fields("function", valves=pw.TextField(null=True)) + migrator.add_fields("function", is_active=pw.BooleanField(default=False)) + + +def rollback(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your rollback migrations here.""" + + migrator.remove_fields("tool", "valves") + migrator.remove_fields("function", "valves") + migrator.remove_fields("function", "is_active") diff --git a/backend/open_webui/internal/migrations/017_add_user_oauth_sub.py b/backend/open_webui/internal/migrations/017_add_user_oauth_sub.py new file mode 100644 index 0000000..eaa3fa5 --- /dev/null +++ b/backend/open_webui/internal/migrations/017_add_user_oauth_sub.py @@ -0,0 +1,45 @@ +"""Peewee migrations -- 017_add_user_oauth_sub.py. +Some examples (model - class or model name):: + > Model = migrator.orm['table_name'] # Return model in current state by name + > Model = migrator.ModelClass # Return model in current state by name + > migrator.sql(sql) # Run custom SQL + > migrator.run(func, *args, **kwargs) # Run python function with the given args + > migrator.create_model(Model) # Create a model (could be used as decorator) + > migrator.remove_model(model, cascade=True) # Remove a model + > migrator.add_fields(model, **fields) # Add fields to a model + > migrator.change_fields(model, **fields) # Change fields + > migrator.remove_fields(model, *field_names, cascade=True) + > migrator.rename_field(model, old_field_name, new_field_name) + > migrator.rename_table(model, new_table_name) + > migrator.add_index(model, *col_names, unique=False) + > migrator.add_not_null(model, *field_names) + > migrator.add_default(model, field_name, default) + > migrator.add_constraint(model, name, sql) + > migrator.drop_index(model, *col_names) + > migrator.drop_not_null(model, *field_names) + > migrator.drop_constraints(model, *constraints) +""" + +from contextlib import suppress + +import peewee as pw +from peewee_migrate import Migrator + + +with suppress(ImportError): + import playhouse.postgres_ext as pw_pext + + +def migrate(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your migrations here.""" + + migrator.add_fields( + "user", + oauth_sub=pw.TextField(null=True, unique=True), + ) + + +def rollback(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your rollback migrations here.""" + + migrator.remove_fields("user", "oauth_sub") diff --git a/backend/open_webui/internal/migrations/018_add_function_is_global.py b/backend/open_webui/internal/migrations/018_add_function_is_global.py new file mode 100644 index 0000000..04cdab7 --- /dev/null +++ b/backend/open_webui/internal/migrations/018_add_function_is_global.py @@ -0,0 +1,49 @@ +"""Peewee migrations -- 017_add_user_oauth_sub.py. + +Some examples (model - class or model name):: + + > Model = migrator.orm['table_name'] # Return model in current state by name + > Model = migrator.ModelClass # Return model in current state by name + + > migrator.sql(sql) # Run custom SQL + > migrator.run(func, *args, **kwargs) # Run python function with the given args + > migrator.create_model(Model) # Create a model (could be used as decorator) + > migrator.remove_model(model, cascade=True) # Remove a model + > migrator.add_fields(model, **fields) # Add fields to a model + > migrator.change_fields(model, **fields) # Change fields + > migrator.remove_fields(model, *field_names, cascade=True) + > migrator.rename_field(model, old_field_name, new_field_name) + > migrator.rename_table(model, new_table_name) + > migrator.add_index(model, *col_names, unique=False) + > migrator.add_not_null(model, *field_names) + > migrator.add_default(model, field_name, default) + > migrator.add_constraint(model, name, sql) + > migrator.drop_index(model, *col_names) + > migrator.drop_not_null(model, *field_names) + > migrator.drop_constraints(model, *constraints) + +""" + +from contextlib import suppress + +import peewee as pw +from peewee_migrate import Migrator + + +with suppress(ImportError): + import playhouse.postgres_ext as pw_pext + + +def migrate(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your migrations here.""" + + migrator.add_fields( + "function", + is_global=pw.BooleanField(default=False), + ) + + +def rollback(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your rollback migrations here.""" + + migrator.remove_fields("function", "is_global") diff --git a/backend/open_webui/internal/wrappers.py b/backend/open_webui/internal/wrappers.py new file mode 100644 index 0000000..ccc62b9 --- /dev/null +++ b/backend/open_webui/internal/wrappers.py @@ -0,0 +1,66 @@ +import logging +from contextvars import ContextVar + +from open_webui.env import SRC_LOG_LEVELS +from peewee import * +from peewee import InterfaceError as PeeWeeInterfaceError +from peewee import PostgresqlDatabase +from playhouse.db_url import connect, parse +from playhouse.shortcuts import ReconnectMixin + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["DB"]) + +db_state_default = {"closed": None, "conn": None, "ctx": None, "transactions": None} +db_state = ContextVar("db_state", default=db_state_default.copy()) + + +class PeeweeConnectionState(object): + def __init__(self, **kwargs): + super().__setattr__("_state", db_state) + super().__init__(**kwargs) + + def __setattr__(self, name, value): + self._state.get()[name] = value + + def __getattr__(self, name): + value = self._state.get()[name] + return value + + +class CustomReconnectMixin(ReconnectMixin): + reconnect_errors = ( + # psycopg2 + (OperationalError, "termin"), + (InterfaceError, "closed"), + # peewee + (PeeWeeInterfaceError, "closed"), + ) + + +class ReconnectingPostgresqlDatabase(CustomReconnectMixin, PostgresqlDatabase): + pass + + +def register_connection(db_url): + db = connect(db_url, unquote_password=True) + if isinstance(db, PostgresqlDatabase): + # Enable autoconnect for SQLite databases, managed by Peewee + db.autoconnect = True + db.reuse_if_open = True + log.info("Connected to PostgreSQL database") + + # Get the connection details + connection = parse(db_url, unquote_password=True) + + # Use our custom database class that supports reconnection + db = ReconnectingPostgresqlDatabase(**connection) + db.connect(reuse_if_open=True) + elif isinstance(db, SqliteDatabase): + # Enable autoconnect for SQLite databases, managed by Peewee + db.autoconnect = True + db.reuse_if_open = True + log.info("Connected to SQLite database") + else: + raise ValueError("Unsupported database connection") + return db diff --git a/backend/open_webui/main.py b/backend/open_webui/main.py new file mode 100644 index 0000000..9676d14 --- /dev/null +++ b/backend/open_webui/main.py @@ -0,0 +1,1384 @@ +import asyncio +import inspect +import json +import logging +import mimetypes +import os +import shutil +import sys +import time +import random + +from contextlib import asynccontextmanager +from urllib.parse import urlencode, parse_qs, urlparse +from pydantic import BaseModel +from sqlalchemy import text + +from typing import Optional +from aiocache import cached +import aiohttp +import requests + + +from fastapi import ( + Depends, + FastAPI, + File, + Form, + HTTPException, + Request, + UploadFile, + status, + applications, + BackgroundTasks, +) + +from fastapi.openapi.docs import get_swagger_ui_html + +from fastapi.middleware.cors import CORSMiddleware +from fastapi.responses import JSONResponse, RedirectResponse +from fastapi.staticfiles import StaticFiles + +from starlette.exceptions import HTTPException as StarletteHTTPException +from starlette.middleware.base import BaseHTTPMiddleware +from starlette.middleware.sessions import SessionMiddleware +from starlette.responses import Response, StreamingResponse + + +from open_webui.utils import logger +from open_webui.utils.audit import AuditLevel, AuditLoggingMiddleware +from open_webui.utils.logger import start_logger +from open_webui.socket.main import ( + app as socket_app, + periodic_usage_pool_cleanup, +) +from open_webui.routers import ( + audio, + images, + ollama, + openai, + retrieval, + pipelines, + tasks, + auths, + channels, + chats, + folders, + configs, + groups, + files, + functions, + memories, + models, + knowledge, + prompts, + evaluations, + tools, + users, + utils, +) + +from open_webui.routers.retrieval import ( + get_embedding_function, + get_ef, + get_rf, +) + +from open_webui.internal.db import Session + +from open_webui.models.functions import Functions +from open_webui.models.models import Models +from open_webui.models.users import UserModel, Users + +from open_webui.config import ( + LICENSE_KEY, + # Ollama + ENABLE_OLLAMA_API, + OLLAMA_BASE_URLS, + OLLAMA_API_CONFIGS, + # OpenAI + ENABLE_OPENAI_API, + ONEDRIVE_CLIENT_ID, + OPENAI_API_BASE_URLS, + OPENAI_API_KEYS, + OPENAI_API_CONFIGS, + # Direct Connections + ENABLE_DIRECT_CONNECTIONS, + # Code Execution + CODE_EXECUTION_ENGINE, + CODE_EXECUTION_JUPYTER_URL, + CODE_EXECUTION_JUPYTER_AUTH, + CODE_EXECUTION_JUPYTER_AUTH_TOKEN, + CODE_EXECUTION_JUPYTER_AUTH_PASSWORD, + CODE_EXECUTION_JUPYTER_TIMEOUT, + ENABLE_CODE_INTERPRETER, + CODE_INTERPRETER_ENGINE, + CODE_INTERPRETER_PROMPT_TEMPLATE, + CODE_INTERPRETER_JUPYTER_URL, + CODE_INTERPRETER_JUPYTER_AUTH, + CODE_INTERPRETER_JUPYTER_AUTH_TOKEN, + CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD, + CODE_INTERPRETER_JUPYTER_TIMEOUT, + # Image + AUTOMATIC1111_API_AUTH, + AUTOMATIC1111_BASE_URL, + AUTOMATIC1111_CFG_SCALE, + AUTOMATIC1111_SAMPLER, + AUTOMATIC1111_SCHEDULER, + COMFYUI_BASE_URL, + COMFYUI_API_KEY, + COMFYUI_WORKFLOW, + COMFYUI_WORKFLOW_NODES, + ENABLE_IMAGE_GENERATION, + ENABLE_IMAGE_PROMPT_GENERATION, + IMAGE_GENERATION_ENGINE, + IMAGE_GENERATION_MODEL, + IMAGE_SIZE, + IMAGE_STEPS, + IMAGES_OPENAI_API_BASE_URL, + IMAGES_OPENAI_API_KEY, + IMAGES_GEMINI_API_BASE_URL, + IMAGES_GEMINI_API_KEY, + # Audio + AUDIO_STT_ENGINE, + AUDIO_STT_MODEL, + AUDIO_STT_OPENAI_API_BASE_URL, + AUDIO_STT_OPENAI_API_KEY, + AUDIO_TTS_API_KEY, + AUDIO_TTS_ENGINE, + AUDIO_TTS_MODEL, + AUDIO_TTS_OPENAI_API_BASE_URL, + AUDIO_TTS_OPENAI_API_KEY, + AUDIO_TTS_SPLIT_ON, + AUDIO_TTS_VOICE, + AUDIO_TTS_AZURE_SPEECH_REGION, + AUDIO_TTS_AZURE_SPEECH_OUTPUT_FORMAT, + PLAYWRIGHT_WS_URI, + FIRECRAWL_API_BASE_URL, + FIRECRAWL_API_KEY, + RAG_WEB_LOADER_ENGINE, + WHISPER_MODEL, + DEEPGRAM_API_KEY, + WHISPER_MODEL_AUTO_UPDATE, + WHISPER_MODEL_DIR, + # Retrieval + RAG_TEMPLATE, + DEFAULT_RAG_TEMPLATE, + RAG_FULL_CONTEXT, + BYPASS_EMBEDDING_AND_RETRIEVAL, + RAG_EMBEDDING_MODEL, + RAG_EMBEDDING_MODEL_AUTO_UPDATE, + RAG_EMBEDDING_MODEL_TRUST_REMOTE_CODE, + RAG_RERANKING_MODEL, + RAG_RERANKING_MODEL_AUTO_UPDATE, + RAG_RERANKING_MODEL_TRUST_REMOTE_CODE, + RAG_EMBEDDING_ENGINE, + RAG_EMBEDDING_BATCH_SIZE, + RAG_RELEVANCE_THRESHOLD, + RAG_FILE_MAX_COUNT, + RAG_FILE_MAX_SIZE, + RAG_OPENAI_API_BASE_URL, + RAG_OPENAI_API_KEY, + RAG_OLLAMA_BASE_URL, + RAG_OLLAMA_API_KEY, + CHUNK_OVERLAP, + CHUNK_SIZE, + CONTENT_EXTRACTION_ENGINE, + TIKA_SERVER_URL, + DOCUMENT_INTELLIGENCE_ENDPOINT, + DOCUMENT_INTELLIGENCE_KEY, + RAG_TOP_K, + RAG_TEXT_SPLITTER, + TIKTOKEN_ENCODING_NAME, + PDF_EXTRACT_IMAGES, + YOUTUBE_LOADER_LANGUAGE, + YOUTUBE_LOADER_PROXY_URL, + # Retrieval (Web Search) + RAG_WEB_SEARCH_ENGINE, + BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL, + RAG_WEB_SEARCH_RESULT_COUNT, + RAG_WEB_SEARCH_CONCURRENT_REQUESTS, + RAG_WEB_SEARCH_TRUST_ENV, + RAG_WEB_SEARCH_DOMAIN_FILTER_LIST, + JINA_API_KEY, + SEARCHAPI_API_KEY, + SEARCHAPI_ENGINE, + SERPAPI_API_KEY, + SERPAPI_ENGINE, + SEARXNG_QUERY_URL, + SERPER_API_KEY, + SERPLY_API_KEY, + SERPSTACK_API_KEY, + SERPSTACK_HTTPS, + TAVILY_API_KEY, + BING_SEARCH_V7_ENDPOINT, + BING_SEARCH_V7_SUBSCRIPTION_KEY, + BRAVE_SEARCH_API_KEY, + EXA_API_KEY, + KAGI_SEARCH_API_KEY, + MOJEEK_SEARCH_API_KEY, + BOCHA_SEARCH_API_KEY, + GOOGLE_PSE_API_KEY, + GOOGLE_PSE_ENGINE_ID, + GOOGLE_DRIVE_CLIENT_ID, + GOOGLE_DRIVE_API_KEY, + ONEDRIVE_CLIENT_ID, + ENABLE_RAG_HYBRID_SEARCH, + ENABLE_RAG_LOCAL_WEB_FETCH, + ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION, + ENABLE_RAG_WEB_SEARCH, + ENABLE_GOOGLE_DRIVE_INTEGRATION, + ENABLE_ONEDRIVE_INTEGRATION, + UPLOAD_DIR, + # WebUI + WEBUI_AUTH, + WEBUI_NAME, + WEBUI_BANNERS, + WEBHOOK_URL, + ADMIN_EMAIL, + SHOW_ADMIN_DETAILS, + JWT_EXPIRES_IN, + ENABLE_SIGNUP, + ENABLE_LOGIN_FORM, + ENABLE_API_KEY, + ENABLE_API_KEY_ENDPOINT_RESTRICTIONS, + API_KEY_ALLOWED_ENDPOINTS, + ENABLE_CHANNELS, + ENABLE_COMMUNITY_SHARING, + ENABLE_MESSAGE_RATING, + ENABLE_EVALUATION_ARENA_MODELS, + USER_PERMISSIONS, + DEFAULT_USER_ROLE, + DEFAULT_PROMPT_SUGGESTIONS, + DEFAULT_MODELS, + DEFAULT_ARENA_MODEL, + MODEL_ORDER_LIST, + EVALUATION_ARENA_MODELS, + # WebUI (OAuth) + ENABLE_OAUTH_ROLE_MANAGEMENT, + OAUTH_ROLES_CLAIM, + OAUTH_EMAIL_CLAIM, + OAUTH_PICTURE_CLAIM, + OAUTH_USERNAME_CLAIM, + OAUTH_ALLOWED_ROLES, + OAUTH_ADMIN_ROLES, + # WebUI (LDAP) + ENABLE_LDAP, + LDAP_SERVER_LABEL, + LDAP_SERVER_HOST, + LDAP_SERVER_PORT, + LDAP_ATTRIBUTE_FOR_MAIL, + LDAP_ATTRIBUTE_FOR_USERNAME, + LDAP_SEARCH_FILTERS, + LDAP_SEARCH_BASE, + LDAP_APP_DN, + LDAP_APP_PASSWORD, + LDAP_USE_TLS, + LDAP_CA_CERT_FILE, + LDAP_CIPHERS, + # Misc + ENV, + CACHE_DIR, + STATIC_DIR, + FRONTEND_BUILD_DIR, + CORS_ALLOW_ORIGIN, + DEFAULT_LOCALE, + OAUTH_PROVIDERS, + WEBUI_URL, + # Admin + ENABLE_ADMIN_CHAT_ACCESS, + ENABLE_ADMIN_EXPORT, + # Tasks + TASK_MODEL, + TASK_MODEL_EXTERNAL, + ENABLE_TAGS_GENERATION, + ENABLE_TITLE_GENERATION, + ENABLE_SEARCH_QUERY_GENERATION, + ENABLE_RETRIEVAL_QUERY_GENERATION, + ENABLE_AUTOCOMPLETE_GENERATION, + TITLE_GENERATION_PROMPT_TEMPLATE, + TAGS_GENERATION_PROMPT_TEMPLATE, + IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE, + TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE, + QUERY_GENERATION_PROMPT_TEMPLATE, + AUTOCOMPLETE_GENERATION_PROMPT_TEMPLATE, + AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH, + AppConfig, + reset_config, +) +from open_webui.env import ( + AUDIT_EXCLUDED_PATHS, + AUDIT_LOG_LEVEL, + CHANGELOG, + GLOBAL_LOG_LEVEL, + MAX_BODY_LOG_SIZE, + SAFE_MODE, + SRC_LOG_LEVELS, + VERSION, + WEBUI_BUILD_HASH, + WEBUI_SECRET_KEY, + WEBUI_SESSION_COOKIE_SAME_SITE, + WEBUI_SESSION_COOKIE_SECURE, + WEBUI_AUTH_TRUSTED_EMAIL_HEADER, + WEBUI_AUTH_TRUSTED_NAME_HEADER, + ENABLE_WEBSOCKET_SUPPORT, + BYPASS_MODEL_ACCESS_CONTROL, + RESET_CONFIG_ON_START, + OFFLINE_MODE, +) + + +from open_webui.utils.models import ( + get_all_models, + get_all_base_models, + check_model_access, +) +from open_webui.utils.chat import ( + generate_chat_completion as chat_completion_handler, + chat_completed as chat_completed_handler, + chat_action as chat_action_handler, +) +from open_webui.utils.middleware import process_chat_payload, process_chat_response +from open_webui.utils.access_control import has_access + +from open_webui.utils.auth import ( + get_license_data, + decode_token, + get_admin_user, + get_verified_user, +) +from open_webui.utils.oauth import OAuthManager +from open_webui.utils.security_headers import SecurityHeadersMiddleware + +from open_webui.tasks import stop_task, list_tasks # Import from tasks.py + + +if SAFE_MODE: + print("SAFE MODE ENABLED") + Functions.deactivate_all_functions() + +logging.basicConfig(stream=sys.stdout, level=GLOBAL_LOG_LEVEL) +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MAIN"]) + + +class SPAStaticFiles(StaticFiles): + async def get_response(self, path: str, scope): + try: + return await super().get_response(path, scope) + except (HTTPException, StarletteHTTPException) as ex: + if ex.status_code == 404: + if path.endswith(".js"): + # Return 404 for javascript files + raise ex + else: + return await super().get_response("index.html", scope) + else: + raise ex + + +print( + rf""" + ██████╗ ██████╗ ███████╗███╗ ██╗ ██╗ ██╗███████╗██████╗ ██╗ ██╗██╗ +██╔═══██╗██╔══██╗██╔════╝████╗ ██║ ██║ ██║██╔════╝██╔══██╗██║ ██║██║ +██║ ██║██████╔╝█████╗ ██╔██╗ ██║ ██║ █╗ ██║█████╗ ██████╔╝██║ ██║██║ +██║ ██║██╔═══╝ ██╔══╝ ██║╚██╗██║ ██║███╗██║██╔══╝ ██╔══██╗██║ ██║██║ +╚██████╔╝██║ ███████╗██║ ╚████║ ╚███╔███╔╝███████╗██████╔╝╚██████╔╝██║ + ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝ ╚══╝╚══╝ ╚══════╝╚═════╝ ╚═════╝ ╚═╝ + + +v{VERSION} - building the best open-source AI user interface. +{f"Commit: {WEBUI_BUILD_HASH}" if WEBUI_BUILD_HASH != "dev-build" else ""} +https://github.com/open-webui/open-webui +""" +) + + +@asynccontextmanager +async def lifespan(app: FastAPI): + start_logger() + if RESET_CONFIG_ON_START: + reset_config() + + if app.state.config.LICENSE_KEY: + get_license_data(app, app.state.config.LICENSE_KEY) + + asyncio.create_task(periodic_usage_pool_cleanup()) + yield + + +app = FastAPI( + docs_url="/docs" if ENV == "dev" else None, + openapi_url="/openapi.json" if ENV == "dev" else None, + redoc_url=None, + lifespan=lifespan, +) + +oauth_manager = OAuthManager(app) + +app.state.config = AppConfig() + +app.state.WEBUI_NAME = WEBUI_NAME +app.state.config.LICENSE_KEY = LICENSE_KEY + +######################################## +# +# OLLAMA +# +######################################## + + +app.state.config.ENABLE_OLLAMA_API = ENABLE_OLLAMA_API +app.state.config.OLLAMA_BASE_URLS = OLLAMA_BASE_URLS +app.state.config.OLLAMA_API_CONFIGS = OLLAMA_API_CONFIGS + +app.state.OLLAMA_MODELS = {} + +######################################## +# +# OPENAI +# +######################################## + +app.state.config.ENABLE_OPENAI_API = ENABLE_OPENAI_API +app.state.config.OPENAI_API_BASE_URLS = OPENAI_API_BASE_URLS +app.state.config.OPENAI_API_KEYS = OPENAI_API_KEYS +app.state.config.OPENAI_API_CONFIGS = OPENAI_API_CONFIGS + +app.state.OPENAI_MODELS = {} + +######################################## +# +# DIRECT CONNECTIONS +# +######################################## + +app.state.config.ENABLE_DIRECT_CONNECTIONS = ENABLE_DIRECT_CONNECTIONS + +######################################## +# +# WEBUI +# +######################################## + +app.state.config.WEBUI_URL = WEBUI_URL +app.state.config.ENABLE_SIGNUP = ENABLE_SIGNUP +app.state.config.ENABLE_LOGIN_FORM = ENABLE_LOGIN_FORM + +app.state.config.ENABLE_API_KEY = ENABLE_API_KEY +app.state.config.ENABLE_API_KEY_ENDPOINT_RESTRICTIONS = ( + ENABLE_API_KEY_ENDPOINT_RESTRICTIONS +) +app.state.config.API_KEY_ALLOWED_ENDPOINTS = API_KEY_ALLOWED_ENDPOINTS + +app.state.config.JWT_EXPIRES_IN = JWT_EXPIRES_IN + +app.state.config.SHOW_ADMIN_DETAILS = SHOW_ADMIN_DETAILS +app.state.config.ADMIN_EMAIL = ADMIN_EMAIL + + +app.state.config.DEFAULT_MODELS = DEFAULT_MODELS +app.state.config.DEFAULT_PROMPT_SUGGESTIONS = DEFAULT_PROMPT_SUGGESTIONS +app.state.config.DEFAULT_USER_ROLE = DEFAULT_USER_ROLE + +app.state.config.USER_PERMISSIONS = USER_PERMISSIONS +app.state.config.WEBHOOK_URL = WEBHOOK_URL +app.state.config.BANNERS = WEBUI_BANNERS +app.state.config.MODEL_ORDER_LIST = MODEL_ORDER_LIST + + +app.state.config.ENABLE_CHANNELS = ENABLE_CHANNELS +app.state.config.ENABLE_COMMUNITY_SHARING = ENABLE_COMMUNITY_SHARING +app.state.config.ENABLE_MESSAGE_RATING = ENABLE_MESSAGE_RATING + +app.state.config.ENABLE_EVALUATION_ARENA_MODELS = ENABLE_EVALUATION_ARENA_MODELS +app.state.config.EVALUATION_ARENA_MODELS = EVALUATION_ARENA_MODELS + +app.state.config.OAUTH_USERNAME_CLAIM = OAUTH_USERNAME_CLAIM +app.state.config.OAUTH_PICTURE_CLAIM = OAUTH_PICTURE_CLAIM +app.state.config.OAUTH_EMAIL_CLAIM = OAUTH_EMAIL_CLAIM + +app.state.config.ENABLE_OAUTH_ROLE_MANAGEMENT = ENABLE_OAUTH_ROLE_MANAGEMENT +app.state.config.OAUTH_ROLES_CLAIM = OAUTH_ROLES_CLAIM +app.state.config.OAUTH_ALLOWED_ROLES = OAUTH_ALLOWED_ROLES +app.state.config.OAUTH_ADMIN_ROLES = OAUTH_ADMIN_ROLES + +app.state.config.ENABLE_LDAP = ENABLE_LDAP +app.state.config.LDAP_SERVER_LABEL = LDAP_SERVER_LABEL +app.state.config.LDAP_SERVER_HOST = LDAP_SERVER_HOST +app.state.config.LDAP_SERVER_PORT = LDAP_SERVER_PORT +app.state.config.LDAP_ATTRIBUTE_FOR_MAIL = LDAP_ATTRIBUTE_FOR_MAIL +app.state.config.LDAP_ATTRIBUTE_FOR_USERNAME = LDAP_ATTRIBUTE_FOR_USERNAME +app.state.config.LDAP_APP_DN = LDAP_APP_DN +app.state.config.LDAP_APP_PASSWORD = LDAP_APP_PASSWORD +app.state.config.LDAP_SEARCH_BASE = LDAP_SEARCH_BASE +app.state.config.LDAP_SEARCH_FILTERS = LDAP_SEARCH_FILTERS +app.state.config.LDAP_USE_TLS = LDAP_USE_TLS +app.state.config.LDAP_CA_CERT_FILE = LDAP_CA_CERT_FILE +app.state.config.LDAP_CIPHERS = LDAP_CIPHERS + + +app.state.AUTH_TRUSTED_EMAIL_HEADER = WEBUI_AUTH_TRUSTED_EMAIL_HEADER +app.state.AUTH_TRUSTED_NAME_HEADER = WEBUI_AUTH_TRUSTED_NAME_HEADER + +app.state.USER_COUNT = None +app.state.TOOLS = {} +app.state.FUNCTIONS = {} + +######################################## +# +# RETRIEVAL +# +######################################## + + +app.state.config.TOP_K = RAG_TOP_K +app.state.config.RELEVANCE_THRESHOLD = RAG_RELEVANCE_THRESHOLD +app.state.config.FILE_MAX_SIZE = RAG_FILE_MAX_SIZE +app.state.config.FILE_MAX_COUNT = RAG_FILE_MAX_COUNT + + +app.state.config.RAG_FULL_CONTEXT = RAG_FULL_CONTEXT +app.state.config.BYPASS_EMBEDDING_AND_RETRIEVAL = BYPASS_EMBEDDING_AND_RETRIEVAL +app.state.config.ENABLE_RAG_HYBRID_SEARCH = ENABLE_RAG_HYBRID_SEARCH +app.state.config.ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION = ( + ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION +) + +app.state.config.CONTENT_EXTRACTION_ENGINE = CONTENT_EXTRACTION_ENGINE +app.state.config.TIKA_SERVER_URL = TIKA_SERVER_URL +app.state.config.DOCUMENT_INTELLIGENCE_ENDPOINT = DOCUMENT_INTELLIGENCE_ENDPOINT +app.state.config.DOCUMENT_INTELLIGENCE_KEY = DOCUMENT_INTELLIGENCE_KEY + +app.state.config.TEXT_SPLITTER = RAG_TEXT_SPLITTER +app.state.config.TIKTOKEN_ENCODING_NAME = TIKTOKEN_ENCODING_NAME + +app.state.config.CHUNK_SIZE = CHUNK_SIZE +app.state.config.CHUNK_OVERLAP = CHUNK_OVERLAP + +app.state.config.RAG_EMBEDDING_ENGINE = RAG_EMBEDDING_ENGINE +app.state.config.RAG_EMBEDDING_MODEL = RAG_EMBEDDING_MODEL +app.state.config.RAG_EMBEDDING_BATCH_SIZE = RAG_EMBEDDING_BATCH_SIZE +app.state.config.RAG_RERANKING_MODEL = RAG_RERANKING_MODEL +app.state.config.RAG_TEMPLATE = RAG_TEMPLATE + +app.state.config.RAG_OPENAI_API_BASE_URL = RAG_OPENAI_API_BASE_URL +app.state.config.RAG_OPENAI_API_KEY = RAG_OPENAI_API_KEY + +app.state.config.RAG_OLLAMA_BASE_URL = RAG_OLLAMA_BASE_URL +app.state.config.RAG_OLLAMA_API_KEY = RAG_OLLAMA_API_KEY + +app.state.config.PDF_EXTRACT_IMAGES = PDF_EXTRACT_IMAGES + +app.state.config.YOUTUBE_LOADER_LANGUAGE = YOUTUBE_LOADER_LANGUAGE +app.state.config.YOUTUBE_LOADER_PROXY_URL = YOUTUBE_LOADER_PROXY_URL + + +app.state.config.ENABLE_RAG_WEB_SEARCH = ENABLE_RAG_WEB_SEARCH +app.state.config.RAG_WEB_SEARCH_ENGINE = RAG_WEB_SEARCH_ENGINE +app.state.config.BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL = ( + BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL +) +app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST = RAG_WEB_SEARCH_DOMAIN_FILTER_LIST + +app.state.config.ENABLE_GOOGLE_DRIVE_INTEGRATION = ENABLE_GOOGLE_DRIVE_INTEGRATION +app.state.config.ENABLE_ONEDRIVE_INTEGRATION = ENABLE_ONEDRIVE_INTEGRATION +app.state.config.SEARXNG_QUERY_URL = SEARXNG_QUERY_URL +app.state.config.GOOGLE_PSE_API_KEY = GOOGLE_PSE_API_KEY +app.state.config.GOOGLE_PSE_ENGINE_ID = GOOGLE_PSE_ENGINE_ID +app.state.config.BRAVE_SEARCH_API_KEY = BRAVE_SEARCH_API_KEY +app.state.config.KAGI_SEARCH_API_KEY = KAGI_SEARCH_API_KEY +app.state.config.MOJEEK_SEARCH_API_KEY = MOJEEK_SEARCH_API_KEY +app.state.config.BOCHA_SEARCH_API_KEY = BOCHA_SEARCH_API_KEY +app.state.config.SERPSTACK_API_KEY = SERPSTACK_API_KEY +app.state.config.SERPSTACK_HTTPS = SERPSTACK_HTTPS +app.state.config.SERPER_API_KEY = SERPER_API_KEY +app.state.config.SERPLY_API_KEY = SERPLY_API_KEY +app.state.config.TAVILY_API_KEY = TAVILY_API_KEY +app.state.config.SEARCHAPI_API_KEY = SEARCHAPI_API_KEY +app.state.config.SEARCHAPI_ENGINE = SEARCHAPI_ENGINE +app.state.config.SERPAPI_API_KEY = SERPAPI_API_KEY +app.state.config.SERPAPI_ENGINE = SERPAPI_ENGINE +app.state.config.JINA_API_KEY = JINA_API_KEY +app.state.config.BING_SEARCH_V7_ENDPOINT = BING_SEARCH_V7_ENDPOINT +app.state.config.BING_SEARCH_V7_SUBSCRIPTION_KEY = BING_SEARCH_V7_SUBSCRIPTION_KEY +app.state.config.EXA_API_KEY = EXA_API_KEY + +app.state.config.RAG_WEB_SEARCH_RESULT_COUNT = RAG_WEB_SEARCH_RESULT_COUNT +app.state.config.RAG_WEB_SEARCH_CONCURRENT_REQUESTS = RAG_WEB_SEARCH_CONCURRENT_REQUESTS +app.state.config.RAG_WEB_LOADER_ENGINE = RAG_WEB_LOADER_ENGINE +app.state.config.RAG_WEB_SEARCH_TRUST_ENV = RAG_WEB_SEARCH_TRUST_ENV +app.state.config.PLAYWRIGHT_WS_URI = PLAYWRIGHT_WS_URI +app.state.config.FIRECRAWL_API_BASE_URL = FIRECRAWL_API_BASE_URL +app.state.config.FIRECRAWL_API_KEY = FIRECRAWL_API_KEY + +app.state.EMBEDDING_FUNCTION = None +app.state.ef = None +app.state.rf = None + +app.state.YOUTUBE_LOADER_TRANSLATION = None + + +try: + app.state.ef = get_ef( + app.state.config.RAG_EMBEDDING_ENGINE, + app.state.config.RAG_EMBEDDING_MODEL, + RAG_EMBEDDING_MODEL_AUTO_UPDATE, + ) + + app.state.rf = get_rf( + app.state.config.RAG_RERANKING_MODEL, + RAG_RERANKING_MODEL_AUTO_UPDATE, + ) +except Exception as e: + log.error(f"Error updating models: {e}") + pass + + +app.state.EMBEDDING_FUNCTION = get_embedding_function( + app.state.config.RAG_EMBEDDING_ENGINE, + app.state.config.RAG_EMBEDDING_MODEL, + app.state.ef, + ( + app.state.config.RAG_OPENAI_API_BASE_URL + if app.state.config.RAG_EMBEDDING_ENGINE == "openai" + else app.state.config.RAG_OLLAMA_BASE_URL + ), + ( + app.state.config.RAG_OPENAI_API_KEY + if app.state.config.RAG_EMBEDDING_ENGINE == "openai" + else app.state.config.RAG_OLLAMA_API_KEY + ), + app.state.config.RAG_EMBEDDING_BATCH_SIZE, +) + +######################################## +# +# CODE EXECUTION +# +######################################## + +app.state.config.CODE_EXECUTION_ENGINE = CODE_EXECUTION_ENGINE +app.state.config.CODE_EXECUTION_JUPYTER_URL = CODE_EXECUTION_JUPYTER_URL +app.state.config.CODE_EXECUTION_JUPYTER_AUTH = CODE_EXECUTION_JUPYTER_AUTH +app.state.config.CODE_EXECUTION_JUPYTER_AUTH_TOKEN = CODE_EXECUTION_JUPYTER_AUTH_TOKEN +app.state.config.CODE_EXECUTION_JUPYTER_AUTH_PASSWORD = ( + CODE_EXECUTION_JUPYTER_AUTH_PASSWORD +) +app.state.config.CODE_EXECUTION_JUPYTER_TIMEOUT = CODE_EXECUTION_JUPYTER_TIMEOUT + +app.state.config.ENABLE_CODE_INTERPRETER = ENABLE_CODE_INTERPRETER +app.state.config.CODE_INTERPRETER_ENGINE = CODE_INTERPRETER_ENGINE +app.state.config.CODE_INTERPRETER_PROMPT_TEMPLATE = CODE_INTERPRETER_PROMPT_TEMPLATE + +app.state.config.CODE_INTERPRETER_JUPYTER_URL = CODE_INTERPRETER_JUPYTER_URL +app.state.config.CODE_INTERPRETER_JUPYTER_AUTH = CODE_INTERPRETER_JUPYTER_AUTH +app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_TOKEN = ( + CODE_INTERPRETER_JUPYTER_AUTH_TOKEN +) +app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD = ( + CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD +) +app.state.config.CODE_INTERPRETER_JUPYTER_TIMEOUT = CODE_INTERPRETER_JUPYTER_TIMEOUT + +######################################## +# +# IMAGES +# +######################################## + +app.state.config.IMAGE_GENERATION_ENGINE = IMAGE_GENERATION_ENGINE +app.state.config.ENABLE_IMAGE_GENERATION = ENABLE_IMAGE_GENERATION +app.state.config.ENABLE_IMAGE_PROMPT_GENERATION = ENABLE_IMAGE_PROMPT_GENERATION + +app.state.config.IMAGES_OPENAI_API_BASE_URL = IMAGES_OPENAI_API_BASE_URL +app.state.config.IMAGES_OPENAI_API_KEY = IMAGES_OPENAI_API_KEY + +app.state.config.IMAGES_GEMINI_API_BASE_URL = IMAGES_GEMINI_API_BASE_URL +app.state.config.IMAGES_GEMINI_API_KEY = IMAGES_GEMINI_API_KEY + +app.state.config.IMAGE_GENERATION_MODEL = IMAGE_GENERATION_MODEL + +app.state.config.AUTOMATIC1111_BASE_URL = AUTOMATIC1111_BASE_URL +app.state.config.AUTOMATIC1111_API_AUTH = AUTOMATIC1111_API_AUTH +app.state.config.AUTOMATIC1111_CFG_SCALE = AUTOMATIC1111_CFG_SCALE +app.state.config.AUTOMATIC1111_SAMPLER = AUTOMATIC1111_SAMPLER +app.state.config.AUTOMATIC1111_SCHEDULER = AUTOMATIC1111_SCHEDULER +app.state.config.COMFYUI_BASE_URL = COMFYUI_BASE_URL +app.state.config.COMFYUI_API_KEY = COMFYUI_API_KEY +app.state.config.COMFYUI_WORKFLOW = COMFYUI_WORKFLOW +app.state.config.COMFYUI_WORKFLOW_NODES = COMFYUI_WORKFLOW_NODES + +app.state.config.IMAGE_SIZE = IMAGE_SIZE +app.state.config.IMAGE_STEPS = IMAGE_STEPS + + +######################################## +# +# AUDIO +# +######################################## + +app.state.config.STT_OPENAI_API_BASE_URL = AUDIO_STT_OPENAI_API_BASE_URL +app.state.config.STT_OPENAI_API_KEY = AUDIO_STT_OPENAI_API_KEY +app.state.config.STT_ENGINE = AUDIO_STT_ENGINE +app.state.config.STT_MODEL = AUDIO_STT_MODEL + +app.state.config.WHISPER_MODEL = WHISPER_MODEL +app.state.config.DEEPGRAM_API_KEY = DEEPGRAM_API_KEY + +app.state.config.TTS_OPENAI_API_BASE_URL = AUDIO_TTS_OPENAI_API_BASE_URL +app.state.config.TTS_OPENAI_API_KEY = AUDIO_TTS_OPENAI_API_KEY +app.state.config.TTS_ENGINE = AUDIO_TTS_ENGINE +app.state.config.TTS_MODEL = AUDIO_TTS_MODEL +app.state.config.TTS_VOICE = AUDIO_TTS_VOICE +app.state.config.TTS_API_KEY = AUDIO_TTS_API_KEY +app.state.config.TTS_SPLIT_ON = AUDIO_TTS_SPLIT_ON + + +app.state.config.TTS_AZURE_SPEECH_REGION = AUDIO_TTS_AZURE_SPEECH_REGION +app.state.config.TTS_AZURE_SPEECH_OUTPUT_FORMAT = AUDIO_TTS_AZURE_SPEECH_OUTPUT_FORMAT + + +app.state.faster_whisper_model = None +app.state.speech_synthesiser = None +app.state.speech_speaker_embeddings_dataset = None + + +######################################## +# +# TASKS +# +######################################## + + +app.state.config.TASK_MODEL = TASK_MODEL +app.state.config.TASK_MODEL_EXTERNAL = TASK_MODEL_EXTERNAL + + +app.state.config.ENABLE_SEARCH_QUERY_GENERATION = ENABLE_SEARCH_QUERY_GENERATION +app.state.config.ENABLE_RETRIEVAL_QUERY_GENERATION = ENABLE_RETRIEVAL_QUERY_GENERATION +app.state.config.ENABLE_AUTOCOMPLETE_GENERATION = ENABLE_AUTOCOMPLETE_GENERATION +app.state.config.ENABLE_TAGS_GENERATION = ENABLE_TAGS_GENERATION +app.state.config.ENABLE_TITLE_GENERATION = ENABLE_TITLE_GENERATION + + +app.state.config.TITLE_GENERATION_PROMPT_TEMPLATE = TITLE_GENERATION_PROMPT_TEMPLATE +app.state.config.TAGS_GENERATION_PROMPT_TEMPLATE = TAGS_GENERATION_PROMPT_TEMPLATE +app.state.config.IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE = ( + IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE +) + +app.state.config.TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE = ( + TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE +) +app.state.config.QUERY_GENERATION_PROMPT_TEMPLATE = QUERY_GENERATION_PROMPT_TEMPLATE +app.state.config.AUTOCOMPLETE_GENERATION_PROMPT_TEMPLATE = ( + AUTOCOMPLETE_GENERATION_PROMPT_TEMPLATE +) +app.state.config.AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH = ( + AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH +) + + +######################################## +# +# WEBUI +# +######################################## + +app.state.MODELS = {} + + +class RedirectMiddleware(BaseHTTPMiddleware): + async def dispatch(self, request: Request, call_next): + # Check if the request is a GET request + if request.method == "GET": + path = request.url.path + query_params = dict(parse_qs(urlparse(str(request.url)).query)) + + # Check for the specific watch path and the presence of 'v' parameter + if path.endswith("/watch") and "v" in query_params: + video_id = query_params["v"][0] # Extract the first 'v' parameter + encoded_video_id = urlencode({"youtube": video_id}) + redirect_url = f"/?{encoded_video_id}" + return RedirectResponse(url=redirect_url) + + # Proceed with the normal flow of other requests + response = await call_next(request) + return response + + +# Add the middleware to the app +app.add_middleware(RedirectMiddleware) +app.add_middleware(SecurityHeadersMiddleware) + + +@app.middleware("http") +async def commit_session_after_request(request: Request, call_next): + response = await call_next(request) + # log.debug("Commit session after request") + Session.commit() + return response + + +@app.middleware("http") +async def check_url(request: Request, call_next): + start_time = int(time.time()) + request.state.enable_api_key = app.state.config.ENABLE_API_KEY + response = await call_next(request) + process_time = int(time.time()) - start_time + response.headers["X-Process-Time"] = str(process_time) + return response + + +@app.middleware("http") +async def inspect_websocket(request: Request, call_next): + if ( + "/ws/socket.io" in request.url.path + and request.query_params.get("transport") == "websocket" + ): + upgrade = (request.headers.get("Upgrade") or "").lower() + connection = (request.headers.get("Connection") or "").lower().split(",") + # Check that there's the correct headers for an upgrade, else reject the connection + # This is to work around this upstream issue: https://github.com/miguelgrinberg/python-engineio/issues/367 + if upgrade != "websocket" or "upgrade" not in connection: + return JSONResponse( + status_code=status.HTTP_400_BAD_REQUEST, + content={"detail": "Invalid WebSocket upgrade request"}, + ) + return await call_next(request) + + +app.add_middleware( + CORSMiddleware, + allow_origins=CORS_ALLOW_ORIGIN, + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + + +app.mount("/ws", socket_app) + + +app.include_router(ollama.router, prefix="/ollama", tags=["ollama"]) +app.include_router(openai.router, prefix="/openai", tags=["openai"]) + + +app.include_router(pipelines.router, prefix="/api/v1/pipelines", tags=["pipelines"]) +app.include_router(tasks.router, prefix="/api/v1/tasks", tags=["tasks"]) +app.include_router(images.router, prefix="/api/v1/images", tags=["images"]) + +app.include_router(audio.router, prefix="/api/v1/audio", tags=["audio"]) +app.include_router(retrieval.router, prefix="/api/v1/retrieval", tags=["retrieval"]) + +app.include_router(configs.router, prefix="/api/v1/configs", tags=["configs"]) + +app.include_router(auths.router, prefix="/api/v1/auths", tags=["auths"]) +app.include_router(users.router, prefix="/api/v1/users", tags=["users"]) + + +app.include_router(channels.router, prefix="/api/v1/channels", tags=["channels"]) +app.include_router(chats.router, prefix="/api/v1/chats", tags=["chats"]) + +app.include_router(models.router, prefix="/api/v1/models", tags=["models"]) +app.include_router(knowledge.router, prefix="/api/v1/knowledge", tags=["knowledge"]) +app.include_router(prompts.router, prefix="/api/v1/prompts", tags=["prompts"]) +app.include_router(tools.router, prefix="/api/v1/tools", tags=["tools"]) + +app.include_router(memories.router, prefix="/api/v1/memories", tags=["memories"]) +app.include_router(folders.router, prefix="/api/v1/folders", tags=["folders"]) +app.include_router(groups.router, prefix="/api/v1/groups", tags=["groups"]) +app.include_router(files.router, prefix="/api/v1/files", tags=["files"]) +app.include_router(functions.router, prefix="/api/v1/functions", tags=["functions"]) +app.include_router( + evaluations.router, prefix="/api/v1/evaluations", tags=["evaluations"] +) +app.include_router(utils.router, prefix="/api/v1/utils", tags=["utils"]) + + +try: + audit_level = AuditLevel(AUDIT_LOG_LEVEL) +except ValueError as e: + logger.error(f"Invalid audit level: {AUDIT_LOG_LEVEL}. Error: {e}") + audit_level = AuditLevel.NONE + +if audit_level != AuditLevel.NONE: + app.add_middleware( + AuditLoggingMiddleware, + audit_level=audit_level, + excluded_paths=AUDIT_EXCLUDED_PATHS, + max_body_size=MAX_BODY_LOG_SIZE, + ) +################################## +# +# Chat Endpoints +# +################################## + + +@app.get("/api/models") +async def get_models(request: Request, user=Depends(get_verified_user)): + def get_filtered_models(models, user): + filtered_models = [] + for model in models: + if model.get("arena"): + if has_access( + user.id, + type="read", + access_control=model.get("info", {}) + .get("meta", {}) + .get("access_control", {}), + ): + filtered_models.append(model) + continue + + model_info = Models.get_model_by_id(model["id"]) + if model_info: + if user.id == model_info.user_id or has_access( + user.id, type="read", access_control=model_info.access_control + ): + filtered_models.append(model) + + return filtered_models + + models = await get_all_models(request, user=user) + + # Filter out filter pipelines + models = [ + model + for model in models + if "pipeline" not in model or model["pipeline"].get("type", None) != "filter" + ] + + model_order_list = request.app.state.config.MODEL_ORDER_LIST + if model_order_list: + model_order_dict = {model_id: i for i, model_id in enumerate(model_order_list)} + # Sort models by order list priority, with fallback for those not in the list + models.sort( + key=lambda x: (model_order_dict.get(x["id"], float("inf")), x["name"]) + ) + + # Filter out models that the user does not have access to + if user.role == "user" and not BYPASS_MODEL_ACCESS_CONTROL: + models = get_filtered_models(models, user) + + log.debug( + f"/api/models returned filtered models accessible to the user: {json.dumps([model['id'] for model in models])}" + ) + return {"data": models} + + +@app.get("/api/models/base") +async def get_base_models(request: Request, user=Depends(get_admin_user)): + models = await get_all_base_models(request, user=user) + return {"data": models} + + +@app.post("/api/chat/completions") +async def chat_completion( + request: Request, + form_data: dict, + user=Depends(get_verified_user), +): + if not request.app.state.MODELS: + await get_all_models(request, user=user) + + model_item = form_data.pop("model_item", {}) + tasks = form_data.pop("background_tasks", None) + + try: + if not model_item.get("direct", False): + model_id = form_data.get("model", None) + if model_id not in request.app.state.MODELS: + raise Exception("Model not found") + + model = request.app.state.MODELS[model_id] + model_info = Models.get_model_by_id(model_id) + + # Check if user has access to the model + if not BYPASS_MODEL_ACCESS_CONTROL and user.role == "user": + try: + check_model_access(user, model) + except Exception as e: + raise e + else: + model = model_item + model_info = None + + request.state.direct = True + request.state.model = model + + metadata = { + "user_id": user.id, + "chat_id": form_data.pop("chat_id", None), + "message_id": form_data.pop("id", None), + "session_id": form_data.pop("session_id", None), + "tool_ids": form_data.get("tool_ids", None), + "files": form_data.get("files", None), + "features": form_data.get("features", None), + "variables": form_data.get("variables", None), + "model": model_info.model_dump() if model_info else model, + "direct": model_item.get("direct", False), + **( + {"function_calling": "native"} + if form_data.get("params", {}).get("function_calling") == "native" + or ( + model_info + and model_info.params.model_dump().get("function_calling") + == "native" + ) + else {} + ), + } + + request.state.metadata = metadata + form_data["metadata"] = metadata + + form_data, metadata, events = await process_chat_payload( + request, form_data, metadata, user, model + ) + + except Exception as e: + log.debug(f"Error processing chat payload: {e}") + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=str(e), + ) + + try: + response = await chat_completion_handler(request, form_data, user) + + return await process_chat_response( + request, response, form_data, user, events, metadata, tasks + ) + except Exception as e: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=str(e), + ) + + +# Alias for chat_completion (Legacy) +generate_chat_completions = chat_completion +generate_chat_completion = chat_completion + + +@app.post("/api/chat/completed") +async def chat_completed( + request: Request, form_data: dict, user=Depends(get_verified_user) +): + try: + model_item = form_data.pop("model_item", {}) + + if model_item.get("direct", False): + request.state.direct = True + request.state.model = model_item + + return await chat_completed_handler(request, form_data, user) + except Exception as e: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=str(e), + ) + + +@app.post("/api/chat/actions/{action_id}") +async def chat_action( + request: Request, action_id: str, form_data: dict, user=Depends(get_verified_user) +): + try: + model_item = form_data.pop("model_item", {}) + + if model_item.get("direct", False): + request.state.direct = True + request.state.model = model_item + + return await chat_action_handler(request, action_id, form_data, user) + except Exception as e: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=str(e), + ) + + +@app.post("/api/tasks/stop/{task_id}") +async def stop_task_endpoint(task_id: str, user=Depends(get_verified_user)): + try: + result = await stop_task(task_id) # Use the function from tasks.py + return result + except ValueError as e: + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e)) + + +@app.get("/api/tasks") +async def list_tasks_endpoint(user=Depends(get_verified_user)): + return {"tasks": list_tasks()} # Use the function from tasks.py + + +################################## +# +# Config Endpoints +# +################################## + + +@app.get("/api/config") +async def get_app_config(request: Request): + user = None + if "token" in request.cookies: + token = request.cookies.get("token") + try: + data = decode_token(token) + except Exception as e: + log.debug(e) + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="Invalid token", + ) + if data is not None and "id" in data: + user = Users.get_user_by_id(data["id"]) + + onboarding = False + if user is None: + user_count = Users.get_num_users() + onboarding = user_count == 0 + + return { + **({"onboarding": True} if onboarding else {}), + "status": True, + "name": app.state.WEBUI_NAME, + "version": VERSION, + "default_locale": str(DEFAULT_LOCALE), + "oauth": { + "providers": { + name: config.get("name", name) + for name, config in OAUTH_PROVIDERS.items() + } + }, + "features": { + "auth": WEBUI_AUTH, + "auth_trusted_header": bool(app.state.AUTH_TRUSTED_EMAIL_HEADER), + "enable_ldap": app.state.config.ENABLE_LDAP, + "enable_api_key": app.state.config.ENABLE_API_KEY, + "enable_signup": app.state.config.ENABLE_SIGNUP, + "enable_login_form": app.state.config.ENABLE_LOGIN_FORM, + "enable_websocket": ENABLE_WEBSOCKET_SUPPORT, + **( + { + "enable_direct_connections": app.state.config.ENABLE_DIRECT_CONNECTIONS, + "enable_channels": app.state.config.ENABLE_CHANNELS, + "enable_web_search": app.state.config.ENABLE_RAG_WEB_SEARCH, + "enable_code_interpreter": app.state.config.ENABLE_CODE_INTERPRETER, + "enable_image_generation": app.state.config.ENABLE_IMAGE_GENERATION, + "enable_autocomplete_generation": app.state.config.ENABLE_AUTOCOMPLETE_GENERATION, + "enable_community_sharing": app.state.config.ENABLE_COMMUNITY_SHARING, + "enable_message_rating": app.state.config.ENABLE_MESSAGE_RATING, + "enable_admin_export": ENABLE_ADMIN_EXPORT, + "enable_admin_chat_access": ENABLE_ADMIN_CHAT_ACCESS, + "enable_google_drive_integration": app.state.config.ENABLE_GOOGLE_DRIVE_INTEGRATION, + "enable_onedrive_integration": app.state.config.ENABLE_ONEDRIVE_INTEGRATION, + } + if user is not None + else {} + ), + }, + **( + { + "default_models": app.state.config.DEFAULT_MODELS, + "default_prompt_suggestions": app.state.config.DEFAULT_PROMPT_SUGGESTIONS, + "code": { + "engine": app.state.config.CODE_EXECUTION_ENGINE, + }, + "audio": { + "tts": { + "engine": app.state.config.TTS_ENGINE, + "voice": app.state.config.TTS_VOICE, + "split_on": app.state.config.TTS_SPLIT_ON, + }, + "stt": { + "engine": app.state.config.STT_ENGINE, + }, + }, + "file": { + "max_size": app.state.config.FILE_MAX_SIZE, + "max_count": app.state.config.FILE_MAX_COUNT, + }, + "permissions": {**app.state.config.USER_PERMISSIONS}, + "google_drive": { + "client_id": GOOGLE_DRIVE_CLIENT_ID.value, + "api_key": GOOGLE_DRIVE_API_KEY.value, + }, + "onedrive": {"client_id": ONEDRIVE_CLIENT_ID.value}, + } + if user is not None + else {} + ), + } + + +class UrlForm(BaseModel): + url: str + + +@app.get("/api/webhook") +async def get_webhook_url(user=Depends(get_admin_user)): + return { + "url": app.state.config.WEBHOOK_URL, + } + + +@app.post("/api/webhook") +async def update_webhook_url(form_data: UrlForm, user=Depends(get_admin_user)): + app.state.config.WEBHOOK_URL = form_data.url + app.state.WEBHOOK_URL = app.state.config.WEBHOOK_URL + return {"url": app.state.config.WEBHOOK_URL} + + +@app.get("/api/version") +async def get_app_version(): + return { + "version": VERSION, + } + + +@app.get("/api/version/updates") +async def get_app_latest_release_version(user=Depends(get_verified_user)): + if OFFLINE_MODE: + log.debug( + f"Offline mode is enabled, returning current version as latest version" + ) + return {"current": VERSION, "latest": VERSION} + try: + timeout = aiohttp.ClientTimeout(total=1) + async with aiohttp.ClientSession(timeout=timeout, trust_env=True) as session: + async with session.get( + "https://api.github.com/repos/open-webui/open-webui/releases/latest" + ) as response: + response.raise_for_status() + data = await response.json() + latest_version = data["tag_name"] + + return {"current": VERSION, "latest": latest_version[1:]} + except Exception as e: + log.debug(e) + return {"current": VERSION, "latest": VERSION} + + +@app.get("/api/changelog") +async def get_app_changelog(): + return {key: CHANGELOG[key] for idx, key in enumerate(CHANGELOG) if idx < 5} + + +############################ +# OAuth Login & Callback +############################ + +# SessionMiddleware is used by authlib for oauth +if len(OAUTH_PROVIDERS) > 0: + app.add_middleware( + SessionMiddleware, + secret_key=WEBUI_SECRET_KEY, + session_cookie="oui-session", + same_site=WEBUI_SESSION_COOKIE_SAME_SITE, + https_only=WEBUI_SESSION_COOKIE_SECURE, + ) + + +@app.get("/oauth/{provider}/login") +async def oauth_login(provider: str, request: Request): + return await oauth_manager.handle_login(request, provider) + + +# OAuth login logic is as follows: +# 1. Attempt to find a user with matching subject ID, tied to the provider +# 2. If OAUTH_MERGE_ACCOUNTS_BY_EMAIL is true, find a user with the email address provided via OAuth +# - This is considered insecure in general, as OAuth providers do not always verify email addresses +# 3. If there is no user, and ENABLE_OAUTH_SIGNUP is true, create a user +# - Email addresses are considered unique, so we fail registration if the email address is already taken +@app.get("/oauth/{provider}/callback") +async def oauth_callback(provider: str, request: Request, response: Response): + return await oauth_manager.handle_callback(request, provider, response) + + +@app.get("/manifest.json") +async def get_manifest_json(): + return { + "name": app.state.WEBUI_NAME, + "short_name": app.state.WEBUI_NAME, + "description": "Open WebUI is an open, extensible, user-friendly interface for AI that adapts to your workflow.", + "start_url": "/", + "display": "standalone", + "background_color": "#343541", + "orientation": "natural", + "icons": [ + { + "src": "/static/logo.png", + "type": "image/png", + "sizes": "500x500", + "purpose": "any", + }, + { + "src": "/static/logo.png", + "type": "image/png", + "sizes": "500x500", + "purpose": "maskable", + }, + ], + } + + +@app.get("/opensearch.xml") +async def get_opensearch_xml(): + xml_content = rf""" + + {app.state.WEBUI_NAME} + Search {app.state.WEBUI_NAME} + UTF-8 + {app.state.config.WEBUI_URL}/static/favicon.png + + {app.state.config.WEBUI_URL} + + """ + return Response(content=xml_content, media_type="application/xml") + + +@app.get("/health") +async def healthcheck(): + return {"status": True} + + +@app.get("/health/db") +async def healthcheck_with_db(): + Session.execute(text("SELECT 1;")).all() + return {"status": True} + + +app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static") +app.mount("/cache", StaticFiles(directory=CACHE_DIR), name="cache") + + +def swagger_ui_html(*args, **kwargs): + return get_swagger_ui_html( + *args, + **kwargs, + swagger_js_url="/static/swagger-ui/swagger-ui-bundle.js", + swagger_css_url="/static/swagger-ui/swagger-ui.css", + swagger_favicon_url="/static/swagger-ui/favicon.png", + ) + + +applications.get_swagger_ui_html = swagger_ui_html + +if os.path.exists(FRONTEND_BUILD_DIR): + mimetypes.add_type("text/javascript", ".js") + app.mount( + "/", + SPAStaticFiles(directory=FRONTEND_BUILD_DIR, html=True), + name="spa-static-files", + ) +else: + log.warning( + f"Frontend build directory not found at '{FRONTEND_BUILD_DIR}'. Serving API only." + ) diff --git a/backend/open_webui/migrations/README b/backend/open_webui/migrations/README new file mode 100644 index 0000000..f1d93df --- /dev/null +++ b/backend/open_webui/migrations/README @@ -0,0 +1,4 @@ +Generic single-database configuration. + +Create new migrations with +DATABASE_URL= alembic revision --autogenerate -m "a description" diff --git a/backend/open_webui/migrations/env.py b/backend/open_webui/migrations/env.py new file mode 100644 index 0000000..1288816 --- /dev/null +++ b/backend/open_webui/migrations/env.py @@ -0,0 +1,81 @@ +from logging.config import fileConfig + +from alembic import context +from open_webui.models.auths import Auth +from open_webui.env import DATABASE_URL +from sqlalchemy import engine_from_config, pool + +# this is the Alembic Config object, which provides +# access to the values within the .ini file in use. +config = context.config + +# Interpret the config file for Python logging. +# This line sets up loggers basically. +if config.config_file_name is not None: + fileConfig(config.config_file_name, disable_existing_loggers=False) + +# add your model's MetaData object here +# for 'autogenerate' support +# from myapp import mymodel +# target_metadata = mymodel.Base.metadata +target_metadata = Auth.metadata + +# other values from the config, defined by the needs of env.py, +# can be acquired: +# my_important_option = config.get_main_option("my_important_option") +# ... etc. + +DB_URL = DATABASE_URL + +if DB_URL: + config.set_main_option("sqlalchemy.url", DB_URL.replace("%", "%%")) + + +def run_migrations_offline() -> None: + """Run migrations in 'offline' mode. + + This configures the context with just a URL + and not an Engine, though an Engine is acceptable + here as well. By skipping the Engine creation + we don't even need a DBAPI to be available. + + Calls to context.execute() here emit the given string to the + script output. + + """ + url = config.get_main_option("sqlalchemy.url") + context.configure( + url=url, + target_metadata=target_metadata, + literal_binds=True, + dialect_opts={"paramstyle": "named"}, + ) + + with context.begin_transaction(): + context.run_migrations() + + +def run_migrations_online() -> None: + """Run migrations in 'online' mode. + + In this scenario we need to create an Engine + and associate a connection with the context. + + """ + connectable = engine_from_config( + config.get_section(config.config_ini_section, {}), + prefix="sqlalchemy.", + poolclass=pool.NullPool, + ) + + with connectable.connect() as connection: + context.configure(connection=connection, target_metadata=target_metadata) + + with context.begin_transaction(): + context.run_migrations() + + +if context.is_offline_mode(): + run_migrations_offline() +else: + run_migrations_online() diff --git a/backend/open_webui/migrations/script.py.mako b/backend/open_webui/migrations/script.py.mako new file mode 100644 index 0000000..bcf5567 --- /dev/null +++ b/backend/open_webui/migrations/script.py.mako @@ -0,0 +1,27 @@ +"""${message} + +Revision ID: ${up_revision} +Revises: ${down_revision | comma,n} +Create Date: ${create_date} + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa +import open_webui.internal.db +${imports if imports else ""} + +# revision identifiers, used by Alembic. +revision: str = ${repr(up_revision)} +down_revision: Union[str, None] = ${repr(down_revision)} +branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)} +depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)} + + +def upgrade() -> None: + ${upgrades if upgrades else "pass"} + + +def downgrade() -> None: + ${downgrades if downgrades else "pass"} diff --git a/backend/open_webui/migrations/util.py b/backend/open_webui/migrations/util.py new file mode 100644 index 0000000..9550666 --- /dev/null +++ b/backend/open_webui/migrations/util.py @@ -0,0 +1,15 @@ +from alembic import op +from sqlalchemy import Inspector + + +def get_existing_tables(): + con = op.get_bind() + inspector = Inspector.from_engine(con) + tables = set(inspector.get_table_names()) + return tables + + +def get_revision_id(): + import uuid + + return str(uuid.uuid4()).replace("-", "")[:12] diff --git a/backend/open_webui/migrations/versions/1af9b942657b_migrate_tags.py b/backend/open_webui/migrations/versions/1af9b942657b_migrate_tags.py new file mode 100644 index 0000000..8a0ab1b --- /dev/null +++ b/backend/open_webui/migrations/versions/1af9b942657b_migrate_tags.py @@ -0,0 +1,151 @@ +"""Migrate tags + +Revision ID: 1af9b942657b +Revises: 242a2047eae0 +Create Date: 2024-10-09 21:02:35.241684 + +""" + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.sql import table, select, update, column +from sqlalchemy.engine.reflection import Inspector + +import json + +revision = "1af9b942657b" +down_revision = "242a2047eae0" +branch_labels = None +depends_on = None + + +def upgrade(): + # Setup an inspection on the existing table to avoid issues + conn = op.get_bind() + inspector = Inspector.from_engine(conn) + + # Clean up potential leftover temp table from previous failures + conn.execute(sa.text("DROP TABLE IF EXISTS _alembic_tmp_tag")) + + # Check if the 'tag' table exists + tables = inspector.get_table_names() + + # Step 1: Modify Tag table using batch mode for SQLite support + if "tag" in tables: + # Get the current columns in the 'tag' table + columns = [col["name"] for col in inspector.get_columns("tag")] + + # Get any existing unique constraints on the 'tag' table + current_constraints = inspector.get_unique_constraints("tag") + + with op.batch_alter_table("tag", schema=None) as batch_op: + # Check if the unique constraint already exists + if not any( + constraint["name"] == "uq_id_user_id" + for constraint in current_constraints + ): + # Create unique constraint if it doesn't exist + batch_op.create_unique_constraint("uq_id_user_id", ["id", "user_id"]) + + # Check if the 'data' column exists before trying to drop it + if "data" in columns: + batch_op.drop_column("data") + + # Check if the 'meta' column needs to be created + if "meta" not in columns: + # Add the 'meta' column if it doesn't already exist + batch_op.add_column(sa.Column("meta", sa.JSON(), nullable=True)) + + tag = table( + "tag", + column("id", sa.String()), + column("name", sa.String()), + column("user_id", sa.String()), + column("meta", sa.JSON()), + ) + + # Step 2: Migrate tags + conn = op.get_bind() + result = conn.execute(sa.select(tag.c.id, tag.c.name, tag.c.user_id)) + + tag_updates = {} + for row in result: + new_id = row.name.replace(" ", "_").lower() + tag_updates[row.id] = new_id + + for tag_id, new_tag_id in tag_updates.items(): + print(f"Updating tag {tag_id} to {new_tag_id}") + if new_tag_id == "pinned": + # delete tag + delete_stmt = sa.delete(tag).where(tag.c.id == tag_id) + conn.execute(delete_stmt) + else: + # Check if the new_tag_id already exists in the database + existing_tag_query = sa.select(tag.c.id).where(tag.c.id == new_tag_id) + existing_tag_result = conn.execute(existing_tag_query).fetchone() + + if existing_tag_result: + # Handle duplicate case: the new_tag_id already exists + print( + f"Tag {new_tag_id} already exists. Removing current tag with ID {tag_id} to avoid duplicates." + ) + # Option 1: Delete the current tag if an update to new_tag_id would cause duplication + delete_stmt = sa.delete(tag).where(tag.c.id == tag_id) + conn.execute(delete_stmt) + else: + update_stmt = sa.update(tag).where(tag.c.id == tag_id) + update_stmt = update_stmt.values(id=new_tag_id) + conn.execute(update_stmt) + + # Add columns `pinned` and `meta` to 'chat' + op.add_column("chat", sa.Column("pinned", sa.Boolean(), nullable=True)) + op.add_column( + "chat", sa.Column("meta", sa.JSON(), nullable=False, server_default="{}") + ) + + chatidtag = table( + "chatidtag", column("chat_id", sa.String()), column("tag_name", sa.String()) + ) + chat = table( + "chat", + column("id", sa.String()), + column("pinned", sa.Boolean()), + column("meta", sa.JSON()), + ) + + # Fetch existing tags + conn = op.get_bind() + result = conn.execute(sa.select(chatidtag.c.chat_id, chatidtag.c.tag_name)) + + chat_updates = {} + for row in result: + chat_id = row.chat_id + tag_name = row.tag_name.replace(" ", "_").lower() + + if tag_name == "pinned": + # Specifically handle 'pinned' tag + if chat_id not in chat_updates: + chat_updates[chat_id] = {"pinned": True, "meta": {}} + else: + chat_updates[chat_id]["pinned"] = True + else: + if chat_id not in chat_updates: + chat_updates[chat_id] = {"pinned": False, "meta": {"tags": [tag_name]}} + else: + tags = chat_updates[chat_id]["meta"].get("tags", []) + tags.append(tag_name) + + chat_updates[chat_id]["meta"]["tags"] = list(set(tags)) + + # Update chats based on accumulated changes + for chat_id, updates in chat_updates.items(): + update_stmt = sa.update(chat).where(chat.c.id == chat_id) + update_stmt = update_stmt.values( + meta=updates.get("meta", {}), pinned=updates.get("pinned", False) + ) + conn.execute(update_stmt) + pass + + +def downgrade(): + pass diff --git a/backend/open_webui/migrations/versions/242a2047eae0_update_chat_table.py b/backend/open_webui/migrations/versions/242a2047eae0_update_chat_table.py new file mode 100644 index 0000000..6017da3 --- /dev/null +++ b/backend/open_webui/migrations/versions/242a2047eae0_update_chat_table.py @@ -0,0 +1,107 @@ +"""Update chat table + +Revision ID: 242a2047eae0 +Revises: 6a39f3d8e55c +Create Date: 2024-10-09 21:02:35.241684 + +""" + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.sql import table, select, update + +import json + +revision = "242a2047eae0" +down_revision = "6a39f3d8e55c" +branch_labels = None +depends_on = None + + +def upgrade(): + conn = op.get_bind() + inspector = sa.inspect(conn) + + columns = inspector.get_columns("chat") + column_dict = {col["name"]: col for col in columns} + + chat_column = column_dict.get("chat") + old_chat_exists = "old_chat" in column_dict + + if chat_column: + if isinstance(chat_column["type"], sa.Text): + print("Converting 'chat' column to JSON") + + if old_chat_exists: + print("Dropping old 'old_chat' column") + op.drop_column("chat", "old_chat") + + # Step 1: Rename current 'chat' column to 'old_chat' + print("Renaming 'chat' column to 'old_chat'") + op.alter_column( + "chat", "chat", new_column_name="old_chat", existing_type=sa.Text() + ) + + # Step 2: Add new 'chat' column of type JSON + print("Adding new 'chat' column of type JSON") + op.add_column("chat", sa.Column("chat", sa.JSON(), nullable=True)) + else: + # If the column is already JSON, no need to do anything + pass + + # Step 3: Migrate data from 'old_chat' to 'chat' + chat_table = table( + "chat", + sa.Column("id", sa.String(), primary_key=True), + sa.Column("old_chat", sa.Text()), + sa.Column("chat", sa.JSON()), + ) + + # - Selecting all data from the table + connection = op.get_bind() + results = connection.execute(select(chat_table.c.id, chat_table.c.old_chat)) + for row in results: + try: + # Convert text JSON to actual JSON object, assuming the text is in JSON format + json_data = json.loads(row.old_chat) + except json.JSONDecodeError: + json_data = None # Handle cases where the text cannot be converted to JSON + + connection.execute( + sa.update(chat_table) + .where(chat_table.c.id == row.id) + .values(chat=json_data) + ) + + # Step 4: Drop 'old_chat' column + print("Dropping 'old_chat' column") + op.drop_column("chat", "old_chat") + + +def downgrade(): + # Step 1: Add 'old_chat' column back as Text + op.add_column("chat", sa.Column("old_chat", sa.Text(), nullable=True)) + + # Step 2: Convert 'chat' JSON data back to text and store in 'old_chat' + chat_table = table( + "chat", + sa.Column("id", sa.String(), primary_key=True), + sa.Column("chat", sa.JSON()), + sa.Column("old_chat", sa.Text()), + ) + + connection = op.get_bind() + results = connection.execute(select(chat_table.c.id, chat_table.c.chat)) + for row in results: + text_data = json.dumps(row.chat) if row.chat is not None else None + connection.execute( + sa.update(chat_table) + .where(chat_table.c.id == row.id) + .values(old_chat=text_data) + ) + + # Step 3: Remove the new 'chat' JSON column + op.drop_column("chat", "chat") + + # Step 4: Rename 'old_chat' back to 'chat' + op.alter_column("chat", "old_chat", new_column_name="chat", existing_type=sa.Text()) diff --git a/backend/open_webui/migrations/versions/3781e22d8b01_update_message_table.py b/backend/open_webui/migrations/versions/3781e22d8b01_update_message_table.py new file mode 100644 index 0000000..16fb0e8 --- /dev/null +++ b/backend/open_webui/migrations/versions/3781e22d8b01_update_message_table.py @@ -0,0 +1,70 @@ +"""Update message & channel tables + +Revision ID: 3781e22d8b01 +Revises: 7826ab40b532 +Create Date: 2024-12-30 03:00:00.000000 + +""" + +from alembic import op +import sqlalchemy as sa + +revision = "3781e22d8b01" +down_revision = "7826ab40b532" +branch_labels = None +depends_on = None + + +def upgrade(): + # Add 'type' column to the 'channel' table + op.add_column( + "channel", + sa.Column( + "type", + sa.Text(), + nullable=True, + ), + ) + + # Add 'parent_id' column to the 'message' table for threads + op.add_column( + "message", + sa.Column("parent_id", sa.Text(), nullable=True), + ) + + op.create_table( + "message_reaction", + sa.Column( + "id", sa.Text(), nullable=False, primary_key=True, unique=True + ), # Unique reaction ID + sa.Column("user_id", sa.Text(), nullable=False), # User who reacted + sa.Column( + "message_id", sa.Text(), nullable=False + ), # Message that was reacted to + sa.Column( + "name", sa.Text(), nullable=False + ), # Reaction name (e.g. "thumbs_up") + sa.Column( + "created_at", sa.BigInteger(), nullable=True + ), # Timestamp of when the reaction was added + ) + + op.create_table( + "channel_member", + sa.Column( + "id", sa.Text(), nullable=False, primary_key=True, unique=True + ), # Record ID for the membership row + sa.Column("channel_id", sa.Text(), nullable=False), # Associated channel + sa.Column("user_id", sa.Text(), nullable=False), # Associated user + sa.Column( + "created_at", sa.BigInteger(), nullable=True + ), # Timestamp of when the user joined the channel + ) + + +def downgrade(): + # Revert 'type' column addition to the 'channel' table + op.drop_column("channel", "type") + op.drop_column("message", "parent_id") + op.drop_table("message_reaction") + op.drop_table("channel_member") diff --git a/backend/open_webui/migrations/versions/3ab32c4b8f59_update_tags.py b/backend/open_webui/migrations/versions/3ab32c4b8f59_update_tags.py new file mode 100644 index 0000000..6e01042 --- /dev/null +++ b/backend/open_webui/migrations/versions/3ab32c4b8f59_update_tags.py @@ -0,0 +1,81 @@ +"""Update tags + +Revision ID: 3ab32c4b8f59 +Revises: 1af9b942657b +Create Date: 2024-10-09 21:02:35.241684 + +""" + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.sql import table, select, update, column +from sqlalchemy.engine.reflection import Inspector + +import json + +revision = "3ab32c4b8f59" +down_revision = "1af9b942657b" +branch_labels = None +depends_on = None + + +def upgrade(): + conn = op.get_bind() + inspector = Inspector.from_engine(conn) + + # Inspecting the 'tag' table constraints and structure + existing_pk = inspector.get_pk_constraint("tag") + unique_constraints = inspector.get_unique_constraints("tag") + existing_indexes = inspector.get_indexes("tag") + + print(f"Primary Key: {existing_pk}") + print(f"Unique Constraints: {unique_constraints}") + print(f"Indexes: {existing_indexes}") + + with op.batch_alter_table("tag", schema=None) as batch_op: + # Drop existing primary key constraint if it exists + if existing_pk and existing_pk.get("constrained_columns"): + pk_name = existing_pk.get("name") + if pk_name: + print(f"Dropping primary key constraint: {pk_name}") + batch_op.drop_constraint(pk_name, type_="primary") + + # Now create the new primary key with the combination of 'id' and 'user_id' + print("Creating new primary key with 'id' and 'user_id'.") + batch_op.create_primary_key("pk_id_user_id", ["id", "user_id"]) + + # Drop unique constraints that could conflict with the new primary key + for constraint in unique_constraints: + if ( + constraint["name"] == "uq_id_user_id" + ): # Adjust this name according to what is actually returned by the inspector + print(f"Dropping unique constraint: {constraint['name']}") + batch_op.drop_constraint(constraint["name"], type_="unique") + + for index in existing_indexes: + if index["unique"]: + if not any( + constraint["name"] == index["name"] + for constraint in unique_constraints + ): + # You are attempting to drop unique indexes + print(f"Dropping unique index: {index['name']}") + batch_op.drop_index(index["name"]) + + +def downgrade(): + conn = op.get_bind() + inspector = Inspector.from_engine(conn) + + current_pk = inspector.get_pk_constraint("tag") + + with op.batch_alter_table("tag", schema=None) as batch_op: + # Drop the current primary key first, if it matches the one we know we added in upgrade + if current_pk and "pk_id_user_id" == current_pk.get("name"): + batch_op.drop_constraint("pk_id_user_id", type_="primary") + + # Restore the original primary key + batch_op.create_primary_key("pk_id", ["id"]) + + # Since primary key on just 'id' is restored, we now add back any unique constraints if necessary + batch_op.create_unique_constraint("uq_id_user_id", ["id", "user_id"]) diff --git a/backend/open_webui/migrations/versions/4ace53fd72c8_update_folder_table_datetime.py b/backend/open_webui/migrations/versions/4ace53fd72c8_update_folder_table_datetime.py new file mode 100644 index 0000000..16f7967 --- /dev/null +++ b/backend/open_webui/migrations/versions/4ace53fd72c8_update_folder_table_datetime.py @@ -0,0 +1,67 @@ +"""Update folder table and change DateTime to BigInteger for timestamp fields + +Revision ID: 4ace53fd72c8 +Revises: af906e964978 +Create Date: 2024-10-23 03:00:00.000000 + +""" + +from alembic import op +import sqlalchemy as sa + +revision = "4ace53fd72c8" +down_revision = "af906e964978" +branch_labels = None +depends_on = None + + +def upgrade(): + # Perform safe alterations using batch operation + with op.batch_alter_table("folder", schema=None) as batch_op: + # Step 1: Remove server defaults for created_at and updated_at + batch_op.alter_column( + "created_at", + server_default=None, # Removing server default + ) + batch_op.alter_column( + "updated_at", + server_default=None, # Removing server default + ) + + # Step 2: Change the column types to BigInteger for created_at + batch_op.alter_column( + "created_at", + type_=sa.BigInteger(), + existing_type=sa.DateTime(), + existing_nullable=False, + postgresql_using="extract(epoch from created_at)::bigint", # Conversion for PostgreSQL + ) + + # Change the column types to BigInteger for updated_at + batch_op.alter_column( + "updated_at", + type_=sa.BigInteger(), + existing_type=sa.DateTime(), + existing_nullable=False, + postgresql_using="extract(epoch from updated_at)::bigint", # Conversion for PostgreSQL + ) + + +def downgrade(): + # Downgrade: Convert columns back to DateTime and restore defaults + with op.batch_alter_table("folder", schema=None) as batch_op: + batch_op.alter_column( + "created_at", + type_=sa.DateTime(), + existing_type=sa.BigInteger(), + existing_nullable=False, + server_default=sa.func.now(), # Restoring server default on downgrade + ) + batch_op.alter_column( + "updated_at", + type_=sa.DateTime(), + existing_type=sa.BigInteger(), + existing_nullable=False, + server_default=sa.func.now(), # Restoring server default on downgrade + onupdate=sa.func.now(), # Restoring onupdate behavior if it was there + ) diff --git a/backend/open_webui/migrations/versions/57c599a3cb57_add_channel_table.py b/backend/open_webui/migrations/versions/57c599a3cb57_add_channel_table.py new file mode 100644 index 0000000..54176dc --- /dev/null +++ b/backend/open_webui/migrations/versions/57c599a3cb57_add_channel_table.py @@ -0,0 +1,48 @@ +"""Add channel table + +Revision ID: 57c599a3cb57 +Revises: 922e7a387820 +Create Date: 2024-12-22 03:00:00.000000 + +""" + +from alembic import op +import sqlalchemy as sa + +revision = "57c599a3cb57" +down_revision = "922e7a387820" +branch_labels = None +depends_on = None + + +def upgrade(): + op.create_table( + "channel", + sa.Column("id", sa.Text(), nullable=False, primary_key=True, unique=True), + sa.Column("user_id", sa.Text()), + sa.Column("name", sa.Text()), + sa.Column("description", sa.Text(), nullable=True), + sa.Column("data", sa.JSON(), nullable=True), + sa.Column("meta", sa.JSON(), nullable=True), + sa.Column("access_control", sa.JSON(), nullable=True), + sa.Column("created_at", sa.BigInteger(), nullable=True), + sa.Column("updated_at", sa.BigInteger(), nullable=True), + ) + + op.create_table( + "message", + sa.Column("id", sa.Text(), nullable=False, primary_key=True, unique=True), + sa.Column("user_id", sa.Text()), + sa.Column("channel_id", sa.Text(), nullable=True), + sa.Column("content", sa.Text()), + sa.Column("data", sa.JSON(), nullable=True), + sa.Column("meta", sa.JSON(), nullable=True), + sa.Column("created_at", sa.BigInteger(), nullable=True), + sa.Column("updated_at", sa.BigInteger(), nullable=True), + ) + + +def downgrade(): + op.drop_table("channel") + + op.drop_table("message") diff --git a/backend/open_webui/migrations/versions/6a39f3d8e55c_add_knowledge_table.py b/backend/open_webui/migrations/versions/6a39f3d8e55c_add_knowledge_table.py new file mode 100644 index 0000000..881e6ae --- /dev/null +++ b/backend/open_webui/migrations/versions/6a39f3d8e55c_add_knowledge_table.py @@ -0,0 +1,80 @@ +"""Add knowledge table + +Revision ID: 6a39f3d8e55c +Revises: c0fbf31ca0db +Create Date: 2024-10-01 14:02:35.241684 + +""" + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.sql import table, column, select +import json + + +revision = "6a39f3d8e55c" +down_revision = "c0fbf31ca0db" +branch_labels = None +depends_on = None + + +def upgrade(): + # Creating the 'knowledge' table + print("Creating knowledge table") + knowledge_table = op.create_table( + "knowledge", + sa.Column("id", sa.Text(), primary_key=True), + sa.Column("user_id", sa.Text(), nullable=False), + sa.Column("name", sa.Text(), nullable=False), + sa.Column("description", sa.Text(), nullable=True), + sa.Column("data", sa.JSON(), nullable=True), + sa.Column("meta", sa.JSON(), nullable=True), + sa.Column("created_at", sa.BigInteger(), nullable=False), + sa.Column("updated_at", sa.BigInteger(), nullable=True), + ) + + print("Migrating data from document table to knowledge table") + # Representation of the existing 'document' table + document_table = table( + "document", + column("collection_name", sa.String()), + column("user_id", sa.String()), + column("name", sa.String()), + column("title", sa.Text()), + column("content", sa.Text()), + column("timestamp", sa.BigInteger()), + ) + + # Select all from existing document table + documents = op.get_bind().execute( + select( + document_table.c.collection_name, + document_table.c.user_id, + document_table.c.name, + document_table.c.title, + document_table.c.content, + document_table.c.timestamp, + ) + ) + + # Insert data into knowledge table from document table + for doc in documents: + op.get_bind().execute( + knowledge_table.insert().values( + id=doc.collection_name, + user_id=doc.user_id, + description=doc.name, + meta={ + "legacy": True, + "document": True, + "tags": json.loads(doc.content or "{}").get("tags", []), + }, + name=doc.title, + created_at=doc.timestamp, + updated_at=doc.timestamp, # using created_at for both created_at and updated_at in project + ) + ) + + +def downgrade(): + op.drop_table("knowledge") diff --git a/backend/open_webui/migrations/versions/7826ab40b532_update_file_table.py b/backend/open_webui/migrations/versions/7826ab40b532_update_file_table.py new file mode 100644 index 0000000..c8afe9d --- /dev/null +++ b/backend/open_webui/migrations/versions/7826ab40b532_update_file_table.py @@ -0,0 +1,26 @@ +"""Update file table + +Revision ID: 7826ab40b532 +Revises: 57c599a3cb57 +Create Date: 2024-12-23 03:00:00.000000 + +""" + +from alembic import op +import sqlalchemy as sa + +revision = "7826ab40b532" +down_revision = "57c599a3cb57" +branch_labels = None +depends_on = None + + +def upgrade(): + op.add_column( + "file", + sa.Column("access_control", sa.JSON(), nullable=True), + ) + + +def downgrade(): + op.drop_column("file", "access_control") diff --git a/backend/open_webui/migrations/versions/7e5b5dc7342b_init.py b/backend/open_webui/migrations/versions/7e5b5dc7342b_init.py new file mode 100644 index 0000000..9e56282 --- /dev/null +++ b/backend/open_webui/migrations/versions/7e5b5dc7342b_init.py @@ -0,0 +1,204 @@ +"""init + +Revision ID: 7e5b5dc7342b +Revises: +Create Date: 2024-06-24 13:15:33.808998 + +""" + +from typing import Sequence, Union + +import sqlalchemy as sa +from alembic import op + +import open_webui.internal.db +from open_webui.internal.db import JSONField +from open_webui.migrations.util import get_existing_tables + +# revision identifiers, used by Alembic. +revision: str = "7e5b5dc7342b" +down_revision: Union[str, None] = None +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + existing_tables = set(get_existing_tables()) + + # ### commands auto generated by Alembic - please adjust! ### + if "auth" not in existing_tables: + op.create_table( + "auth", + sa.Column("id", sa.String(), nullable=False), + sa.Column("email", sa.String(), nullable=True), + sa.Column("password", sa.Text(), nullable=True), + sa.Column("active", sa.Boolean(), nullable=True), + sa.PrimaryKeyConstraint("id"), + ) + + if "chat" not in existing_tables: + op.create_table( + "chat", + sa.Column("id", sa.String(), nullable=False), + sa.Column("user_id", sa.String(), nullable=True), + sa.Column("title", sa.Text(), nullable=True), + sa.Column("chat", sa.Text(), nullable=True), + sa.Column("created_at", sa.BigInteger(), nullable=True), + sa.Column("updated_at", sa.BigInteger(), nullable=True), + sa.Column("share_id", sa.Text(), nullable=True), + sa.Column("archived", sa.Boolean(), nullable=True), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("share_id"), + ) + + if "chatidtag" not in existing_tables: + op.create_table( + "chatidtag", + sa.Column("id", sa.String(), nullable=False), + sa.Column("tag_name", sa.String(), nullable=True), + sa.Column("chat_id", sa.String(), nullable=True), + sa.Column("user_id", sa.String(), nullable=True), + sa.Column("timestamp", sa.BigInteger(), nullable=True), + sa.PrimaryKeyConstraint("id"), + ) + + if "document" not in existing_tables: + op.create_table( + "document", + sa.Column("collection_name", sa.String(), nullable=False), + sa.Column("name", sa.String(), nullable=True), + sa.Column("title", sa.Text(), nullable=True), + sa.Column("filename", sa.Text(), nullable=True), + sa.Column("content", sa.Text(), nullable=True), + sa.Column("user_id", sa.String(), nullable=True), + sa.Column("timestamp", sa.BigInteger(), nullable=True), + sa.PrimaryKeyConstraint("collection_name"), + sa.UniqueConstraint("name"), + ) + + if "file" not in existing_tables: + op.create_table( + "file", + sa.Column("id", sa.String(), nullable=False), + sa.Column("user_id", sa.String(), nullable=True), + sa.Column("filename", sa.Text(), nullable=True), + sa.Column("meta", JSONField(), nullable=True), + sa.Column("created_at", sa.BigInteger(), nullable=True), + sa.PrimaryKeyConstraint("id"), + ) + + if "function" not in existing_tables: + op.create_table( + "function", + sa.Column("id", sa.String(), nullable=False), + sa.Column("user_id", sa.String(), nullable=True), + sa.Column("name", sa.Text(), nullable=True), + sa.Column("type", sa.Text(), nullable=True), + sa.Column("content", sa.Text(), nullable=True), + sa.Column("meta", JSONField(), nullable=True), + sa.Column("valves", JSONField(), nullable=True), + sa.Column("is_active", sa.Boolean(), nullable=True), + sa.Column("is_global", sa.Boolean(), nullable=True), + sa.Column("updated_at", sa.BigInteger(), nullable=True), + sa.Column("created_at", sa.BigInteger(), nullable=True), + sa.PrimaryKeyConstraint("id"), + ) + + if "memory" not in existing_tables: + op.create_table( + "memory", + sa.Column("id", sa.String(), nullable=False), + sa.Column("user_id", sa.String(), nullable=True), + sa.Column("content", sa.Text(), nullable=True), + sa.Column("updated_at", sa.BigInteger(), nullable=True), + sa.Column("created_at", sa.BigInteger(), nullable=True), + sa.PrimaryKeyConstraint("id"), + ) + + if "model" not in existing_tables: + op.create_table( + "model", + sa.Column("id", sa.Text(), nullable=False), + sa.Column("user_id", sa.Text(), nullable=True), + sa.Column("base_model_id", sa.Text(), nullable=True), + sa.Column("name", sa.Text(), nullable=True), + sa.Column("params", JSONField(), nullable=True), + sa.Column("meta", JSONField(), nullable=True), + sa.Column("updated_at", sa.BigInteger(), nullable=True), + sa.Column("created_at", sa.BigInteger(), nullable=True), + sa.PrimaryKeyConstraint("id"), + ) + + if "prompt" not in existing_tables: + op.create_table( + "prompt", + sa.Column("command", sa.String(), nullable=False), + sa.Column("user_id", sa.String(), nullable=True), + sa.Column("title", sa.Text(), nullable=True), + sa.Column("content", sa.Text(), nullable=True), + sa.Column("timestamp", sa.BigInteger(), nullable=True), + sa.PrimaryKeyConstraint("command"), + ) + + if "tag" not in existing_tables: + op.create_table( + "tag", + sa.Column("id", sa.String(), nullable=False), + sa.Column("name", sa.String(), nullable=True), + sa.Column("user_id", sa.String(), nullable=True), + sa.Column("data", sa.Text(), nullable=True), + sa.PrimaryKeyConstraint("id"), + ) + + if "tool" not in existing_tables: + op.create_table( + "tool", + sa.Column("id", sa.String(), nullable=False), + sa.Column("user_id", sa.String(), nullable=True), + sa.Column("name", sa.Text(), nullable=True), + sa.Column("content", sa.Text(), nullable=True), + sa.Column("specs", JSONField(), nullable=True), + sa.Column("meta", JSONField(), nullable=True), + sa.Column("valves", JSONField(), nullable=True), + sa.Column("updated_at", sa.BigInteger(), nullable=True), + sa.Column("created_at", sa.BigInteger(), nullable=True), + sa.PrimaryKeyConstraint("id"), + ) + + if "user" not in existing_tables: + op.create_table( + "user", + sa.Column("id", sa.String(), nullable=False), + sa.Column("name", sa.String(), nullable=True), + sa.Column("email", sa.String(), nullable=True), + sa.Column("role", sa.String(), nullable=True), + sa.Column("profile_image_url", sa.Text(), nullable=True), + sa.Column("last_active_at", sa.BigInteger(), nullable=True), + sa.Column("updated_at", sa.BigInteger(), nullable=True), + sa.Column("created_at", sa.BigInteger(), nullable=True), + sa.Column("api_key", sa.String(), nullable=True), + sa.Column("settings", JSONField(), nullable=True), + sa.Column("info", JSONField(), nullable=True), + sa.Column("oauth_sub", sa.Text(), nullable=True), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("api_key"), + sa.UniqueConstraint("oauth_sub"), + ) + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table("user") + op.drop_table("tool") + op.drop_table("tag") + op.drop_table("prompt") + op.drop_table("model") + op.drop_table("memory") + op.drop_table("function") + op.drop_table("file") + op.drop_table("document") + op.drop_table("chatidtag") + op.drop_table("chat") + op.drop_table("auth") + # ### end Alembic commands ### diff --git a/backend/open_webui/migrations/versions/922e7a387820_add_group_table.py b/backend/open_webui/migrations/versions/922e7a387820_add_group_table.py new file mode 100644 index 0000000..a752115 --- /dev/null +++ b/backend/open_webui/migrations/versions/922e7a387820_add_group_table.py @@ -0,0 +1,85 @@ +"""Add group table + +Revision ID: 922e7a387820 +Revises: 4ace53fd72c8 +Create Date: 2024-11-14 03:00:00.000000 + +""" + +from alembic import op +import sqlalchemy as sa + +revision = "922e7a387820" +down_revision = "4ace53fd72c8" +branch_labels = None +depends_on = None + + +def upgrade(): + op.create_table( + "group", + sa.Column("id", sa.Text(), nullable=False, primary_key=True, unique=True), + sa.Column("user_id", sa.Text(), nullable=True), + sa.Column("name", sa.Text(), nullable=True), + sa.Column("description", sa.Text(), nullable=True), + sa.Column("data", sa.JSON(), nullable=True), + sa.Column("meta", sa.JSON(), nullable=True), + sa.Column("permissions", sa.JSON(), nullable=True), + sa.Column("user_ids", sa.JSON(), nullable=True), + sa.Column("created_at", sa.BigInteger(), nullable=True), + sa.Column("updated_at", sa.BigInteger(), nullable=True), + ) + + # Add 'access_control' column to 'model' table + op.add_column( + "model", + sa.Column("access_control", sa.JSON(), nullable=True), + ) + + # Add 'is_active' column to 'model' table + op.add_column( + "model", + sa.Column( + "is_active", + sa.Boolean(), + nullable=False, + server_default=sa.sql.expression.true(), + ), + ) + + # Add 'access_control' column to 'knowledge' table + op.add_column( + "knowledge", + sa.Column("access_control", sa.JSON(), nullable=True), + ) + + # Add 'access_control' column to 'prompt' table + op.add_column( + "prompt", + sa.Column("access_control", sa.JSON(), nullable=True), + ) + + # Add 'access_control' column to 'tools' table + op.add_column( + "tool", + sa.Column("access_control", sa.JSON(), nullable=True), + ) + + +def downgrade(): + op.drop_table("group") + + # Drop 'access_control' column from 'model' table + op.drop_column("model", "access_control") + + # Drop 'is_active' column from 'model' table + op.drop_column("model", "is_active") + + # Drop 'access_control' column from 'knowledge' table + op.drop_column("knowledge", "access_control") + + # Drop 'access_control' column from 'prompt' table + op.drop_column("prompt", "access_control") + + # Drop 'access_control' column from 'tools' table + op.drop_column("tool", "access_control") diff --git a/backend/open_webui/migrations/versions/af906e964978_add_feedback_table.py b/backend/open_webui/migrations/versions/af906e964978_add_feedback_table.py new file mode 100644 index 0000000..9116aa3 --- /dev/null +++ b/backend/open_webui/migrations/versions/af906e964978_add_feedback_table.py @@ -0,0 +1,51 @@ +"""Add feedback table + +Revision ID: af906e964978 +Revises: c29facfe716b +Create Date: 2024-10-20 17:02:35.241684 + +""" + +from alembic import op +import sqlalchemy as sa + +# Revision identifiers, used by Alembic. +revision = "af906e964978" +down_revision = "c29facfe716b" +branch_labels = None +depends_on = None + + +def upgrade(): + # ### Create feedback table ### + op.create_table( + "feedback", + sa.Column( + "id", sa.Text(), primary_key=True + ), # Unique identifier for each feedback (TEXT type) + sa.Column( + "user_id", sa.Text(), nullable=True + ), # ID of the user providing the feedback (TEXT type) + sa.Column( + "version", sa.BigInteger(), default=0 + ), # Version of feedback (BIGINT type) + sa.Column("type", sa.Text(), nullable=True), # Type of feedback (TEXT type) + sa.Column("data", sa.JSON(), nullable=True), # Feedback data (JSON type) + sa.Column( + "meta", sa.JSON(), nullable=True + ), # Metadata for feedback (JSON type) + sa.Column( + "snapshot", sa.JSON(), nullable=True + ), # snapshot data for feedback (JSON type) + sa.Column( + "created_at", sa.BigInteger(), nullable=False + ), # Feedback creation timestamp (BIGINT representing epoch) + sa.Column( + "updated_at", sa.BigInteger(), nullable=False + ), # Feedback update timestamp (BIGINT representing epoch) + ) + + +def downgrade(): + # ### Drop feedback table ### + op.drop_table("feedback") diff --git a/backend/open_webui/migrations/versions/c0fbf31ca0db_update_file_table.py b/backend/open_webui/migrations/versions/c0fbf31ca0db_update_file_table.py new file mode 100644 index 0000000..5f7f2ab --- /dev/null +++ b/backend/open_webui/migrations/versions/c0fbf31ca0db_update_file_table.py @@ -0,0 +1,32 @@ +"""Update file table + +Revision ID: c0fbf31ca0db +Revises: ca81bd47c050 +Create Date: 2024-09-20 15:26:35.241684 + +""" + +from typing import Sequence, Union + +import sqlalchemy as sa +from alembic import op + +# revision identifiers, used by Alembic. +revision: str = "c0fbf31ca0db" +down_revision: Union[str, None] = "ca81bd47c050" +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column("file", sa.Column("hash", sa.Text(), nullable=True)) + op.add_column("file", sa.Column("data", sa.JSON(), nullable=True)) + op.add_column("file", sa.Column("updated_at", sa.BigInteger(), nullable=True)) + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column("file", "updated_at") + op.drop_column("file", "data") + op.drop_column("file", "hash") diff --git a/backend/open_webui/migrations/versions/c29facfe716b_update_file_table_path.py b/backend/open_webui/migrations/versions/c29facfe716b_update_file_table_path.py new file mode 100644 index 0000000..de82854 --- /dev/null +++ b/backend/open_webui/migrations/versions/c29facfe716b_update_file_table_path.py @@ -0,0 +1,79 @@ +"""Update file table path + +Revision ID: c29facfe716b +Revises: c69f45358db4 +Create Date: 2024-10-20 17:02:35.241684 + +""" + +from alembic import op +import sqlalchemy as sa +import json +from sqlalchemy.sql import table, column +from sqlalchemy import String, Text, JSON, and_ + + +revision = "c29facfe716b" +down_revision = "c69f45358db4" +branch_labels = None +depends_on = None + + +def upgrade(): + # 1. Add the `path` column to the "file" table. + op.add_column("file", sa.Column("path", sa.Text(), nullable=True)) + + # 2. Convert the `meta` column from Text/JSONField to `JSON()` + # Use Alembic's default batch_op for dialect compatibility. + with op.batch_alter_table("file", schema=None) as batch_op: + batch_op.alter_column( + "meta", + type_=sa.JSON(), + existing_type=sa.Text(), + existing_nullable=True, + nullable=True, + postgresql_using="meta::json", + ) + + # 3. Migrate legacy data from `meta` JSONField + # Fetch and process `meta` data from the table, add values to the new `path` column as necessary. + # We will use SQLAlchemy core bindings to ensure safety across different databases. + + file_table = table( + "file", column("id", String), column("meta", JSON), column("path", Text) + ) + + # Create connection to the database + connection = op.get_bind() + + # Get the rows where `meta` has a path and `path` column is null (new column) + # Loop through each row in the result set to update the path + results = connection.execute( + sa.select(file_table.c.id, file_table.c.meta).where( + and_(file_table.c.path.is_(None), file_table.c.meta.isnot(None)) + ) + ).fetchall() + + # Iterate over each row to extract and update the `path` from `meta` column + for row in results: + if "path" in row.meta: + # Extract the `path` field from the `meta` JSON + path = row.meta.get("path") + + # Update the `file` table with the new `path` value + connection.execute( + file_table.update() + .where(file_table.c.id == row.id) + .values({"path": path}) + ) + + +def downgrade(): + # 1. Remove the `path` column + op.drop_column("file", "path") + + # 2. Revert the `meta` column back to Text/JSONField + with op.batch_alter_table("file", schema=None) as batch_op: + batch_op.alter_column( + "meta", type_=sa.Text(), existing_type=sa.JSON(), existing_nullable=True + ) diff --git a/backend/open_webui/migrations/versions/c69f45358db4_add_folder_table.py b/backend/open_webui/migrations/versions/c69f45358db4_add_folder_table.py new file mode 100644 index 0000000..83e0dc2 --- /dev/null +++ b/backend/open_webui/migrations/versions/c69f45358db4_add_folder_table.py @@ -0,0 +1,50 @@ +"""Add folder table + +Revision ID: c69f45358db4 +Revises: 3ab32c4b8f59 +Create Date: 2024-10-16 02:02:35.241684 + +""" + +from alembic import op +import sqlalchemy as sa + +revision = "c69f45358db4" +down_revision = "3ab32c4b8f59" +branch_labels = None +depends_on = None + + +def upgrade(): + op.create_table( + "folder", + sa.Column("id", sa.Text(), nullable=False), + sa.Column("parent_id", sa.Text(), nullable=True), + sa.Column("user_id", sa.Text(), nullable=False), + sa.Column("name", sa.Text(), nullable=False), + sa.Column("items", sa.JSON(), nullable=True), + sa.Column("meta", sa.JSON(), nullable=True), + sa.Column("is_expanded", sa.Boolean(), default=False, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.func.now(), nullable=False + ), + sa.Column( + "updated_at", + sa.DateTime(), + nullable=False, + server_default=sa.func.now(), + onupdate=sa.func.now(), + ), + sa.PrimaryKeyConstraint("id", "user_id"), + ) + + op.add_column( + "chat", + sa.Column("folder_id", sa.Text(), nullable=True), + ) + + +def downgrade(): + op.drop_column("chat", "folder_id") + + op.drop_table("folder") diff --git a/backend/open_webui/migrations/versions/ca81bd47c050_add_config_table.py b/backend/open_webui/migrations/versions/ca81bd47c050_add_config_table.py new file mode 100644 index 0000000..1540aa6 --- /dev/null +++ b/backend/open_webui/migrations/versions/ca81bd47c050_add_config_table.py @@ -0,0 +1,41 @@ +"""Add config table + +Revision ID: ca81bd47c050 +Revises: 7e5b5dc7342b +Create Date: 2024-08-25 15:26:35.241684 + +""" + +from typing import Sequence, Union + +import sqlalchemy as sa +from alembic import op + +# revision identifiers, used by Alembic. +revision: str = "ca81bd47c050" +down_revision: Union[str, None] = "7e5b5dc7342b" +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade(): + op.create_table( + "config", + sa.Column("id", sa.Integer, primary_key=True), + sa.Column("data", sa.JSON(), nullable=False), + sa.Column("version", sa.Integer, nullable=False), + sa.Column( + "created_at", sa.DateTime(), nullable=False, server_default=sa.func.now() + ), + sa.Column( + "updated_at", + sa.DateTime(), + nullable=True, + server_default=sa.func.now(), + onupdate=sa.func.now(), + ), + ) + + +def downgrade(): + op.drop_table("config") diff --git a/backend/open_webui/models/auths.py b/backend/open_webui/models/auths.py new file mode 100644 index 0000000..f07c36c --- /dev/null +++ b/backend/open_webui/models/auths.py @@ -0,0 +1,206 @@ +import logging +import uuid +from typing import Optional + +from open_webui.internal.db import Base, get_db +from open_webui.models.users import UserModel, Users +from open_webui.env import SRC_LOG_LEVELS +from pydantic import BaseModel +from sqlalchemy import Boolean, Column, String, Text +from open_webui.utils.auth import verify_password + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MODELS"]) + +#################### +# DB MODEL +#################### + + +class Auth(Base): + __tablename__ = "auth" + + id = Column(String, primary_key=True) + email = Column(String) + password = Column(Text) + active = Column(Boolean) + + +class AuthModel(BaseModel): + id: str + email: str + password: str + active: bool = True + + +#################### +# Forms +#################### + + +class Token(BaseModel): + token: str + token_type: str + + +class ApiKey(BaseModel): + api_key: Optional[str] = None + + +class UserResponse(BaseModel): + id: str + email: str + name: str + role: str + profile_image_url: str + + +class SigninResponse(Token, UserResponse): + pass + + +class SigninForm(BaseModel): + email: str + password: str + + +class LdapForm(BaseModel): + user: str + password: str + + +class ProfileImageUrlForm(BaseModel): + profile_image_url: str + + +class UpdateProfileForm(BaseModel): + profile_image_url: str + name: str + + +class UpdatePasswordForm(BaseModel): + password: str + new_password: str + + +class SignupForm(BaseModel): + name: str + email: str + password: str + profile_image_url: Optional[str] = "/user.png" + + +class AddUserForm(SignupForm): + role: Optional[str] = "pending" + + +class AuthsTable: + def insert_new_auth( + self, + email: str, + password: str, + name: str, + profile_image_url: str = "/user.png", + role: str = "pending", + oauth_sub: Optional[str] = None, + ) -> Optional[UserModel]: + with get_db() as db: + log.info("insert_new_auth") + + id = str(uuid.uuid4()) + + auth = AuthModel( + **{"id": id, "email": email, "password": password, "active": True} + ) + result = Auth(**auth.model_dump()) + db.add(result) + + user = Users.insert_new_user( + id, name, email, profile_image_url, role, oauth_sub + ) + + db.commit() + db.refresh(result) + + if result and user: + return user + else: + return None + + def authenticate_user(self, email: str, password: str) -> Optional[UserModel]: + log.info(f"authenticate_user: {email}") + try: + with get_db() as db: + auth = db.query(Auth).filter_by(email=email, active=True).first() + if auth: + if verify_password(password, auth.password): + user = Users.get_user_by_id(auth.id) + return user + else: + return None + else: + return None + except Exception: + return None + + def authenticate_user_by_api_key(self, api_key: str) -> Optional[UserModel]: + log.info(f"authenticate_user_by_api_key: {api_key}") + # if no api_key, return None + if not api_key: + return None + + try: + user = Users.get_user_by_api_key(api_key) + return user if user else None + except Exception: + return False + + def authenticate_user_by_trusted_header(self, email: str) -> Optional[UserModel]: + log.info(f"authenticate_user_by_trusted_header: {email}") + try: + with get_db() as db: + auth = db.query(Auth).filter_by(email=email, active=True).first() + if auth: + user = Users.get_user_by_id(auth.id) + return user + except Exception: + return None + + def update_user_password_by_id(self, id: str, new_password: str) -> bool: + try: + with get_db() as db: + result = ( + db.query(Auth).filter_by(id=id).update({"password": new_password}) + ) + db.commit() + return True if result == 1 else False + except Exception: + return False + + def update_email_by_id(self, id: str, email: str) -> bool: + try: + with get_db() as db: + result = db.query(Auth).filter_by(id=id).update({"email": email}) + db.commit() + return True if result == 1 else False + except Exception: + return False + + def delete_auth_by_id(self, id: str) -> bool: + try: + with get_db() as db: + # Delete User + result = Users.delete_user_by_id(id) + + if result: + db.query(Auth).filter_by(id=id).delete() + db.commit() + + return True + else: + return False + except Exception: + return False + + +Auths = AuthsTable() diff --git a/backend/open_webui/models/channels.py b/backend/open_webui/models/channels.py new file mode 100644 index 0000000..92f238c --- /dev/null +++ b/backend/open_webui/models/channels.py @@ -0,0 +1,136 @@ +import json +import time +import uuid +from typing import Optional + +from open_webui.internal.db import Base, get_db +from open_webui.utils.access_control import has_access + +from pydantic import BaseModel, ConfigDict +from sqlalchemy import BigInteger, Boolean, Column, String, Text, JSON +from sqlalchemy import or_, func, select, and_, text +from sqlalchemy.sql import exists + +#################### +# Channel DB Schema +#################### + + +class Channel(Base): + __tablename__ = "channel" + + id = Column(Text, primary_key=True) + user_id = Column(Text) + type = Column(Text, nullable=True) + + name = Column(Text) + description = Column(Text, nullable=True) + + data = Column(JSON, nullable=True) + meta = Column(JSON, nullable=True) + access_control = Column(JSON, nullable=True) + + created_at = Column(BigInteger) + updated_at = Column(BigInteger) + + +class ChannelModel(BaseModel): + model_config = ConfigDict(from_attributes=True) + + id: str + user_id: str + type: Optional[str] = None + + name: str + description: Optional[str] = None + + data: Optional[dict] = None + meta: Optional[dict] = None + access_control: Optional[dict] = None + + created_at: int # timestamp in epoch + updated_at: int # timestamp in epoch + + +#################### +# Forms +#################### + + +class ChannelForm(BaseModel): + name: str + description: Optional[str] = None + data: Optional[dict] = None + meta: Optional[dict] = None + access_control: Optional[dict] = None + + +class ChannelTable: + def insert_new_channel( + self, type: Optional[str], form_data: ChannelForm, user_id: str + ) -> Optional[ChannelModel]: + with get_db() as db: + channel = ChannelModel( + **{ + **form_data.model_dump(), + "type": type, + "name": form_data.name.lower(), + "id": str(uuid.uuid4()), + "user_id": user_id, + "created_at": int(time.time_ns()), + "updated_at": int(time.time_ns()), + } + ) + + new_channel = Channel(**channel.model_dump()) + + db.add(new_channel) + db.commit() + return channel + + def get_channels(self) -> list[ChannelModel]: + with get_db() as db: + channels = db.query(Channel).all() + return [ChannelModel.model_validate(channel) for channel in channels] + + def get_channels_by_user_id( + self, user_id: str, permission: str = "read" + ) -> list[ChannelModel]: + channels = self.get_channels() + return [ + channel + for channel in channels + if channel.user_id == user_id + or has_access(user_id, permission, channel.access_control) + ] + + def get_channel_by_id(self, id: str) -> Optional[ChannelModel]: + with get_db() as db: + channel = db.query(Channel).filter(Channel.id == id).first() + return ChannelModel.model_validate(channel) if channel else None + + def update_channel_by_id( + self, id: str, form_data: ChannelForm + ) -> Optional[ChannelModel]: + with get_db() as db: + channel = db.query(Channel).filter(Channel.id == id).first() + if not channel: + return None + + channel.name = form_data.name + channel.data = form_data.data + channel.meta = form_data.meta + channel.access_control = form_data.access_control + channel.updated_at = int(time.time_ns()) + + db.commit() + return ChannelModel.model_validate(channel) if channel else None + + def delete_channel_by_id(self, id: str): + with get_db() as db: + db.query(Channel).filter(Channel.id == id).delete() + db.commit() + return True + + +Channels = ChannelTable() diff --git a/backend/open_webui/models/chats.py b/backend/open_webui/models/chats.py new file mode 100644 index 0000000..a222d22 --- /dev/null +++ b/backend/open_webui/models/chats.py @@ -0,0 +1,912 @@ +import logging +import json +import time +import uuid +from typing import Optional + +from open_webui.internal.db import Base, get_db +from open_webui.models.tags import TagModel, Tag, Tags +from open_webui.env import SRC_LOG_LEVELS + +from pydantic import BaseModel, ConfigDict +from sqlalchemy import BigInteger, Boolean, Column, String, Text, JSON +from sqlalchemy import or_, func, select, and_, text +from sqlalchemy.sql import exists + +#################### +# Chat DB Schema +#################### + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MODELS"]) + + +class Chat(Base): + __tablename__ = "chat" + + id = Column(String, primary_key=True) + user_id = Column(String) + title = Column(Text) + chat = Column(JSON) + + created_at = Column(BigInteger) + updated_at = Column(BigInteger) + + share_id = Column(Text, unique=True, nullable=True) + archived = Column(Boolean, default=False) + pinned = Column(Boolean, default=False, nullable=True) + + meta = Column(JSON, server_default="{}") + folder_id = Column(Text, nullable=True) + + +class ChatModel(BaseModel): + model_config = ConfigDict(from_attributes=True) + + id: str + user_id: str + title: str + chat: dict + + created_at: int # timestamp in epoch + updated_at: int # timestamp in epoch + + share_id: Optional[str] = None + archived: bool = False + pinned: Optional[bool] = False + + meta: dict = {} + folder_id: Optional[str] = None + + +#################### +# Forms +#################### + + +class ChatForm(BaseModel): + chat: dict + + +class ChatImportForm(ChatForm): + meta: Optional[dict] = {} + pinned: Optional[bool] = False + folder_id: Optional[str] = None + + +class ChatTitleMessagesForm(BaseModel): + title: str + messages: list[dict] + + +class ChatTitleForm(BaseModel): + title: str + + +class ChatResponse(BaseModel): + id: str + user_id: str + title: str + chat: dict + updated_at: int # timestamp in epoch + created_at: int # timestamp in epoch + share_id: Optional[str] = None # id of the chat to be shared + archived: bool + pinned: Optional[bool] = False + meta: dict = {} + folder_id: Optional[str] = None + + +class ChatTitleIdResponse(BaseModel): + id: str + title: str + updated_at: int + created_at: int + + +class ChatTable: + def insert_new_chat(self, user_id: str, form_data: ChatForm) -> Optional[ChatModel]: + with get_db() as db: + id = str(uuid.uuid4()) + chat = ChatModel( + **{ + "id": id, + "user_id": user_id, + "title": ( + form_data.chat["title"] + if "title" in form_data.chat + else "New Chat" + ), + "chat": form_data.chat, + "created_at": int(time.time()), + "updated_at": int(time.time()), + } + ) + + result = Chat(**chat.model_dump()) + db.add(result) + db.commit() + db.refresh(result) + return ChatModel.model_validate(result) if result else None + + def import_chat( + self, user_id: str, form_data: ChatImportForm + ) -> Optional[ChatModel]: + with get_db() as db: + id = str(uuid.uuid4()) + chat = ChatModel( + **{ + "id": id, + "user_id": user_id, + "title": ( + form_data.chat["title"] + if "title" in form_data.chat + else "New Chat" + ), + "chat": form_data.chat, + "meta": form_data.meta, + "pinned": form_data.pinned, + "folder_id": form_data.folder_id, + "created_at": int(time.time()), + "updated_at": int(time.time()), + } + ) + + result = Chat(**chat.model_dump()) + db.add(result) + db.commit() + db.refresh(result) + return ChatModel.model_validate(result) if result else None + + def update_chat_by_id(self, id: str, chat: dict) -> Optional[ChatModel]: + try: + with get_db() as db: + chat_item = db.get(Chat, id) + chat_item.chat = chat + chat_item.title = chat["title"] if "title" in chat else "New Chat" + chat_item.updated_at = int(time.time()) + db.commit() + db.refresh(chat_item) + + return ChatModel.model_validate(chat_item) + except Exception: + return None + + def update_chat_title_by_id(self, id: str, title: str) -> Optional[ChatModel]: + chat = self.get_chat_by_id(id) + if chat is None: + return None + + chat = chat.chat + chat["title"] = title + + return self.update_chat_by_id(id, chat) + + def update_chat_tags_by_id( + self, id: str, tags: list[str], user + ) -> Optional[ChatModel]: + chat = self.get_chat_by_id(id) + if chat is None: + return None + + self.delete_all_tags_by_id_and_user_id(id, user.id) + + for tag in chat.meta.get("tags", []): + if self.count_chats_by_tag_name_and_user_id(tag, user.id) == 0: + Tags.delete_tag_by_name_and_user_id(tag, user.id) + + for tag_name in tags: + if tag_name.lower() == "none": + continue + + self.add_chat_tag_by_id_and_user_id_and_tag_name(id, user.id, tag_name) + return self.get_chat_by_id(id) + + def get_chat_title_by_id(self, id: str) -> Optional[str]: + chat = self.get_chat_by_id(id) + if chat is None: + return None + + return chat.chat.get("title", "New Chat") + + def get_messages_by_chat_id(self, id: str) -> Optional[dict]: + chat = self.get_chat_by_id(id) + if chat is None: + return None + + return chat.chat.get("history", {}).get("messages", {}) or {} + + def get_message_by_id_and_message_id( + self, id: str, message_id: str + ) -> Optional[dict]: + chat = self.get_chat_by_id(id) + if chat is None: + return None + + return chat.chat.get("history", {}).get("messages", {}).get(message_id, {}) + + def upsert_message_to_chat_by_id_and_message_id( + self, id: str, message_id: str, message: dict + ) -> Optional[ChatModel]: + chat = self.get_chat_by_id(id) + if chat is None: + return None + + chat = chat.chat + history = chat.get("history", {}) + + if message_id in history.get("messages", {}): + history["messages"][message_id] = { + **history["messages"][message_id], + **message, + } + else: + history["messages"][message_id] = message + + history["currentId"] = message_id + + chat["history"] = history + return self.update_chat_by_id(id, chat) + + def add_message_status_to_chat_by_id_and_message_id( + self, id: str, message_id: str, status: dict + ) -> Optional[ChatModel]: + chat = self.get_chat_by_id(id) + if chat is None: + return None + + chat = chat.chat + history = chat.get("history", {}) + + if message_id in history.get("messages", {}): + status_history = history["messages"][message_id].get("statusHistory", []) + status_history.append(status) + history["messages"][message_id]["statusHistory"] = status_history + + chat["history"] = history + return self.update_chat_by_id(id, chat) + + def insert_shared_chat_by_chat_id(self, chat_id: str) -> Optional[ChatModel]: + with get_db() as db: + # Get the existing chat to share + chat = db.get(Chat, chat_id) + # Check if the chat is already shared + if chat.share_id: + return self.get_chat_by_id_and_user_id(chat.share_id, "shared") + # Create a new chat with the same data, but with a new ID + shared_chat = ChatModel( + **{ + "id": str(uuid.uuid4()), + "user_id": f"shared-{chat_id}", + "title": chat.title, + "chat": chat.chat, + "created_at": chat.created_at, + "updated_at": int(time.time()), + } + ) + shared_result = Chat(**shared_chat.model_dump()) + db.add(shared_result) + db.commit() + db.refresh(shared_result) + + # Update the original chat with the share_id + result = ( + db.query(Chat) + .filter_by(id=chat_id) + .update({"share_id": shared_chat.id}) + ) + db.commit() + return shared_chat if (shared_result and result) else None + + def update_shared_chat_by_chat_id(self, chat_id: str) -> Optional[ChatModel]: + try: + with get_db() as db: + chat = db.get(Chat, chat_id) + shared_chat = ( + db.query(Chat).filter_by(user_id=f"shared-{chat_id}").first() + ) + + if shared_chat is None: + return self.insert_shared_chat_by_chat_id(chat_id) + + shared_chat.title = chat.title + shared_chat.chat = chat.chat + + shared_chat.updated_at = int(time.time()) + db.commit() + db.refresh(shared_chat) + + return ChatModel.model_validate(shared_chat) + except Exception: + return None + + def delete_shared_chat_by_chat_id(self, chat_id: str) -> bool: + try: + with get_db() as db: + db.query(Chat).filter_by(user_id=f"shared-{chat_id}").delete() + db.commit() + + return True + except Exception: + return False + + def update_chat_share_id_by_id( + self, id: str, share_id: Optional[str] + ) -> Optional[ChatModel]: + try: + with get_db() as db: + chat = db.get(Chat, id) + chat.share_id = share_id + db.commit() + db.refresh(chat) + return ChatModel.model_validate(chat) + except Exception: + return None + + def toggle_chat_pinned_by_id(self, id: str) -> Optional[ChatModel]: + try: + with get_db() as db: + chat = db.get(Chat, id) + chat.pinned = not chat.pinned + chat.updated_at = int(time.time()) + db.commit() + db.refresh(chat) + return ChatModel.model_validate(chat) + except Exception: + return None + + def toggle_chat_archive_by_id(self, id: str) -> Optional[ChatModel]: + try: + with get_db() as db: + chat = db.get(Chat, id) + chat.archived = not chat.archived + chat.updated_at = int(time.time()) + db.commit() + db.refresh(chat) + return ChatModel.model_validate(chat) + except Exception: + return None + + def archive_all_chats_by_user_id(self, user_id: str) -> bool: + try: + with get_db() as db: + db.query(Chat).filter_by(user_id=user_id).update({"archived": True}) + db.commit() + return True + except Exception: + return False + + def get_archived_chat_list_by_user_id( + self, user_id: str, skip: int = 0, limit: int = 50 + ) -> list[ChatModel]: + with get_db() as db: + all_chats = ( + db.query(Chat) + .filter_by(user_id=user_id, archived=True) + .order_by(Chat.updated_at.desc()) + # .limit(limit).offset(skip) + .all() + ) + return [ChatModel.model_validate(chat) for chat in all_chats] + + def get_chat_list_by_user_id( + self, + user_id: str, + include_archived: bool = False, + skip: int = 0, + limit: int = 50, + ) -> list[ChatModel]: + with get_db() as db: + query = db.query(Chat).filter_by(user_id=user_id) + if not include_archived: + query = query.filter_by(archived=False) + + query = query.order_by(Chat.updated_at.desc()) + + if skip: + query = query.offset(skip) + if limit: + query = query.limit(limit) + + all_chats = query.all() + return [ChatModel.model_validate(chat) for chat in all_chats] + + def get_chat_title_id_list_by_user_id( + self, + user_id: str, + include_archived: bool = False, + skip: Optional[int] = None, + limit: Optional[int] = None, + ) -> list[ChatTitleIdResponse]: + with get_db() as db: + query = db.query(Chat).filter_by(user_id=user_id).filter_by(folder_id=None) + query = query.filter(or_(Chat.pinned == False, Chat.pinned == None)) + + if not include_archived: + query = query.filter_by(archived=False) + + query = query.order_by(Chat.updated_at.desc()).with_entities( + Chat.id, Chat.title, Chat.updated_at, Chat.created_at + ) + + if skip: + query = query.offset(skip) + if limit: + query = query.limit(limit) + + all_chats = query.all() + + # result has to be destrctured from sqlalchemy `row` and mapped to a dict since the `ChatModel`is not the returned dataclass. + return [ + ChatTitleIdResponse.model_validate( + { + "id": chat[0], + "title": chat[1], + "updated_at": chat[2], + "created_at": chat[3], + } + ) + for chat in all_chats + ] + + def get_chat_list_by_chat_ids( + self, chat_ids: list[str], skip: int = 0, limit: int = 50 + ) -> list[ChatModel]: + with get_db() as db: + all_chats = ( + db.query(Chat) + .filter(Chat.id.in_(chat_ids)) + .filter_by(archived=False) + .order_by(Chat.updated_at.desc()) + .all() + ) + return [ChatModel.model_validate(chat) for chat in all_chats] + + def get_chat_by_id(self, id: str) -> Optional[ChatModel]: + try: + with get_db() as db: + chat = db.get(Chat, id) + return ChatModel.model_validate(chat) + except Exception: + return None + + def get_chat_by_share_id(self, id: str) -> Optional[ChatModel]: + try: + with get_db() as db: + # it is possible that the shared link was deleted. hence, + # we check if the chat is still shared by checking if a chat with the share_id exists + chat = db.query(Chat).filter_by(share_id=id).first() + + if chat: + return self.get_chat_by_id(id) + else: + return None + except Exception: + return None + + def get_chat_by_id_and_user_id(self, id: str, user_id: str) -> Optional[ChatModel]: + try: + with get_db() as db: + chat = db.query(Chat).filter_by(id=id, user_id=user_id).first() + return ChatModel.model_validate(chat) + except Exception: + return None + + def get_chats(self, skip: int = 0, limit: int = 50) -> list[ChatModel]: + with get_db() as db: + all_chats = ( + db.query(Chat) + # .limit(limit).offset(skip) + .order_by(Chat.updated_at.desc()) + ) + return [ChatModel.model_validate(chat) for chat in all_chats] + + def get_chats_by_user_id(self, user_id: str) -> list[ChatModel]: + with get_db() as db: + all_chats = ( + db.query(Chat) + .filter_by(user_id=user_id) + .order_by(Chat.updated_at.desc()) + ) + return [ChatModel.model_validate(chat) for chat in all_chats] + + def get_pinned_chats_by_user_id(self, user_id: str) -> list[ChatModel]: + with get_db() as db: + all_chats = ( + db.query(Chat) + .filter_by(user_id=user_id, pinned=True, archived=False) + .order_by(Chat.updated_at.desc()) + ) + return [ChatModel.model_validate(chat) for chat in all_chats] + + def get_archived_chats_by_user_id(self, user_id: str) -> list[ChatModel]: + with get_db() as db: + all_chats = ( + db.query(Chat) + .filter_by(user_id=user_id, archived=True) + .order_by(Chat.updated_at.desc()) + ) + return [ChatModel.model_validate(chat) for chat in all_chats] + + def get_chats_by_user_id_and_search_text( + self, + user_id: str, + search_text: str, + include_archived: bool = False, + skip: int = 0, + limit: int = 60, + ) -> list[ChatModel]: + """ + Filters chats based on a search query using Python, allowing pagination using skip and limit. + """ + search_text = search_text.lower().strip() + + if not search_text: + return self.get_chat_list_by_user_id(user_id, include_archived, skip, limit) + + search_text_words = search_text.split(" ") + + # search_text might contain 'tag:tag_name' format so we need to extract the tag_name, split the search_text and remove the tags + tag_ids = [ + word.replace("tag:", "").replace(" ", "_").lower() + for word in search_text_words + if word.startswith("tag:") + ] + + search_text_words = [ + word for word in search_text_words if not word.startswith("tag:") + ] + + search_text = " ".join(search_text_words) + + with get_db() as db: + query = db.query(Chat).filter(Chat.user_id == user_id) + + if not include_archived: + query = query.filter(Chat.archived == False) + + query = query.order_by(Chat.updated_at.desc()) + + # Check if the database dialect is either 'sqlite' or 'postgresql' + dialect_name = db.bind.dialect.name + if dialect_name == "sqlite": + # SQLite case: using JSON1 extension for JSON searching + query = query.filter( + ( + Chat.title.ilike( + f"%{search_text}%" + ) # Case-insensitive search in title + | text( + """ + EXISTS ( + SELECT 1 + FROM json_each(Chat.chat, '$.messages') AS message + WHERE LOWER(message.value->>'content') LIKE '%' || :search_text || '%' + ) + """ + ) + ).params(search_text=search_text) + ) + + # Check if there are any tags to filter, it should have all the tags + if "none" in tag_ids: + query = query.filter( + text( + """ + NOT EXISTS ( + SELECT 1 + FROM json_each(Chat.meta, '$.tags') AS tag + ) + """ + ) + ) + elif tag_ids: + query = query.filter( + and_( + *[ + text( + f""" + EXISTS ( + SELECT 1 + FROM json_each(Chat.meta, '$.tags') AS tag + WHERE tag.value = :tag_id_{tag_idx} + ) + """ + ).params(**{f"tag_id_{tag_idx}": tag_id}) + for tag_idx, tag_id in enumerate(tag_ids) + ] + ) + ) + + elif dialect_name == "postgresql": + # PostgreSQL relies on proper JSON query for search + query = query.filter( + ( + Chat.title.ilike( + f"%{search_text}%" + ) # Case-insensitive search in title + | text( + """ + EXISTS ( + SELECT 1 + FROM json_array_elements(Chat.chat->'messages') AS message + WHERE LOWER(message->>'content') LIKE '%' || :search_text || '%' + ) + """ + ) + ).params(search_text=search_text) + ) + + # Check if there are any tags to filter, it should have all the tags + if "none" in tag_ids: + query = query.filter( + text( + """ + NOT EXISTS ( + SELECT 1 + FROM json_array_elements_text(Chat.meta->'tags') AS tag + ) + """ + ) + ) + elif tag_ids: + query = query.filter( + and_( + *[ + text( + f""" + EXISTS ( + SELECT 1 + FROM json_array_elements_text(Chat.meta->'tags') AS tag + WHERE tag = :tag_id_{tag_idx} + ) + """ + ).params(**{f"tag_id_{tag_idx}": tag_id}) + for tag_idx, tag_id in enumerate(tag_ids) + ] + ) + ) + else: + raise NotImplementedError( + f"Unsupported dialect: {db.bind.dialect.name}" + ) + + # Perform pagination at the SQL level + all_chats = query.offset(skip).limit(limit).all() + + log.info(f"The number of chats: {len(all_chats)}") + + # Validate and return chats + return [ChatModel.model_validate(chat) for chat in all_chats] + + def get_chats_by_folder_id_and_user_id( + self, folder_id: str, user_id: str + ) -> list[ChatModel]: + with get_db() as db: + query = db.query(Chat).filter_by(folder_id=folder_id, user_id=user_id) + query = query.filter(or_(Chat.pinned == False, Chat.pinned == None)) + query = query.filter_by(archived=False) + + query = query.order_by(Chat.updated_at.desc()) + + all_chats = query.all() + return [ChatModel.model_validate(chat) for chat in all_chats] + + def get_chats_by_folder_ids_and_user_id( + self, folder_ids: list[str], user_id: str + ) -> list[ChatModel]: + with get_db() as db: + query = db.query(Chat).filter( + Chat.folder_id.in_(folder_ids), Chat.user_id == user_id + ) + query = query.filter(or_(Chat.pinned == False, Chat.pinned == None)) + query = query.filter_by(archived=False) + + query = query.order_by(Chat.updated_at.desc()) + + all_chats = query.all() + return [ChatModel.model_validate(chat) for chat in all_chats] + + def update_chat_folder_id_by_id_and_user_id( + self, id: str, user_id: str, folder_id: str + ) -> Optional[ChatModel]: + try: + with get_db() as db: + chat = db.get(Chat, id) + chat.folder_id = folder_id + chat.updated_at = int(time.time()) + chat.pinned = False + db.commit() + db.refresh(chat) + return ChatModel.model_validate(chat) + except Exception: + return None + + def get_chat_tags_by_id_and_user_id(self, id: str, user_id: str) -> list[TagModel]: + with get_db() as db: + chat = db.get(Chat, id) + tags = chat.meta.get("tags", []) + return [Tags.get_tag_by_name_and_user_id(tag, user_id) for tag in tags] + + def get_chat_list_by_user_id_and_tag_name( + self, user_id: str, tag_name: str, skip: int = 0, limit: int = 50 + ) -> list[ChatModel]: + with get_db() as db: + query = db.query(Chat).filter_by(user_id=user_id) + tag_id = tag_name.replace(" ", "_").lower() + + log.info(f"DB dialect name: {db.bind.dialect.name}") + if db.bind.dialect.name == "sqlite": + # SQLite JSON1 querying for tags within the meta JSON field + query = query.filter( + text( + f"EXISTS (SELECT 1 FROM json_each(Chat.meta, '$.tags') WHERE json_each.value = :tag_id)" + ) + ).params(tag_id=tag_id) + elif db.bind.dialect.name == "postgresql": + # PostgreSQL JSON query for tags within the meta JSON field (for `json` type) + query = query.filter( + text( + "EXISTS (SELECT 1 FROM json_array_elements_text(Chat.meta->'tags') elem WHERE elem = :tag_id)" + ) + ).params(tag_id=tag_id) + else: + raise NotImplementedError( + f"Unsupported dialect: {db.bind.dialect.name}" + ) + + all_chats = query.all() + log.debug(f"all_chats: {all_chats}") + return [ChatModel.model_validate(chat) for chat in all_chats] + + def add_chat_tag_by_id_and_user_id_and_tag_name( + self, id: str, user_id: str, tag_name: str + ) -> Optional[ChatModel]: + tag = Tags.get_tag_by_name_and_user_id(tag_name, user_id) + if tag is None: + tag = Tags.insert_new_tag(tag_name, user_id) + try: + with get_db() as db: + chat = db.get(Chat, id) + + tag_id = tag.id + if tag_id not in chat.meta.get("tags", []): + chat.meta = { + **chat.meta, + "tags": list(set(chat.meta.get("tags", []) + [tag_id])), + } + + db.commit() + db.refresh(chat) + return ChatModel.model_validate(chat) + except Exception: + return None + + def count_chats_by_tag_name_and_user_id(self, tag_name: str, user_id: str) -> int: + with get_db() as db: # Assuming `get_db()` returns a session object + query = db.query(Chat).filter_by(user_id=user_id, archived=False) + + # Normalize the tag_name for consistency + tag_id = tag_name.replace(" ", "_").lower() + + if db.bind.dialect.name == "sqlite": + # SQLite JSON1 support for querying the tags inside the `meta` JSON field + query = query.filter( + text( + f"EXISTS (SELECT 1 FROM json_each(Chat.meta, '$.tags') WHERE json_each.value = :tag_id)" + ) + ).params(tag_id=tag_id) + + elif db.bind.dialect.name == "postgresql": + # PostgreSQL JSONB support for querying the tags inside the `meta` JSON field + query = query.filter( + text( + "EXISTS (SELECT 1 FROM json_array_elements_text(Chat.meta->'tags') elem WHERE elem = :tag_id)" + ) + ).params(tag_id=tag_id) + + else: + raise NotImplementedError( + f"Unsupported dialect: {db.bind.dialect.name}" + ) + + # Get the count of matching records + count = query.count() + + # Debugging output for inspection + log.info(f"Count of chats for tag '{tag_name}': {count}") + + return count + + def delete_tag_by_id_and_user_id_and_tag_name( + self, id: str, user_id: str, tag_name: str + ) -> bool: + try: + with get_db() as db: + chat = db.get(Chat, id) + tags = chat.meta.get("tags", []) + tag_id = tag_name.replace(" ", "_").lower() + + tags = [tag for tag in tags if tag != tag_id] + chat.meta = { + **chat.meta, + "tags": list(set(tags)), + } + db.commit() + return True + except Exception: + return False + + def delete_all_tags_by_id_and_user_id(self, id: str, user_id: str) -> bool: + try: + with get_db() as db: + chat = db.get(Chat, id) + chat.meta = { + **chat.meta, + "tags": [], + } + db.commit() + + return True + except Exception: + return False + + def delete_chat_by_id(self, id: str) -> bool: + try: + with get_db() as db: + db.query(Chat).filter_by(id=id).delete() + db.commit() + + return True and self.delete_shared_chat_by_chat_id(id) + except Exception: + return False + + def delete_chat_by_id_and_user_id(self, id: str, user_id: str) -> bool: + try: + with get_db() as db: + db.query(Chat).filter_by(id=id, user_id=user_id).delete() + db.commit() + + return True and self.delete_shared_chat_by_chat_id(id) + except Exception: + return False + + def delete_chats_by_user_id(self, user_id: str) -> bool: + try: + with get_db() as db: + self.delete_shared_chats_by_user_id(user_id) + + db.query(Chat).filter_by(user_id=user_id).delete() + db.commit() + + return True + except Exception: + return False + + def delete_chats_by_user_id_and_folder_id( + self, user_id: str, folder_id: str + ) -> bool: + try: + with get_db() as db: + db.query(Chat).filter_by(user_id=user_id, folder_id=folder_id).delete() + db.commit() + + return True + except Exception: + return False + + def delete_shared_chats_by_user_id(self, user_id: str) -> bool: + try: + with get_db() as db: + chats_by_user = db.query(Chat).filter_by(user_id=user_id).all() + shared_chat_ids = [f"shared-{chat.id}" for chat in chats_by_user] + + db.query(Chat).filter(Chat.user_id.in_(shared_chat_ids)).delete() + db.commit() + + return True + except Exception: + return False + + +Chats = ChatTable() diff --git a/backend/open_webui/models/feedbacks.py b/backend/open_webui/models/feedbacks.py new file mode 100644 index 0000000..215e36a --- /dev/null +++ b/backend/open_webui/models/feedbacks.py @@ -0,0 +1,254 @@ +import logging +import time +import uuid +from typing import Optional + +from open_webui.internal.db import Base, get_db +from open_webui.models.chats import Chats + +from open_webui.env import SRC_LOG_LEVELS +from pydantic import BaseModel, ConfigDict +from sqlalchemy import BigInteger, Column, Text, JSON, Boolean + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MODELS"]) + + +#################### +# Feedback DB Schema +#################### + + +class Feedback(Base): + __tablename__ = "feedback" + id = Column(Text, primary_key=True) + user_id = Column(Text) + version = Column(BigInteger, default=0) + type = Column(Text) + data = Column(JSON, nullable=True) + meta = Column(JSON, nullable=True) + snapshot = Column(JSON, nullable=True) + created_at = Column(BigInteger) + updated_at = Column(BigInteger) + + +class FeedbackModel(BaseModel): + id: str + user_id: str + version: int + type: str + data: Optional[dict] = None + meta: Optional[dict] = None + snapshot: Optional[dict] = None + created_at: int + updated_at: int + + model_config = ConfigDict(from_attributes=True) + + +#################### +# Forms +#################### + + +class FeedbackResponse(BaseModel): + id: str + user_id: str + version: int + type: str + data: Optional[dict] = None + meta: Optional[dict] = None + created_at: int + updated_at: int + + +class RatingData(BaseModel): + rating: Optional[str | int] = None + model_id: Optional[str] = None + sibling_model_ids: Optional[list[str]] = None + reason: Optional[str] = None + comment: Optional[str] = None + model_config = ConfigDict(extra="allow", protected_namespaces=()) + + +class MetaData(BaseModel): + arena: Optional[bool] = None + chat_id: Optional[str] = None + message_id: Optional[str] = None + tags: Optional[list[str]] = None + model_config = ConfigDict(extra="allow") + + +class SnapshotData(BaseModel): + chat: Optional[dict] = None + model_config = ConfigDict(extra="allow") + + +class FeedbackForm(BaseModel): + type: str + data: Optional[RatingData] = None + meta: Optional[dict] = None + snapshot: Optional[SnapshotData] = None + model_config = ConfigDict(extra="allow") + + +class FeedbackTable: + def insert_new_feedback( + self, user_id: str, form_data: FeedbackForm + ) -> Optional[FeedbackModel]: + with get_db() as db: + id = str(uuid.uuid4()) + feedback = FeedbackModel( + **{ + "id": id, + "user_id": user_id, + "version": 0, + **form_data.model_dump(), + "created_at": int(time.time()), + "updated_at": int(time.time()), + } + ) + try: + result = Feedback(**feedback.model_dump()) + db.add(result) + db.commit() + db.refresh(result) + if result: + return FeedbackModel.model_validate(result) + else: + return None + except Exception as e: + log.exception(f"Error creating a new feedback: {e}") + return None + + def get_feedback_by_id(self, id: str) -> Optional[FeedbackModel]: + try: + with get_db() as db: + feedback = db.query(Feedback).filter_by(id=id).first() + if not feedback: + return None + return FeedbackModel.model_validate(feedback) + except Exception: + return None + + def get_feedback_by_id_and_user_id( + self, id: str, user_id: str + ) -> Optional[FeedbackModel]: + try: + with get_db() as db: + feedback = db.query(Feedback).filter_by(id=id, user_id=user_id).first() + if not feedback: + return None + return FeedbackModel.model_validate(feedback) + except Exception: + return None + + def get_all_feedbacks(self) -> list[FeedbackModel]: + with get_db() as db: + return [ + FeedbackModel.model_validate(feedback) + for feedback in db.query(Feedback) + .order_by(Feedback.updated_at.desc()) + .all() + ] + + def get_feedbacks_by_type(self, type: str) -> list[FeedbackModel]: + with get_db() as db: + return [ + FeedbackModel.model_validate(feedback) + for feedback in db.query(Feedback) + .filter_by(type=type) + .order_by(Feedback.updated_at.desc()) + .all() + ] + + def get_feedbacks_by_user_id(self, user_id: str) -> list[FeedbackModel]: + with get_db() as db: + return [ + FeedbackModel.model_validate(feedback) + for feedback in db.query(Feedback) + .filter_by(user_id=user_id) + .order_by(Feedback.updated_at.desc()) + .all() + ] + + def update_feedback_by_id( + self, id: str, form_data: FeedbackForm + ) -> Optional[FeedbackModel]: + with get_db() as db: + feedback = db.query(Feedback).filter_by(id=id).first() + if not feedback: + return None + + if form_data.data: + feedback.data = form_data.data.model_dump() + if form_data.meta: + feedback.meta = form_data.meta + if form_data.snapshot: + feedback.snapshot = form_data.snapshot.model_dump() + + feedback.updated_at = int(time.time()) + + db.commit() + return FeedbackModel.model_validate(feedback) + + def update_feedback_by_id_and_user_id( + self, id: str, user_id: str, form_data: FeedbackForm + ) -> Optional[FeedbackModel]: + with get_db() as db: + feedback = db.query(Feedback).filter_by(id=id, user_id=user_id).first() + if not feedback: + return None + + if form_data.data: + feedback.data = form_data.data.model_dump() + if form_data.meta: + feedback.meta = form_data.meta + if form_data.snapshot: + feedback.snapshot = form_data.snapshot.model_dump() + + feedback.updated_at = int(time.time()) + + db.commit() + return FeedbackModel.model_validate(feedback) + + def delete_feedback_by_id(self, id: str) -> bool: + with get_db() as db: + feedback = db.query(Feedback).filter_by(id=id).first() + if not feedback: + return False + db.delete(feedback) + db.commit() + return True + + def delete_feedback_by_id_and_user_id(self, id: str, user_id: str) -> bool: + with get_db() as db: + feedback = db.query(Feedback).filter_by(id=id, user_id=user_id).first() + if not feedback: + return False + db.delete(feedback) + db.commit() + return True + + def delete_feedbacks_by_user_id(self, user_id: str) -> bool: + with get_db() as db: + feedbacks = db.query(Feedback).filter_by(user_id=user_id).all() + if not feedbacks: + return False + for feedback in feedbacks: + db.delete(feedback) + db.commit() + return True + + def delete_all_feedbacks(self) -> bool: + with get_db() as db: + feedbacks = db.query(Feedback).all() + if not feedbacks: + return False + for feedback in feedbacks: + db.delete(feedback) + db.commit() + return True + + +Feedbacks = FeedbackTable() diff --git a/backend/open_webui/models/files.py b/backend/open_webui/models/files.py new file mode 100644 index 0000000..6f1511c --- /dev/null +++ b/backend/open_webui/models/files.py @@ -0,0 +1,235 @@ +import logging +import time +from typing import Optional + +from open_webui.internal.db import Base, JSONField, get_db +from open_webui.env import SRC_LOG_LEVELS +from pydantic import BaseModel, ConfigDict +from sqlalchemy import BigInteger, Column, String, Text, JSON + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MODELS"]) + +#################### +# Files DB Schema +#################### + + +class File(Base): + __tablename__ = "file" + id = Column(String, primary_key=True) + user_id = Column(String) + hash = Column(Text, nullable=True) + + filename = Column(Text) + path = Column(Text, nullable=True) + + data = Column(JSON, nullable=True) + meta = Column(JSON, nullable=True) + + access_control = Column(JSON, nullable=True) + + created_at = Column(BigInteger) + updated_at = Column(BigInteger) + + +class FileModel(BaseModel): + model_config = ConfigDict(from_attributes=True) + + id: str + user_id: str + hash: Optional[str] = None + + filename: str + path: Optional[str] = None + + data: Optional[dict] = None + meta: Optional[dict] = None + + access_control: Optional[dict] = None + + created_at: Optional[int] # timestamp in epoch + updated_at: Optional[int] # timestamp in epoch + + +#################### +# Forms +#################### + + +class FileMeta(BaseModel): + name: Optional[str] = None + content_type: Optional[str] = None + size: Optional[int] = None + + model_config = ConfigDict(extra="allow") + + +class FileModelResponse(BaseModel): + id: str + user_id: str + hash: Optional[str] = None + + filename: str + data: Optional[dict] = None + meta: FileMeta + + created_at: int # timestamp in epoch + updated_at: int # timestamp in epoch + + model_config = ConfigDict(extra="allow") + + +class FileMetadataResponse(BaseModel): + id: str + meta: dict + created_at: int # timestamp in epoch + updated_at: int # timestamp in epoch + + +class FileForm(BaseModel): + id: str + hash: Optional[str] = None + filename: str + path: str + data: dict = {} + meta: dict = {} + access_control: Optional[dict] = None + + +class FilesTable: + def insert_new_file(self, user_id: str, form_data: FileForm) -> Optional[FileModel]: + with get_db() as db: + file = FileModel( + **{ + **form_data.model_dump(), + "user_id": user_id, + "created_at": int(time.time()), + "updated_at": int(time.time()), + } + ) + + try: + result = File(**file.model_dump()) + db.add(result) + db.commit() + db.refresh(result) + if result: + return FileModel.model_validate(result) + else: + return None + except Exception as e: + log.exception(f"Error inserting a new file: {e}") + return None + + def get_file_by_id(self, id: str) -> Optional[FileModel]: + with get_db() as db: + try: + file = db.get(File, id) + return FileModel.model_validate(file) + except Exception: + return None + + def get_file_metadata_by_id(self, id: str) -> Optional[FileMetadataResponse]: + with get_db() as db: + try: + file = db.get(File, id) + return FileMetadataResponse( + id=file.id, + meta=file.meta, + created_at=file.created_at, + updated_at=file.updated_at, + ) + except Exception: + return None + + def get_files(self) -> list[FileModel]: + with get_db() as db: + return [FileModel.model_validate(file) for file in db.query(File).all()] + + def get_files_by_ids(self, ids: list[str]) -> list[FileModel]: + with get_db() as db: + return [ + FileModel.model_validate(file) + for file in db.query(File) + .filter(File.id.in_(ids)) + .order_by(File.updated_at.desc()) + .all() + ] + + def get_file_metadatas_by_ids(self, ids: list[str]) -> list[FileMetadataResponse]: + with get_db() as db: + return [ + FileMetadataResponse( + id=file.id, + meta=file.meta, + created_at=file.created_at, + updated_at=file.updated_at, + ) + for file in db.query(File) + .filter(File.id.in_(ids)) + .order_by(File.updated_at.desc()) + .all() + ] + + def get_files_by_user_id(self, user_id: str) -> list[FileModel]: + with get_db() as db: + return [ + FileModel.model_validate(file) + for file in db.query(File).filter_by(user_id=user_id).all() + ] + + def update_file_hash_by_id(self, id: str, hash: str) -> Optional[FileModel]: + with get_db() as db: + try: + file = db.query(File).filter_by(id=id).first() + file.hash = hash + db.commit() + + return FileModel.model_validate(file) + except Exception: + return None + + def update_file_data_by_id(self, id: str, data: dict) -> Optional[FileModel]: + with get_db() as db: + try: + file = db.query(File).filter_by(id=id).first() + file.data = {**(file.data if file.data else {}), **data} + db.commit() + return FileModel.model_validate(file) + except Exception as e: + + return None + + def update_file_metadata_by_id(self, id: str, meta: dict) -> Optional[FileModel]: + with get_db() as db: + try: + file = db.query(File).filter_by(id=id).first() + file.meta = {**(file.meta if file.meta else {}), **meta} + db.commit() + return FileModel.model_validate(file) + except Exception: + return None + + def delete_file_by_id(self, id: str) -> bool: + with get_db() as db: + try: + db.query(File).filter_by(id=id).delete() + db.commit() + + return True + except Exception: + return False + + def delete_all_files(self) -> bool: + with get_db() as db: + try: + db.query(File).delete() + db.commit() + + return True + except Exception: + return False + + +Files = FilesTable() diff --git a/backend/open_webui/models/folders.py b/backend/open_webui/models/folders.py new file mode 100644 index 0000000..19739bc --- /dev/null +++ b/backend/open_webui/models/folders.py @@ -0,0 +1,271 @@ +import logging +import time +import uuid +from typing import Optional + +from open_webui.internal.db import Base, get_db +from open_webui.models.chats import Chats + +from open_webui.env import SRC_LOG_LEVELS +from pydantic import BaseModel, ConfigDict +from sqlalchemy import BigInteger, Column, Text, JSON, Boolean + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MODELS"]) + + +#################### +# Folder DB Schema +#################### + + +class Folder(Base): + __tablename__ = "folder" + id = Column(Text, primary_key=True) + parent_id = Column(Text, nullable=True) + user_id = Column(Text) + name = Column(Text) + items = Column(JSON, nullable=True) + meta = Column(JSON, nullable=True) + is_expanded = Column(Boolean, default=False) + created_at = Column(BigInteger) + updated_at = Column(BigInteger) + + +class FolderModel(BaseModel): + id: str + parent_id: Optional[str] = None + user_id: str + name: str + items: Optional[dict] = None + meta: Optional[dict] = None + is_expanded: bool = False + created_at: int + updated_at: int + + model_config = ConfigDict(from_attributes=True) + + +#################### +# Forms +#################### + + +class FolderForm(BaseModel): + name: str + model_config = ConfigDict(extra="allow") + + +class FolderTable: + def insert_new_folder( + self, user_id: str, name: str, parent_id: Optional[str] = None + ) -> Optional[FolderModel]: + with get_db() as db: + id = str(uuid.uuid4()) + folder = FolderModel( + **{ + "id": id, + "user_id": user_id, + "name": name, + "parent_id": parent_id, + "created_at": int(time.time()), + "updated_at": int(time.time()), + } + ) + try: + result = Folder(**folder.model_dump()) + db.add(result) + db.commit() + db.refresh(result) + if result: + return FolderModel.model_validate(result) + else: + return None + except Exception as e: + log.exception(f"Error inserting a new folder: {e}") + return None + + def get_folder_by_id_and_user_id( + self, id: str, user_id: str + ) -> Optional[FolderModel]: + try: + with get_db() as db: + folder = db.query(Folder).filter_by(id=id, user_id=user_id).first() + + if not folder: + return None + + return FolderModel.model_validate(folder) + except Exception: + return None + + def get_children_folders_by_id_and_user_id( + self, id: str, user_id: str + ) -> Optional[FolderModel]: + try: + with get_db() as db: + folders = [] + + def get_children(folder): + children = self.get_folders_by_parent_id_and_user_id( + folder.id, user_id + ) + for child in children: + get_children(child) + folders.append(child) + + folder = db.query(Folder).filter_by(id=id, user_id=user_id).first() + if not folder: + return None + + get_children(folder) + return folders + except Exception: + return None + + def get_folders_by_user_id(self, user_id: str) -> list[FolderModel]: + with get_db() as db: + return [ + FolderModel.model_validate(folder) + for folder in db.query(Folder).filter_by(user_id=user_id).all() + ] + + def get_folder_by_parent_id_and_user_id_and_name( + self, parent_id: Optional[str], user_id: str, name: str + ) -> Optional[FolderModel]: + try: + with get_db() as db: + # Check if folder exists + folder = ( + db.query(Folder) + .filter_by(parent_id=parent_id, user_id=user_id) + .filter(Folder.name.ilike(name)) + .first() + ) + + if not folder: + return None + + return FolderModel.model_validate(folder) + except Exception as e: + log.error(f"get_folder_by_parent_id_and_user_id_and_name: {e}") + return None + + def get_folders_by_parent_id_and_user_id( + self, parent_id: Optional[str], user_id: str + ) -> list[FolderModel]: + with get_db() as db: + return [ + FolderModel.model_validate(folder) + for folder in db.query(Folder) + .filter_by(parent_id=parent_id, user_id=user_id) + .all() + ] + + def update_folder_parent_id_by_id_and_user_id( + self, + id: str, + user_id: str, + parent_id: str, + ) -> Optional[FolderModel]: + try: + with get_db() as db: + folder = db.query(Folder).filter_by(id=id, user_id=user_id).first() + + if not folder: + return None + + folder.parent_id = parent_id + folder.updated_at = int(time.time()) + + db.commit() + + return FolderModel.model_validate(folder) + except Exception as e: + log.error(f"update_folder: {e}") + return + + def update_folder_name_by_id_and_user_id( + self, id: str, user_id: str, name: str + ) -> Optional[FolderModel]: + try: + with get_db() as db: + folder = db.query(Folder).filter_by(id=id, user_id=user_id).first() + + if not folder: + return None + + existing_folder = ( + db.query(Folder) + .filter_by(name=name, parent_id=folder.parent_id, user_id=user_id) + .first() + ) + + if existing_folder: + return None + + folder.name = name + folder.updated_at = int(time.time()) + + db.commit() + + return FolderModel.model_validate(folder) + except Exception as e: + log.error(f"update_folder: {e}") + return + + def update_folder_is_expanded_by_id_and_user_id( + self, id: str, user_id: str, is_expanded: bool + ) -> Optional[FolderModel]: + try: + with get_db() as db: + folder = db.query(Folder).filter_by(id=id, user_id=user_id).first() + + if not folder: + return None + + folder.is_expanded = is_expanded + folder.updated_at = int(time.time()) + + db.commit() + + return FolderModel.model_validate(folder) + except Exception as e: + log.error(f"update_folder: {e}") + return + + def delete_folder_by_id_and_user_id(self, id: str, user_id: str) -> bool: + try: + with get_db() as db: + folder = db.query(Folder).filter_by(id=id, user_id=user_id).first() + if not folder: + return False + + # Delete all chats in the folder + Chats.delete_chats_by_user_id_and_folder_id(user_id, folder.id) + + # Delete all children folders + def delete_children(folder): + folder_children = self.get_folders_by_parent_id_and_user_id( + folder.id, user_id + ) + for folder_child in folder_children: + Chats.delete_chats_by_user_id_and_folder_id( + user_id, folder_child.id + ) + delete_children(folder_child) + + folder = db.query(Folder).filter_by(id=folder_child.id).first() + db.delete(folder) + db.commit() + + delete_children(folder) + db.delete(folder) + db.commit() + return True + except Exception as e: + log.error(f"delete_folder: {e}") + return False + + +Folders = FolderTable() diff --git a/backend/open_webui/models/functions.py b/backend/open_webui/models/functions.py new file mode 100644 index 0000000..8cbfc5d --- /dev/null +++ b/backend/open_webui/models/functions.py @@ -0,0 +1,274 @@ +import logging +import time +from typing import Optional + +from open_webui.internal.db import Base, JSONField, get_db +from open_webui.models.users import Users +from open_webui.env import SRC_LOG_LEVELS +from pydantic import BaseModel, ConfigDict +from sqlalchemy import BigInteger, Boolean, Column, String, Text + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MODELS"]) + +#################### +# Functions DB Schema +#################### + + +class Function(Base): + __tablename__ = "function" + + id = Column(String, primary_key=True) + user_id = Column(String) + name = Column(Text) + type = Column(Text) + content = Column(Text) + meta = Column(JSONField) + valves = Column(JSONField) + is_active = Column(Boolean) + is_global = Column(Boolean) + updated_at = Column(BigInteger) + created_at = Column(BigInteger) + + +class FunctionMeta(BaseModel): + description: Optional[str] = None + manifest: Optional[dict] = {} + + +class FunctionModel(BaseModel): + id: str + user_id: str + name: str + type: str + content: str + meta: FunctionMeta + is_active: bool = False + is_global: bool = False + updated_at: int # timestamp in epoch + created_at: int # timestamp in epoch + + model_config = ConfigDict(from_attributes=True) + + +#################### +# Forms +#################### + + +class FunctionResponse(BaseModel): + id: str + user_id: str + type: str + name: str + meta: FunctionMeta + is_active: bool + is_global: bool + updated_at: int # timestamp in epoch + created_at: int # timestamp in epoch + + +class FunctionForm(BaseModel): + id: str + name: str + content: str + meta: FunctionMeta + + +class FunctionValves(BaseModel): + valves: Optional[dict] = None + + +class FunctionsTable: + def insert_new_function( + self, user_id: str, type: str, form_data: FunctionForm + ) -> Optional[FunctionModel]: + function = FunctionModel( + **{ + **form_data.model_dump(), + "user_id": user_id, + "type": type, + "updated_at": int(time.time()), + "created_at": int(time.time()), + } + ) + + try: + with get_db() as db: + result = Function(**function.model_dump()) + db.add(result) + db.commit() + db.refresh(result) + if result: + return FunctionModel.model_validate(result) + else: + return None + except Exception as e: + log.exception(f"Error creating a new function: {e}") + return None + + def get_function_by_id(self, id: str) -> Optional[FunctionModel]: + try: + with get_db() as db: + function = db.get(Function, id) + return FunctionModel.model_validate(function) + except Exception: + return None + + def get_functions(self, active_only=False) -> list[FunctionModel]: + with get_db() as db: + if active_only: + return [ + FunctionModel.model_validate(function) + for function in db.query(Function).filter_by(is_active=True).all() + ] + else: + return [ + FunctionModel.model_validate(function) + for function in db.query(Function).all() + ] + + def get_functions_by_type( + self, type: str, active_only=False + ) -> list[FunctionModel]: + with get_db() as db: + if active_only: + return [ + FunctionModel.model_validate(function) + for function in db.query(Function) + .filter_by(type=type, is_active=True) + .all() + ] + else: + return [ + FunctionModel.model_validate(function) + for function in db.query(Function).filter_by(type=type).all() + ] + + def get_global_filter_functions(self) -> list[FunctionModel]: + with get_db() as db: + return [ + FunctionModel.model_validate(function) + for function in db.query(Function) + .filter_by(type="filter", is_active=True, is_global=True) + .all() + ] + + def get_global_action_functions(self) -> list[FunctionModel]: + with get_db() as db: + return [ + FunctionModel.model_validate(function) + for function in db.query(Function) + .filter_by(type="action", is_active=True, is_global=True) + .all() + ] + + def get_function_valves_by_id(self, id: str) -> Optional[dict]: + with get_db() as db: + try: + function = db.get(Function, id) + return function.valves if function.valves else {} + except Exception as e: + log.exception(f"Error getting function valves by id {id}: {e}") + return None + + def update_function_valves_by_id( + self, id: str, valves: dict + ) -> Optional[FunctionValves]: + with get_db() as db: + try: + function = db.get(Function, id) + function.valves = valves + function.updated_at = int(time.time()) + db.commit() + db.refresh(function) + return self.get_function_by_id(id) + except Exception: + return None + + def get_user_valves_by_id_and_user_id( + self, id: str, user_id: str + ) -> Optional[dict]: + try: + user = Users.get_user_by_id(user_id) + user_settings = user.settings.model_dump() if user.settings else {} + + # Check if user has "functions" and "valves" settings + if "functions" not in user_settings: + user_settings["functions"] = {} + if "valves" not in user_settings["functions"]: + user_settings["functions"]["valves"] = {} + + return user_settings["functions"]["valves"].get(id, {}) + except Exception as e: + log.exception( + f"Error getting user values by id {id} and user id {user_id}: {e}" + ) + return None + + def update_user_valves_by_id_and_user_id( + self, id: str, user_id: str, valves: dict + ) -> Optional[dict]: + try: + user = Users.get_user_by_id(user_id) + user_settings = user.settings.model_dump() if user.settings else {} + + # Check if user has "functions" and "valves" settings + if "functions" not in user_settings: + user_settings["functions"] = {} + if "valves" not in user_settings["functions"]: + user_settings["functions"]["valves"] = {} + + user_settings["functions"]["valves"][id] = valves + + # Update the user settings in the database + Users.update_user_by_id(user_id, {"settings": user_settings}) + + return user_settings["functions"]["valves"][id] + except Exception as e: + log.exception( + f"Error updating user valves by id {id} and user_id {user_id}: {e}" + ) + return None + + def update_function_by_id(self, id: str, updated: dict) -> Optional[FunctionModel]: + with get_db() as db: + try: + db.query(Function).filter_by(id=id).update( + { + **updated, + "updated_at": int(time.time()), + } + ) + db.commit() + return self.get_function_by_id(id) + except Exception: + return None + + def deactivate_all_functions(self) -> Optional[bool]: + with get_db() as db: + try: + db.query(Function).update( + { + "is_active": False, + "updated_at": int(time.time()), + } + ) + db.commit() + return True + except Exception: + return None + + def delete_function_by_id(self, id: str) -> bool: + with get_db() as db: + try: + db.query(Function).filter_by(id=id).delete() + db.commit() + + return True + except Exception: + return False + + +Functions = FunctionsTable() diff --git a/backend/open_webui/models/groups.py b/backend/open_webui/models/groups.py new file mode 100644 index 0000000..763340f --- /dev/null +++ b/backend/open_webui/models/groups.py @@ -0,0 +1,211 @@ +import json +import logging +import time +from typing import Optional +import uuid + +from open_webui.internal.db import Base, get_db +from open_webui.env import SRC_LOG_LEVELS + +from open_webui.models.files import FileMetadataResponse + + +from pydantic import BaseModel, ConfigDict +from sqlalchemy import BigInteger, Column, String, Text, JSON, func + + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MODELS"]) + +#################### +# UserGroup DB Schema +#################### + + +class Group(Base): + __tablename__ = "group" + + id = Column(Text, unique=True, primary_key=True) + user_id = Column(Text) + + name = Column(Text) + description = Column(Text) + + data = Column(JSON, nullable=True) + meta = Column(JSON, nullable=True) + + permissions = Column(JSON, nullable=True) + user_ids = Column(JSON, nullable=True) + + created_at = Column(BigInteger) + updated_at = Column(BigInteger) + + +class GroupModel(BaseModel): + model_config = ConfigDict(from_attributes=True) + id: str + user_id: str + + name: str + description: str + + data: Optional[dict] = None + meta: Optional[dict] = None + + permissions: Optional[dict] = None + user_ids: list[str] = [] + + created_at: int # timestamp in epoch + updated_at: int # timestamp in epoch + + +#################### +# Forms +#################### + + +class GroupResponse(BaseModel): + id: str + user_id: str + name: str + description: str + permissions: Optional[dict] = None + data: Optional[dict] = None + meta: Optional[dict] = None + user_ids: list[str] = [] + created_at: int # timestamp in epoch + updated_at: int # timestamp in epoch + + +class GroupForm(BaseModel): + name: str + description: str + permissions: Optional[dict] = None + + +class GroupUpdateForm(GroupForm): + user_ids: Optional[list[str]] = None + + +class GroupTable: + def insert_new_group( + self, user_id: str, form_data: GroupForm + ) -> Optional[GroupModel]: + with get_db() as db: + group = GroupModel( + **{ + **form_data.model_dump(exclude_none=True), + "id": str(uuid.uuid4()), + "user_id": user_id, + "created_at": int(time.time()), + "updated_at": int(time.time()), + } + ) + + try: + result = Group(**group.model_dump()) + db.add(result) + db.commit() + db.refresh(result) + if result: + return GroupModel.model_validate(result) + else: + return None + + except Exception: + return None + + def get_groups(self) -> list[GroupModel]: + with get_db() as db: + return [ + GroupModel.model_validate(group) + for group in db.query(Group).order_by(Group.updated_at.desc()).all() + ] + + def get_groups_by_member_id(self, user_id: str) -> list[GroupModel]: + with get_db() as db: + return [ + GroupModel.model_validate(group) + for group in db.query(Group) + .filter( + func.json_array_length(Group.user_ids) > 0 + ) # Ensure array exists + .filter( + Group.user_ids.cast(String).like(f'%"{user_id}"%') + ) # String-based check + .order_by(Group.updated_at.desc()) + .all() + ] + + def get_group_by_id(self, id: str) -> Optional[GroupModel]: + try: + with get_db() as db: + group = db.query(Group).filter_by(id=id).first() + return GroupModel.model_validate(group) if group else None + except Exception: + return None + + def get_group_user_ids_by_id(self, id: str) -> Optional[str]: + group = self.get_group_by_id(id) + if group: + return group.user_ids + else: + return None + + def update_group_by_id( + self, id: str, form_data: GroupUpdateForm, overwrite: bool = False + ) -> Optional[GroupModel]: + try: + with get_db() as db: + db.query(Group).filter_by(id=id).update( + { + **form_data.model_dump(exclude_none=True), + "updated_at": int(time.time()), + } + ) + db.commit() + return self.get_group_by_id(id=id) + except Exception as e: + log.exception(e) + return None + + def delete_group_by_id(self, id: str) -> bool: + try: + with get_db() as db: + db.query(Group).filter_by(id=id).delete() + db.commit() + return True + except Exception: + return False + + def delete_all_groups(self) -> bool: + with get_db() as db: + try: + db.query(Group).delete() + db.commit() + + return True + except Exception: + return False + + def remove_user_from_all_groups(self, user_id: str) -> bool: + with get_db() as db: + try: + groups = self.get_groups_by_member_id(user_id) + + for group in groups: + group.user_ids.remove(user_id) + db.query(Group).filter_by(id=group.id).update( + { + "user_ids": group.user_ids, + "updated_at": int(time.time()), + } + ) + db.commit() + + return True + except Exception: + return False + + +Groups = GroupTable() diff --git a/backend/open_webui/models/knowledge.py b/backend/open_webui/models/knowledge.py new file mode 100644 index 0000000..bed3d55 --- /dev/null +++ b/backend/open_webui/models/knowledge.py @@ -0,0 +1,221 @@ +import json +import logging +import time +from typing import Optional +import uuid + +from open_webui.internal.db import Base, get_db +from open_webui.env import SRC_LOG_LEVELS + +from open_webui.models.files import FileMetadataResponse +from open_webui.models.users import Users, UserResponse + + +from pydantic import BaseModel, ConfigDict +from sqlalchemy import BigInteger, Column, String, Text, JSON + +from open_webui.utils.access_control import has_access + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MODELS"]) + +#################### +# Knowledge DB Schema +#################### + + +class Knowledge(Base): + __tablename__ = "knowledge" + + id = Column(Text, unique=True, primary_key=True) + user_id = Column(Text) + + name = Column(Text) + description = Column(Text) + + data = Column(JSON, nullable=True) + meta = Column(JSON, nullable=True) + + access_control = Column(JSON, nullable=True) # Controls data access levels. + # Defines access control rules for this entry. + # - `None`: Public access, available to all users with the "user" role. + # - `{}`: Private access, restricted exclusively to the owner. + # - Custom permissions: Specific access control for reading and writing; + # Can specify group or user-level restrictions: + # { + # "read": { + # "group_ids": ["group_id1", "group_id2"], + # "user_ids": ["user_id1", "user_id2"] + # }, + # "write": { + # "group_ids": ["group_id1", "group_id2"], + # "user_ids": ["user_id1", "user_id2"] + # } + # } + + created_at = Column(BigInteger) + updated_at = Column(BigInteger) + + +class KnowledgeModel(BaseModel): + model_config = ConfigDict(from_attributes=True) + + id: str + user_id: str + + name: str + description: str + + data: Optional[dict] = None + meta: Optional[dict] = None + + access_control: Optional[dict] = None + + created_at: int # timestamp in epoch + updated_at: int # timestamp in epoch + + +#################### +# Forms +#################### + + +class KnowledgeUserModel(KnowledgeModel): + user: Optional[UserResponse] = None + + +class KnowledgeResponse(KnowledgeModel): + files: Optional[list[FileMetadataResponse | dict]] = None + + +class KnowledgeUserResponse(KnowledgeUserModel): + files: Optional[list[FileMetadataResponse | dict]] = None + + +class KnowledgeForm(BaseModel): + name: str + description: str + data: Optional[dict] = None + access_control: Optional[dict] = None + + +class KnowledgeTable: + def insert_new_knowledge( + self, user_id: str, form_data: KnowledgeForm + ) -> Optional[KnowledgeModel]: + with get_db() as db: + knowledge = KnowledgeModel( + **{ + **form_data.model_dump(), + "id": str(uuid.uuid4()), + "user_id": user_id, + "created_at": int(time.time()), + "updated_at": int(time.time()), + } + ) + + try: + result = Knowledge(**knowledge.model_dump()) + db.add(result) + db.commit() + db.refresh(result) + if result: + return KnowledgeModel.model_validate(result) + else: + return None + except Exception: + return None + + def get_knowledge_bases(self) -> list[KnowledgeUserModel]: + with get_db() as db: + knowledge_bases = [] + for knowledge in ( + db.query(Knowledge).order_by(Knowledge.updated_at.desc()).all() + ): + user = Users.get_user_by_id(knowledge.user_id) + knowledge_bases.append( + KnowledgeUserModel.model_validate( + { + **KnowledgeModel.model_validate(knowledge).model_dump(), + "user": user.model_dump() if user else None, + } + ) + ) + return knowledge_bases + + def get_knowledge_bases_by_user_id( + self, user_id: str, permission: str = "write" + ) -> list[KnowledgeUserModel]: + knowledge_bases = self.get_knowledge_bases() + return [ + knowledge_base + for knowledge_base in knowledge_bases + if knowledge_base.user_id == user_id + or has_access(user_id, permission, knowledge_base.access_control) + ] + + def get_knowledge_by_id(self, id: str) -> Optional[KnowledgeModel]: + try: + with get_db() as db: + knowledge = db.query(Knowledge).filter_by(id=id).first() + return KnowledgeModel.model_validate(knowledge) if knowledge else None + except Exception: + return None + + def update_knowledge_by_id( + self, id: str, form_data: KnowledgeForm, overwrite: bool = False + ) -> Optional[KnowledgeModel]: + try: + with get_db() as db: + knowledge = self.get_knowledge_by_id(id=id) + db.query(Knowledge).filter_by(id=id).update( + { + **form_data.model_dump(), + "updated_at": int(time.time()), + } + ) + db.commit() + return self.get_knowledge_by_id(id=id) + except Exception as e: + log.exception(e) + return None + + def update_knowledge_data_by_id( + self, id: str, data: dict + ) -> Optional[KnowledgeModel]: + try: + with get_db() as db: + knowledge = self.get_knowledge_by_id(id=id) + db.query(Knowledge).filter_by(id=id).update( + { + "data": data, + "updated_at": int(time.time()), + } + ) + db.commit() + return self.get_knowledge_by_id(id=id) + except Exception as e: + log.exception(e) + return None + + def delete_knowledge_by_id(self, id: str) -> bool: + try: + with get_db() as db: + db.query(Knowledge).filter_by(id=id).delete() + db.commit() + return True + except Exception: + return False + + def delete_all_knowledge(self) -> bool: + with get_db() as db: + try: + db.query(Knowledge).delete() + db.commit() + + return True + except Exception: + return False + + +Knowledges = KnowledgeTable() diff --git a/backend/open_webui/models/memories.py b/backend/open_webui/models/memories.py new file mode 100644 index 0000000..c8dae97 --- /dev/null +++ b/backend/open_webui/models/memories.py @@ -0,0 +1,137 @@ +import time +import uuid +from typing import Optional + +from open_webui.internal.db import Base, get_db +from pydantic import BaseModel, ConfigDict +from sqlalchemy import BigInteger, Column, String, Text + +#################### +# Memory DB Schema +#################### + + +class Memory(Base): + __tablename__ = "memory" + + id = Column(String, primary_key=True) + user_id = Column(String) + content = Column(Text) + updated_at = Column(BigInteger) + created_at = Column(BigInteger) + + +class MemoryModel(BaseModel): + id: str + user_id: str + content: str + updated_at: int # timestamp in epoch + created_at: int # timestamp in epoch + + model_config = ConfigDict(from_attributes=True) + + +#################### +# Forms +#################### + + +class MemoriesTable: + def insert_new_memory( + self, + user_id: str, + content: str, + ) -> Optional[MemoryModel]: + with get_db() as db: + id = str(uuid.uuid4()) + + memory = MemoryModel( + **{ + "id": id, + "user_id": user_id, + "content": content, + "created_at": int(time.time()), + "updated_at": int(time.time()), + } + ) + result = Memory(**memory.model_dump()) + db.add(result) + db.commit() + db.refresh(result) + if result: + return MemoryModel.model_validate(result) + else: + return None + + def update_memory_by_id( + self, + id: str, + content: str, + ) -> Optional[MemoryModel]: + with get_db() as db: + try: + db.query(Memory).filter_by(id=id).update( + {"content": content, "updated_at": int(time.time())} + ) + db.commit() + return self.get_memory_by_id(id) + except Exception: + return None + + def get_memories(self) -> list[MemoryModel]: + with get_db() as db: + try: + memories = db.query(Memory).all() + return [MemoryModel.model_validate(memory) for memory in memories] + except Exception: + return None + + def get_memories_by_user_id(self, user_id: str) -> list[MemoryModel]: + with get_db() as db: + try: + memories = db.query(Memory).filter_by(user_id=user_id).all() + return [MemoryModel.model_validate(memory) for memory in memories] + except Exception: + return None + + def get_memory_by_id(self, id: str) -> Optional[MemoryModel]: + with get_db() as db: + try: + memory = db.get(Memory, id) + return MemoryModel.model_validate(memory) + except Exception: + return None + + def delete_memory_by_id(self, id: str) -> bool: + with get_db() as db: + try: + db.query(Memory).filter_by(id=id).delete() + db.commit() + + return True + + except Exception: + return False + + def delete_memories_by_user_id(self, user_id: str) -> bool: + with get_db() as db: + try: + db.query(Memory).filter_by(user_id=user_id).delete() + db.commit() + + return True + except Exception: + return False + + def delete_memory_by_id_and_user_id(self, id: str, user_id: str) -> bool: + with get_db() as db: + try: + db.query(Memory).filter_by(id=id, user_id=user_id).delete() + db.commit() + + return True + except Exception: + return False + + +Memories = MemoriesTable() diff --git a/backend/open_webui/models/messages.py b/backend/open_webui/models/messages.py new file mode 100644 index 0000000..a27ae52 --- /dev/null +++ b/backend/open_webui/models/messages.py @@ -0,0 +1,279 @@ +import json +import time +import uuid +from typing import Optional + +from open_webui.internal.db import Base, get_db +from open_webui.models.tags import TagModel, Tag, Tags + + +from pydantic import BaseModel, ConfigDict +from sqlalchemy import BigInteger, Boolean, Column, String, Text, JSON +from sqlalchemy import or_, func, select, and_, text +from sqlalchemy.sql import exists + +#################### +# Message DB Schema +#################### + + +class MessageReaction(Base): + __tablename__ = "message_reaction" + id = Column(Text, primary_key=True) + user_id = Column(Text) + message_id = Column(Text) + name = Column(Text) + created_at = Column(BigInteger) + + +class MessageReactionModel(BaseModel): + model_config = ConfigDict(from_attributes=True) + + id: str + user_id: str + message_id: str + name: str + created_at: int # timestamp in epoch + + +class Message(Base): + __tablename__ = "message" + id = Column(Text, primary_key=True) + + user_id = Column(Text) + channel_id = Column(Text, nullable=True) + + parent_id = Column(Text, nullable=True) + + content = Column(Text) + data = Column(JSON, nullable=True) + meta = Column(JSON, nullable=True) + + created_at = Column(BigInteger) # time_ns + updated_at = Column(BigInteger) # time_ns + + +class MessageModel(BaseModel): + model_config = ConfigDict(from_attributes=True) + + id: str + user_id: str + channel_id: Optional[str] = None + + parent_id: Optional[str] = None + + content: str + data: Optional[dict] = None + meta: Optional[dict] = None + + created_at: int # timestamp in epoch + updated_at: int # timestamp in epoch + + +#################### +# Forms +#################### + + +class MessageForm(BaseModel): + content: str + parent_id: Optional[str] = None + data: Optional[dict] = None + meta: Optional[dict] = None + + +class Reactions(BaseModel): + name: str + user_ids: list[str] + count: int + + +class MessageResponse(MessageModel): + latest_reply_at: Optional[int] + reply_count: int + reactions: list[Reactions] + + +class MessageTable: + def insert_new_message( + self, form_data: MessageForm, channel_id: str, user_id: str + ) -> Optional[MessageModel]: + with get_db() as db: + id = str(uuid.uuid4()) + + ts = int(time.time_ns()) + message = MessageModel( + **{ + "id": id, + "user_id": user_id, + "channel_id": channel_id, + "parent_id": form_data.parent_id, + "content": form_data.content, + "data": form_data.data, + "meta": form_data.meta, + "created_at": ts, + "updated_at": ts, + } + ) + + result = Message(**message.model_dump()) + db.add(result) + db.commit() + db.refresh(result) + return MessageModel.model_validate(result) if result else None + + def get_message_by_id(self, id: str) -> Optional[MessageResponse]: + with get_db() as db: + message = db.get(Message, id) + if not message: + return None + + reactions = self.get_reactions_by_message_id(id) + replies = self.get_replies_by_message_id(id) + + return MessageResponse( + **{ + **MessageModel.model_validate(message).model_dump(), + "latest_reply_at": replies[0].created_at if replies else None, + "reply_count": len(replies), + "reactions": reactions, + } + ) + + def get_replies_by_message_id(self, id: str) -> list[MessageModel]: + with get_db() as db: + all_messages = ( + db.query(Message) + .filter_by(parent_id=id) + .order_by(Message.created_at.desc()) + .all() + ) + return [MessageModel.model_validate(message) for message in all_messages] + + def get_reply_user_ids_by_message_id(self, id: str) -> list[str]: + with get_db() as db: + return [ + message.user_id + for message in db.query(Message).filter_by(parent_id=id).all() + ] + + def get_messages_by_channel_id( + self, channel_id: str, skip: int = 0, limit: int = 50 + ) -> list[MessageModel]: + with get_db() as db: + all_messages = ( + db.query(Message) + .filter_by(channel_id=channel_id, parent_id=None) + .order_by(Message.created_at.desc()) + .offset(skip) + .limit(limit) + .all() + ) + return [MessageModel.model_validate(message) for message in all_messages] + + def get_messages_by_parent_id( + self, channel_id: str, parent_id: str, skip: int = 0, limit: int = 50 + ) -> list[MessageModel]: + with get_db() as db: + message = db.get(Message, parent_id) + + if not message: + return [] + + all_messages = ( + db.query(Message) + .filter_by(channel_id=channel_id, parent_id=parent_id) + .order_by(Message.created_at.desc()) + .offset(skip) + .limit(limit) + .all() + ) + + # If length of all_messages is less than limit, then add the parent message + if len(all_messages) < limit: + all_messages.append(message) + + return [MessageModel.model_validate(message) for message in all_messages] + + def update_message_by_id( + self, id: str, form_data: MessageForm + ) -> Optional[MessageModel]: + with get_db() as db: + message = db.get(Message, id) + message.content = form_data.content + message.data = form_data.data + message.meta = form_data.meta + message.updated_at = int(time.time_ns()) + db.commit() + db.refresh(message) + return MessageModel.model_validate(message) if message else None + + def add_reaction_to_message( + self, id: str, user_id: str, name: str + ) -> Optional[MessageReactionModel]: + with get_db() as db: + reaction_id = str(uuid.uuid4()) + reaction = MessageReactionModel( + id=reaction_id, + user_id=user_id, + message_id=id, + name=name, + created_at=int(time.time_ns()), + ) + result = MessageReaction(**reaction.model_dump()) + db.add(result) + db.commit() + db.refresh(result) + return MessageReactionModel.model_validate(result) if result else None + + def get_reactions_by_message_id(self, id: str) -> list[Reactions]: + with get_db() as db: + all_reactions = db.query(MessageReaction).filter_by(message_id=id).all() + + reactions = {} + for reaction in all_reactions: + if reaction.name not in reactions: + reactions[reaction.name] = { + "name": reaction.name, + "user_ids": [], + "count": 0, + } + reactions[reaction.name]["user_ids"].append(reaction.user_id) + reactions[reaction.name]["count"] += 1 + + return [Reactions(**reaction) for reaction in reactions.values()] + + def remove_reaction_by_id_and_user_id_and_name( + self, id: str, user_id: str, name: str + ) -> bool: + with get_db() as db: + db.query(MessageReaction).filter_by( + message_id=id, user_id=user_id, name=name + ).delete() + db.commit() + return True + + def delete_reactions_by_id(self, id: str) -> bool: + with get_db() as db: + db.query(MessageReaction).filter_by(message_id=id).delete() + db.commit() + return True + + def delete_replies_by_id(self, id: str) -> bool: + with get_db() as db: + db.query(Message).filter_by(parent_id=id).delete() + db.commit() + return True + + def delete_message_by_id(self, id: str) -> bool: + with get_db() as db: + db.query(Message).filter_by(id=id).delete() + + # Delete all reactions to this message + db.query(MessageReaction).filter_by(message_id=id).delete() + + db.commit() + return True + + +Messages = MessageTable() diff --git a/backend/open_webui/models/models.py b/backend/open_webui/models/models.py new file mode 100755 index 0000000..7df8d86 --- /dev/null +++ b/backend/open_webui/models/models.py @@ -0,0 +1,273 @@ +import logging +import time +from typing import Optional + +from open_webui.internal.db import Base, JSONField, get_db +from open_webui.env import SRC_LOG_LEVELS + +from open_webui.models.users import Users, UserResponse + + +from pydantic import BaseModel, ConfigDict + +from sqlalchemy import or_, and_, func +from sqlalchemy.dialects import postgresql, sqlite +from sqlalchemy import BigInteger, Column, Text, JSON, Boolean + + +from open_webui.utils.access_control import has_access + + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MODELS"]) + + +#################### +# Models DB Schema +#################### + + +# ModelParams is a model for the data stored in the params field of the Model table +class ModelParams(BaseModel): + model_config = ConfigDict(extra="allow") + pass + + +# ModelMeta is a model for the data stored in the meta field of the Model table +class ModelMeta(BaseModel): + profile_image_url: Optional[str] = "/static/favicon.png" + + description: Optional[str] = None + """ + User-facing description of the model. + """ + + capabilities: Optional[dict] = None + + model_config = ConfigDict(extra="allow") + + pass + + +class Model(Base): + __tablename__ = "model" + + id = Column(Text, primary_key=True) + """ + The model's id as used in the API. If set to an existing model, it will override the model. + """ + user_id = Column(Text) + + base_model_id = Column(Text, nullable=True) + """ + An optional pointer to the actual model that should be used when proxying requests. + """ + + name = Column(Text) + """ + The human-readable display name of the model. + """ + + params = Column(JSONField) + """ + Holds a JSON encoded blob of parameters, see `ModelParams`. + """ + + meta = Column(JSONField) + """ + Holds a JSON encoded blob of metadata, see `ModelMeta`. + """ + + access_control = Column(JSON, nullable=True) # Controls data access levels. + # Defines access control rules for this entry. + # - `None`: Public access, available to all users with the "user" role. + # - `{}`: Private access, restricted exclusively to the owner. + # - Custom permissions: Specific access control for reading and writing; + # Can specify group or user-level restrictions: + # { + # "read": { + # "group_ids": ["group_id1", "group_id2"], + # "user_ids": ["user_id1", "user_id2"] + # }, + # "write": { + # "group_ids": ["group_id1", "group_id2"], + # "user_ids": ["user_id1", "user_id2"] + # } + # } + + is_active = Column(Boolean, default=True) + + updated_at = Column(BigInteger) + created_at = Column(BigInteger) + + +class ModelModel(BaseModel): + id: str + user_id: str + base_model_id: Optional[str] = None + + name: str + params: ModelParams + meta: ModelMeta + + access_control: Optional[dict] = None + + is_active: bool + updated_at: int # timestamp in epoch + created_at: int # timestamp in epoch + + model_config = ConfigDict(from_attributes=True) + + +#################### +# Forms +#################### + + +class ModelUserResponse(ModelModel): + user: Optional[UserResponse] = None + + +class ModelResponse(ModelModel): + pass + + +class ModelForm(BaseModel): + id: str + base_model_id: Optional[str] = None + name: str + meta: ModelMeta + params: ModelParams + access_control: Optional[dict] = None + is_active: bool = True + + +class ModelsTable: + def insert_new_model( + self, form_data: ModelForm, user_id: str + ) -> Optional[ModelModel]: + model = ModelModel( + **{ + **form_data.model_dump(), + "user_id": user_id, + "created_at": int(time.time()), + "updated_at": int(time.time()), + } + ) + try: + with get_db() as db: + result = Model(**model.model_dump()) + db.add(result) + db.commit() + db.refresh(result) + + if result: + return ModelModel.model_validate(result) + else: + return None + except Exception as e: + log.exception(f"Failed to insert a new model: {e}") + return None + + def get_all_models(self) -> list[ModelModel]: + with get_db() as db: + return [ModelModel.model_validate(model) for model in db.query(Model).all()] + + def get_models(self) -> list[ModelUserResponse]: + with get_db() as db: + models = [] + for model in db.query(Model).filter(Model.base_model_id != None).all(): + user = Users.get_user_by_id(model.user_id) + models.append( + ModelUserResponse.model_validate( + { + **ModelModel.model_validate(model).model_dump(), + "user": user.model_dump() if user else None, + } + ) + ) + return models + + def get_base_models(self) -> list[ModelModel]: + with get_db() as db: + return [ + ModelModel.model_validate(model) + for model in db.query(Model).filter(Model.base_model_id == None).all() + ] + + def get_models_by_user_id( + self, user_id: str, permission: str = "write" + ) -> list[ModelUserResponse]: + models = self.get_models() + return [ + model + for model in models + if model.user_id == user_id + or has_access(user_id, permission, model.access_control) + ] + + def get_model_by_id(self, id: str) -> Optional[ModelModel]: + try: + with get_db() as db: + model = db.get(Model, id) + return ModelModel.model_validate(model) + except Exception: + return None + + def toggle_model_by_id(self, id: str) -> Optional[ModelModel]: + with get_db() as db: + try: + is_active = db.query(Model).filter_by(id=id).first().is_active + + db.query(Model).filter_by(id=id).update( + { + "is_active": not is_active, + "updated_at": int(time.time()), + } + ) + db.commit() + + return self.get_model_by_id(id) + except Exception: + return None + + def update_model_by_id(self, id: str, model: ModelForm) -> Optional[ModelModel]: + try: + with get_db() as db: + # update only the fields that are present in the model + result = ( + db.query(Model) + .filter_by(id=id) + .update(model.model_dump(exclude={"id"})) + ) + db.commit() + + model = db.get(Model, id) + db.refresh(model) + return ModelModel.model_validate(model) + except Exception as e: + log.exception(f"Failed to update the model by id {id}: {e}") + return None + + def delete_model_by_id(self, id: str) -> bool: + try: + with get_db() as db: + db.query(Model).filter_by(id=id).delete() + db.commit() + + return True + except Exception: + return False + + def delete_all_models(self) -> bool: + try: + with get_db() as db: + db.query(Model).delete() + db.commit() + + return True + except Exception: + return False + + +Models = ModelsTable() diff --git a/backend/open_webui/models/prompts.py b/backend/open_webui/models/prompts.py new file mode 100644 index 0000000..8ef4cd2 --- /dev/null +++ b/backend/open_webui/models/prompts.py @@ -0,0 +1,159 @@ +import time +from typing import Optional + +from open_webui.internal.db import Base, get_db +from open_webui.models.users import Users, UserResponse + +from pydantic import BaseModel, ConfigDict +from sqlalchemy import BigInteger, Column, String, Text, JSON + +from open_webui.utils.access_control import has_access + +#################### +# Prompts DB Schema +#################### + + +class Prompt(Base): + __tablename__ = "prompt" + + command = Column(String, primary_key=True) + user_id = Column(String) + title = Column(Text) + content = Column(Text) + timestamp = Column(BigInteger) + + access_control = Column(JSON, nullable=True) # Controls data access levels. + # Defines access control rules for this entry. + # - `None`: Public access, available to all users with the "user" role. + # - `{}`: Private access, restricted exclusively to the owner. + # - Custom permissions: Specific access control for reading and writing; + # Can specify group or user-level restrictions: + # { + # "read": { + # "group_ids": ["group_id1", "group_id2"], + # "user_ids": ["user_id1", "user_id2"] + # }, + # "write": { + # "group_ids": ["group_id1", "group_id2"], + # "user_ids": ["user_id1", "user_id2"] + # } + # } + + +class PromptModel(BaseModel): + command: str + user_id: str + title: str + content: str + timestamp: int # timestamp in epoch + + access_control: Optional[dict] = None + model_config = ConfigDict(from_attributes=True) + + +#################### +# Forms +#################### + + +class PromptUserResponse(PromptModel): + user: Optional[UserResponse] = None + + +class PromptForm(BaseModel): + command: str + title: str + content: str + access_control: Optional[dict] = None + + +class PromptsTable: + def insert_new_prompt( + self, user_id: str, form_data: PromptForm + ) -> Optional[PromptModel]: + prompt = PromptModel( + **{ + "user_id": user_id, + **form_data.model_dump(), + "timestamp": int(time.time()), + } + ) + + try: + with get_db() as db: + result = Prompt(**prompt.model_dump()) + db.add(result) + db.commit() + db.refresh(result) + if result: + return PromptModel.model_validate(result) + else: + return None + except Exception: + return None + + def get_prompt_by_command(self, command: str) -> Optional[PromptModel]: + try: + with get_db() as db: + prompt = db.query(Prompt).filter_by(command=command).first() + return PromptModel.model_validate(prompt) + except Exception: + return None + + def get_prompts(self) -> list[PromptUserResponse]: + with get_db() as db: + prompts = [] + + for prompt in db.query(Prompt).order_by(Prompt.timestamp.desc()).all(): + user = Users.get_user_by_id(prompt.user_id) + prompts.append( + PromptUserResponse.model_validate( + { + **PromptModel.model_validate(prompt).model_dump(), + "user": user.model_dump() if user else None, + } + ) + ) + + return prompts + + def get_prompts_by_user_id( + self, user_id: str, permission: str = "write" + ) -> list[PromptUserResponse]: + prompts = self.get_prompts() + + return [ + prompt + for prompt in prompts + if prompt.user_id == user_id + or has_access(user_id, permission, prompt.access_control) + ] + + def update_prompt_by_command( + self, command: str, form_data: PromptForm + ) -> Optional[PromptModel]: + try: + with get_db() as db: + prompt = db.query(Prompt).filter_by(command=command).first() + prompt.title = form_data.title + prompt.content = form_data.content + prompt.access_control = form_data.access_control + prompt.timestamp = int(time.time()) + db.commit() + return PromptModel.model_validate(prompt) + except Exception: + return None + + def delete_prompt_by_command(self, command: str) -> bool: + try: + with get_db() as db: + db.query(Prompt).filter_by(command=command).delete() + db.commit() + + return True + except Exception: + return False + + +Prompts = PromptsTable() diff --git a/backend/open_webui/models/tags.py b/backend/open_webui/models/tags.py new file mode 100644 index 0000000..279dc62 --- /dev/null +++ b/backend/open_webui/models/tags.py @@ -0,0 +1,109 @@ +import logging +import time +import uuid +from typing import Optional + +from open_webui.internal.db import Base, get_db + + +from open_webui.env import SRC_LOG_LEVELS +from pydantic import BaseModel, ConfigDict +from sqlalchemy import BigInteger, Column, String, JSON, PrimaryKeyConstraint + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MODELS"]) + + +#################### +# Tag DB Schema +#################### +class Tag(Base): + __tablename__ = "tag" + id = Column(String) + name = Column(String) + user_id = Column(String) + meta = Column(JSON, nullable=True) + + # Unique constraint ensuring (id, user_id) is unique, not just the `id` column + __table_args__ = (PrimaryKeyConstraint("id", "user_id", name="pk_id_user_id"),) + + +class TagModel(BaseModel): + id: str + name: str + user_id: str + meta: Optional[dict] = None + model_config = ConfigDict(from_attributes=True) + + +#################### +# Forms +#################### + + +class TagChatIdForm(BaseModel): + name: str + chat_id: str + + +class TagTable: + def insert_new_tag(self, name: str, user_id: str) -> Optional[TagModel]: + with get_db() as db: + id = name.replace(" ", "_").lower() + tag = TagModel(**{"id": id, "user_id": user_id, "name": name}) + try: + result = Tag(**tag.model_dump()) + db.add(result) + db.commit() + db.refresh(result) + if result: + return TagModel.model_validate(result) + else: + return None + except Exception as e: + log.exception(f"Error inserting a new tag: {e}") + return None + + def get_tag_by_name_and_user_id( + self, name: str, user_id: str + ) -> Optional[TagModel]: + try: + id = name.replace(" ", "_").lower() + with get_db() as db: + tag = db.query(Tag).filter_by(id=id, user_id=user_id).first() + return TagModel.model_validate(tag) + except Exception: + return None + + def get_tags_by_user_id(self, user_id: str) -> list[TagModel]: + with get_db() as db: + return [ + TagModel.model_validate(tag) + for tag in (db.query(Tag).filter_by(user_id=user_id).all()) + ] + + def get_tags_by_ids_and_user_id( + self, ids: list[str], user_id: str + ) -> list[TagModel]: + with get_db() as db: + return [ + TagModel.model_validate(tag) + for tag in ( + db.query(Tag).filter(Tag.id.in_(ids), Tag.user_id == user_id).all() + ) + ] + + def delete_tag_by_name_and_user_id(self, name: str, user_id: str) -> bool: + try: + with get_db() as db: + id = name.replace(" ", "_").lower() + res = db.query(Tag).filter_by(id=id, user_id=user_id).delete() + log.debug(f"res: {res}") + db.commit() + return True + except Exception as e: + log.error(f"delete_tag: {e}") + return False + + +Tags = TagTable() diff --git a/backend/open_webui/models/tools.py b/backend/open_webui/models/tools.py new file mode 100644 index 0000000..68a83ea --- /dev/null +++ b/backend/open_webui/models/tools.py @@ -0,0 +1,262 @@ +import logging +import time +from typing import Optional + +from open_webui.internal.db import Base, JSONField, get_db +from open_webui.models.users import Users, UserResponse +from open_webui.env import SRC_LOG_LEVELS +from pydantic import BaseModel, ConfigDict +from sqlalchemy import BigInteger, Column, String, Text, JSON + +from open_webui.utils.access_control import has_access + + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MODELS"]) + +#################### +# Tools DB Schema +#################### + + +class Tool(Base): + __tablename__ = "tool" + + id = Column(String, primary_key=True) + user_id = Column(String) + name = Column(Text) + content = Column(Text) + specs = Column(JSONField) + meta = Column(JSONField) + valves = Column(JSONField) + + access_control = Column(JSON, nullable=True) # Controls data access levels. + # Defines access control rules for this entry. + # - `None`: Public access, available to all users with the "user" role. + # - `{}`: Private access, restricted exclusively to the owner. + # - Custom permissions: Specific access control for reading and writing; + # Can specify group or user-level restrictions: + # { + # "read": { + # "group_ids": ["group_id1", "group_id2"], + # "user_ids": ["user_id1", "user_id2"] + # }, + # "write": { + # "group_ids": ["group_id1", "group_id2"], + # "user_ids": ["user_id1", "user_id2"] + # } + # } + + updated_at = Column(BigInteger) + created_at = Column(BigInteger) + + +class ToolMeta(BaseModel): + description: Optional[str] = None + manifest: Optional[dict] = {} + + +class ToolModel(BaseModel): + id: str + user_id: str + name: str + content: str + specs: list[dict] + meta: ToolMeta + access_control: Optional[dict] = None + + updated_at: int # timestamp in epoch + created_at: int # timestamp in epoch + + model_config = ConfigDict(from_attributes=True) + + +#################### +# Forms +#################### + + +class ToolUserModel(ToolModel): + user: Optional[UserResponse] = None + + +class ToolResponse(BaseModel): + id: str + user_id: str + name: str + meta: ToolMeta + access_control: Optional[dict] = None + updated_at: int # timestamp in epoch + created_at: int # timestamp in epoch + + +class ToolUserResponse(ToolResponse): + user: Optional[UserResponse] = None + + +class ToolForm(BaseModel): + id: str + name: str + content: str + meta: ToolMeta + access_control: Optional[dict] = None + + +class ToolValves(BaseModel): + valves: Optional[dict] = None + + +class ToolsTable: + def insert_new_tool( + self, user_id: str, form_data: ToolForm, specs: list[dict] + ) -> Optional[ToolModel]: + with get_db() as db: + tool = ToolModel( + **{ + **form_data.model_dump(), + "specs": specs, + "user_id": user_id, + "updated_at": int(time.time()), + "created_at": int(time.time()), + } + ) + + try: + result = Tool(**tool.model_dump()) + db.add(result) + db.commit() + db.refresh(result) + if result: + return ToolModel.model_validate(result) + else: + return None + except Exception as e: + log.exception(f"Error creating a new tool: {e}") + return None + + def get_tool_by_id(self, id: str) -> Optional[ToolModel]: + try: + with get_db() as db: + tool = db.get(Tool, id) + return ToolModel.model_validate(tool) + except Exception: + return None + + def get_tools(self) -> list[ToolUserModel]: + with get_db() as db: + tools = [] + for tool in db.query(Tool).order_by(Tool.updated_at.desc()).all(): + user = Users.get_user_by_id(tool.user_id) + tools.append( + ToolUserModel.model_validate( + { + **ToolModel.model_validate(tool).model_dump(), + "user": user.model_dump() if user else None, + } + ) + ) + return tools + + def get_tools_by_user_id( + self, user_id: str, permission: str = "write" + ) -> list[ToolUserModel]: + tools = self.get_tools() + + return [ + tool + for tool in tools + if tool.user_id == user_id + or has_access(user_id, permission, tool.access_control) + ] + + def get_tool_valves_by_id(self, id: str) -> Optional[dict]: + try: + with get_db() as db: + tool = db.get(Tool, id) + return tool.valves if tool.valves else {} + except Exception as e: + log.exception(f"Error getting tool valves by id {id}: {e}") + return None + + def update_tool_valves_by_id(self, id: str, valves: dict) -> Optional[ToolValves]: + try: + with get_db() as db: + db.query(Tool).filter_by(id=id).update( + {"valves": valves, "updated_at": int(time.time())} + ) + db.commit() + return self.get_tool_by_id(id) + except Exception: + return None + + def get_user_valves_by_id_and_user_id( + self, id: str, user_id: str + ) -> Optional[dict]: + try: + user = Users.get_user_by_id(user_id) + user_settings = user.settings.model_dump() if user.settings else {} + + # Check if user has "tools" and "valves" settings + if "tools" not in user_settings: + user_settings["tools"] = {} + if "valves" not in user_settings["tools"]: + user_settings["tools"]["valves"] = {} + + return user_settings["tools"]["valves"].get(id, {}) + except Exception as e: + log.exception( + f"Error getting user values by id {id} and user_id {user_id}: {e}" + ) + return None + + def update_user_valves_by_id_and_user_id( + self, id: str, user_id: str, valves: dict + ) -> Optional[dict]: + try: + user = Users.get_user_by_id(user_id) + user_settings = user.settings.model_dump() if user.settings else {} + + # Check if user has "tools" and "valves" settings + if "tools" not in user_settings: + user_settings["tools"] = {} + if "valves" not in user_settings["tools"]: + user_settings["tools"]["valves"] = {} + + user_settings["tools"]["valves"][id] = valves + + # Update the user settings in the database + Users.update_user_by_id(user_id, {"settings": user_settings}) + + return user_settings["tools"]["valves"][id] + except Exception as e: + log.exception( + f"Error updating user valves by id {id} and user_id {user_id}: {e}" + ) + return None + + def update_tool_by_id(self, id: str, updated: dict) -> Optional[ToolModel]: + try: + with get_db() as db: + db.query(Tool).filter_by(id=id).update( + {**updated, "updated_at": int(time.time())} + ) + db.commit() + + tool = db.query(Tool).get(id) + db.refresh(tool) + return ToolModel.model_validate(tool) + except Exception: + return None + + def delete_tool_by_id(self, id: str) -> bool: + try: + with get_db() as db: + db.query(Tool).filter_by(id=id).delete() + db.commit() + + return True + except Exception: + return False + + +Tools = ToolsTable() diff --git a/backend/open_webui/models/users.py b/backend/open_webui/models/users.py new file mode 100644 index 0000000..6052995 --- /dev/null +++ b/backend/open_webui/models/users.py @@ -0,0 +1,334 @@ +import time +from typing import Optional + +from open_webui.internal.db import Base, JSONField, get_db + + +from open_webui.models.chats import Chats +from open_webui.models.groups import Groups + + +from pydantic import BaseModel, ConfigDict +from sqlalchemy import BigInteger, Column, String, Text + +#################### +# User DB Schema +#################### + + +class User(Base): + __tablename__ = "user" + + id = Column(String, primary_key=True) + name = Column(String) + email = Column(String) + role = Column(String) + profile_image_url = Column(Text) + + last_active_at = Column(BigInteger) + updated_at = Column(BigInteger) + created_at = Column(BigInteger) + + api_key = Column(String, nullable=True, unique=True) + settings = Column(JSONField, nullable=True) + info = Column(JSONField, nullable=True) + + oauth_sub = Column(Text, unique=True) + + +class UserSettings(BaseModel): + ui: Optional[dict] = {} + model_config = ConfigDict(extra="allow") + pass + + +class UserModel(BaseModel): + id: str + name: str + email: str + role: str = "pending" + profile_image_url: str + + last_active_at: int # timestamp in epoch + updated_at: int # timestamp in epoch + created_at: int # timestamp in epoch + + api_key: Optional[str] = None + settings: Optional[UserSettings] = None + info: Optional[dict] = None + + oauth_sub: Optional[str] = None + + model_config = ConfigDict(from_attributes=True) + + +#################### +# Forms +#################### + + +class UserResponse(BaseModel): + id: str + name: str + email: str + role: str + profile_image_url: str + + +class UserNameResponse(BaseModel): + id: str + name: str + role: str + profile_image_url: str + + +class UserRoleUpdateForm(BaseModel): + id: str + role: str + + +class UserUpdateForm(BaseModel): + name: str + email: str + profile_image_url: str + password: Optional[str] = None + + +class UsersTable: + def insert_new_user( + self, + id: str, + name: str, + email: str, + profile_image_url: str = "/user.png", + role: str = "pending", + oauth_sub: Optional[str] = None, + ) -> Optional[UserModel]: + with get_db() as db: + user = UserModel( + **{ + "id": id, + "name": name, + "email": email, + "role": role, + "profile_image_url": profile_image_url, + "last_active_at": int(time.time()), + "created_at": int(time.time()), + "updated_at": int(time.time()), + "oauth_sub": oauth_sub, + } + ) + result = User(**user.model_dump()) + db.add(result) + db.commit() + db.refresh(result) + if result: + return user + else: + return None + + def get_user_by_id(self, id: str) -> Optional[UserModel]: + try: + with get_db() as db: + user = db.query(User).filter_by(id=id).first() + return UserModel.model_validate(user) + except Exception: + return None + + def get_user_by_api_key(self, api_key: str) -> Optional[UserModel]: + try: + with get_db() as db: + user = db.query(User).filter_by(api_key=api_key).first() + return UserModel.model_validate(user) + except Exception: + return None + + def get_user_by_email(self, email: str) -> Optional[UserModel]: + try: + with get_db() as db: + user = db.query(User).filter_by(email=email).first() + return UserModel.model_validate(user) + except Exception: + return None + + def get_user_by_oauth_sub(self, sub: str) -> Optional[UserModel]: + try: + with get_db() as db: + user = db.query(User).filter_by(oauth_sub=sub).first() + return UserModel.model_validate(user) + except Exception: + return None + + def get_users( + self, skip: Optional[int] = None, limit: Optional[int] = None + ) -> list[UserModel]: + with get_db() as db: + + query = db.query(User).order_by(User.created_at.desc()) + + if skip: + query = query.offset(skip) + if limit: + query = query.limit(limit) + + users = query.all() + + return [UserModel.model_validate(user) for user in users] + + def get_users_by_user_ids(self, user_ids: list[str]) -> list[UserModel]: + with get_db() as db: + users = db.query(User).filter(User.id.in_(user_ids)).all() + return [UserModel.model_validate(user) for user in users] + + def get_num_users(self) -> Optional[int]: + with get_db() as db: + return db.query(User).count() + + def get_first_user(self) -> UserModel: + try: + with get_db() as db: + user = db.query(User).order_by(User.created_at).first() + return UserModel.model_validate(user) + except Exception: + return None + + def get_user_webhook_url_by_id(self, id: str) -> Optional[str]: + try: + with get_db() as db: + user = db.query(User).filter_by(id=id).first() + + if user.settings is None: + return None + else: + return ( + user.settings.get("ui", {}) + .get("notifications", {}) + .get("webhook_url", None) + ) + except Exception: + return None + + def update_user_role_by_id(self, id: str, role: str) -> Optional[UserModel]: + try: + with get_db() as db: + db.query(User).filter_by(id=id).update({"role": role}) + db.commit() + user = db.query(User).filter_by(id=id).first() + return UserModel.model_validate(user) + except Exception: + return None + + def update_user_profile_image_url_by_id( + self, id: str, profile_image_url: str + ) -> Optional[UserModel]: + try: + with get_db() as db: + db.query(User).filter_by(id=id).update( + {"profile_image_url": profile_image_url} + ) + db.commit() + + user = db.query(User).filter_by(id=id).first() + return UserModel.model_validate(user) + except Exception: + return None + + def update_user_last_active_by_id(self, id: str) -> Optional[UserModel]: + try: + with get_db() as db: + db.query(User).filter_by(id=id).update( + {"last_active_at": int(time.time())} + ) + db.commit() + + user = db.query(User).filter_by(id=id).first() + return UserModel.model_validate(user) + except Exception: + return None + + def update_user_oauth_sub_by_id( + self, id: str, oauth_sub: str + ) -> Optional[UserModel]: + try: + with get_db() as db: + db.query(User).filter_by(id=id).update({"oauth_sub": oauth_sub}) + db.commit() + + user = db.query(User).filter_by(id=id).first() + return UserModel.model_validate(user) + except Exception: + return None + + def update_user_by_id(self, id: str, updated: dict) -> Optional[UserModel]: + try: + with get_db() as db: + db.query(User).filter_by(id=id).update(updated) + db.commit() + + user = db.query(User).filter_by(id=id).first() + return UserModel.model_validate(user) + # return UserModel(**user.dict()) + except Exception: + return None + + def update_user_settings_by_id(self, id: str, updated: dict) -> Optional[UserModel]: + try: + with get_db() as db: + user_settings = db.query(User).filter_by(id=id).first().settings + + if user_settings is None: + user_settings = {} + + user_settings.update(updated) + + db.query(User).filter_by(id=id).update({"settings": user_settings}) + db.commit() + + user = db.query(User).filter_by(id=id).first() + return UserModel.model_validate(user) + except Exception: + return None + + def delete_user_by_id(self, id: str) -> bool: + try: + # Remove User from Groups + Groups.remove_user_from_all_groups(id) + + # Delete User Chats + result = Chats.delete_chats_by_user_id(id) + if result: + with get_db() as db: + # Delete User + db.query(User).filter_by(id=id).delete() + db.commit() + + return True + else: + return False + except Exception: + return False + + def update_user_api_key_by_id(self, id: str, api_key: str) -> str: + try: + with get_db() as db: + result = db.query(User).filter_by(id=id).update({"api_key": api_key}) + db.commit() + return True if result == 1 else False + except Exception: + return False + + def get_user_api_key_by_id(self, id: str) -> Optional[str]: + try: + with get_db() as db: + user = db.query(User).filter_by(id=id).first() + return user.api_key + except Exception: + return None + + def get_valid_user_ids(self, user_ids: list[str]) -> list[str]: + with get_db() as db: + users = db.query(User).filter(User.id.in_(user_ids)).all() + return [user.id for user in users] + + +Users = UsersTable() diff --git a/backend/open_webui/retrieval/loaders/main.py b/backend/open_webui/retrieval/loaders/main.py new file mode 100644 index 0000000..7fa24ce --- /dev/null +++ b/backend/open_webui/retrieval/loaders/main.py @@ -0,0 +1,215 @@ +import requests +import logging +import ftfy +import sys + +from langchain_community.document_loaders import ( + AzureAIDocumentIntelligenceLoader, + BSHTMLLoader, + CSVLoader, + Docx2txtLoader, + OutlookMessageLoader, + PyPDFLoader, + TextLoader, + UnstructuredEPubLoader, + UnstructuredExcelLoader, + UnstructuredMarkdownLoader, + UnstructuredPowerPointLoader, + UnstructuredRSTLoader, + UnstructuredXMLLoader, + YoutubeLoader, +) +from langchain_core.documents import Document +from open_webui.env import SRC_LOG_LEVELS, GLOBAL_LOG_LEVEL + +logging.basicConfig(stream=sys.stdout, level=GLOBAL_LOG_LEVEL) +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["RAG"]) + +known_source_ext = [ + "go", + "py", + "java", + "sh", + "bat", + "ps1", + "cmd", + "js", + "ts", + "css", + "cpp", + "hpp", + "h", + "c", + "cs", + "sql", + "log", + "ini", + "pl", + "pm", + "r", + "dart", + "dockerfile", + "env", + "php", + "hs", + "hsc", + "lua", + "nginxconf", + "conf", + "m", + "mm", + "plsql", + "perl", + "rb", + "rs", + "db2", + "scala", + "bash", + "swift", + "vue", + "svelte", + "msg", + "ex", + "exs", + "erl", + "tsx", + "jsx", + "hs", + "lhs", + "json", +] + + +class TikaLoader: + def __init__(self, url, file_path, mime_type=None): + self.url = url + self.file_path = file_path + self.mime_type = mime_type + + def load(self) -> list[Document]: + with open(self.file_path, "rb") as f: + data = f.read() + + if self.mime_type is not None: + headers = {"Content-Type": self.mime_type} + else: + headers = {} + + endpoint = self.url + if not endpoint.endswith("/"): + endpoint += "/" + endpoint += "tika/text" + + r = requests.put(endpoint, data=data, headers=headers) + + if r.ok: + raw_metadata = r.json() + text = raw_metadata.get("X-TIKA:content", "") + + if "Content-Type" in raw_metadata: + headers["Content-Type"] = raw_metadata["Content-Type"] + + log.debug("Tika extracted text: %s", text) + + return [Document(page_content=text, metadata=headers)] + else: + raise Exception(f"Error calling Tika: {r.reason}") + + +class Loader: + def __init__(self, engine: str = "", **kwargs): + self.engine = engine + self.kwargs = kwargs + + def load( + self, filename: str, file_content_type: str, file_path: str + ) -> list[Document]: + loader = self._get_loader(filename, file_content_type, file_path) + docs = loader.load() + + return [ + Document( + page_content=ftfy.fix_text(doc.page_content), metadata=doc.metadata + ) + for doc in docs + ] + + def _get_loader(self, filename: str, file_content_type: str, file_path: str): + file_ext = filename.split(".")[-1].lower() + + if self.engine == "tika" and self.kwargs.get("TIKA_SERVER_URL"): + if file_ext in known_source_ext or ( + file_content_type and file_content_type.find("text/") >= 0 + ): + loader = TextLoader(file_path, autodetect_encoding=True) + else: + loader = TikaLoader( + url=self.kwargs.get("TIKA_SERVER_URL"), + file_path=file_path, + mime_type=file_content_type, + ) + elif ( + self.engine == "document_intelligence" + and self.kwargs.get("DOCUMENT_INTELLIGENCE_ENDPOINT") != "" + and self.kwargs.get("DOCUMENT_INTELLIGENCE_KEY") != "" + and ( + file_ext in ["pdf", "xls", "xlsx", "docx", "ppt", "pptx"] + or file_content_type + in [ + "application/vnd.ms-excel", + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + "application/vnd.ms-powerpoint", + "application/vnd.openxmlformats-officedocument.presentationml.presentation", + ] + ) + ): + loader = AzureAIDocumentIntelligenceLoader( + file_path=file_path, + api_endpoint=self.kwargs.get("DOCUMENT_INTELLIGENCE_ENDPOINT"), + api_key=self.kwargs.get("DOCUMENT_INTELLIGENCE_KEY"), + ) + else: + if file_ext == "pdf": + loader = PyPDFLoader( + file_path, extract_images=self.kwargs.get("PDF_EXTRACT_IMAGES") + ) + elif file_ext == "csv": + loader = CSVLoader(file_path) + elif file_ext == "rst": + loader = UnstructuredRSTLoader(file_path, mode="elements") + elif file_ext == "xml": + loader = UnstructuredXMLLoader(file_path) + elif file_ext in ["htm", "html"]: + loader = BSHTMLLoader(file_path, open_encoding="unicode_escape") + elif file_ext == "md": + loader = TextLoader(file_path, autodetect_encoding=True) + elif file_content_type == "application/epub+zip": + loader = UnstructuredEPubLoader(file_path) + elif ( + file_content_type + == "application/vnd.openxmlformats-officedocument.wordprocessingml.document" + or file_ext == "docx" + ): + loader = Docx2txtLoader(file_path) + elif file_content_type in [ + "application/vnd.ms-excel", + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + ] or file_ext in ["xls", "xlsx"]: + loader = UnstructuredExcelLoader(file_path) + elif file_content_type in [ + "application/vnd.ms-powerpoint", + "application/vnd.openxmlformats-officedocument.presentationml.presentation", + ] or file_ext in ["ppt", "pptx"]: + loader = UnstructuredPowerPointLoader(file_path) + elif file_ext == "msg": + loader = OutlookMessageLoader(file_path) + elif file_ext in known_source_ext or ( + file_content_type and file_content_type.find("text/") >= 0 + ): + loader = TextLoader(file_path, autodetect_encoding=True) + else: + loader = TextLoader(file_path, autodetect_encoding=True) + + return loader diff --git a/backend/open_webui/retrieval/loaders/youtube.py b/backend/open_webui/retrieval/loaders/youtube.py new file mode 100644 index 0000000..8eb4848 --- /dev/null +++ b/backend/open_webui/retrieval/loaders/youtube.py @@ -0,0 +1,117 @@ +import logging + +from typing import Any, Dict, Generator, List, Optional, Sequence, Union +from urllib.parse import parse_qs, urlparse +from langchain_core.documents import Document +from open_webui.env import SRC_LOG_LEVELS + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["RAG"]) + +ALLOWED_SCHEMES = {"http", "https"} +ALLOWED_NETLOCS = { + "youtu.be", + "m.youtube.com", + "youtube.com", + "www.youtube.com", + "www.youtube-nocookie.com", + "vid.plus", +} + + +def _parse_video_id(url: str) -> Optional[str]: + """Parse a YouTube URL and return the video ID if valid, otherwise None.""" + parsed_url = urlparse(url) + + if parsed_url.scheme not in ALLOWED_SCHEMES: + return None + + if parsed_url.netloc not in ALLOWED_NETLOCS: + return None + + path = parsed_url.path + + if path.endswith("/watch"): + query = parsed_url.query + parsed_query = parse_qs(query) + if "v" in parsed_query: + ids = parsed_query["v"] + video_id = ids if isinstance(ids, str) else ids[0] + else: + return None + else: + path = parsed_url.path.lstrip("/") + video_id = path.split("/")[-1] + + if len(video_id) != 11: # Video IDs are 11 characters long + return None + + return video_id + + +class YoutubeLoader: + """Load `YouTube` video transcripts.""" + + def __init__( + self, + video_id: str, + language: Union[str, Sequence[str]] = "en", + proxy_url: Optional[str] = None, + ): + """Initialize with YouTube video ID.""" + _video_id = _parse_video_id(video_id) + self.video_id = _video_id if _video_id is not None else video_id + self._metadata = {"source": video_id} + self.language = language + self.proxy_url = proxy_url + if isinstance(language, str): + self.language = [language] + else: + self.language = language + + def load(self) -> List[Document]: + """Load YouTube transcripts into `Document` objects.""" + try: + from youtube_transcript_api import ( + NoTranscriptFound, + TranscriptsDisabled, + YouTubeTranscriptApi, + ) + except ImportError: + raise ImportError( + 'Could not import "youtube_transcript_api" Python package. ' + "Please install it with `pip install youtube-transcript-api`." + ) + + if self.proxy_url: + youtube_proxies = { + "http": self.proxy_url, + "https": self.proxy_url, + } + # Don't log complete URL because it might contain secrets + log.debug(f"Using proxy URL: {self.proxy_url[:14]}...") + else: + youtube_proxies = None + + try: + transcript_list = YouTubeTranscriptApi.list_transcripts( + self.video_id, proxies=youtube_proxies + ) + except Exception as e: + log.exception("Loading YouTube transcript failed") + return [] + + try: + transcript = transcript_list.find_transcript(self.language) + except NoTranscriptFound: + transcript = transcript_list.find_transcript(["en"]) + + transcript_pieces: List[Dict[str, Any]] = transcript.fetch() + + transcript = " ".join( + map( + lambda transcript_piece: transcript_piece["text"].strip(" "), + transcript_pieces, + ) + ) + return [Document(page_content=transcript, metadata=self._metadata)] diff --git a/backend/open_webui/retrieval/models/colbert.py b/backend/open_webui/retrieval/models/colbert.py new file mode 100644 index 0000000..5b7499f --- /dev/null +++ b/backend/open_webui/retrieval/models/colbert.py @@ -0,0 +1,87 @@ +import os +import logging +import torch +import numpy as np +from colbert.infra import ColBERTConfig +from colbert.modeling.checkpoint import Checkpoint + +from open_webui.env import SRC_LOG_LEVELS + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["RAG"]) + + +class ColBERT: + def __init__(self, name, **kwargs) -> None: + log.info("ColBERT: Loading model", name) + self.device = "cuda" if torch.cuda.is_available() else "cpu" + + DOCKER = kwargs.get("env") == "docker" + if DOCKER: + # This is a workaround for the issue with the docker container + # where the torch extension is not loaded properly + # and the following error is thrown: + # /root/.cache/torch_extensions/py311_cpu/segmented_maxsim_cpp/segmented_maxsim_cpp.so: cannot open shared object file: No such file or directory + + lock_file = ( + "/root/.cache/torch_extensions/py311_cpu/segmented_maxsim_cpp/lock" + ) + if os.path.exists(lock_file): + os.remove(lock_file) + + self.ckpt = Checkpoint( + name, + colbert_config=ColBERTConfig(model_name=name), + ).to(self.device) + pass + + def calculate_similarity_scores(self, query_embeddings, document_embeddings): + + query_embeddings = query_embeddings.to(self.device) + document_embeddings = document_embeddings.to(self.device) + + # Validate dimensions to ensure compatibility + if query_embeddings.dim() != 3: + raise ValueError( + f"Expected query embeddings to have 3 dimensions, but got {query_embeddings.dim()}." + ) + if document_embeddings.dim() != 3: + raise ValueError( + f"Expected document embeddings to have 3 dimensions, but got {document_embeddings.dim()}." + ) + if query_embeddings.size(0) not in [1, document_embeddings.size(0)]: + raise ValueError( + "There should be either one query or queries equal to the number of documents." + ) + + # Transpose the query embeddings to align for matrix multiplication + transposed_query_embeddings = query_embeddings.permute(0, 2, 1) + # Compute similarity scores using batch matrix multiplication + computed_scores = torch.matmul(document_embeddings, transposed_query_embeddings) + # Apply max pooling to extract the highest semantic similarity across each document's sequence + maximum_scores = torch.max(computed_scores, dim=1).values + + # Sum up the maximum scores across features to get the overall document relevance scores + final_scores = maximum_scores.sum(dim=1) + + normalized_scores = torch.softmax(final_scores, dim=0) + + return normalized_scores.detach().cpu().numpy().astype(np.float32) + + def predict(self, sentences): + + query = sentences[0][0] + docs = [i[1] for i in sentences] + + # Embedding the documents + embedded_docs = self.ckpt.docFromText(docs, bsize=32)[0] + # Embedding the queries + embedded_queries = self.ckpt.queryFromText([query], bsize=32) + embedded_query = embedded_queries[0] + + # Calculate retrieval scores for the query against all documents + scores = self.calculate_similarity_scores( + embedded_query.unsqueeze(0), embedded_docs + ) + + return scores diff --git a/backend/open_webui/retrieval/utils.py b/backend/open_webui/retrieval/utils.py new file mode 100644 index 0000000..b6253e6 --- /dev/null +++ b/backend/open_webui/retrieval/utils.py @@ -0,0 +1,699 @@ +import logging +import os +import uuid +from typing import Optional, Union + +import asyncio +import requests +import hashlib + +from huggingface_hub import snapshot_download +from langchain.retrievers import ContextualCompressionRetriever, EnsembleRetriever +from langchain_community.retrievers import BM25Retriever +from langchain_core.documents import Document + + +from open_webui.config import VECTOR_DB +from open_webui.retrieval.vector.connector import VECTOR_DB_CLIENT +from open_webui.utils.misc import get_last_user_message, calculate_sha256_string + +from open_webui.models.users import UserModel +from open_webui.models.files import Files + +from open_webui.env import ( + SRC_LOG_LEVELS, + OFFLINE_MODE, + ENABLE_FORWARD_USER_INFO_HEADERS, +) + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["RAG"]) + + +from typing import Any + +from langchain_core.callbacks import CallbackManagerForRetrieverRun +from langchain_core.retrievers import BaseRetriever + + +class VectorSearchRetriever(BaseRetriever): + collection_name: Any + embedding_function: Any + top_k: int + + def _get_relevant_documents( + self, + query: str, + *, + run_manager: CallbackManagerForRetrieverRun, + ) -> list[Document]: + result = VECTOR_DB_CLIENT.search( + collection_name=self.collection_name, + vectors=[self.embedding_function(query)], + limit=self.top_k, + ) + + ids = result.ids[0] + metadatas = result.metadatas[0] + documents = result.documents[0] + + results = [] + for idx in range(len(ids)): + results.append( + Document( + metadata=metadatas[idx], + page_content=documents[idx], + ) + ) + return results + + +def query_doc( + collection_name: str, query_embedding: list[float], k: int, user: UserModel = None +): + try: + result = VECTOR_DB_CLIENT.search( + collection_name=collection_name, + vectors=[query_embedding], + limit=k, + ) + + if result: + log.info(f"query_doc:result {result.ids} {result.metadatas}") + + return result + except Exception as e: + log.exception(f"Error querying doc {collection_name} with limit {k}: {e}") + raise e + + +def get_doc(collection_name: str, user: UserModel = None): + try: + result = VECTOR_DB_CLIENT.get(collection_name=collection_name) + + if result: + log.info(f"query_doc:result {result.ids} {result.metadatas}") + + return result + except Exception as e: + log.exception(f"Error getting doc {collection_name}: {e}") + raise e + + +def query_doc_with_hybrid_search( + collection_name: str, + query: str, + embedding_function, + k: int, + reranking_function, + r: float, +) -> dict: + try: + result = VECTOR_DB_CLIENT.get(collection_name=collection_name) + + bm25_retriever = BM25Retriever.from_texts( + texts=result.documents[0], + metadatas=result.metadatas[0], + ) + bm25_retriever.k = k + + vector_search_retriever = VectorSearchRetriever( + collection_name=collection_name, + embedding_function=embedding_function, + top_k=k, + ) + + ensemble_retriever = EnsembleRetriever( + retrievers=[bm25_retriever, vector_search_retriever], weights=[0.5, 0.5] + ) + compressor = RerankCompressor( + embedding_function=embedding_function, + top_n=k, + reranking_function=reranking_function, + r_score=r, + ) + + compression_retriever = ContextualCompressionRetriever( + base_compressor=compressor, base_retriever=ensemble_retriever + ) + + result = compression_retriever.invoke(query) + result = { + "distances": [[d.metadata.get("score") for d in result]], + "documents": [[d.page_content for d in result]], + "metadatas": [[d.metadata for d in result]], + } + + log.info( + "query_doc_with_hybrid_search:result " + + f'{result["metadatas"]} {result["distances"]}' + ) + return result + except Exception as e: + raise e + + +def merge_get_results(get_results: list[dict]) -> dict: + # Initialize lists to store combined data + combined_documents = [] + combined_metadatas = [] + combined_ids = [] + + for data in get_results: + combined_documents.extend(data["documents"][0]) + combined_metadatas.extend(data["metadatas"][0]) + combined_ids.extend(data["ids"][0]) + + # Create the output dictionary + result = { + "documents": [combined_documents], + "metadatas": [combined_metadatas], + "ids": [combined_ids], + } + + return result + + +def merge_and_sort_query_results( + query_results: list[dict], k: int, reverse: bool = False +) -> dict: + # Initialize lists to store combined data + combined = [] + seen_hashes = set() # To store unique document hashes + + for data in query_results: + distances = data["distances"][0] + documents = data["documents"][0] + metadatas = data["metadatas"][0] + + for distance, document, metadata in zip(distances, documents, metadatas): + if isinstance(document, str): + doc_hash = hashlib.md5( + document.encode() + ).hexdigest() # Compute a hash for uniqueness + + if doc_hash not in seen_hashes: + seen_hashes.add(doc_hash) + combined.append((distance, document, metadata)) + + # Sort the list based on distances + combined.sort(key=lambda x: x[0], reverse=reverse) + + # Slice to keep only the top k elements + sorted_distances, sorted_documents, sorted_metadatas = ( + zip(*combined[:k]) if combined else ([], [], []) + ) + + # Create and return the output dictionary + return { + "distances": [list(sorted_distances)], + "documents": [list(sorted_documents)], + "metadatas": [list(sorted_metadatas)], + } + + +def get_all_items_from_collections(collection_names: list[str]) -> dict: + results = [] + + for collection_name in collection_names: + if collection_name: + try: + result = get_doc(collection_name=collection_name) + if result is not None: + results.append(result.model_dump()) + except Exception as e: + log.exception(f"Error when querying the collection: {e}") + else: + pass + + return merge_get_results(results) + + +def query_collection( + collection_names: list[str], + queries: list[str], + embedding_function, + k: int, +) -> dict: + results = [] + for query in queries: + query_embedding = embedding_function(query) + for collection_name in collection_names: + if collection_name: + try: + result = query_doc( + collection_name=collection_name, + k=k, + query_embedding=query_embedding, + ) + if result is not None: + results.append(result.model_dump()) + except Exception as e: + log.exception(f"Error when querying the collection: {e}") + else: + pass + + if VECTOR_DB == "chroma": + # Chroma uses unconventional cosine similarity, so we don't need to reverse the results + # https://docs.trychroma.com/docs/collections/configure#configuring-chroma-collections + return merge_and_sort_query_results(results, k=k, reverse=False) + else: + return merge_and_sort_query_results(results, k=k, reverse=True) + + +def query_collection_with_hybrid_search( + collection_names: list[str], + queries: list[str], + embedding_function, + k: int, + reranking_function, + r: float, +) -> dict: + results = [] + error = False + for collection_name in collection_names: + try: + for query in queries: + result = query_doc_with_hybrid_search( + collection_name=collection_name, + query=query, + embedding_function=embedding_function, + k=k, + reranking_function=reranking_function, + r=r, + ) + results.append(result) + except Exception as e: + log.exception( + "Error when querying the collection with " f"hybrid_search: {e}" + ) + error = True + + if error: + raise Exception( + "Hybrid search failed for all collections. Using Non hybrid search as fallback." + ) + + if VECTOR_DB == "chroma": + # Chroma uses unconventional cosine similarity, so we don't need to reverse the results + # https://docs.trychroma.com/docs/collections/configure#configuring-chroma-collections + return merge_and_sort_query_results(results, k=k, reverse=False) + else: + return merge_and_sort_query_results(results, k=k, reverse=True) + + +def get_embedding_function( + embedding_engine, + embedding_model, + embedding_function, + url, + key, + embedding_batch_size, +): + if embedding_engine == "": + return lambda query, user=None: embedding_function.encode(query).tolist() + elif embedding_engine in ["ollama", "openai"]: + func = lambda query, user=None: generate_embeddings( + engine=embedding_engine, + model=embedding_model, + text=query, + url=url, + key=key, + user=user, + ) + + def generate_multiple(query, user, func): + if isinstance(query, list): + embeddings = [] + for i in range(0, len(query), embedding_batch_size): + embeddings.extend( + func(query[i : i + embedding_batch_size], user=user) + ) + return embeddings + else: + return func(query, user) + + return lambda query, user=None: generate_multiple(query, user, func) + else: + raise ValueError(f"Unknown embedding engine: {embedding_engine}") + + +def get_sources_from_files( + request, + files, + queries, + embedding_function, + k, + reranking_function, + r, + hybrid_search, + full_context=False, +): + log.debug( + f"files: {files} {queries} {embedding_function} {reranking_function} {full_context}" + ) + + extracted_collections = [] + relevant_contexts = [] + + for file in files: + + context = None + if file.get("docs"): + # BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL + context = { + "documents": [[doc.get("content") for doc in file.get("docs")]], + "metadatas": [[doc.get("metadata") for doc in file.get("docs")]], + } + elif file.get("context") == "full": + # Manual Full Mode Toggle + context = { + "documents": [[file.get("file").get("data", {}).get("content")]], + "metadatas": [[{"file_id": file.get("id"), "name": file.get("name")}]], + } + elif ( + file.get("type") != "web_search" + and request.app.state.config.BYPASS_EMBEDDING_AND_RETRIEVAL + ): + # BYPASS_EMBEDDING_AND_RETRIEVAL + if file.get("type") == "collection": + file_ids = file.get("data", {}).get("file_ids", []) + + documents = [] + metadatas = [] + for file_id in file_ids: + file_object = Files.get_file_by_id(file_id) + + if file_object: + documents.append(file_object.data.get("content", "")) + metadatas.append( + { + "file_id": file_id, + "name": file_object.filename, + "source": file_object.filename, + } + ) + + context = { + "documents": [documents], + "metadatas": [metadatas], + } + + elif file.get("id"): + file_object = Files.get_file_by_id(file.get("id")) + if file_object: + context = { + "documents": [[file_object.data.get("content", "")]], + "metadatas": [ + [ + { + "file_id": file.get("id"), + "name": file_object.filename, + "source": file_object.filename, + } + ] + ], + } + else: + collection_names = [] + if file.get("type") == "collection": + if file.get("legacy"): + collection_names = file.get("collection_names", []) + else: + collection_names.append(file["id"]) + elif file.get("collection_name"): + collection_names.append(file["collection_name"]) + elif file.get("id"): + if file.get("legacy"): + collection_names.append(f"{file['id']}") + else: + collection_names.append(f"file-{file['id']}") + + collection_names = set(collection_names).difference(extracted_collections) + if not collection_names: + log.debug(f"skipping {file} as it has already been extracted") + continue + + if full_context: + try: + context = get_all_items_from_collections(collection_names) + except Exception as e: + log.exception(e) + + else: + try: + context = None + if file.get("type") == "text": + context = file["content"] + else: + if hybrid_search: + try: + context = query_collection_with_hybrid_search( + collection_names=collection_names, + queries=queries, + embedding_function=embedding_function, + k=k, + reranking_function=reranking_function, + r=r, + ) + except Exception as e: + log.debug( + "Error when using hybrid search, using" + " non hybrid search as fallback." + ) + + if (not hybrid_search) or (context is None): + context = query_collection( + collection_names=collection_names, + queries=queries, + embedding_function=embedding_function, + k=k, + ) + except Exception as e: + log.exception(e) + + extracted_collections.extend(collection_names) + + if context: + if "data" in file: + del file["data"] + + relevant_contexts.append({**context, "file": file}) + + sources = [] + for context in relevant_contexts: + try: + if "documents" in context: + if "metadatas" in context: + source = { + "source": context["file"], + "document": context["documents"][0], + "metadata": context["metadatas"][0], + } + if "distances" in context and context["distances"]: + source["distances"] = context["distances"][0] + + sources.append(source) + except Exception as e: + log.exception(e) + + return sources + + +def get_model_path(model: str, update_model: bool = False): + # Construct huggingface_hub kwargs with local_files_only to return the snapshot path + cache_dir = os.getenv("SENTENCE_TRANSFORMERS_HOME") + + local_files_only = not update_model + + if OFFLINE_MODE: + local_files_only = True + + snapshot_kwargs = { + "cache_dir": cache_dir, + "local_files_only": local_files_only, + } + + log.debug(f"model: {model}") + log.debug(f"snapshot_kwargs: {snapshot_kwargs}") + + # Inspiration from upstream sentence_transformers + if ( + os.path.exists(model) + or ("\\" in model or model.count("/") > 1) + and local_files_only + ): + # If fully qualified path exists, return input, else set repo_id + return model + elif "/" not in model: + # Set valid repo_id for model short-name + model = "sentence-transformers" + "/" + model + + snapshot_kwargs["repo_id"] = model + + # Attempt to query the huggingface_hub library to determine the local path and/or to update + try: + model_repo_path = snapshot_download(**snapshot_kwargs) + log.debug(f"model_repo_path: {model_repo_path}") + return model_repo_path + except Exception as e: + log.exception(f"Cannot determine model snapshot path: {e}") + return model + + +def generate_openai_batch_embeddings( + model: str, + texts: list[str], + url: str = "https://api.openai.com/v1", + key: str = "", + user: UserModel = None, +) -> Optional[list[list[float]]]: + try: + r = requests.post( + f"{url}/embeddings", + headers={ + "Content-Type": "application/json", + "Authorization": f"Bearer {key}", + **( + { + "X-OpenWebUI-User-Name": user.name, + "X-OpenWebUI-User-Id": user.id, + "X-OpenWebUI-User-Email": user.email, + "X-OpenWebUI-User-Role": user.role, + } + if ENABLE_FORWARD_USER_INFO_HEADERS and user + else {} + ), + }, + json={"input": texts, "model": model}, + ) + r.raise_for_status() + data = r.json() + if "data" in data: + return [elem["embedding"] for elem in data["data"]] + else: + raise "Something went wrong :/" + except Exception as e: + log.exception(f"Error generating openai batch embeddings: {e}") + return None + + +def generate_ollama_batch_embeddings( + model: str, texts: list[str], url: str, key: str = "", user: UserModel = None +) -> Optional[list[list[float]]]: + try: + r = requests.post( + f"{url}/api/embed", + headers={ + "Content-Type": "application/json", + "Authorization": f"Bearer {key}", + **( + { + "X-OpenWebUI-User-Name": user.name, + "X-OpenWebUI-User-Id": user.id, + "X-OpenWebUI-User-Email": user.email, + "X-OpenWebUI-User-Role": user.role, + } + if ENABLE_FORWARD_USER_INFO_HEADERS + else {} + ), + }, + json={"input": texts, "model": model}, + ) + r.raise_for_status() + data = r.json() + + if "embeddings" in data: + return data["embeddings"] + else: + raise "Something went wrong :/" + except Exception as e: + log.exception(f"Error generating ollama batch embeddings: {e}") + return None + + +def generate_embeddings(engine: str, model: str, text: Union[str, list[str]], **kwargs): + url = kwargs.get("url", "") + key = kwargs.get("key", "") + user = kwargs.get("user") + + if engine == "ollama": + if isinstance(text, list): + embeddings = generate_ollama_batch_embeddings( + **{"model": model, "texts": text, "url": url, "key": key, "user": user} + ) + else: + embeddings = generate_ollama_batch_embeddings( + **{ + "model": model, + "texts": [text], + "url": url, + "key": key, + "user": user, + } + ) + return embeddings[0] if isinstance(text, str) else embeddings + elif engine == "openai": + if isinstance(text, list): + embeddings = generate_openai_batch_embeddings(model, text, url, key, user) + else: + embeddings = generate_openai_batch_embeddings(model, [text], url, key, user) + + return embeddings[0] if isinstance(text, str) else embeddings + + +import operator +from typing import Optional, Sequence + +from langchain_core.callbacks import Callbacks +from langchain_core.documents import BaseDocumentCompressor, Document + + +class RerankCompressor(BaseDocumentCompressor): + embedding_function: Any + top_n: int + reranking_function: Any + r_score: float + + class Config: + extra = "forbid" + arbitrary_types_allowed = True + + def compress_documents( + self, + documents: Sequence[Document], + query: str, + callbacks: Optional[Callbacks] = None, + ) -> Sequence[Document]: + reranking = self.reranking_function is not None + + if reranking: + scores = self.reranking_function.predict( + [(query, doc.page_content) for doc in documents] + ) + else: + from sentence_transformers import util + + query_embedding = self.embedding_function(query) + document_embedding = self.embedding_function( + [doc.page_content for doc in documents] + ) + scores = util.cos_sim(query_embedding, document_embedding)[0] + + docs_with_scores = list(zip(documents, scores.tolist())) + if self.r_score: + docs_with_scores = [ + (d, s) for d, s in docs_with_scores if s >= self.r_score + ] + + result = sorted(docs_with_scores, key=operator.itemgetter(1), reverse=True) + final_results = [] + for doc, doc_score in result[: self.top_n]: + metadata = doc.metadata + metadata["score"] = doc_score + doc = Document( + page_content=doc.page_content, + metadata=metadata, + ) + final_results.append(doc) + return final_results diff --git a/backend/open_webui/retrieval/vector/connector.py b/backend/open_webui/retrieval/vector/connector.py new file mode 100644 index 0000000..bf97bc7 --- /dev/null +++ b/backend/open_webui/retrieval/vector/connector.py @@ -0,0 +1,22 @@ +from open_webui.config import VECTOR_DB + +if VECTOR_DB == "milvus": + from open_webui.retrieval.vector.dbs.milvus import MilvusClient + + VECTOR_DB_CLIENT = MilvusClient() +elif VECTOR_DB == "qdrant": + from open_webui.retrieval.vector.dbs.qdrant import QdrantClient + + VECTOR_DB_CLIENT = QdrantClient() +elif VECTOR_DB == "opensearch": + from open_webui.retrieval.vector.dbs.opensearch import OpenSearchClient + + VECTOR_DB_CLIENT = OpenSearchClient() +elif VECTOR_DB == "pgvector": + from open_webui.retrieval.vector.dbs.pgvector import PgvectorClient + + VECTOR_DB_CLIENT = PgvectorClient() +else: + from open_webui.retrieval.vector.dbs.chroma import ChromaClient + + VECTOR_DB_CLIENT = ChromaClient() diff --git a/backend/open_webui/retrieval/vector/dbs/chroma.py b/backend/open_webui/retrieval/vector/dbs/chroma.py new file mode 100755 index 0000000..006ee20 --- /dev/null +++ b/backend/open_webui/retrieval/vector/dbs/chroma.py @@ -0,0 +1,178 @@ +import chromadb +import logging +from chromadb import Settings +from chromadb.utils.batch_utils import create_batches + +from typing import Optional + +from open_webui.retrieval.vector.main import VectorItem, SearchResult, GetResult +from open_webui.config import ( + CHROMA_DATA_PATH, + CHROMA_HTTP_HOST, + CHROMA_HTTP_PORT, + CHROMA_HTTP_HEADERS, + CHROMA_HTTP_SSL, + CHROMA_TENANT, + CHROMA_DATABASE, + CHROMA_CLIENT_AUTH_PROVIDER, + CHROMA_CLIENT_AUTH_CREDENTIALS, +) +from open_webui.env import SRC_LOG_LEVELS + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["RAG"]) + + +class ChromaClient: + def __init__(self): + settings_dict = { + "allow_reset": True, + "anonymized_telemetry": False, + } + if CHROMA_CLIENT_AUTH_PROVIDER is not None: + settings_dict["chroma_client_auth_provider"] = CHROMA_CLIENT_AUTH_PROVIDER + if CHROMA_CLIENT_AUTH_CREDENTIALS is not None: + settings_dict["chroma_client_auth_credentials"] = ( + CHROMA_CLIENT_AUTH_CREDENTIALS + ) + + if CHROMA_HTTP_HOST != "": + self.client = chromadb.HttpClient( + host=CHROMA_HTTP_HOST, + port=CHROMA_HTTP_PORT, + headers=CHROMA_HTTP_HEADERS, + ssl=CHROMA_HTTP_SSL, + tenant=CHROMA_TENANT, + database=CHROMA_DATABASE, + settings=Settings(**settings_dict), + ) + else: + self.client = chromadb.PersistentClient( + path=CHROMA_DATA_PATH, + settings=Settings(**settings_dict), + tenant=CHROMA_TENANT, + database=CHROMA_DATABASE, + ) + + def has_collection(self, collection_name: str) -> bool: + # Check if the collection exists based on the collection name. + collection_names = self.client.list_collections() + return collection_name in collection_names + + def delete_collection(self, collection_name: str): + # Delete the collection based on the collection name. + return self.client.delete_collection(name=collection_name) + + def search( + self, collection_name: str, vectors: list[list[float | int]], limit: int + ) -> Optional[SearchResult]: + # Search for the nearest neighbor items based on the vectors and return 'limit' number of results. + try: + collection = self.client.get_collection(name=collection_name) + if collection: + result = collection.query( + query_embeddings=vectors, + n_results=limit, + ) + + return SearchResult( + **{ + "ids": result["ids"], + "distances": result["distances"], + "documents": result["documents"], + "metadatas": result["metadatas"], + } + ) + return None + except Exception as e: + return None + + def query( + self, collection_name: str, filter: dict, limit: Optional[int] = None + ) -> Optional[GetResult]: + # Query the items from the collection based on the filter. + try: + collection = self.client.get_collection(name=collection_name) + if collection: + result = collection.get( + where=filter, + limit=limit, + ) + + return GetResult( + **{ + "ids": [result["ids"]], + "documents": [result["documents"]], + "metadatas": [result["metadatas"]], + } + ) + return None + except: + return None + + def get(self, collection_name: str) -> Optional[GetResult]: + # Get all the items in the collection. + collection = self.client.get_collection(name=collection_name) + if collection: + result = collection.get() + return GetResult( + **{ + "ids": [result["ids"]], + "documents": [result["documents"]], + "metadatas": [result["metadatas"]], + } + ) + return None + + def insert(self, collection_name: str, items: list[VectorItem]): + # Insert the items into the collection, if the collection does not exist, it will be created. + collection = self.client.get_or_create_collection( + name=collection_name, metadata={"hnsw:space": "cosine"} + ) + + ids = [item["id"] for item in items] + documents = [item["text"] for item in items] + embeddings = [item["vector"] for item in items] + metadatas = [item["metadata"] for item in items] + + for batch in create_batches( + api=self.client, + documents=documents, + embeddings=embeddings, + ids=ids, + metadatas=metadatas, + ): + collection.add(*batch) + + def upsert(self, collection_name: str, items: list[VectorItem]): + # Update the items in the collection, if the items are not present, insert them. If the collection does not exist, it will be created. + collection = self.client.get_or_create_collection( + name=collection_name, metadata={"hnsw:space": "cosine"} + ) + + ids = [item["id"] for item in items] + documents = [item["text"] for item in items] + embeddings = [item["vector"] for item in items] + metadatas = [item["metadata"] for item in items] + + collection.upsert( + ids=ids, documents=documents, embeddings=embeddings, metadatas=metadatas + ) + + def delete( + self, + collection_name: str, + ids: Optional[list[str]] = None, + filter: Optional[dict] = None, + ): + # Delete the items from the collection based on the ids. + collection = self.client.get_collection(name=collection_name) + if collection: + if ids: + collection.delete(ids=ids) + elif filter: + collection.delete(where=filter) + + def reset(self): + # Resets the database. This will delete all collections and item entries. + return self.client.reset() diff --git a/backend/open_webui/retrieval/vector/dbs/milvus.py b/backend/open_webui/retrieval/vector/dbs/milvus.py new file mode 100644 index 0000000..3fd5b1c --- /dev/null +++ b/backend/open_webui/retrieval/vector/dbs/milvus.py @@ -0,0 +1,297 @@ +from pymilvus import MilvusClient as Client +from pymilvus import FieldSchema, DataType +import json +import logging +from typing import Optional + +from open_webui.retrieval.vector.main import VectorItem, SearchResult, GetResult +from open_webui.config import ( + MILVUS_URI, + MILVUS_DB, + MILVUS_TOKEN, +) +from open_webui.env import SRC_LOG_LEVELS + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["RAG"]) + + +class MilvusClient: + def __init__(self): + self.collection_prefix = "open_webui" + if MILVUS_TOKEN is None: + self.client = Client(uri=MILVUS_URI, database=MILVUS_DB) + else: + self.client = Client(uri=MILVUS_URI, database=MILVUS_DB, token=MILVUS_TOKEN) + + def _result_to_get_result(self, result) -> GetResult: + ids = [] + documents = [] + metadatas = [] + + for match in result: + _ids = [] + _documents = [] + _metadatas = [] + for item in match: + _ids.append(item.get("id")) + _documents.append(item.get("data", {}).get("text")) + _metadatas.append(item.get("metadata")) + + ids.append(_ids) + documents.append(_documents) + metadatas.append(_metadatas) + + return GetResult( + **{ + "ids": ids, + "documents": documents, + "metadatas": metadatas, + } + ) + + def _result_to_search_result(self, result) -> SearchResult: + ids = [] + distances = [] + documents = [] + metadatas = [] + + for match in result: + _ids = [] + _distances = [] + _documents = [] + _metadatas = [] + + for item in match: + _ids.append(item.get("id")) + _distances.append(item.get("distance")) + _documents.append(item.get("entity", {}).get("data", {}).get("text")) + _metadatas.append(item.get("entity", {}).get("metadata")) + + ids.append(_ids) + distances.append(_distances) + documents.append(_documents) + metadatas.append(_metadatas) + + return SearchResult( + **{ + "ids": ids, + "distances": distances, + "documents": documents, + "metadatas": metadatas, + } + ) + + def _create_collection(self, collection_name: str, dimension: int): + schema = self.client.create_schema( + auto_id=False, + enable_dynamic_field=True, + ) + schema.add_field( + field_name="id", + datatype=DataType.VARCHAR, + is_primary=True, + max_length=65535, + ) + schema.add_field( + field_name="vector", + datatype=DataType.FLOAT_VECTOR, + dim=dimension, + description="vector", + ) + schema.add_field(field_name="data", datatype=DataType.JSON, description="data") + schema.add_field( + field_name="metadata", datatype=DataType.JSON, description="metadata" + ) + + index_params = self.client.prepare_index_params() + index_params.add_index( + field_name="vector", + index_type="HNSW", + metric_type="COSINE", + params={"M": 16, "efConstruction": 100}, + ) + + self.client.create_collection( + collection_name=f"{self.collection_prefix}_{collection_name}", + schema=schema, + index_params=index_params, + ) + + def has_collection(self, collection_name: str) -> bool: + # Check if the collection exists based on the collection name. + collection_name = collection_name.replace("-", "_") + return self.client.has_collection( + collection_name=f"{self.collection_prefix}_{collection_name}" + ) + + def delete_collection(self, collection_name: str): + # Delete the collection based on the collection name. + collection_name = collection_name.replace("-", "_") + return self.client.drop_collection( + collection_name=f"{self.collection_prefix}_{collection_name}" + ) + + def search( + self, collection_name: str, vectors: list[list[float | int]], limit: int + ) -> Optional[SearchResult]: + # Search for the nearest neighbor items based on the vectors and return 'limit' number of results. + collection_name = collection_name.replace("-", "_") + result = self.client.search( + collection_name=f"{self.collection_prefix}_{collection_name}", + data=vectors, + limit=limit, + output_fields=["data", "metadata"], + ) + + return self._result_to_search_result(result) + + def query(self, collection_name: str, filter: dict, limit: Optional[int] = None): + # Construct the filter string for querying + collection_name = collection_name.replace("-", "_") + if not self.has_collection(collection_name): + return None + + filter_string = " && ".join( + [ + f'metadata["{key}"] == {json.dumps(value)}' + for key, value in filter.items() + ] + ) + + max_limit = 16383 # The maximum number of records per request + all_results = [] + + if limit is None: + limit = float("inf") # Use infinity as a placeholder for no limit + + # Initialize offset and remaining to handle pagination + offset = 0 + remaining = limit + + try: + # Loop until there are no more items to fetch or the desired limit is reached + while remaining > 0: + log.info(f"remaining: {remaining}") + current_fetch = min( + max_limit, remaining + ) # Determine how many items to fetch in this iteration + + results = self.client.query( + collection_name=f"{self.collection_prefix}_{collection_name}", + filter=filter_string, + output_fields=["*"], + limit=current_fetch, + offset=offset, + ) + + if not results: + break + + all_results.extend(results) + results_count = len(results) + remaining -= ( + results_count # Decrease remaining by the number of items fetched + ) + offset += results_count + + # Break the loop if the results returned are less than the requested fetch count + if results_count < current_fetch: + break + + log.debug(all_results) + return self._result_to_get_result([all_results]) + except Exception as e: + log.exception( + f"Error querying collection {collection_name} with limit {limit}: {e}" + ) + return None + + def get(self, collection_name: str) -> Optional[GetResult]: + # Get all the items in the collection. + collection_name = collection_name.replace("-", "_") + result = self.client.query( + collection_name=f"{self.collection_prefix}_{collection_name}", + filter='id != ""', + ) + return self._result_to_get_result([result]) + + def insert(self, collection_name: str, items: list[VectorItem]): + # Insert the items into the collection, if the collection does not exist, it will be created. + collection_name = collection_name.replace("-", "_") + if not self.client.has_collection( + collection_name=f"{self.collection_prefix}_{collection_name}" + ): + self._create_collection( + collection_name=collection_name, dimension=len(items[0]["vector"]) + ) + + return self.client.insert( + collection_name=f"{self.collection_prefix}_{collection_name}", + data=[ + { + "id": item["id"], + "vector": item["vector"], + "data": {"text": item["text"]}, + "metadata": item["metadata"], + } + for item in items + ], + ) + + def upsert(self, collection_name: str, items: list[VectorItem]): + # Update the items in the collection, if the items are not present, insert them. If the collection does not exist, it will be created. + collection_name = collection_name.replace("-", "_") + if not self.client.has_collection( + collection_name=f"{self.collection_prefix}_{collection_name}" + ): + self._create_collection( + collection_name=collection_name, dimension=len(items[0]["vector"]) + ) + + return self.client.upsert( + collection_name=f"{self.collection_prefix}_{collection_name}", + data=[ + { + "id": item["id"], + "vector": item["vector"], + "data": {"text": item["text"]}, + "metadata": item["metadata"], + } + for item in items + ], + ) + + def delete( + self, + collection_name: str, + ids: Optional[list[str]] = None, + filter: Optional[dict] = None, + ): + # Delete the items from the collection based on the ids. + collection_name = collection_name.replace("-", "_") + if ids: + return self.client.delete( + collection_name=f"{self.collection_prefix}_{collection_name}", + ids=ids, + ) + elif filter: + # Convert the filter dictionary to a string using JSON_CONTAINS. + filter_string = " && ".join( + [ + f'metadata["{key}"] == {json.dumps(value)}' + for key, value in filter.items() + ] + ) + + return self.client.delete( + collection_name=f"{self.collection_prefix}_{collection_name}", + filter=filter_string, + ) + + def reset(self): + # Resets the database. This will delete all collections and item entries. + collection_names = self.client.list_collections() + for collection_name in collection_names: + if collection_name.startswith(self.collection_prefix): + self.client.drop_collection(collection_name=collection_name) diff --git a/backend/open_webui/retrieval/vector/dbs/opensearch.py b/backend/open_webui/retrieval/vector/dbs/opensearch.py new file mode 100644 index 0000000..b8186b3 --- /dev/null +++ b/backend/open_webui/retrieval/vector/dbs/opensearch.py @@ -0,0 +1,206 @@ +from opensearchpy import OpenSearch +from typing import Optional + +from open_webui.retrieval.vector.main import VectorItem, SearchResult, GetResult +from open_webui.config import ( + OPENSEARCH_URI, + OPENSEARCH_SSL, + OPENSEARCH_CERT_VERIFY, + OPENSEARCH_USERNAME, + OPENSEARCH_PASSWORD, +) + + +class OpenSearchClient: + def __init__(self): + self.index_prefix = "open_webui" + self.client = OpenSearch( + hosts=[OPENSEARCH_URI], + use_ssl=OPENSEARCH_SSL, + verify_certs=OPENSEARCH_CERT_VERIFY, + http_auth=(OPENSEARCH_USERNAME, OPENSEARCH_PASSWORD), + ) + + def _result_to_get_result(self, result) -> GetResult: + ids = [] + documents = [] + metadatas = [] + + for hit in result["hits"]["hits"]: + ids.append(hit["_id"]) + documents.append(hit["_source"].get("text")) + metadatas.append(hit["_source"].get("metadata")) + + return GetResult(ids=ids, documents=documents, metadatas=metadatas) + + def _result_to_search_result(self, result) -> SearchResult: + ids = [] + distances = [] + documents = [] + metadatas = [] + + for hit in result["hits"]["hits"]: + ids.append(hit["_id"]) + distances.append(hit["_score"]) + documents.append(hit["_source"].get("text")) + metadatas.append(hit["_source"].get("metadata")) + + return SearchResult( + ids=ids, distances=distances, documents=documents, metadatas=metadatas + ) + + def _create_index(self, index_name: str, dimension: int): + body = { + "mappings": { + "properties": { + "id": {"type": "keyword"}, + "vector": { + "type": "dense_vector", + "dims": dimension, # Adjust based on your vector dimensions + "index": true, + "similarity": "faiss", + "method": { + "name": "hnsw", + "space_type": "ip", # Use inner product to approximate cosine similarity + "engine": "faiss", + "ef_construction": 128, + "m": 16, + }, + }, + "text": {"type": "text"}, + "metadata": {"type": "object"}, + } + } + } + self.client.indices.create(index=f"{self.index_prefix}_{index_name}", body=body) + + def _create_batches(self, items: list[VectorItem], batch_size=100): + for i in range(0, len(items), batch_size): + yield items[i : i + batch_size] + + def has_collection(self, index_name: str) -> bool: + # has_collection here means has index. + # We are simply adapting to the norms of the other DBs. + return self.client.indices.exists(index=f"{self.index_prefix}_{index_name}") + + def delete_colleciton(self, index_name: str): + # delete_collection here means delete index. + # We are simply adapting to the norms of the other DBs. + self.client.indices.delete(index=f"{self.index_prefix}_{index_name}") + + def search( + self, index_name: str, vectors: list[list[float]], limit: int + ) -> Optional[SearchResult]: + query = { + "size": limit, + "_source": ["text", "metadata"], + "query": { + "script_score": { + "query": {"match_all": {}}, + "script": { + "source": "cosineSimilarity(params.vector, 'vector') + 1.0", + "params": { + "vector": vectors[0] + }, # Assuming single query vector + }, + } + }, + } + + result = self.client.search( + index=f"{self.index_prefix}_{index_name}", body=query + ) + + return self._result_to_search_result(result) + + def query( + self, collection_name: str, filter: dict, limit: Optional[int] = None + ) -> Optional[GetResult]: + if not self.has_collection(collection_name): + return None + + query_body = { + "query": {"bool": {"filter": []}}, + "_source": ["text", "metadata"], + } + + for field, value in filter.items(): + query_body["query"]["bool"]["filter"].append({"term": {field: value}}) + + size = limit if limit else 10 + + try: + result = self.client.search( + index=f"{self.index_prefix}_{collection_name}", + body=query_body, + size=size, + ) + + return self._result_to_get_result(result) + + except Exception as e: + return None + + def get_or_create_index(self, index_name: str, dimension: int): + if not self.has_index(index_name): + self._create_index(index_name, dimension) + + def get(self, index_name: str) -> Optional[GetResult]: + query = {"query": {"match_all": {}}, "_source": ["text", "metadata"]} + + result = self.client.search( + index=f"{self.index_prefix}_{index_name}", body=query + ) + return self._result_to_get_result(result) + + def insert(self, index_name: str, items: list[VectorItem]): + if not self.has_index(index_name): + self._create_index(index_name, dimension=len(items[0]["vector"])) + + for batch in self._create_batches(items): + actions = [ + { + "index": { + "_id": item["id"], + "_source": { + "vector": item["vector"], + "text": item["text"], + "metadata": item["metadata"], + }, + } + } + for item in batch + ] + self.client.bulk(actions) + + def upsert(self, index_name: str, items: list[VectorItem]): + if not self.has_index(index_name): + self._create_index(index_name, dimension=len(items[0]["vector"])) + + for batch in self._create_batches(items): + actions = [ + { + "index": { + "_id": item["id"], + "_source": { + "vector": item["vector"], + "text": item["text"], + "metadata": item["metadata"], + }, + } + } + for item in batch + ] + self.client.bulk(actions) + + def delete(self, index_name: str, ids: list[str]): + actions = [ + {"delete": {"_index": f"{self.index_prefix}_{index_name}", "_id": id}} + for id in ids + ] + self.client.bulk(body=actions) + + def reset(self): + indices = self.client.indices.get(index=f"{self.index_prefix}_*") + for index in indices: + self.client.indices.delete(index=index) diff --git a/backend/open_webui/retrieval/vector/dbs/pgvector.py b/backend/open_webui/retrieval/vector/dbs/pgvector.py new file mode 100644 index 0000000..eab0223 --- /dev/null +++ b/backend/open_webui/retrieval/vector/dbs/pgvector.py @@ -0,0 +1,403 @@ +from typing import Optional, List, Dict, Any +import logging +from sqlalchemy import ( + cast, + column, + create_engine, + Column, + Integer, + MetaData, + select, + text, + Text, + Table, + values, +) +from sqlalchemy.sql import true +from sqlalchemy.pool import NullPool + +from sqlalchemy.orm import declarative_base, scoped_session, sessionmaker +from sqlalchemy.dialects.postgresql import JSONB, array +from pgvector.sqlalchemy import Vector +from sqlalchemy.ext.mutable import MutableDict +from sqlalchemy.exc import NoSuchTableError + +from open_webui.retrieval.vector.main import VectorItem, SearchResult, GetResult +from open_webui.config import PGVECTOR_DB_URL, PGVECTOR_INITIALIZE_MAX_VECTOR_LENGTH + +from open_webui.env import SRC_LOG_LEVELS + +VECTOR_LENGTH = PGVECTOR_INITIALIZE_MAX_VECTOR_LENGTH +Base = declarative_base() + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["RAG"]) + + +class DocumentChunk(Base): + __tablename__ = "document_chunk" + + id = Column(Text, primary_key=True) + vector = Column(Vector(dim=VECTOR_LENGTH), nullable=True) + collection_name = Column(Text, nullable=False) + text = Column(Text, nullable=True) + vmetadata = Column(MutableDict.as_mutable(JSONB), nullable=True) + + +class PgvectorClient: + def __init__(self) -> None: + + # if no pgvector uri, use the existing database connection + if not PGVECTOR_DB_URL: + from open_webui.internal.db import Session + + self.session = Session + else: + engine = create_engine( + PGVECTOR_DB_URL, pool_pre_ping=True, poolclass=NullPool + ) + SessionLocal = sessionmaker( + autocommit=False, autoflush=False, bind=engine, expire_on_commit=False + ) + self.session = scoped_session(SessionLocal) + + try: + # Ensure the pgvector extension is available + self.session.execute(text("CREATE EXTENSION IF NOT EXISTS vector;")) + + # Check vector length consistency + self.check_vector_length() + + # Create the tables if they do not exist + # Base.metadata.create_all requires a bind (engine or connection) + # Get the connection from the session + connection = self.session.connection() + Base.metadata.create_all(bind=connection) + + # Create an index on the vector column if it doesn't exist + self.session.execute( + text( + "CREATE INDEX IF NOT EXISTS idx_document_chunk_vector " + "ON document_chunk USING ivfflat (vector vector_cosine_ops) WITH (lists = 100);" + ) + ) + self.session.execute( + text( + "CREATE INDEX IF NOT EXISTS idx_document_chunk_collection_name " + "ON document_chunk (collection_name);" + ) + ) + self.session.commit() + log.info("Initialization complete.") + except Exception as e: + self.session.rollback() + log.exception(f"Error during initialization: {e}") + raise + + def check_vector_length(self) -> None: + """ + Check if the VECTOR_LENGTH matches the existing vector column dimension in the database. + Raises an exception if there is a mismatch. + """ + metadata = MetaData() + try: + # Attempt to reflect the 'document_chunk' table + document_chunk_table = Table( + "document_chunk", metadata, autoload_with=self.session.bind + ) + except NoSuchTableError: + # Table does not exist; no action needed + return + + # Proceed to check the vector column + if "vector" in document_chunk_table.columns: + vector_column = document_chunk_table.columns["vector"] + vector_type = vector_column.type + if isinstance(vector_type, Vector): + db_vector_length = vector_type.dim + if db_vector_length != VECTOR_LENGTH: + raise Exception( + f"VECTOR_LENGTH {VECTOR_LENGTH} does not match existing vector column dimension {db_vector_length}. " + "Cannot change vector size after initialization without migrating the data." + ) + else: + raise Exception( + "The 'vector' column exists but is not of type 'Vector'." + ) + else: + raise Exception( + "The 'vector' column does not exist in the 'document_chunk' table." + ) + + def adjust_vector_length(self, vector: List[float]) -> List[float]: + # Adjust vector to have length VECTOR_LENGTH + current_length = len(vector) + if current_length < VECTOR_LENGTH: + # Pad the vector with zeros + vector += [0.0] * (VECTOR_LENGTH - current_length) + elif current_length > VECTOR_LENGTH: + raise Exception( + f"Vector length {current_length} not supported. Max length must be <= {VECTOR_LENGTH}" + ) + return vector + + def insert(self, collection_name: str, items: List[VectorItem]) -> None: + try: + new_items = [] + for item in items: + vector = self.adjust_vector_length(item["vector"]) + new_chunk = DocumentChunk( + id=item["id"], + vector=vector, + collection_name=collection_name, + text=item["text"], + vmetadata=item["metadata"], + ) + new_items.append(new_chunk) + self.session.bulk_save_objects(new_items) + self.session.commit() + log.info( + f"Inserted {len(new_items)} items into collection '{collection_name}'." + ) + except Exception as e: + self.session.rollback() + log.exception(f"Error during insert: {e}") + raise + + def upsert(self, collection_name: str, items: List[VectorItem]) -> None: + try: + for item in items: + vector = self.adjust_vector_length(item["vector"]) + existing = ( + self.session.query(DocumentChunk) + .filter(DocumentChunk.id == item["id"]) + .first() + ) + if existing: + existing.vector = vector + existing.text = item["text"] + existing.vmetadata = item["metadata"] + existing.collection_name = ( + collection_name # Update collection_name if necessary + ) + else: + new_chunk = DocumentChunk( + id=item["id"], + vector=vector, + collection_name=collection_name, + text=item["text"], + vmetadata=item["metadata"], + ) + self.session.add(new_chunk) + self.session.commit() + log.info( + f"Upserted {len(items)} items into collection '{collection_name}'." + ) + except Exception as e: + self.session.rollback() + log.exception(f"Error during upsert: {e}") + raise + + def search( + self, + collection_name: str, + vectors: List[List[float]], + limit: Optional[int] = None, + ) -> Optional[SearchResult]: + try: + if not vectors: + return None + + # Adjust query vectors to VECTOR_LENGTH + vectors = [self.adjust_vector_length(vector) for vector in vectors] + num_queries = len(vectors) + + def vector_expr(vector): + return cast(array(vector), Vector(VECTOR_LENGTH)) + + # Create the values for query vectors + qid_col = column("qid", Integer) + q_vector_col = column("q_vector", Vector(VECTOR_LENGTH)) + query_vectors = ( + values(qid_col, q_vector_col) + .data( + [(idx, vector_expr(vector)) for idx, vector in enumerate(vectors)] + ) + .alias("query_vectors") + ) + + # Build the lateral subquery for each query vector + subq = ( + select( + DocumentChunk.id, + DocumentChunk.text, + DocumentChunk.vmetadata, + ( + DocumentChunk.vector.cosine_distance(query_vectors.c.q_vector) + ).label("distance"), + ) + .where(DocumentChunk.collection_name == collection_name) + .order_by( + (DocumentChunk.vector.cosine_distance(query_vectors.c.q_vector)) + ) + ) + if limit is not None: + subq = subq.limit(limit) + subq = subq.lateral("result") + + # Build the main query by joining query_vectors and the lateral subquery + stmt = ( + select( + query_vectors.c.qid, + subq.c.id, + subq.c.text, + subq.c.vmetadata, + subq.c.distance, + ) + .select_from(query_vectors) + .join(subq, true()) + .order_by(query_vectors.c.qid, subq.c.distance) + ) + + result_proxy = self.session.execute(stmt) + results = result_proxy.all() + + ids = [[] for _ in range(num_queries)] + distances = [[] for _ in range(num_queries)] + documents = [[] for _ in range(num_queries)] + metadatas = [[] for _ in range(num_queries)] + + if not results: + return SearchResult( + ids=ids, + distances=distances, + documents=documents, + metadatas=metadatas, + ) + + for row in results: + qid = int(row.qid) + ids[qid].append(row.id) + distances[qid].append(row.distance) + documents[qid].append(row.text) + metadatas[qid].append(row.vmetadata) + + return SearchResult( + ids=ids, distances=distances, documents=documents, metadatas=metadatas + ) + except Exception as e: + log.exception(f"Error during search: {e}") + return None + + def query( + self, collection_name: str, filter: Dict[str, Any], limit: Optional[int] = None + ) -> Optional[GetResult]: + try: + query = self.session.query(DocumentChunk).filter( + DocumentChunk.collection_name == collection_name + ) + + for key, value in filter.items(): + query = query.filter(DocumentChunk.vmetadata[key].astext == str(value)) + + if limit is not None: + query = query.limit(limit) + + results = query.all() + + if not results: + return None + + ids = [[result.id for result in results]] + documents = [[result.text for result in results]] + metadatas = [[result.vmetadata for result in results]] + + return GetResult( + ids=ids, + documents=documents, + metadatas=metadatas, + ) + except Exception as e: + log.exception(f"Error during query: {e}") + return None + + def get( + self, collection_name: str, limit: Optional[int] = None + ) -> Optional[GetResult]: + try: + query = self.session.query(DocumentChunk).filter( + DocumentChunk.collection_name == collection_name + ) + if limit is not None: + query = query.limit(limit) + + results = query.all() + + if not results: + return None + + ids = [[result.id for result in results]] + documents = [[result.text for result in results]] + metadatas = [[result.vmetadata for result in results]] + + return GetResult(ids=ids, documents=documents, metadatas=metadatas) + except Exception as e: + log.exception(f"Error during get: {e}") + return None + + def delete( + self, + collection_name: str, + ids: Optional[List[str]] = None, + filter: Optional[Dict[str, Any]] = None, + ) -> None: + try: + query = self.session.query(DocumentChunk).filter( + DocumentChunk.collection_name == collection_name + ) + if ids: + query = query.filter(DocumentChunk.id.in_(ids)) + if filter: + for key, value in filter.items(): + query = query.filter( + DocumentChunk.vmetadata[key].astext == str(value) + ) + deleted = query.delete(synchronize_session=False) + self.session.commit() + log.info(f"Deleted {deleted} items from collection '{collection_name}'.") + except Exception as e: + self.session.rollback() + log.exception(f"Error during delete: {e}") + raise + + def reset(self) -> None: + try: + deleted = self.session.query(DocumentChunk).delete() + self.session.commit() + log.info( + f"Reset complete. Deleted {deleted} items from 'document_chunk' table." + ) + except Exception as e: + self.session.rollback() + log.exception(f"Error during reset: {e}") + raise + + def close(self) -> None: + pass + + def has_collection(self, collection_name: str) -> bool: + try: + exists = ( + self.session.query(DocumentChunk) + .filter(DocumentChunk.collection_name == collection_name) + .first() + is not None + ) + return exists + except Exception as e: + log.exception(f"Error checking collection existence: {e}") + return False + + def delete_collection(self, collection_name: str) -> None: + self.delete(collection_name) + log.info(f"Collection '{collection_name}' deleted.") diff --git a/backend/open_webui/retrieval/vector/dbs/qdrant.py b/backend/open_webui/retrieval/vector/dbs/qdrant.py new file mode 100644 index 0000000..28f0b37 --- /dev/null +++ b/backend/open_webui/retrieval/vector/dbs/qdrant.py @@ -0,0 +1,189 @@ +from typing import Optional +import logging + +from qdrant_client import QdrantClient as Qclient +from qdrant_client.http.models import PointStruct +from qdrant_client.models import models + +from open_webui.retrieval.vector.main import VectorItem, SearchResult, GetResult +from open_webui.config import QDRANT_URI, QDRANT_API_KEY +from open_webui.env import SRC_LOG_LEVELS + +NO_LIMIT = 999999999 + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["RAG"]) + + +class QdrantClient: + def __init__(self): + self.collection_prefix = "open-webui" + self.QDRANT_URI = QDRANT_URI + self.QDRANT_API_KEY = QDRANT_API_KEY + self.client = ( + Qclient(url=self.QDRANT_URI, api_key=self.QDRANT_API_KEY) + if self.QDRANT_URI + else None + ) + + def _result_to_get_result(self, points) -> GetResult: + ids = [] + documents = [] + metadatas = [] + + for point in points: + payload = point.payload + ids.append(point.id) + documents.append(payload["text"]) + metadatas.append(payload["metadata"]) + + return GetResult( + **{ + "ids": [ids], + "documents": [documents], + "metadatas": [metadatas], + } + ) + + def _create_collection(self, collection_name: str, dimension: int): + collection_name_with_prefix = f"{self.collection_prefix}_{collection_name}" + self.client.create_collection( + collection_name=collection_name_with_prefix, + vectors_config=models.VectorParams( + size=dimension, distance=models.Distance.COSINE + ), + ) + + log.info(f"collection {collection_name_with_prefix} successfully created!") + + def _create_collection_if_not_exists(self, collection_name, dimension): + if not self.has_collection(collection_name=collection_name): + self._create_collection( + collection_name=collection_name, dimension=dimension + ) + + def _create_points(self, items: list[VectorItem]): + return [ + PointStruct( + id=item["id"], + vector=item["vector"], + payload={"text": item["text"], "metadata": item["metadata"]}, + ) + for item in items + ] + + def has_collection(self, collection_name: str) -> bool: + return self.client.collection_exists( + f"{self.collection_prefix}_{collection_name}" + ) + + def delete_collection(self, collection_name: str): + return self.client.delete_collection( + collection_name=f"{self.collection_prefix}_{collection_name}" + ) + + def search( + self, collection_name: str, vectors: list[list[float | int]], limit: int + ) -> Optional[SearchResult]: + # Search for the nearest neighbor items based on the vectors and return 'limit' number of results. + if limit is None: + limit = NO_LIMIT # otherwise qdrant would set limit to 10! + + query_response = self.client.query_points( + collection_name=f"{self.collection_prefix}_{collection_name}", + query=vectors[0], + limit=limit, + ) + get_result = self._result_to_get_result(query_response.points) + return SearchResult( + ids=get_result.ids, + documents=get_result.documents, + metadatas=get_result.metadatas, + distances=[[point.score for point in query_response.points]], + ) + + def query(self, collection_name: str, filter: dict, limit: Optional[int] = None): + # Construct the filter string for querying + if not self.has_collection(collection_name): + return None + try: + if limit is None: + limit = NO_LIMIT # otherwise qdrant would set limit to 10! + + field_conditions = [] + for key, value in filter.items(): + field_conditions.append( + models.FieldCondition( + key=f"metadata.{key}", match=models.MatchValue(value=value) + ) + ) + + points = self.client.query_points( + collection_name=f"{self.collection_prefix}_{collection_name}", + query_filter=models.Filter(should=field_conditions), + limit=limit, + ) + return self._result_to_get_result(points.points) + except Exception as e: + log.exception(f"Error querying a collection '{collection_name}': {e}") + return None + + def get(self, collection_name: str) -> Optional[GetResult]: + # Get all the items in the collection. + points = self.client.query_points( + collection_name=f"{self.collection_prefix}_{collection_name}", + limit=NO_LIMIT, # otherwise qdrant would set limit to 10! + ) + return self._result_to_get_result(points.points) + + def insert(self, collection_name: str, items: list[VectorItem]): + # Insert the items into the collection, if the collection does not exist, it will be created. + self._create_collection_if_not_exists(collection_name, len(items[0]["vector"])) + points = self._create_points(items) + self.client.upload_points(f"{self.collection_prefix}_{collection_name}", points) + + def upsert(self, collection_name: str, items: list[VectorItem]): + # Update the items in the collection, if the items are not present, insert them. If the collection does not exist, it will be created. + self._create_collection_if_not_exists(collection_name, len(items[0]["vector"])) + points = self._create_points(items) + return self.client.upsert(f"{self.collection_prefix}_{collection_name}", points) + + def delete( + self, + collection_name: str, + ids: Optional[list[str]] = None, + filter: Optional[dict] = None, + ): + # Delete the items from the collection based on the ids. + field_conditions = [] + + if ids: + for id_value in ids: + field_conditions.append( + models.FieldCondition( + key="metadata.id", + match=models.MatchValue(value=id_value), + ), + ), + elif filter: + for key, value in filter.items(): + field_conditions.append( + models.FieldCondition( + key=f"metadata.{key}", + match=models.MatchValue(value=value), + ), + ), + + return self.client.delete( + collection_name=f"{self.collection_prefix}_{collection_name}", + points_selector=models.FilterSelector( + filter=models.Filter(must=field_conditions) + ), + ) + + def reset(self): + # Resets the database. This will delete all collections and item entries. + collection_names = self.client.get_collections().collections + for collection_name in collection_names: + if collection_name.name.startswith(self.collection_prefix): + self.client.delete_collection(collection_name=collection_name.name) diff --git a/backend/open_webui/retrieval/vector/main.py b/backend/open_webui/retrieval/vector/main.py new file mode 100644 index 0000000..f0cf0c0 --- /dev/null +++ b/backend/open_webui/retrieval/vector/main.py @@ -0,0 +1,19 @@ +from pydantic import BaseModel +from typing import Optional, List, Any + + +class VectorItem(BaseModel): + id: str + text: str + vector: List[float | int] + metadata: Any + + +class GetResult(BaseModel): + ids: Optional[List[List[str]]] + documents: Optional[List[List[str]]] + metadatas: Optional[List[List[Any]]] + + +class SearchResult(GetResult): + distances: Optional[List[List[float | int]]] diff --git a/backend/open_webui/retrieval/web/bing.py b/backend/open_webui/retrieval/web/bing.py new file mode 100644 index 0000000..0a3ba46 --- /dev/null +++ b/backend/open_webui/retrieval/web/bing.py @@ -0,0 +1,73 @@ +import logging +import os +from pprint import pprint +from typing import Optional +import requests +from open_webui.retrieval.web.main import SearchResult, get_filtered_results +from open_webui.env import SRC_LOG_LEVELS +import argparse + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["RAG"]) +""" +Documentation: https://docs.microsoft.com/en-us/bing/search-apis/bing-web-search/overview +""" + + +def search_bing( + subscription_key: str, + endpoint: str, + locale: str, + query: str, + count: int, + filter_list: Optional[list[str]] = None, +) -> list[SearchResult]: + mkt = locale + params = {"q": query, "mkt": mkt, "count": count} + headers = {"Ocp-Apim-Subscription-Key": subscription_key} + + try: + response = requests.get(endpoint, headers=headers, params=params) + response.raise_for_status() + json_response = response.json() + results = json_response.get("webPages", {}).get("value", []) + if filter_list: + results = get_filtered_results(results, filter_list) + return [ + SearchResult( + link=result["url"], + title=result.get("name"), + snippet=result.get("snippet"), + ) + for result in results + ] + except Exception as ex: + log.error(f"Error: {ex}") + raise ex + + +def main(): + parser = argparse.ArgumentParser(description="Search Bing from the command line.") + parser.add_argument( + "query", + type=str, + default="Top 10 international news today", + help="The search query.", + ) + parser.add_argument( + "--count", type=int, default=10, help="Number of search results to return." + ) + parser.add_argument( + "--filter", nargs="*", help="List of filters to apply to the search results." + ) + parser.add_argument( + "--locale", + type=str, + default="en-US", + help="The locale to use for the search, maps to market in api", + ) + + args = parser.parse_args() + + results = search_bing(args.locale, args.query, args.count, args.filter) + pprint(results) diff --git a/backend/open_webui/retrieval/web/bocha.py b/backend/open_webui/retrieval/web/bocha.py new file mode 100644 index 0000000..f26da36 --- /dev/null +++ b/backend/open_webui/retrieval/web/bocha.py @@ -0,0 +1,65 @@ +import logging +from typing import Optional + +import requests +import json +from open_webui.retrieval.web.main import SearchResult, get_filtered_results +from open_webui.env import SRC_LOG_LEVELS + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["RAG"]) + + +def _parse_response(response): + result = {} + if "data" in response: + data = response["data"] + if "webPages" in data: + webPages = data["webPages"] + if "value" in webPages: + result["webpage"] = [ + { + "id": item.get("id", ""), + "name": item.get("name", ""), + "url": item.get("url", ""), + "snippet": item.get("snippet", ""), + "summary": item.get("summary", ""), + "siteName": item.get("siteName", ""), + "siteIcon": item.get("siteIcon", ""), + "datePublished": item.get("datePublished", "") + or item.get("dateLastCrawled", ""), + } + for item in webPages["value"] + ] + return result + + +def search_bocha( + api_key: str, query: str, count: int, filter_list: Optional[list[str]] = None +) -> list[SearchResult]: + """Search using Bocha's Search API and return the results as a list of SearchResult objects. + + Args: + api_key (str): A Bocha Search API key + query (str): The query to search for + """ + url = "https://api.bochaai.com/v1/web-search?utm_source=ollama" + headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"} + + payload = json.dumps( + {"query": query, "summary": True, "freshness": "noLimit", "count": count} + ) + + response = requests.post(url, headers=headers, data=payload, timeout=5) + response.raise_for_status() + results = _parse_response(response.json()) + print(results) + if filter_list: + results = get_filtered_results(results, filter_list) + + return [ + SearchResult( + link=result["url"], title=result.get("name"), snippet=result.get("summary") + ) + for result in results.get("webpage", [])[:count] + ] diff --git a/backend/open_webui/retrieval/web/brave.py b/backend/open_webui/retrieval/web/brave.py new file mode 100644 index 0000000..3075db9 --- /dev/null +++ b/backend/open_webui/retrieval/web/brave.py @@ -0,0 +1,42 @@ +import logging +from typing import Optional + +import requests +from open_webui.retrieval.web.main import SearchResult, get_filtered_results +from open_webui.env import SRC_LOG_LEVELS + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["RAG"]) + + +def search_brave( + api_key: str, query: str, count: int, filter_list: Optional[list[str]] = None +) -> list[SearchResult]: + """Search using Brave's Search API and return the results as a list of SearchResult objects. + + Args: + api_key (str): A Brave Search API key + query (str): The query to search for + """ + url = "https://api.search.brave.com/res/v1/web/search" + headers = { + "Accept": "application/json", + "Accept-Encoding": "gzip", + "X-Subscription-Token": api_key, + } + params = {"q": query, "count": count} + + response = requests.get(url, headers=headers, params=params) + response.raise_for_status() + + json_response = response.json() + results = json_response.get("web", {}).get("results", []) + if filter_list: + results = get_filtered_results(results, filter_list) + + return [ + SearchResult( + link=result["url"], title=result.get("title"), snippet=result.get("snippet") + ) + for result in results[:count] + ] diff --git a/backend/open_webui/retrieval/web/duckduckgo.py b/backend/open_webui/retrieval/web/duckduckgo.py new file mode 100644 index 0000000..d950866 --- /dev/null +++ b/backend/open_webui/retrieval/web/duckduckgo.py @@ -0,0 +1,46 @@ +import logging +from typing import Optional + +from open_webui.retrieval.web.main import SearchResult, get_filtered_results +from duckduckgo_search import DDGS +from open_webui.env import SRC_LOG_LEVELS + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["RAG"]) + + +def search_duckduckgo( + query: str, count: int, filter_list: Optional[list[str]] = None +) -> list[SearchResult]: + """ + Search using DuckDuckGo's Search API and return the results as a list of SearchResult objects. + Args: + query (str): The query to search for + count (int): The number of results to return + + Returns: + list[SearchResult]: A list of search results + """ + # Use the DDGS context manager to create a DDGS object + with DDGS() as ddgs: + # Use the ddgs.text() method to perform the search + ddgs_gen = ddgs.text( + query, safesearch="moderate", max_results=count, backend="api" + ) + # Check if there are search results + if ddgs_gen: + # Convert the search results into a list + search_results = [r for r in ddgs_gen] + + if filter_list: + search_results = get_filtered_results(search_results, filter_list) + + # Return the list of search results + return [ + SearchResult( + link=result["href"], + title=result.get("title"), + snippet=result.get("body"), + ) + for result in search_results + ] diff --git a/backend/open_webui/retrieval/web/exa.py b/backend/open_webui/retrieval/web/exa.py new file mode 100644 index 0000000..927adef --- /dev/null +++ b/backend/open_webui/retrieval/web/exa.py @@ -0,0 +1,76 @@ +import logging +from dataclasses import dataclass +from typing import Optional + +import requests +from open_webui.env import SRC_LOG_LEVELS +from open_webui.retrieval.web.main import SearchResult + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["RAG"]) + +EXA_API_BASE = "https://api.exa.ai" + + +@dataclass +class ExaResult: + url: str + title: str + text: str + + +def search_exa( + api_key: str, + query: str, + count: int, + filter_list: Optional[list[str]] = None, +) -> list[SearchResult]: + """Search using Exa Search API and return the results as a list of SearchResult objects. + + Args: + api_key (str): A Exa Search API key + query (str): The query to search for + count (int): Number of results to return + filter_list (Optional[list[str]]): List of domains to filter results by + """ + log.info(f"Searching with Exa for query: {query}") + + headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"} + + payload = { + "query": query, + "numResults": count or 5, + "includeDomains": filter_list, + "contents": {"text": True, "highlights": True}, + "type": "auto", # Use the auto search type (keyword or neural) + } + + try: + response = requests.post( + f"{EXA_API_BASE}/search", headers=headers, json=payload + ) + response.raise_for_status() + data = response.json() + + results = [] + for result in data["results"]: + results.append( + ExaResult( + url=result["url"], + title=result["title"], + text=result["text"], + ) + ) + + log.info(f"Found {len(results)} results") + return [ + SearchResult( + link=result.url, + title=result.title, + snippet=result.text, + ) + for result in results + ] + except Exception as e: + log.error(f"Error searching Exa: {e}") + return [] diff --git a/backend/open_webui/retrieval/web/google_pse.py b/backend/open_webui/retrieval/web/google_pse.py new file mode 100644 index 0000000..2d2b863 --- /dev/null +++ b/backend/open_webui/retrieval/web/google_pse.py @@ -0,0 +1,69 @@ +import logging +from typing import Optional + +import requests +from open_webui.retrieval.web.main import SearchResult, get_filtered_results +from open_webui.env import SRC_LOG_LEVELS + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["RAG"]) + + +def search_google_pse( + api_key: str, + search_engine_id: str, + query: str, + count: int, + filter_list: Optional[list[str]] = None, +) -> list[SearchResult]: + """Search using Google's Programmable Search Engine API and return the results as a list of SearchResult objects. + Handles pagination for counts greater than 10. + + Args: + api_key (str): A Programmable Search Engine API key + search_engine_id (str): A Programmable Search Engine ID + query (str): The query to search for + count (int): The number of results to return (max 100, as PSE max results per query is 10 and max page is 10) + filter_list (Optional[list[str]], optional): A list of keywords to filter out from results. Defaults to None. + + Returns: + list[SearchResult]: A list of SearchResult objects. + """ + url = "https://www.googleapis.com/customsearch/v1" + headers = {"Content-Type": "application/json"} + all_results = [] + start_index = 1 # Google PSE start parameter is 1-based + + while count > 0: + num_results_this_page = min(count, 10) # Google PSE max results per page is 10 + params = { + "cx": search_engine_id, + "q": query, + "key": api_key, + "num": num_results_this_page, + "start": start_index, + } + response = requests.request("GET", url, headers=headers, params=params) + response.raise_for_status() + json_response = response.json() + results = json_response.get("items", []) + if results: # check if results are returned. If not, no more pages to fetch. + all_results.extend(results) + count -= len( + results + ) # Decrement count by the number of results fetched in this page. + start_index += 10 # Increment start index for the next page + else: + break # No more results from Google PSE, break the loop + + if filter_list: + all_results = get_filtered_results(all_results, filter_list) + + return [ + SearchResult( + link=result["link"], + title=result.get("title"), + snippet=result.get("snippet"), + ) + for result in all_results + ] diff --git a/backend/open_webui/retrieval/web/jina_search.py b/backend/open_webui/retrieval/web/jina_search.py new file mode 100644 index 0000000..a87293d --- /dev/null +++ b/backend/open_webui/retrieval/web/jina_search.py @@ -0,0 +1,48 @@ +import logging + +import requests +from open_webui.retrieval.web.main import SearchResult +from open_webui.env import SRC_LOG_LEVELS +from yarl import URL + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["RAG"]) + + +def search_jina(api_key: str, query: str, count: int) -> list[SearchResult]: + """ + Search using Jina's Search API and return the results as a list of SearchResult objects. + Args: + query (str): The query to search for + count (int): The number of results to return + + Returns: + list[SearchResult]: A list of search results + """ + jina_search_endpoint = "https://s.jina.ai/" + + headers = { + "Accept": "application/json", + "Content-Type": "application/json", + "Authorization": api_key, + "X-Retain-Images": "none", + } + + payload = {"q": query, "count": count if count <= 10 else 10} + + url = str(URL(jina_search_endpoint)) + response = requests.post(url, headers=headers, json=payload) + response.raise_for_status() + data = response.json() + + results = [] + for result in data["data"]: + results.append( + SearchResult( + link=result["url"], + title=result.get("title"), + snippet=result.get("content"), + ) + ) + + return results diff --git a/backend/open_webui/retrieval/web/kagi.py b/backend/open_webui/retrieval/web/kagi.py new file mode 100644 index 0000000..0b69da8 --- /dev/null +++ b/backend/open_webui/retrieval/web/kagi.py @@ -0,0 +1,48 @@ +import logging +from typing import Optional + +import requests +from open_webui.retrieval.web.main import SearchResult, get_filtered_results +from open_webui.env import SRC_LOG_LEVELS + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["RAG"]) + + +def search_kagi( + api_key: str, query: str, count: int, filter_list: Optional[list[str]] = None +) -> list[SearchResult]: + """Search using Kagi's Search API and return the results as a list of SearchResult objects. + + The Search API will inherit the settings in your account, including results personalization and snippet length. + + Args: + api_key (str): A Kagi Search API key + query (str): The query to search for + count (int): The number of results to return + """ + url = "https://kagi.com/api/v0/search" + headers = { + "Authorization": f"Bot {api_key}", + } + params = {"q": query, "limit": count} + + response = requests.get(url, headers=headers, params=params) + response.raise_for_status() + json_response = response.json() + search_results = json_response.get("data", []) + + results = [ + SearchResult( + link=result["url"], title=result["title"], snippet=result.get("snippet") + ) + for result in search_results + if result["t"] == 0 + ] + + print(results) + + if filter_list: + results = get_filtered_results(results, filter_list) + + return results diff --git a/backend/open_webui/retrieval/web/main.py b/backend/open_webui/retrieval/web/main.py new file mode 100644 index 0000000..28a749e --- /dev/null +++ b/backend/open_webui/retrieval/web/main.py @@ -0,0 +1,26 @@ +import validators + +from typing import Optional +from urllib.parse import urlparse + +from pydantic import BaseModel + + +def get_filtered_results(results, filter_list): + if not filter_list: + return results + filtered_results = [] + for result in results: + url = result.get("url") or result.get("link", "") + if not validators.url(url): + continue + domain = urlparse(url).netloc + if any(domain.endswith(filtered_domain) for filtered_domain in filter_list): + filtered_results.append(result) + return filtered_results + + +class SearchResult(BaseModel): + link: str + title: Optional[str] + snippet: Optional[str] diff --git a/backend/open_webui/retrieval/web/mojeek.py b/backend/open_webui/retrieval/web/mojeek.py new file mode 100644 index 0000000..d298b0e --- /dev/null +++ b/backend/open_webui/retrieval/web/mojeek.py @@ -0,0 +1,40 @@ +import logging +from typing import Optional + +import requests +from open_webui.retrieval.web.main import SearchResult, get_filtered_results +from open_webui.env import SRC_LOG_LEVELS + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["RAG"]) + + +def search_mojeek( + api_key: str, query: str, count: int, filter_list: Optional[list[str]] = None +) -> list[SearchResult]: + """Search using Mojeek's Search API and return the results as a list of SearchResult objects. + + Args: + api_key (str): A Mojeek Search API key + query (str): The query to search for + """ + url = "https://api.mojeek.com/search" + headers = { + "Accept": "application/json", + } + params = {"q": query, "api_key": api_key, "fmt": "json", "t": count} + + response = requests.get(url, headers=headers, params=params) + response.raise_for_status() + json_response = response.json() + results = json_response.get("response", {}).get("results", []) + print(results) + if filter_list: + results = get_filtered_results(results, filter_list) + + return [ + SearchResult( + link=result["url"], title=result.get("title"), snippet=result.get("desc") + ) + for result in results + ] diff --git a/backend/open_webui/retrieval/web/searchapi.py b/backend/open_webui/retrieval/web/searchapi.py new file mode 100644 index 0000000..38bc0b5 --- /dev/null +++ b/backend/open_webui/retrieval/web/searchapi.py @@ -0,0 +1,48 @@ +import logging +from typing import Optional +from urllib.parse import urlencode + +import requests +from open_webui.retrieval.web.main import SearchResult, get_filtered_results +from open_webui.env import SRC_LOG_LEVELS + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["RAG"]) + + +def search_searchapi( + api_key: str, + engine: str, + query: str, + count: int, + filter_list: Optional[list[str]] = None, +) -> list[SearchResult]: + """Search using searchapi.io's API and return the results as a list of SearchResult objects. + + Args: + api_key (str): A searchapi.io API key + query (str): The query to search for + """ + url = "https://www.searchapi.io/api/v1/search" + + engine = engine or "google" + + payload = {"engine": engine, "q": query, "api_key": api_key} + + url = f"{url}?{urlencode(payload)}" + response = requests.request("GET", url) + + json_response = response.json() + log.info(f"results from searchapi search: {json_response}") + + results = sorted( + json_response.get("organic_results", []), key=lambda x: x.get("position", 0) + ) + if filter_list: + results = get_filtered_results(results, filter_list) + return [ + SearchResult( + link=result["link"], title=result["title"], snippet=result["snippet"] + ) + for result in results[:count] + ] diff --git a/backend/open_webui/retrieval/web/searxng.py b/backend/open_webui/retrieval/web/searxng.py new file mode 100644 index 0000000..15e3c09 --- /dev/null +++ b/backend/open_webui/retrieval/web/searxng.py @@ -0,0 +1,91 @@ +import logging +from typing import Optional + +import requests +from open_webui.retrieval.web.main import SearchResult, get_filtered_results +from open_webui.env import SRC_LOG_LEVELS + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["RAG"]) + + +def search_searxng( + query_url: str, + query: str, + count: int, + filter_list: Optional[list[str]] = None, + **kwargs, +) -> list[SearchResult]: + """ + Search a SearXNG instance for a given query and return the results as a list of SearchResult objects. + + The function allows passing additional parameters such as language or time_range to tailor the search result. + + Args: + query_url (str): The base URL of the SearXNG server. + query (str): The search term or question to find in the SearXNG database. + count (int): The maximum number of results to retrieve from the search. + + Keyword Args: + language (str): Language filter for the search results; e.g., "en-US". Defaults to an empty string. + safesearch (int): Safe search filter for safer web results; 0 = off, 1 = moderate, 2 = strict. Defaults to 1 (moderate). + time_range (str): Time range for filtering results by date; e.g., "2023-04-05..today" or "all-time". Defaults to ''. + categories: (Optional[list[str]]): Specific categories within which the search should be performed, defaulting to an empty string if not provided. + + Returns: + list[SearchResult]: A list of SearchResults sorted by relevance score in descending order. + + Raise: + requests.exceptions.RequestException: If a request error occurs during the search process. + """ + + # Default values for optional parameters are provided as empty strings or None when not specified. + language = kwargs.get("language", "en-US") + safesearch = kwargs.get("safesearch", "1") + time_range = kwargs.get("time_range", "") + categories = "".join(kwargs.get("categories", [])) + + params = { + "q": query, + "format": "json", + "pageno": 1, + "safesearch": safesearch, + "language": language, + "time_range": time_range, + "categories": categories, + "theme": "simple", + "image_proxy": 0, + } + + # Legacy query format + if "" in query_url: + # Strip all query parameters from the URL + query_url = query_url.split("?")[0] + + log.debug(f"searching {query_url}") + + response = requests.get( + query_url, + headers={ + "User-Agent": "Open WebUI (https://github.com/open-webui/open-webui) RAG Bot", + "Accept": "text/html", + "Accept-Encoding": "gzip, deflate", + "Accept-Language": "en-US,en;q=0.5", + "Connection": "keep-alive", + }, + params=params, + ) + + response.raise_for_status() # Raise an exception for HTTP errors. + + json_response = response.json() + results = json_response.get("results", []) + sorted_results = sorted(results, key=lambda x: x.get("score", 0), reverse=True) + if filter_list: + sorted_results = get_filtered_results(sorted_results, filter_list) + return [ + SearchResult( + link=result["url"], title=result.get("title"), snippet=result.get("content") + ) + for result in sorted_results[:count] + ] diff --git a/backend/open_webui/retrieval/web/serpapi.py b/backend/open_webui/retrieval/web/serpapi.py new file mode 100644 index 0000000..028b6bc --- /dev/null +++ b/backend/open_webui/retrieval/web/serpapi.py @@ -0,0 +1,48 @@ +import logging +from typing import Optional +from urllib.parse import urlencode + +import requests +from open_webui.retrieval.web.main import SearchResult, get_filtered_results +from open_webui.env import SRC_LOG_LEVELS + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["RAG"]) + + +def search_serpapi( + api_key: str, + engine: str, + query: str, + count: int, + filter_list: Optional[list[str]] = None, +) -> list[SearchResult]: + """Search using serpapi.com's API and return the results as a list of SearchResult objects. + + Args: + api_key (str): A serpapi.com API key + query (str): The query to search for + """ + url = "https://serpapi.com/search" + + engine = engine or "google" + + payload = {"engine": engine, "q": query, "api_key": api_key} + + url = f"{url}?{urlencode(payload)}" + response = requests.request("GET", url) + + json_response = response.json() + log.info(f"results from serpapi search: {json_response}") + + results = sorted( + json_response.get("organic_results", []), key=lambda x: x.get("position", 0) + ) + if filter_list: + results = get_filtered_results(results, filter_list) + return [ + SearchResult( + link=result["link"], title=result["title"], snippet=result["snippet"] + ) + for result in results[:count] + ] diff --git a/backend/open_webui/retrieval/web/serper.py b/backend/open_webui/retrieval/web/serper.py new file mode 100644 index 0000000..685e343 --- /dev/null +++ b/backend/open_webui/retrieval/web/serper.py @@ -0,0 +1,43 @@ +import json +import logging +from typing import Optional + +import requests +from open_webui.retrieval.web.main import SearchResult, get_filtered_results +from open_webui.env import SRC_LOG_LEVELS + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["RAG"]) + + +def search_serper( + api_key: str, query: str, count: int, filter_list: Optional[list[str]] = None +) -> list[SearchResult]: + """Search using serper.dev's API and return the results as a list of SearchResult objects. + + Args: + api_key (str): A serper.dev API key + query (str): The query to search for + """ + url = "https://google.serper.dev/search" + + payload = json.dumps({"q": query}) + headers = {"X-API-KEY": api_key, "Content-Type": "application/json"} + + response = requests.request("POST", url, headers=headers, data=payload) + response.raise_for_status() + + json_response = response.json() + results = sorted( + json_response.get("organic", []), key=lambda x: x.get("position", 0) + ) + if filter_list: + results = get_filtered_results(results, filter_list) + return [ + SearchResult( + link=result["link"], + title=result.get("title"), + snippet=result.get("description"), + ) + for result in results[:count] + ] diff --git a/backend/open_webui/retrieval/web/serply.py b/backend/open_webui/retrieval/web/serply.py new file mode 100644 index 0000000..a9b473e --- /dev/null +++ b/backend/open_webui/retrieval/web/serply.py @@ -0,0 +1,69 @@ +import logging +from typing import Optional +from urllib.parse import urlencode + +import requests +from open_webui.retrieval.web.main import SearchResult, get_filtered_results +from open_webui.env import SRC_LOG_LEVELS + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["RAG"]) + + +def search_serply( + api_key: str, + query: str, + count: int, + hl: str = "us", + limit: int = 10, + device_type: str = "desktop", + proxy_location: str = "US", + filter_list: Optional[list[str]] = None, +) -> list[SearchResult]: + """Search using serper.dev's API and return the results as a list of SearchResult objects. + + Args: + api_key (str): A serply.io API key + query (str): The query to search for + hl (str): Host Language code to display results in (reference https://developers.google.com/custom-search/docs/xml_results?hl=en#wsInterfaceLanguages) + limit (int): The maximum number of results to return [10-100, defaults to 10] + """ + log.info("Searching with Serply") + + url = "https://api.serply.io/v1/search/" + + query_payload = { + "q": query, + "language": "en", + "num": limit, + "gl": proxy_location.upper(), + "hl": hl.lower(), + } + + url = f"{url}{urlencode(query_payload)}" + headers = { + "X-API-KEY": api_key, + "X-User-Agent": device_type, + "User-Agent": "open-webui", + "X-Proxy-Location": proxy_location, + } + + response = requests.request("GET", url, headers=headers) + response.raise_for_status() + + json_response = response.json() + log.info(f"results from serply search: {json_response}") + + results = sorted( + json_response.get("results", []), key=lambda x: x.get("realPosition", 0) + ) + if filter_list: + results = get_filtered_results(results, filter_list) + return [ + SearchResult( + link=result["link"], + title=result.get("title"), + snippet=result.get("description"), + ) + for result in results[:count] + ] diff --git a/backend/open_webui/retrieval/web/serpstack.py b/backend/open_webui/retrieval/web/serpstack.py new file mode 100644 index 0000000..d4dbda5 --- /dev/null +++ b/backend/open_webui/retrieval/web/serpstack.py @@ -0,0 +1,48 @@ +import logging +from typing import Optional + +import requests +from open_webui.retrieval.web.main import SearchResult, get_filtered_results +from open_webui.env import SRC_LOG_LEVELS + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["RAG"]) + + +def search_serpstack( + api_key: str, + query: str, + count: int, + filter_list: Optional[list[str]] = None, + https_enabled: bool = True, +) -> list[SearchResult]: + """Search using serpstack.com's and return the results as a list of SearchResult objects. + + Args: + api_key (str): A serpstack.com API key + query (str): The query to search for + https_enabled (bool): Whether to use HTTPS or HTTP for the API request + """ + url = f"{'https' if https_enabled else 'http'}://api.serpstack.com/search" + + headers = {"Content-Type": "application/json"} + params = { + "access_key": api_key, + "query": query, + } + + response = requests.request("POST", url, headers=headers, params=params) + response.raise_for_status() + + json_response = response.json() + results = sorted( + json_response.get("organic_results", []), key=lambda x: x.get("position", 0) + ) + if filter_list: + results = get_filtered_results(results, filter_list) + return [ + SearchResult( + link=result["url"], title=result.get("title"), snippet=result.get("snippet") + ) + for result in results[:count] + ] diff --git a/backend/open_webui/retrieval/web/tavily.py b/backend/open_webui/retrieval/web/tavily.py new file mode 100644 index 0000000..da70aa8 --- /dev/null +++ b/backend/open_webui/retrieval/web/tavily.py @@ -0,0 +1,44 @@ +import logging +from typing import Optional + +import requests +from open_webui.retrieval.web.main import SearchResult +from open_webui.env import SRC_LOG_LEVELS + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["RAG"]) + + +def search_tavily( + api_key: str, + query: str, + count: int, + filter_list: Optional[list[str]] = None, + # **kwargs, +) -> list[SearchResult]: + """Search using Tavily's Search API and return the results as a list of SearchResult objects. + + Args: + api_key (str): A Tavily Search API key + query (str): The query to search for + + Returns: + list[SearchResult]: A list of search results + """ + url = "https://api.tavily.com/search" + data = {"query": query, "api_key": api_key} + response = requests.post(url, json=data) + response.raise_for_status() + + json_response = response.json() + + raw_search_results = json_response.get("results", []) + + return [ + SearchResult( + link=result["url"], + title=result.get("title", ""), + snippet=result.get("content"), + ) + for result in raw_search_results[:count] + ] diff --git a/backend/open_webui/retrieval/web/testdata/bing.json b/backend/open_webui/retrieval/web/testdata/bing.json new file mode 100644 index 0000000..80324f3 --- /dev/null +++ b/backend/open_webui/retrieval/web/testdata/bing.json @@ -0,0 +1,58 @@ +{ + "_type": "SearchResponse", + "queryContext": { + "originalQuery": "Top 10 international results" + }, + "webPages": { + "webSearchUrl": "https://www.bing.com/search?q=Top+10+international+results", + "totalEstimatedMatches": 687, + "value": [ + { + "id": "https://api.bing.microsoft.com/api/v7/#WebPages.0", + "name": "2024 Mexican Grand Prix - F1 results and latest standings ... - PlanetF1", + "url": "https://www.planetf1.com/news/f1-results-2024-mexican-grand-prix-race-standings", + "datePublished": "2024-10-27T00:00:00.0000000", + "datePublishedFreshnessText": "1 day ago", + "isFamilyFriendly": true, + "displayUrl": "https://www.planetf1.com/news/f1-results-2024-mexican-grand-prix-race-standings", + "snippet": "Nico Hulkenberg and Pierre Gasly completed the top 10. A full report of the Mexican Grand Prix is available at the bottom of this article. F1 results – 2024 Mexican Grand Prix", + "dateLastCrawled": "2024-10-28T07:15:00.0000000Z", + "cachedPageUrl": "https://cc.bingj.com/cache.aspx?q=Top+10+international+results&d=916492551782&mkt=en-US&setlang=en-US&w=zBsfaAPyF2tUrHFHr_vFFdUm8sng4g34", + "language": "en", + "isNavigational": false, + "noCache": false + }, + { + "id": "https://api.bing.microsoft.com/api/v7/#WebPages.1", + "name": "F1 Results Today: HUGE Verstappen penalties cause major title change", + "url": "https://www.gpfans.com/en/f1-news/1033512/f1-results-today-mexican-grand-prix-huge-max-verstappen-penalties-cause-major-title-change/", + "datePublished": "2024-10-27T00:00:00.0000000", + "datePublishedFreshnessText": "1 day ago", + "isFamilyFriendly": true, + "displayUrl": "https://www.gpfans.com/en/f1-news/1033512/f1-results-today-mexican-grand-prix-huge-max...", + "snippet": "Elsewhere, Mercedes duo Lewis Hamilton and George Russell came home in P4 and P5 respectively. Meanwhile, the surprise package of the day were Haas, with both Kevin Magnussen and Nico Hulkenberg finishing inside the points.. READ MORE: RB star issues apology after red flag CRASH at Mexican GP Mexican Grand Prix 2024 results. 1. Carlos Sainz [Ferrari] 2. Lando Norris [McLaren] - +4.705", + "dateLastCrawled": "2024-10-28T06:06:00.0000000Z", + "cachedPageUrl": "https://cc.bingj.com/cache.aspx?q=Top+10+international+results&d=2840656522642&mkt=en-US&setlang=en-US&w=-Tbkwxnq52jZCvG7l3CtgcwT1vwAjIUD", + "language": "en", + "isNavigational": false, + "noCache": false + }, + { + "id": "https://api.bing.microsoft.com/api/v7/#WebPages.2", + "name": "International Power Rankings: England flying, Kangaroos cruising, Fiji rise", + "url": "https://www.loverugbyleague.com/post/international-power-rankings-england-flying-kangaroos-cruising-fiji-rise", + "datePublished": "2024-10-28T00:00:00.0000000", + "datePublishedFreshnessText": "7 hours ago", + "isFamilyFriendly": true, + "displayUrl": "https://www.loverugbyleague.com/post/international-power-rankings-england-flying...", + "snippet": "LRL RECOMMENDS: England player ratings from first Test against Samoa as omnificent George Williams scores perfect 10. 2. Australia (Men) – SAME. The Kangaroos remain 2nd in our Power Rankings after their 22-10 win against New Zealand in Christchurch on Sunday. As was the case in their win against Tonga last week, Mal Meninga’s side weren ...", + "dateLastCrawled": "2024-10-28T07:09:00.0000000Z", + "cachedPageUrl": "https://cc.bingj.com/cache.aspx?q=Top+10+international+results&d=1535008462672&mkt=en-US&setlang=en-US&w=82ujhH4Kp0iuhCS7wh1xLUFYUeetaVVm", + "language": "en", + "isNavigational": false, + "noCache": false + } + ], + "someResultsRemoved": true + } +} diff --git a/backend/open_webui/retrieval/web/testdata/brave.json b/backend/open_webui/retrieval/web/testdata/brave.json new file mode 100644 index 0000000..0cc7210 --- /dev/null +++ b/backend/open_webui/retrieval/web/testdata/brave.json @@ -0,0 +1,998 @@ +{ + "query": { + "original": "python", + "show_strict_warning": false, + "is_navigational": true, + "is_news_breaking": false, + "spellcheck_off": true, + "country": "us", + "bad_results": false, + "should_fallback": false, + "postal_code": "", + "city": "", + "header_country": "", + "more_results_available": true, + "state": "" + }, + "mixed": { + "type": "mixed", + "main": [ + { + "type": "web", + "index": 0, + "all": false + }, + { + "type": "web", + "index": 1, + "all": false + }, + { + "type": "news", + "all": true + }, + { + "type": "web", + "index": 2, + "all": false + }, + { + "type": "videos", + "all": true + }, + { + "type": "web", + "index": 3, + "all": false + }, + { + "type": "web", + "index": 4, + "all": false + }, + { + "type": "web", + "index": 5, + "all": false + }, + { + "type": "web", + "index": 6, + "all": false + }, + { + "type": "web", + "index": 7, + "all": false + }, + { + "type": "web", + "index": 8, + "all": false + }, + { + "type": "web", + "index": 9, + "all": false + }, + { + "type": "web", + "index": 10, + "all": false + }, + { + "type": "web", + "index": 11, + "all": false + }, + { + "type": "web", + "index": 12, + "all": false + }, + { + "type": "web", + "index": 13, + "all": false + }, + { + "type": "web", + "index": 14, + "all": false + }, + { + "type": "web", + "index": 15, + "all": false + }, + { + "type": "web", + "index": 16, + "all": false + }, + { + "type": "web", + "index": 17, + "all": false + }, + { + "type": "web", + "index": 18, + "all": false + }, + { + "type": "web", + "index": 19, + "all": false + } + ], + "top": [], + "side": [] + }, + "news": { + "type": "news", + "results": [ + { + "title": "Google lays off staff from Flutter, Dart and Python teams weeks before its developer conference | TechCrunch", + "url": "https://techcrunch.com/2024/05/01/google-lays-off-staff-from-flutter-dart-python-weeks-before-its-developer-conference/", + "is_source_local": false, + "is_source_both": false, + "description": "Google told TechCrunch that Flutter will have new updates to share at I/O this year.", + "page_age": "2024-05-02T17:40:05", + "family_friendly": true, + "meta_url": { + "scheme": "https", + "netloc": "techcrunch.com", + "hostname": "techcrunch.com", + "favicon": "https://imgs.search.brave.com/N6VSEVahheQOb7lqfb47dhUOB4XD-6sfQOP94sCe3Oo/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvZGI5Njk0Yzlk/YWM3ZWMwZjg1MTM1/NmIyMWEyNzBjZDZj/ZDQyNmFlNGU0NDRi/MDgyYjQwOGU0Y2Qy/ZWMwNWQ2ZC90ZWNo/Y3J1bmNoLmNvbS8", + "path": "› 2024 › 05 › 01 › google-lays-off-staff-from-flutter-dart-python-weeks-before-its-developer-conference" + }, + "breaking": false, + "thumbnail": { + "src": "https://imgs.search.brave.com/gCI5UG8muOEOZDAx9vpu6L6r6R00mD7jOF08-biFoyQ/rs:fit:200:200:1/g:ce/aHR0cHM6Ly90ZWNo/Y3J1bmNoLmNvbS93/cC1jb250ZW50L3Vw/bG9hZHMvMjAxOC8x/MS9HZXR0eUltYWdl/cy0xMDAyNDg0NzQ2/LmpwZz9yZXNpemU9/MTIwMCw4MDA" + }, + "age": "3 days ago", + "extra_snippets": [ + "Ahead of Google’s annual I/O developer conference in May, the tech giant has laid off staff across key teams like Flutter, Dart, Python and others, according to reports from affected employees shared on social media. Google confirmed the layoffs to TechCrunch, but not the specific teams, roles or how many people were let go.", + "In a separate post on Reddit, another commenter noted the Python team affected by the layoffs were those who managed the internal Python runtimes and toolchains and worked with OSS Python. Included in this group were “multiple current and former core devs and steering council members,” they said.", + "Meanwhile, others shared on Y Combinator’s Hacker News, where a Python team member detailed their specific duties on the technical front and noted that, for years, much of the work was done with fewer than 10 people. Another Hacker News commenter said their early years on the Python team were spent paying down internal technical debt accumulated from not having a strong Python strategy.", + "CNBC reports that a total of 200 people were let go across Google’s “Core” teams, which included those working on Python, app platforms, and other engineering roles. Some jobs were being shifted to India and Mexico, it said, citing internal documents." + ] + } + ], + "mutated_by_goggles": false + }, + "type": "search", + "videos": { + "type": "videos", + "results": [ + { + "type": "video_result", + "url": "https://www.youtube.com/watch?v=b093aqAZiPU", + "title": "👩‍💻 Python for Beginners Tutorial - YouTube", + "description": "In this step-by-step Python for beginner's tutorial, learn how you can get started programming in Python. In this video, I assume that you are completely new...", + "age": "March 25, 2021", + "page_age": "2021-03-25T10:00:08", + "video": {}, + "meta_url": { + "scheme": "https", + "netloc": "youtube.com", + "hostname": "www.youtube.com", + "favicon": "https://imgs.search.brave.com/Ux4Hee4evZhvjuTKwtapBycOGjGDci2Gvn2pbSzvbC0/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvOTkyZTZiMWU3/YzU3Nzc5YjExYzUy/N2VhZTIxOWNlYjM5/ZGVjN2MyZDY4Nzdh/ZDYzMTYxNmI5N2Rk/Y2Q3N2FkNy93d3cu/eW91dHViZS5jb20v", + "path": "› watch" + }, + "thumbnail": { + "src": "https://imgs.search.brave.com/tZI4Do4_EYcTCsD_MvE3Jx8FzjIXwIJ5ZuKhwiWTyZs/rs:fit:200:200:1/g:ce/aHR0cHM6Ly9pLnl0/aW1nLmNvbS92aS9i/MDkzYXFBWmlQVS9t/YXhyZXNkZWZhdWx0/LmpwZw" + } + }, + { + "type": "video_result", + "url": "https://www.youtube.com/watch?v=rfscVS0vtbw", + "title": "Learn Python - Full Course for Beginners [Tutorial] - YouTube", + "description": "This course will give you a full introduction into all of the core concepts in python. Follow along with the videos and you'll be a python programmer in no t...", + "age": "July 11, 2018", + "page_age": "2018-07-11T18:00:42", + "video": {}, + "meta_url": { + "scheme": "https", + "netloc": "youtube.com", + "hostname": "www.youtube.com", + "favicon": "https://imgs.search.brave.com/Ux4Hee4evZhvjuTKwtapBycOGjGDci2Gvn2pbSzvbC0/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvOTkyZTZiMWU3/YzU3Nzc5YjExYzUy/N2VhZTIxOWNlYjM5/ZGVjN2MyZDY4Nzdh/ZDYzMTYxNmI5N2Rk/Y2Q3N2FkNy93d3cu/eW91dHViZS5jb20v", + "path": "› watch" + }, + "thumbnail": { + "src": "https://imgs.search.brave.com/65zkx_kPU_zJb-4nmvvY-q5-ZZwzceChz-N00V8cqvk/rs:fit:200:200:1/g:ce/aHR0cHM6Ly9pLnl0/aW1nLmNvbS92aS9y/ZnNjVlMwdnRidy9t/YXhyZXNkZWZhdWx0/LmpwZw" + } + }, + { + "type": "video_result", + "url": "https://www.youtube.com/watch?v=_uQrJ0TkZlc", + "title": "Python Tutorial - Python Full Course for Beginners - YouTube", + "description": "Become a Python pro! 🚀 This comprehensive tutorial takes you from beginner to hero, covering the basics, machine learning, and web development projects.🚀 W...", + "age": "February 18, 2019", + "page_age": "2019-02-18T15:00:08", + "video": {}, + "meta_url": { + "scheme": "https", + "netloc": "youtube.com", + "hostname": "www.youtube.com", + "favicon": "https://imgs.search.brave.com/Ux4Hee4evZhvjuTKwtapBycOGjGDci2Gvn2pbSzvbC0/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvOTkyZTZiMWU3/YzU3Nzc5YjExYzUy/N2VhZTIxOWNlYjM5/ZGVjN2MyZDY4Nzdh/ZDYzMTYxNmI5N2Rk/Y2Q3N2FkNy93d3cu/eW91dHViZS5jb20v", + "path": "› watch" + }, + "thumbnail": { + "src": "https://imgs.search.brave.com/Djiv1pXLq1ClqBSE_86jQnEYR8bW8UJP6Cs7LrgyQzQ/rs:fit:200:200:1/g:ce/aHR0cHM6Ly9pLnl0/aW1nLmNvbS92aS9f/dVFySjBUa1psYy9t/YXhyZXNkZWZhdWx0/LmpwZw" + } + }, + { + "type": "video_result", + "url": "https://www.youtube.com/watch?v=wRKgzC-MhIc", + "title": "[] and {} vs list() and dict(), which is better?", + "description": "Enjoy the videos and music you love, upload original content, and share it all with friends, family, and the world on YouTube.", + "video": {}, + "meta_url": { + "scheme": "https", + "netloc": "youtube.com", + "hostname": "www.youtube.com", + "favicon": "https://imgs.search.brave.com/Ux4Hee4evZhvjuTKwtapBycOGjGDci2Gvn2pbSzvbC0/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvOTkyZTZiMWU3/YzU3Nzc5YjExYzUy/N2VhZTIxOWNlYjM5/ZGVjN2MyZDY4Nzdh/ZDYzMTYxNmI5N2Rk/Y2Q3N2FkNy93d3cu/eW91dHViZS5jb20v", + "path": "› watch" + }, + "thumbnail": { + "src": "https://imgs.search.brave.com/Hw9ep2Pio13X1VZjRw_h9R2VH_XvZFOuGlQJVnVkeq0/rs:fit:200:200:1/g:ce/aHR0cHM6Ly9pLnl0/aW1nLmNvbS92aS93/UktnekMtTWhJYy9o/cWRlZmF1bHQuanBn" + } + }, + { + "type": "video_result", + "url": "https://www.youtube.com/watch?v=LWdsF79H1Pg", + "title": "print() vs. return in Python Functions - YouTube", + "description": "In this video, you will learn the differences between the return statement and the print function when they are used inside Python functions. We will see an ...", + "age": "June 11, 2022", + "page_age": "2022-06-11T21:33:26", + "video": {}, + "meta_url": { + "scheme": "https", + "netloc": "youtube.com", + "hostname": "www.youtube.com", + "favicon": "https://imgs.search.brave.com/Ux4Hee4evZhvjuTKwtapBycOGjGDci2Gvn2pbSzvbC0/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvOTkyZTZiMWU3/YzU3Nzc5YjExYzUy/N2VhZTIxOWNlYjM5/ZGVjN2MyZDY4Nzdh/ZDYzMTYxNmI5N2Rk/Y2Q3N2FkNy93d3cu/eW91dHViZS5jb20v", + "path": "› watch" + }, + "thumbnail": { + "src": "https://imgs.search.brave.com/ebglnr5_jwHHpvon3WU-5hzt0eHdTZSVGg3Ts6R38xY/rs:fit:200:200:1/g:ce/aHR0cHM6Ly9pLnl0/aW1nLmNvbS92aS9M/V2RzRjc5SDFQZy9t/YXhyZXNkZWZhdWx0/LmpwZw" + } + }, + { + "type": "video_result", + "url": "https://www.youtube.com/watch?v=AovxLr8jUH4", + "title": "Python Tutorial for Beginners 5 - Python print() and input() Function ...", + "description": "In this Video I am going to show How to use print() Function and input() Function in Python. In python The print() function is used to print the specified ...", + "age": "August 28, 2018", + "page_age": "2018-08-28T20:11:09", + "video": {}, + "meta_url": { + "scheme": "https", + "netloc": "youtube.com", + "hostname": "www.youtube.com", + "favicon": "https://imgs.search.brave.com/Ux4Hee4evZhvjuTKwtapBycOGjGDci2Gvn2pbSzvbC0/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvOTkyZTZiMWU3/YzU3Nzc5YjExYzUy/N2VhZTIxOWNlYjM5/ZGVjN2MyZDY4Nzdh/ZDYzMTYxNmI5N2Rk/Y2Q3N2FkNy93d3cu/eW91dHViZS5jb20v", + "path": "› watch" + }, + "thumbnail": { + "src": "https://imgs.search.brave.com/nCoLEcWkKtiecprWbS6nufwGCaSbPH7o0-sMeIkFmjI/rs:fit:200:200:1/g:ce/aHR0cHM6Ly9pLnl0/aW1nLmNvbS92aS9B/b3Z4THI4alVINC9o/cWRlZmF1bHQuanBn" + } + } + ], + "mutated_by_goggles": false + }, + "web": { + "type": "search", + "results": [ + { + "title": "Welcome to Python.org", + "url": "https://www.python.org", + "is_source_local": false, + "is_source_both": false, + "description": "The official home of the Python Programming Language", + "page_age": "2023-09-09T15:55:05", + "profile": { + "name": "Python", + "url": "https://www.python.org", + "long_name": "python.org", + "img": "https://imgs.search.brave.com/vBaRH-v6oPS4csO4cdvuKhZ7-xDVvydin3oe3zXYxAI/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvNTJjMzZjNDBj/MmIzODgwMGUyOTRj/Y2E5MjM3YjRkYTZj/YWI1Yzk1NTlmYTgw/ZDBjNzM0MGMxZjQz/YWFjNTczYy93d3cu/cHl0aG9uLm9yZy8" + }, + "language": "en", + "family_friendly": true, + "type": "search_result", + "subtype": "generic", + "meta_url": { + "scheme": "https", + "netloc": "python.org", + "hostname": "www.python.org", + "favicon": "https://imgs.search.brave.com/vBaRH-v6oPS4csO4cdvuKhZ7-xDVvydin3oe3zXYxAI/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvNTJjMzZjNDBj/MmIzODgwMGUyOTRj/Y2E5MjM3YjRkYTZj/YWI1Yzk1NTlmYTgw/ZDBjNzM0MGMxZjQz/YWFjNTczYy93d3cu/cHl0aG9uLm9yZy8", + "path": "" + }, + "thumbnail": { + "src": "https://imgs.search.brave.com/GGfNfe5rxJ8QWEoxXniSLc0-POLU3qPyTIpuqPdbmXk/rs:fit:200:200:1/g:ce/aHR0cHM6Ly93d3cu/cHl0aG9uLm9yZy9z/dGF0aWMvb3Blbmdy/YXBoLWljb24tMjAw/eDIwMC5wbmc", + "original": "https://www.python.org/static/opengraph-icon-200x200.png", + "logo": false + }, + "age": "September 9, 2023", + "cluster_type": "generic", + "cluster": [ + { + "title": "Downloads", + "url": "https://www.python.org/downloads/", + "is_source_local": false, + "is_source_both": false, + "description": "The official home of the Python Programming Language", + "family_friendly": true + }, + { + "title": "Macos", + "url": "https://www.python.org/downloads/macos/", + "is_source_local": false, + "is_source_both": false, + "description": "The official home of the Python Programming Language", + "family_friendly": true + }, + { + "title": "Windows", + "url": "https://www.python.org/downloads/windows/", + "is_source_local": false, + "is_source_both": false, + "description": "The official home of the Python Programming Language", + "family_friendly": true + }, + { + "title": "Getting Started", + "url": "https://www.python.org/about/gettingstarted/", + "is_source_local": false, + "is_source_both": false, + "description": "The official home of the Python Programming Language", + "family_friendly": true + } + ], + "extra_snippets": [ + "Calculations are simple with Python, and expression syntax is straightforward: the operators +, -, * and / work as expected; parentheses () can be used for grouping. More about simple math functions in Python 3.", + "The core of extensible programming is defining functions. Python allows mandatory and optional arguments, keyword arguments, and even arbitrary argument lists. More about defining functions in Python 3", + "Lists (known as arrays in other languages) are one of the compound data types that Python understands. Lists can be indexed, sliced and manipulated with other built-in functions. More about lists in Python 3", + "# Python 3: Simple output (with Unicode) >>> print(\"Hello, I'm Python!\") Hello, I'm Python! # Input, assignment >>> name = input('What is your name?\\n') >>> print('Hi, %s.' % name) What is your name? Python Hi, Python." + ] + }, + { + "title": "Python (programming language) - Wikipedia", + "url": "https://en.wikipedia.org/wiki/Python_(programming_language)", + "is_source_local": false, + "is_source_both": false, + "description": "Python is a high-level, general-purpose programming language. Its design philosophy emphasizes code readability with the use of significant indentation. Python is dynamically typed and garbage-collected. It supports multiple programming paradigms, including structured (particularly procedural), ...", + "page_age": "2024-05-01T12:54:03", + "profile": { + "name": "Wikipedia", + "url": "https://en.wikipedia.org/wiki/Python_(programming_language)", + "long_name": "en.wikipedia.org", + "img": "https://imgs.search.brave.com/0kxnVOiqv-faZvOJc7zpym4Zin1CTs1f1svfNZSzmfU/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvNjQwNGZhZWY0/ZTQ1YWUzYzQ3MDUw/MmMzMGY3NTQ0ZjNj/NDUwMDk5ZTI3MWRk/NWYyNTM4N2UwOTE0/NTI3ZDQzNy9lbi53/aWtpcGVkaWEub3Jn/Lw" + }, + "language": "en", + "family_friendly": true, + "type": "search_result", + "subtype": "generic", + "meta_url": { + "scheme": "https", + "netloc": "en.wikipedia.org", + "hostname": "en.wikipedia.org", + "favicon": "https://imgs.search.brave.com/0kxnVOiqv-faZvOJc7zpym4Zin1CTs1f1svfNZSzmfU/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvNjQwNGZhZWY0/ZTQ1YWUzYzQ3MDUw/MmMzMGY3NTQ0ZjNj/NDUwMDk5ZTI3MWRk/NWYyNTM4N2UwOTE0/NTI3ZDQzNy9lbi53/aWtpcGVkaWEub3Jn/Lw", + "path": "› wiki › Python_(programming_language)" + }, + "age": "4 days ago", + "extra_snippets": [ + "Python is dynamically typed and garbage-collected. It supports multiple programming paradigms, including structured (particularly procedural), object-oriented and functional programming. It is often described as a \"batteries included\" language due to its comprehensive standard library.", + "Guido van Rossum began working on Python in the late 1980s as a successor to the ABC programming language and first released it in 1991 as Python 0.9.0. Python 2.0 was released in 2000. Python 3.0, released in 2008, was a major revision not completely backward-compatible with earlier versions. Python 2.7.18, released in 2020, was the last release of Python 2.", + "Python was invented in the late 1980s by Guido van Rossum at Centrum Wiskunde & Informatica (CWI) in the Netherlands as a successor to the ABC programming language, which was inspired by SETL, capable of exception handling and interfacing with the Amoeba operating system.", + "Python consistently ranks as one of the most popular programming languages, and has gained widespread use in the machine learning community." + ] + }, + { + "title": "Python Tutorial", + "url": "https://www.w3schools.com/python/", + "is_source_local": false, + "is_source_both": false, + "description": "W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.", + "page_age": "2017-12-07T00:00:00", + "profile": { + "name": "W3Schools", + "url": "https://www.w3schools.com/python/", + "long_name": "w3schools.com", + "img": "https://imgs.search.brave.com/JwO5r7z3HTBkU29vgNH_4rrSWLf2M4-8FMWNvbxrKX8/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvYjVlMGVkZDVj/ZGMyZWRmMzAwODRi/ZDAwZGE4NWI3NmU4/MjRhNjEzOGFhZWY3/ZGViMjY1OWY2ZDYw/YTZiOGUyZS93d3cu/dzNzY2hvb2xzLmNv/bS8" + }, + "language": "en", + "family_friendly": true, + "type": "search_result", + "subtype": "generic", + "meta_url": { + "scheme": "https", + "netloc": "w3schools.com", + "hostname": "www.w3schools.com", + "favicon": "https://imgs.search.brave.com/JwO5r7z3HTBkU29vgNH_4rrSWLf2M4-8FMWNvbxrKX8/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvYjVlMGVkZDVj/ZGMyZWRmMzAwODRi/ZDAwZGE4NWI3NmU4/MjRhNjEzOGFhZWY3/ZGViMjY1OWY2ZDYw/YTZiOGUyZS93d3cu/dzNzY2hvb2xzLmNv/bS8", + "path": "› python" + }, + "thumbnail": { + "src": "https://imgs.search.brave.com/EMfp8dodbJehmj0yCJh8317RHuaumsddnHI4bujvFcg/rs:fit:200:200:1/g:ce/aHR0cHM6Ly93d3cu/dzNzY2hvb2xzLmNv/bS9pbWFnZXMvdzNz/Y2hvb2xzX2xvZ29f/NDM2XzIucG5n", + "original": "https://www.w3schools.com/images/w3schools_logo_436_2.png", + "logo": true + }, + "age": "December 7, 2017", + "extra_snippets": [ + "Well organized and easy to understand Web building tutorials with lots of examples of how to use HTML, CSS, JavaScript, SQL, Python, PHP, Bootstrap, Java, XML and more.", + "HTML CSS JAVASCRIPT SQL PYTHON JAVA PHP HOW TO W3.CSS C C++ C# BOOTSTRAP REACT MYSQL JQUERY EXCEL XML DJANGO NUMPY PANDAS NODEJS R TYPESCRIPT ANGULAR GIT POSTGRESQL MONGODB ASP AI GO KOTLIN SASS VUE DSA GEN AI SCIPY AWS CYBERSECURITY DATA SCIENCE", + "Python Variables Variable Names Assign Multiple Values Output Variables Global Variables Variable Exercises Python Data Types Python Numbers Python Casting Python Strings", + "Python Strings Slicing Strings Modify Strings Concatenate Strings Format Strings Escape Characters String Methods String Exercises Python Booleans Python Operators Python Lists" + ] + }, + { + "title": "Online Python - IDE, Editor, Compiler, Interpreter", + "url": "https://www.online-python.com/", + "is_source_local": false, + "is_source_both": false, + "description": "Build and Run your Python code instantly. Online-Python is a quick and easy tool that helps you to build, compile, test your python programs.", + "profile": { + "name": "Online-python", + "url": "https://www.online-python.com/", + "long_name": "online-python.com", + "img": "https://imgs.search.brave.com/kfaEvapwHxSsRObO52-I-otYFPHpG1h7UXJyUqDM2Ec/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvZGYxODdjNWQ0/NjZjZTNiMjk5NDY1/MWI5MTgyYjU3Y2Q3/MTI3NGM5MjUzY2Fi/OGQ3MTQ4MmIxMTQx/ZTcxNWFhMC93d3cu/b25saW5lLXB5dGhv/bi5jb20v" + }, + "language": "en", + "family_friendly": true, + "type": "search_result", + "subtype": "generic", + "meta_url": { + "scheme": "https", + "netloc": "online-python.com", + "hostname": "www.online-python.com", + "favicon": "https://imgs.search.brave.com/kfaEvapwHxSsRObO52-I-otYFPHpG1h7UXJyUqDM2Ec/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvZGYxODdjNWQ0/NjZjZTNiMjk5NDY1/MWI5MTgyYjU3Y2Q3/MTI3NGM5MjUzY2Fi/OGQ3MTQ4MmIxMTQx/ZTcxNWFhMC93d3cu/b25saW5lLXB5dGhv/bi5jb20v", + "path": "" + }, + "extra_snippets": [ + "Build, run, and share Python code online for free with the help of online-integrated python's development environment (IDE). It is one of the most efficient, dependable, and potent online compilers for the Python programming language. It is not necessary for you to bother about establishing a Python environment in your local.", + "It is one of the most efficient, dependable, and potent online compilers for the Python programming language. It is not necessary for you to bother about establishing a Python environment in your local. Now You can immediately execute the Python code in the web browser of your choice.", + "It is not necessary for you to bother about establishing a Python environment in your local. Now You can immediately execute the Python code in the web browser of your choice. Using this Python editor is simple and quick to get up and running with. Simply type in the programme, and then press the RUN button!", + "Now You can immediately execute the Python code in the web browser of your choice. Using this Python editor is simple and quick to get up and running with. Simply type in the programme, and then press the RUN button! The code can be saved online by choosing the SHARE option, which also gives you the ability to access your code from any location providing you have internet access." + ] + }, + { + "title": "Python · GitHub", + "url": "https://github.com/python", + "is_source_local": false, + "is_source_both": false, + "description": "Repositories related to the Python Programming language - Python", + "page_age": "2023-03-06T00:00:00", + "profile": { + "name": "GitHub", + "url": "https://github.com/python", + "long_name": "github.com", + "img": "https://imgs.search.brave.com/v8685zI4XInM0zxlNI2s7oE_2Sb-EL7lAy81WXbkQD8/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvYWQyNWM1NjA5/ZjZmZjNlYzI2MDNk/N2VkNmJhYjE2MzZl/MDY5ZTMxMDUzZmY1/NmU3NWIzNWVmMjk0/NTBjMjJjZi9naXRo/dWIuY29tLw" + }, + "language": "en", + "family_friendly": true, + "type": "search_result", + "subtype": "generic", + "meta_url": { + "scheme": "https", + "netloc": "github.com", + "hostname": "github.com", + "favicon": "https://imgs.search.brave.com/v8685zI4XInM0zxlNI2s7oE_2Sb-EL7lAy81WXbkQD8/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvYWQyNWM1NjA5/ZjZmZjNlYzI2MDNk/N2VkNmJhYjE2MzZl/MDY5ZTMxMDUzZmY1/NmU3NWIzNWVmMjk0/NTBjMjJjZi9naXRo/dWIuY29tLw", + "path": "› python" + }, + "thumbnail": { + "src": "https://imgs.search.brave.com/POoaRfu_7gfp-D_O3qMNJrwDqJNbiDu1HuBpNJ_MpVQ/rs:fit:200:200:1/g:ce/aHR0cHM6Ly9hdmF0/YXJzLmdpdGh1YnVz/ZXJjb250ZW50LmNv/bS91LzE1MjU5ODE_/cz0yMDAmYW1wO3Y9/NA", + "original": "https://avatars.githubusercontent.com/u/1525981?s=200&v=4", + "logo": false + }, + "age": "March 6, 2023", + "extra_snippets": ["Configuration for Python planets (e.g. http://planetpython.org)"] + }, + { + "title": "Online Python Compiler (Interpreter)", + "url": "https://www.programiz.com/python-programming/online-compiler/", + "is_source_local": false, + "is_source_both": false, + "description": "Write and run Python code using our online compiler (interpreter). You can use Python Shell like IDLE, and take inputs from the user in our Python compiler.", + "page_age": "2020-06-02T00:00:00", + "profile": { + "name": "Programiz", + "url": "https://www.programiz.com/python-programming/online-compiler/", + "long_name": "programiz.com", + "img": "https://imgs.search.brave.com/ozj4JFayZ3Fs5c9eTp7M5g12azQ_Hblgu4dpTuHRz6U/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvMGJlN2U1YjVi/Y2M3ZDU5OGMwMWNi/M2Q3YjhjOTM1ZTFk/Y2NkZjE4NGQwOGIx/MTQ4NjI2YmNhODVj/MzFkMmJhYy93d3cu/cHJvZ3JhbWl6LmNv/bS8" + }, + "language": "en", + "family_friendly": true, + "type": "search_result", + "subtype": "generic", + "meta_url": { + "scheme": "https", + "netloc": "programiz.com", + "hostname": "www.programiz.com", + "favicon": "https://imgs.search.brave.com/ozj4JFayZ3Fs5c9eTp7M5g12azQ_Hblgu4dpTuHRz6U/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvMGJlN2U1YjVi/Y2M3ZDU5OGMwMWNi/M2Q3YjhjOTM1ZTFk/Y2NkZjE4NGQwOGIx/MTQ4NjI2YmNhODVj/MzFkMmJhYy93d3cu/cHJvZ3JhbWl6LmNv/bS8", + "path": "› python-programming › online-compiler" + }, + "age": "June 2, 2020", + "extra_snippets": [ + "Python Online Compiler Online R Compiler SQL Online Editor Online HTML/CSS Editor Online Java Compiler C Online Compiler C++ Online Compiler C# Online Compiler JavaScript Online Compiler Online GoLang Compiler Online PHP Compiler Online Swift Compiler Online Rust Compiler", + "# Online Python compiler (interpreter) to run Python online. # Write Python 3 code in this online editor and run it. print(\"Try programiz.pro\")" + ] + }, + { + "title": "Python Developer", + "url": "https://twitter.com/Python_Dv/status/1786763460992544791", + "is_source_local": false, + "is_source_both": false, + "description": "Python Developer", + "page_age": "2024-05-04T14:30:03", + "profile": { + "name": "X", + "url": "https://twitter.com/Python_Dv/status/1786763460992544791", + "long_name": "twitter.com", + "img": "https://imgs.search.brave.com/Zq483bGX0GnSgym-1P7iyOyEDX3PkDZSNT8m56F862A/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvN2MxOTUxNzhj/OTY1ZTQ3N2I0MjJk/MTY5NGM0MTRlYWVi/MjU1YWE2NDUwYmQ2/YTA2MDFhMDlkZDEx/NTAzZGNiNi90d2l0/dGVyLmNvbS8" + }, + "language": "en", + "family_friendly": true, + "type": "search_result", + "subtype": "generic", + "meta_url": { + "scheme": "https", + "netloc": "twitter.com", + "hostname": "twitter.com", + "favicon": "https://imgs.search.brave.com/Zq483bGX0GnSgym-1P7iyOyEDX3PkDZSNT8m56F862A/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvN2MxOTUxNzhj/OTY1ZTQ3N2I0MjJk/MTY5NGM0MTRlYWVi/MjU1YWE2NDUwYmQ2/YTA2MDFhMDlkZDEx/NTAzZGNiNi90d2l0/dGVyLmNvbS8", + "path": "› Python_Dv › status › 1786763460992544791" + }, + "age": "20 hours ago" + }, + { + "title": "input table name? - python script - KNIME Extensions - KNIME Community Forum", + "url": "https://forum.knime.com/t/input-table-name-python-script/78978", + "is_source_local": false, + "is_source_both": false, + "description": "Hi, when running a python script node, I get the error seen on the screenshot Same happens with this code too: The script input is output from the csv reader node. How can I get the right name for that table? Best wishes, Dario", + "page_age": "2024-05-04T09:20:44", + "profile": { + "name": "Knime", + "url": "https://forum.knime.com/t/input-table-name-python-script/78978", + "long_name": "forum.knime.com", + "img": "https://imgs.search.brave.com/WQoOhAD5i6uEhJ-qXvlWMJwbGA52f2Ycc_ns36EK698/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvOTAxNzMxNjFl/MzJjNzU5NzRkOTMz/Mjg4NDU2OWUxM2Rj/YzVkOGM3MzIwNzI2/YTY1NzYxNzA1MDE5/NzQzOWU3NC9mb3J1/bS5rbmltZS5jb20v" + }, + "language": "en", + "family_friendly": true, + "type": "search_result", + "subtype": "article", + "meta_url": { + "scheme": "https", + "netloc": "forum.knime.com", + "hostname": "forum.knime.com", + "favicon": "https://imgs.search.brave.com/WQoOhAD5i6uEhJ-qXvlWMJwbGA52f2Ycc_ns36EK698/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvOTAxNzMxNjFl/MzJjNzU5NzRkOTMz/Mjg4NDU2OWUxM2Rj/YzVkOGM3MzIwNzI2/YTY1NzYxNzA1MDE5/NzQzOWU3NC9mb3J1/bS5rbmltZS5jb20v", + "path": " › knime extensions" + }, + "thumbnail": { + "src": "https://imgs.search.brave.com/DtEl38dcvuM1kGfhN0T5HfOrsMJcztWNyriLvtDJmKI/rs:fit:200:200:1/g:ce/aHR0cHM6Ly9mb3J1/bS1jZG4ua25pbWUu/Y29tL3VwbG9hZHMv/ZGVmYXVsdC9vcmln/aW5hbC8zWC9lLzYv/ZTY0M2M2NzFlNzAz/MDg2MjkwMWY2YzJh/OWFjOWI5ZmEwM2M3/ZjMwZi5wbmc", + "original": "https://forum-cdn.knime.com/uploads/default/original/3X/e/6/e643c671e7030862901f6c2a9ac9b9fa03c7f30f.png", + "logo": false + }, + "age": "1 day ago", + "extra_snippets": [ + "Hi, when running a python script node, I get the error seen on the screenshot Same happens with this code too: The script input is output from the csv reader node. How can I get the right name for that table? …" + ] + }, + { + "title": "What does the Double Star operator mean in Python? - GeeksforGeeks", + "url": "https://www.geeksforgeeks.org/what-does-the-double-star-operator-mean-in-python/", + "is_source_local": false, + "is_source_both": false, + "description": "A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.", + "page_age": "2023-03-14T17:15:04", + "profile": { + "name": "GeeksforGeeks", + "url": "https://www.geeksforgeeks.org/what-does-the-double-star-operator-mean-in-python/", + "long_name": "geeksforgeeks.org", + "img": "https://imgs.search.brave.com/fhzcfv5xltx6-YBvJI9RZgS7xZo0dPNaASsrB8YOsCs/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvYjBhOGQ3MmNi/ZWE5N2EwMmZjYzA1/ZTI0ZTFhMGUyMTE0/MGM0ZTBmMWZlM2Y2/Yzk2ODMxZTRhYTBi/NDdjYTE0OS93d3cu/Z2Vla3Nmb3JnZWVr/cy5vcmcv" + }, + "language": "en", + "family_friendly": true, + "type": "search_result", + "subtype": "article", + "meta_url": { + "scheme": "https", + "netloc": "geeksforgeeks.org", + "hostname": "www.geeksforgeeks.org", + "favicon": "https://imgs.search.brave.com/fhzcfv5xltx6-YBvJI9RZgS7xZo0dPNaASsrB8YOsCs/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvYjBhOGQ3MmNi/ZWE5N2EwMmZjYzA1/ZTI0ZTFhMGUyMTE0/MGM0ZTBmMWZlM2Y2/Yzk2ODMxZTRhYTBi/NDdjYTE0OS93d3cu/Z2Vla3Nmb3JnZWVr/cy5vcmcv", + "path": "› what-does-the-double-star-operator-mean-in-python" + }, + "thumbnail": { + "src": "https://imgs.search.brave.com/GcR-j_dLbyHkbHEI3ffLMi6xpXGhF_2Z8POIoqtokhM/rs:fit:200:200:1/g:ce/aHR0cHM6Ly9tZWRp/YS5nZWVrc2Zvcmdl/ZWtzLm9yZy93cC1j/b250ZW50L3VwbG9h/ZHMvZ2ZnXzIwMFgy/MDAtMTAweDEwMC5w/bmc", + "original": "https://media.geeksforgeeks.org/wp-content/uploads/gfg_200X200-100x100.png", + "logo": false + }, + "age": "March 14, 2023", + "extra_snippets": [ + "Difference between / vs. // operator in Python", + "Double Star or (**) is one of the Arithmetic Operator (Like +, -, *, **, /, //, %) in Python Language. It is also known as Power Operator.", + "The time complexity of the given Python program is O(n), where n is the number of key-value pairs in the input dictionary.", + "Inplace Operators in Python | Set 2 (ixor(), iand(), ipow(),…)" + ] + }, + { + "title": "r/Python", + "url": "https://www.reddit.com/r/Python/", + "is_source_local": false, + "is_source_both": false, + "description": "The official Python community for Reddit! Stay up to date with the latest news, packages, and meta information relating to the Python programming language. --- If you have questions or are new to Python use r/LearnPython", + "page_age": "2022-12-30T16:25:02", + "profile": { + "name": "Reddit", + "url": "https://www.reddit.com/r/Python/", + "long_name": "reddit.com", + "img": "https://imgs.search.brave.com/mAZYEK9Wi13WLDUge7XZ8YuDTwm6DP6gBjvz1GdYZVY/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvN2ZiNTU0M2Nj/MTFhZjRiYWViZDlk/MjJiMjBjMzFjMDRk/Y2IzYWI0MGI0MjVk/OGY5NzQzOGQ5NzQ5/NWJhMWI0NC93d3cu/cmVkZGl0LmNvbS8" + }, + "language": "en", + "family_friendly": true, + "type": "search_result", + "subtype": "generic", + "meta_url": { + "scheme": "https", + "netloc": "reddit.com", + "hostname": "www.reddit.com", + "favicon": "https://imgs.search.brave.com/mAZYEK9Wi13WLDUge7XZ8YuDTwm6DP6gBjvz1GdYZVY/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvN2ZiNTU0M2Nj/MTFhZjRiYWViZDlk/MjJiMjBjMzFjMDRk/Y2IzYWI0MGI0MjVk/OGY5NzQzOGQ5NzQ5/NWJhMWI0NC93d3cu/cmVkZGl0LmNvbS8", + "path": "› r › Python" + }, + "thumbnail": { + "src": "https://imgs.search.brave.com/zWd10t3zg34ciHiAB-K5WWK3h_H4LedeDot9BVX7Ydo/rs:fit:200:200:1/g:ce/aHR0cHM6Ly9zdHls/ZXMucmVkZGl0bWVk/aWEuY29tL3Q1XzJx/aDB5L3N0eWxlcy9j/b21tdW5pdHlJY29u/X2NpZmVobDR4dDdu/YzEucG5n", + "original": "https://styles.redditmedia.com/t5_2qh0y/styles/communityIcon_cifehl4xt7nc1.png", + "logo": false + }, + "age": "December 30, 2022", + "extra_snippets": [ + "r/Python: The official Python community for Reddit! Stay up to date with the latest news, packages, and meta information relating to the Python…", + "By default, Python allows you to import and use anything, anywhere. Over time, this results in modules that were intended to be separate getting tightly coupled together, and domain boundaries breaking down. We experienced this first-hand at a unicorn startup, where the eng team paused development for over a year in an attempt to split up packages into independent services.", + "Hello r/Python! It's time to share what you've been working on! Whether it's a work-in-progress, a completed masterpiece, or just a rough idea, let us know what you're up to!", + "Whether it's your job, your hobby, or your passion project, all Python-related work is welcome here." + ] + }, + { + "title": "GitHub - python/cpython: The Python programming language", + "url": "https://github.com/python/cpython", + "is_source_local": false, + "is_source_both": false, + "description": "The Python programming language. Contribute to python/cpython development by creating an account on GitHub.", + "page_age": "2022-10-29T00:00:00", + "profile": { + "name": "GitHub", + "url": "https://github.com/python/cpython", + "long_name": "github.com", + "img": "https://imgs.search.brave.com/v8685zI4XInM0zxlNI2s7oE_2Sb-EL7lAy81WXbkQD8/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvYWQyNWM1NjA5/ZjZmZjNlYzI2MDNk/N2VkNmJhYjE2MzZl/MDY5ZTMxMDUzZmY1/NmU3NWIzNWVmMjk0/NTBjMjJjZi9naXRo/dWIuY29tLw" + }, + "language": "en", + "family_friendly": true, + "type": "search_result", + "subtype": "software", + "meta_url": { + "scheme": "https", + "netloc": "github.com", + "hostname": "github.com", + "favicon": "https://imgs.search.brave.com/v8685zI4XInM0zxlNI2s7oE_2Sb-EL7lAy81WXbkQD8/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvYWQyNWM1NjA5/ZjZmZjNlYzI2MDNk/N2VkNmJhYjE2MzZl/MDY5ZTMxMDUzZmY1/NmU3NWIzNWVmMjk0/NTBjMjJjZi9naXRo/dWIuY29tLw", + "path": "› python › cpython" + }, + "thumbnail": { + "src": "https://imgs.search.brave.com/BJbWFRUqgP-tKIyGK9ByXjuYjHO2mtYigUOEFNz_gXk/rs:fit:200:200:1/g:ce/aHR0cHM6Ly9vcGVu/Z3JhcGguZ2l0aHVi/YXNzZXRzLmNvbS82/MTY5YmJkNTQ0YzAy/NDg0MGU4NDdjYTU1/YTU3ZGZmMDA2ZDAw/YWQ1NDIzOTFmYTQ3/YmJjODg3OWM0NWYw/MTZhL3B5dGhvbi9j/cHl0aG9u", + "original": "https://opengraph.githubassets.com/6169bbd544c024840e847ca55a57dff006d00ad542391fa47bbc8879c45f016a/python/cpython", + "logo": false + }, + "age": "October 29, 2022", + "extra_snippets": [ + "You can pass many options to the configure script; run ./configure --help to find out more. On macOS case-insensitive file systems and on Cygwin, the executable is called python.exe; elsewhere it's just python.", + "Building a complete Python installation requires the use of various additional third-party libraries, depending on your build platform and configure options. Not all standard library modules are buildable or usable on all platforms. Refer to the Install dependencies section of the Developer Guide for current detailed information on dependencies for various Linux distributions and macOS.", + "To get an optimized build of Python, configure --enable-optimizations before you run make. This sets the default make targets up to enable Profile Guided Optimization (PGO) and may be used to auto-enable Link Time Optimization (LTO) on some platforms. For more details, see the sections below.", + "Copyright © 2001-2024 Python Software Foundation. All rights reserved." + ] + }, + { + "title": "5. Data Structures — Python 3.12.3 documentation", + "url": "https://docs.python.org/3/tutorial/datastructures.html", + "is_source_local": false, + "is_source_both": false, + "description": "This chapter describes some things you’ve learned about already in more detail, and adds some new things as well. More on Lists: The list data type has some more methods. Here are all of the method...", + "page_age": "2023-07-04T00:00:00", + "profile": { + "name": "Python documentation", + "url": "https://docs.python.org/3/tutorial/datastructures.html", + "long_name": "docs.python.org", + "img": "https://imgs.search.brave.com/F5Ym7eSElhGdGUFKLRxDj9Z_tc180ldpeMvQ2Q6ARbA/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvMTUzOTFjOGVi/YTcyOTVmODA3ODIy/YjE2NzFjY2ViMjhl/NzRlY2JhYTc5YjNm/ZjhmODAyZWI2OGUw/ZjU4NDVlNy9kb2Nz/LnB5dGhvbi5vcmcv" + }, + "language": "en", + "family_friendly": true, + "type": "search_result", + "subtype": "generic", + "meta_url": { + "scheme": "https", + "netloc": "docs.python.org", + "hostname": "docs.python.org", + "favicon": "https://imgs.search.brave.com/F5Ym7eSElhGdGUFKLRxDj9Z_tc180ldpeMvQ2Q6ARbA/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvMTUzOTFjOGVi/YTcyOTVmODA3ODIy/YjE2NzFjY2ViMjhl/NzRlY2JhYTc5YjNm/ZjhmODAyZWI2OGUw/ZjU4NDVlNy9kb2Nz/LnB5dGhvbi5vcmcv", + "path": "› 3 › tutorial › datastructures.html" + }, + "thumbnail": { + "src": "https://imgs.search.brave.com/Y7GrMRF8WorDIMLuOl97XC8ltYpoOCqNwWF2pQIIKls/rs:fit:200:200:1/g:ce/aHR0cHM6Ly9kb2Nz/LnB5dGhvbi5vcmcv/My9fc3RhdGljL29n/LWltYWdlLnBuZw", + "original": "https://docs.python.org/3/_static/og-image.png", + "logo": false + }, + "age": "July 4, 2023", + "extra_snippets": [ + "You might have noticed that methods like insert, remove or sort that only modify the list have no return value printed – they return the default None. [1] This is a design principle for all mutable data structures in Python.", + "We saw that lists and strings have many common properties, such as indexing and slicing operations. They are two examples of sequence data types (see Sequence Types — list, tuple, range). Since Python is an evolving language, other sequence data types may be added. There is also another standard sequence data type: the tuple.", + "Python also includes a data type for sets. A set is an unordered collection with no duplicate elements. Basic uses include membership testing and eliminating duplicate entries. Set objects also support mathematical operations like union, intersection, difference, and symmetric difference.", + "Another useful data type built into Python is the dictionary (see Mapping Types — dict). Dictionaries are sometimes found in other languages as “associative memories” or “associative arrays”. Unlike sequences, which are indexed by a range of numbers, dictionaries are indexed by keys, which can be any immutable type; strings and numbers can always be keys." + ] + }, + { + "title": "Something wrong with python packages / AUR Issues, Discussion & PKGBUILD Requests / Arch Linux Forums", + "url": "https://bbs.archlinux.org/viewtopic.php?id=295466", + "is_source_local": false, + "is_source_both": false, + "description": "Big Python updates require Python packages to be rebuild. For some reason they didn't think a bump that made it necessary to rebuild half the official repo was a news post.", + "page_age": "2024-05-04T08:30:02", + "profile": { + "name": "Archlinux", + "url": "https://bbs.archlinux.org/viewtopic.php?id=295466", + "long_name": "bbs.archlinux.org", + "img": "https://imgs.search.brave.com/3au9oqkzSri_aLEec3jo-0bFgLuICkydrWfjFcC8lkI/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvNWNkODM1MWJl/ZmJhMzkzNzYzMDkz/NmEyMWMxNjI5MjNk/NGJmZjFhNTBlZDNl/Mzk5MzJjOGZkYjZl/MjNmY2IzNS9iYnMu/YXJjaGxpbnV4Lm9y/Zy8" + }, + "language": "en", + "family_friendly": true, + "type": "search_result", + "subtype": "generic", + "meta_url": { + "scheme": "https", + "netloc": "bbs.archlinux.org", + "hostname": "bbs.archlinux.org", + "favicon": "https://imgs.search.brave.com/3au9oqkzSri_aLEec3jo-0bFgLuICkydrWfjFcC8lkI/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvNWNkODM1MWJl/ZmJhMzkzNzYzMDkz/NmEyMWMxNjI5MjNk/NGJmZjFhNTBlZDNl/Mzk5MzJjOGZkYjZl/MjNmY2IzNS9iYnMu/YXJjaGxpbnV4Lm9y/Zy8", + "path": "› viewtopic.php" + }, + "age": "1 day ago", + "extra_snippets": [ + "Traceback (most recent call last): File \"/usr/lib/python3.12/importlib/metadata/__init__.py\", line 397, in from_name return next(cls.discover(name=name)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ StopIteration During handling of the above exception, another exception occurred: Traceback (most recent call last): File \"/usr/bin/informant\", line 33, in sys.exit(load_entry_point('informant==0.5.0', 'console_scripts', 'informant')()) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File \"/usr/bin/informant\", line 22, in importlib_load_entry_point for entry_point in distribution(dis" + ] + }, + { + "title": "Introduction to Python", + "url": "https://www.w3schools.com/python/python_intro.asp", + "is_source_local": false, + "is_source_both": false, + "description": "W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.", + "profile": { + "name": "W3Schools", + "url": "https://www.w3schools.com/python/python_intro.asp", + "long_name": "w3schools.com", + "img": "https://imgs.search.brave.com/JwO5r7z3HTBkU29vgNH_4rrSWLf2M4-8FMWNvbxrKX8/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvYjVlMGVkZDVj/ZGMyZWRmMzAwODRi/ZDAwZGE4NWI3NmU4/MjRhNjEzOGFhZWY3/ZGViMjY1OWY2ZDYw/YTZiOGUyZS93d3cu/dzNzY2hvb2xzLmNv/bS8" + }, + "language": "en", + "family_friendly": true, + "type": "search_result", + "subtype": "generic", + "meta_url": { + "scheme": "https", + "netloc": "w3schools.com", + "hostname": "www.w3schools.com", + "favicon": "https://imgs.search.brave.com/JwO5r7z3HTBkU29vgNH_4rrSWLf2M4-8FMWNvbxrKX8/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvYjVlMGVkZDVj/ZGMyZWRmMzAwODRi/ZDAwZGE4NWI3NmU4/MjRhNjEzOGFhZWY3/ZGViMjY1OWY2ZDYw/YTZiOGUyZS93d3cu/dzNzY2hvb2xzLmNv/bS8", + "path": "› python › python_intro.asp" + }, + "thumbnail": { + "src": "https://imgs.search.brave.com/EMfp8dodbJehmj0yCJh8317RHuaumsddnHI4bujvFcg/rs:fit:200:200:1/g:ce/aHR0cHM6Ly93d3cu/dzNzY2hvb2xzLmNv/bS9pbWFnZXMvdzNz/Y2hvb2xzX2xvZ29f/NDM2XzIucG5n", + "original": "https://www.w3schools.com/images/w3schools_logo_436_2.png", + "logo": true + }, + "extra_snippets": [ + "Well organized and easy to understand Web building tutorials with lots of examples of how to use HTML, CSS, JavaScript, SQL, Python, PHP, Bootstrap, Java, XML and more.", + "HTML CSS JAVASCRIPT SQL PYTHON JAVA PHP HOW TO W3.CSS C C++ C# BOOTSTRAP REACT MYSQL JQUERY EXCEL XML DJANGO NUMPY PANDAS NODEJS R TYPESCRIPT ANGULAR GIT POSTGRESQL MONGODB ASP AI GO KOTLIN SASS VUE DSA GEN AI SCIPY AWS CYBERSECURITY DATA SCIENCE", + "Python Variables Variable Names Assign Multiple Values Output Variables Global Variables Variable Exercises Python Data Types Python Numbers Python Casting Python Strings", + "Python Strings Slicing Strings Modify Strings Concatenate Strings Format Strings Escape Characters String Methods String Exercises Python Booleans Python Operators Python Lists" + ] + }, + { + "title": "bug: AUR package wants to use python but does not find any preset version · Issue #1740 · asdf-vm/asdf", + "url": "https://github.com/asdf-vm/asdf/issues/1740", + "is_source_local": false, + "is_source_both": false, + "description": "Describe the Bug I am not sure why this is happening, I am trying to install tlpui from AUR and it fails, here are some logs to help: ==> Making package: tlpui 2:1.6.5-1 (Mi 10 apr 2024 23:19:15 +0...", + "page_age": "2024-05-04T06:45:04", + "profile": { + "name": "GitHub", + "url": "https://github.com/asdf-vm/asdf/issues/1740", + "long_name": "github.com", + "img": "https://imgs.search.brave.com/v8685zI4XInM0zxlNI2s7oE_2Sb-EL7lAy81WXbkQD8/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvYWQyNWM1NjA5/ZjZmZjNlYzI2MDNk/N2VkNmJhYjE2MzZl/MDY5ZTMxMDUzZmY1/NmU3NWIzNWVmMjk0/NTBjMjJjZi9naXRo/dWIuY29tLw" + }, + "language": "en", + "family_friendly": true, + "type": "search_result", + "subtype": "software", + "meta_url": { + "scheme": "https", + "netloc": "github.com", + "hostname": "github.com", + "favicon": "https://imgs.search.brave.com/v8685zI4XInM0zxlNI2s7oE_2Sb-EL7lAy81WXbkQD8/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvYWQyNWM1NjA5/ZjZmZjNlYzI2MDNk/N2VkNmJhYjE2MzZl/MDY5ZTMxMDUzZmY1/NmU3NWIzNWVmMjk0/NTBjMjJjZi9naXRo/dWIuY29tLw", + "path": "› asdf-vm › asdf › issues › 1740" + }, + "thumbnail": { + "src": "https://imgs.search.brave.com/KrLW5s_2n4jyP8XLbc3ZPVBaLD963tQgWzG9EWPZlQs/rs:fit:200:200:1/g:ce/aHR0cHM6Ly9vcGVu/Z3JhcGguZ2l0aHVi/YXNzZXRzLmNvbS81/MTE0ZTdkOGIwODM2/YmQ2MTY3NzQ1ZGI4/MmZjMGE3OGUyMjcw/MGFlY2ZjMWZkODBl/MDYzZTNiN2ZjOWNj/NzYyL2FzZGYtdm0v/YXNkZi9pc3N1ZXMv/MTc0MA", + "original": "https://opengraph.githubassets.com/5114e7d8b0836bd6167745db82fc0a78e22700aecfc1fd80e063e3b7fc9cc762/asdf-vm/asdf/issues/1740", + "logo": false + }, + "age": "1 day ago", + "extra_snippets": [ + "==> Starting build()... No preset version installed for command python Please install a version by running one of the following: asdf install python 3.8 or add one of the following versions in your config file at /home/ferret/.tool-versions python 3.11.0 python 3.12.1 python 3.12.3 ==> ERROR: A failure occurred in build(). Aborting...", + "-> error making: tlpui-exit status 4 -> Failed to install the following packages. Manual intervention is required: tlpui - exit status 4 ferret@FX505DT in ~ $ cat /home/ferret/.tool-versions nodejs 21.6.0 python 3.12.3 ferret@FX505DT in ~ $ python -V Python 3.12.3 ferret@FX505DT in ~ $ which python /home/ferret/.asdf/shims/python", + "Describe the Bug I am not sure why this is happening, I am trying to install tlpui from AUR and it fails, here are some logs to help: ==> Making package: tlpui 2:1.6.5-1 (Mi 10 apr 2024 23:19:15 +0300) ==> Retrieving sources... -> Found ..." + ] + }, + { + "title": "What are python.exe and python3.exe, and why do they appear to point to App Installer? | Windows 11 Forum", + "url": "https://www.elevenforum.com/t/what-are-python-exe-and-python3-exe-and-why-do-they-appear-to-point-to-app-installer.24886/", + "is_source_local": false, + "is_source_both": false, + "description": "I was looking at App execution aliases (Settings > Apps > Advanced app settings > App execution aliases) on my new computer -- my first Windows 11 computer. Why are python.exe and python3.exe listed as App Installer? I assume that App Installer refers to installation of Microsoft Store / UWP...", + "page_age": "2024-05-03T17:30:04", + "profile": { + "name": "Windows 11 Forum", + "url": "https://www.elevenforum.com/t/what-are-python-exe-and-python3-exe-and-why-do-they-appear-to-point-to-app-installer.24886/", + "long_name": "elevenforum.com", + "img": "https://imgs.search.brave.com/XVRAYMEj6Im8i7jV5RxeTwpiRPtY9IWg4wRIuh-WhEw/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvZjk5MDZkMDIw/M2U1OWIwNjM5Y2U1/M2U2NzNiNzVkNTA5/NzA5OTI1ZTFmOTc4/MzU3OTlhYzU5OTVi/ZGNjNTY4MS93d3cu/ZWxldmVuZm9ydW0u/Y29tLw" + }, + "language": "en", + "family_friendly": true, + "type": "search_result", + "subtype": "generic", + "meta_url": { + "scheme": "https", + "netloc": "elevenforum.com", + "hostname": "www.elevenforum.com", + "favicon": "https://imgs.search.brave.com/XVRAYMEj6Im8i7jV5RxeTwpiRPtY9IWg4wRIuh-WhEw/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvZjk5MDZkMDIw/M2U1OWIwNjM5Y2U1/M2U2NzNiNzVkNTA5/NzA5OTI1ZTFmOTc4/MzU3OTlhYzU5OTVi/ZGNjNTY4MS93d3cu/ZWxldmVuZm9ydW0u/Y29tLw", + "path": " › windows support forums › apps and software" + }, + "thumbnail": { + "src": "https://imgs.search.brave.com/DVoFcE6d_-lx3BVGNS-RZK_lZzxQ8VhwZVf3AVqEJFA/rs:fit:200:200:1/g:ce/aHR0cHM6Ly93d3cu/ZWxldmVuZm9ydW0u/Y29tL2RhdGEvYXNz/ZXRzL2xvZ28vbWV0/YTEtMjAxLnBuZw", + "original": "https://www.elevenforum.com/data/assets/logo/meta1-201.png", + "logo": true + }, + "age": "2 days ago", + "extra_snippets": [ + "Why are python.exe and python3.exe listed as App Installer? I assume that App Installer refers to installation of Microsoft Store / UWP apps, but if that's the case, then why are they called python.exe and python3.exe? Or are python.exe and python3.exe simply serving as aliases / pointers pointing to App Installer, which is itself a Microsoft Store App?", + "Or are python.exe and python3.exe simply serving as aliases / pointers pointing to App Installer, which is itself a Microsoft Store App? I wish to soon install Python, along with an integrated development editor (IDE), on my machine, so that I can code in Python.", + "I wish to soon install Python, along with an integrated development editor (IDE), on my machine, so that I can code in Python. But is a Python interpreter already on my computer as suggested, if obliquely, by the presence of python.exe and python3.exe? I kind of doubt it." + ] + }, + { + "title": "How to Watermark Your Images Using Python OpenCV in ...", + "url": "https://medium.com/@daily_data_prep/how-to-watermark-your-images-using-python-opencv-in-bulk-e472085389a1", + "is_source_local": false, + "is_source_both": false, + "description": "Medium is an open platform where readers find dynamic thinking, and where expert and undiscovered voices can share their writing on any topic.", + "page_age": "2024-05-03T14:05:06", + "profile": { + "name": "Medium", + "url": "https://medium.com/@daily_data_prep/how-to-watermark-your-images-using-python-opencv-in-bulk-e472085389a1", + "long_name": "medium.com", + "img": "https://imgs.search.brave.com/qvE2kIQCiAsnPv2C6P9xM5J2VVWdm55g-A-2Q_yIJ0g/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvOTZhYmQ1N2Q4/NDg4ZDcyODIyMDZi/MzFmOWNhNjE3Y2E4/Y2YzMThjNjljNDIx/ZjllZmNhYTcwODhl/YTcwNDEzYy9tZWRp/dW0uY29tLw" + }, + "language": "en", + "family_friendly": true, + "type": "search_result", + "subtype": "generic", + "meta_url": { + "scheme": "https", + "netloc": "medium.com", + "hostname": "medium.com", + "favicon": "https://imgs.search.brave.com/qvE2kIQCiAsnPv2C6P9xM5J2VVWdm55g-A-2Q_yIJ0g/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvOTZhYmQ1N2Q4/NDg4ZDcyODIyMDZi/MzFmOWNhNjE3Y2E4/Y2YzMThjNjljNDIx/ZjllZmNhYTcwODhl/YTcwNDEzYy9tZWRp/dW0uY29tLw", + "path": "› @daily_data_prep › how-to-watermark-your-images-using-python-opencv-in-bulk-e472085389a1" + }, + "age": "2 days ago" + }, + { + "title": "Increment and Decrement Operators in Python?", + "url": "https://www.tutorialspoint.com/increment-and-decrement-operators-in-python", + "is_source_local": false, + "is_source_both": false, + "description": "Increment and Decrement Operators in Python - Python does not have unary increment/decrement operator (++/--). Instead to increment a value, usea += 1to decrement a value, use −a -= 1Example>>> a = 0 >>> >>> #Increment >>> a +=1 >>> >>> #Decrement >>> a -= 1 >>> >>> #value of a >>> a 0Python ...", + "page_age": "2023-08-23T00:00:00", + "profile": { + "name": "Tutorialspoint", + "url": "https://www.tutorialspoint.com/increment-and-decrement-operators-in-python", + "long_name": "tutorialspoint.com", + "img": "https://imgs.search.brave.com/Wt8BSkivPlFwcU5yBtf7YzuvTuRExyd_502cdABCS5c/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvYjcyYjAzYmVl/ODU4MzZiMjJiYTFh/MjJhZDNmNWE4YzA5/MDgyYTZhMDg3NTYw/M2NiY2NiZTUxN2I5/MjU1MWFmMS93d3cu/dHV0b3JpYWxzcG9p/bnQuY29tLw" + }, + "language": "en", + "family_friendly": true, + "type": "search_result", + "subtype": "generic", + "meta_url": { + "scheme": "https", + "netloc": "tutorialspoint.com", + "hostname": "www.tutorialspoint.com", + "favicon": "https://imgs.search.brave.com/Wt8BSkivPlFwcU5yBtf7YzuvTuRExyd_502cdABCS5c/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvYjcyYjAzYmVl/ODU4MzZiMjJiYTFh/MjJhZDNmNWE4YzA5/MDgyYTZhMDg3NTYw/M2NiY2NiZTUxN2I5/MjU1MWFmMS93d3cu/dHV0b3JpYWxzcG9p/bnQuY29tLw", + "path": "› increment-and-decrement-operators-in-python" + }, + "thumbnail": { + "src": "https://imgs.search.brave.com/ddG5vyZGLVudvecEbQJPeG8tGuaZ7g3Xz6Gyjdl5WA8/rs:fit:200:200:1/g:ce/aHR0cHM6Ly93d3cu/dHV0b3JpYWxzcG9p/bnQuY29tL2ltYWdl/cy90cF9sb2dvXzQz/Ni5wbmc", + "original": "https://www.tutorialspoint.com/images/tp_logo_436.png", + "logo": true + }, + "age": "August 23, 2023", + "extra_snippets": [ + "Increment and Decrement Operators in Python - Python does not have unary increment/decrement operator (++/--). Instead to increment a value, usea += 1to decrement a value, use −a -= 1Example>>> a = 0 >>> >>> #Increment >>> a +=1 >>> >>> #Decrement >>> a -= 1 >>> >>> #value of a >>> a 0Python does not provide multiple ways to do the same thing", + "So what above statement means in python is: create an object of type int having value 1 and give the name a to it. The object is an instance of int having value 1 and the name a refers to it. The assigned name a and the object to which it refers are distinct.", + "Python does not provide multiple ways to do the same thing .", + "However, be careful if you are coming from a language like C, Python doesn’t have \"variables\" in the sense that C does, instead python uses names and objects and in python integers (int’s) are immutable." + ] + }, + { + "title": "Gumroad – How not to suck at Python / SideFX Houdini | CG Persia", + "url": "https://cgpersia.com/2024/05/gumroad-how-not-to-suck-at-python-sidefx-houdini-195370.html", + "is_source_local": false, + "is_source_both": false, + "description": "Info: This course is made for artists or TD (technical director) willing to learn Python to improve their workflows inside SideFX Houdini, get faster in production and develop all the tools you always wished you had.", + "page_age": "2024-05-03T08:35:03", + "profile": { + "name": "Cgpersia", + "url": "https://cgpersia.com/2024/05/gumroad-how-not-to-suck-at-python-sidefx-houdini-195370.html", + "long_name": "cgpersia.com", + "img": "https://imgs.search.brave.com/VjyaopAm-M9sWvM7n-KnGZ3T5swIOwwE80iF5QVqQPg/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvYmE0MzQ4NmI2/NjFhMTA1ZDBiN2Iw/ZWNiNDUxNjUwYjdh/MGE5ZjQ0ZjIxNzll/NmVkZDE2YzYyMDBh/NDNiMDgwMy9jZ3Bl/cnNpYS5jb20v" + }, + "language": "en", + "family_friendly": true, + "type": "search_result", + "subtype": "generic", + "meta_url": { + "scheme": "https", + "netloc": "cgpersia.com", + "hostname": "cgpersia.com", + "favicon": "https://imgs.search.brave.com/VjyaopAm-M9sWvM7n-KnGZ3T5swIOwwE80iF5QVqQPg/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvYmE0MzQ4NmI2/NjFhMTA1ZDBiN2Iw/ZWNiNDUxNjUwYjdh/MGE5ZjQ0ZjIxNzll/NmVkZDE2YzYyMDBh/NDNiMDgwMy9jZ3Bl/cnNpYS5jb20v", + "path": "› 2024 › 05 › gumroad-how-not-to-suck-at-python-sidefx-houdini-195370.html" + }, + "age": "2 days ago", + "extra_snippets": [ + "Posted in: 2D, CG Releases, Downloads, Learning, Tutorials, Videos. Tagged: Gumroad, Python, Sidefx. Leave a Comment", + "01 – Python – Fundamentals Get the Fundamentals of python before starting the fun stuff ! 02 – Python Construction Part02 digging further into python concepts 03 – Houdini – Python Basics Applying some basic python in Houdini and starting to make tools !", + "02 – Python Construction Part02 digging further into python concepts 03 – Houdini – Python Basics Applying some basic python in Houdini and starting to make tools ! 04 – Houdini – Python Intermediate Applying some more advanced python in Houdini to make tools ! 05 – Houdini – Python Expert Using QtDesigner in combinaison with Houdini Python/Pyside to create advanced tools." + ] + }, + { + "title": "How to install Python: The complete Python programmer’s guide", + "url": "https://www.pluralsight.com/resources/blog/software-development/python-installation-guide", + "is_source_local": false, + "is_source_both": false, + "description": "An easy guide on how set up your operating system so you can program in Python, and how to update or uninstall it. For Linux, Windows, and macOS.", + "page_age": "2024-05-02T07:30:02", + "profile": { + "name": "Pluralsight", + "url": "https://www.pluralsight.com/resources/blog/software-development/python-installation-guide", + "long_name": "pluralsight.com", + "img": "https://imgs.search.brave.com/zvwQNSVu9-jR2CRlNcsTzxjaXKPlXNuh-Jo9-0yA1OE/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvMTNkNWQyNjk3/M2Q0NzYyMmUyNDc3/ZjYwMWFlZDI5YTI4/ODhmYzc2MDkzMjAy/MjNkMWY1MDE3NTQw/MzI5NWVkZS93d3cu/cGx1cmFsc2lnaHQu/Y29tLw" + }, + "language": "en", + "family_friendly": true, + "type": "search_result", + "subtype": "generic", + "meta_url": { + "scheme": "https", + "netloc": "pluralsight.com", + "hostname": "www.pluralsight.com", + "favicon": "https://imgs.search.brave.com/zvwQNSVu9-jR2CRlNcsTzxjaXKPlXNuh-Jo9-0yA1OE/rs:fit:32:32:1/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvMTNkNWQyNjk3/M2Q0NzYyMmUyNDc3/ZjYwMWFlZDI5YTI4/ODhmYzc2MDkzMjAy/MjNkMWY1MDE3NTQw/MzI5NWVkZS93d3cu/cGx1cmFsc2lnaHQu/Y29tLw", + "path": " › blog › blog" + }, + "thumbnail": { + "src": "https://imgs.search.brave.com/xrv5PHH2Bzmq2rcIYzk__8h5RqCj6kS3I6SGCNw5dZM/rs:fit:200:200:1/g:ce/aHR0cHM6Ly93d3cu/cGx1cmFsc2lnaHQu/Y29tL2NvbnRlbnQv/ZGFtL3BzL2ltYWdl/cy9yZXNvdXJjZS1j/ZW50ZXIvYmxvZy9o/ZWFkZXItaGVyby1p/bWFnZXMvUHl0aG9u/LndlYnA", + "original": "https://www.pluralsight.com/content/dam/ps/images/resource-center/blog/header-hero-images/Python.webp", + "logo": false + }, + "age": "3 days ago", + "extra_snippets": [ + "Whether it’s your first time programming or you’re a seasoned programmer, you’ll have to install or update Python every now and then --- or if necessary, uninstall it. In this article, you'll learn how to do just that.", + "Some systems come with Python, so to start off, we’ll first check to see if it’s installed on your system before we proceed. To do that, we’ll need to open a terminal. Since you might be new to programming, let’s go over how to open a terminal for Linux, Windows, and macOS.", + "Before we dive into setting up your system so you can program in Python, let’s talk terminal basics and benefits.", + "However, let’s focus on why we need it for working with Python. We use a terminal, or command line, to:" + ] + } + ], + "family_friendly": true + } +} diff --git a/backend/open_webui/retrieval/web/testdata/google_pse.json b/backend/open_webui/retrieval/web/testdata/google_pse.json new file mode 100644 index 0000000..15da972 --- /dev/null +++ b/backend/open_webui/retrieval/web/testdata/google_pse.json @@ -0,0 +1,442 @@ +{ + "kind": "customsearch#search", + "url": { + "type": "application/json", + "template": "https://www.googleapis.com/customsearch/v1?q={searchTerms}&num={count?}&start={startIndex?}&lr={language?}&safe={safe?}&cx={cx?}&sort={sort?}&filter={filter?}&gl={gl?}&cr={cr?}&googlehost={googleHost?}&c2coff={disableCnTwTranslation?}&hq={hq?}&hl={hl?}&siteSearch={siteSearch?}&siteSearchFilter={siteSearchFilter?}&exactTerms={exactTerms?}&excludeTerms={excludeTerms?}&linkSite={linkSite?}&orTerms={orTerms?}&dateRestrict={dateRestrict?}&lowRange={lowRange?}&highRange={highRange?}&searchType={searchType}&fileType={fileType?}&rights={rights?}&imgSize={imgSize?}&imgType={imgType?}&imgColorType={imgColorType?}&imgDominantColor={imgDominantColor?}&alt=json" + }, + "queries": { + "request": [ + { + "title": "Google Custom Search - lectures", + "totalResults": "2450000000", + "searchTerms": "lectures", + "count": 10, + "startIndex": 1, + "inputEncoding": "utf8", + "outputEncoding": "utf8", + "safe": "off", + "cx": "0473ef98502d44e18" + } + ], + "nextPage": [ + { + "title": "Google Custom Search - lectures", + "totalResults": "2450000000", + "searchTerms": "lectures", + "count": 10, + "startIndex": 11, + "inputEncoding": "utf8", + "outputEncoding": "utf8", + "safe": "off", + "cx": "0473ef98502d44e18" + } + ] + }, + "context": { + "title": "LLM Search" + }, + "searchInformation": { + "searchTime": 0.445959, + "formattedSearchTime": "0.45", + "totalResults": "2450000000", + "formattedTotalResults": "2,450,000,000" + }, + "items": [ + { + "kind": "customsearch#result", + "title": "The Feynman Lectures on Physics", + "htmlTitle": "The Feynman \u003cb\u003eLectures\u003c/b\u003e on Physics", + "link": "https://www.feynmanlectures.caltech.edu/", + "displayLink": "www.feynmanlectures.caltech.edu", + "snippet": "This edition has been designed for ease of reading on devices of any size or shape; text, figures and equations can all be zoomed without degradation.", + "htmlSnippet": "This edition has been designed for ease of reading on devices of any size or shape; text, figures and equations can all be zoomed without degradation.", + "cacheId": "CyXMWYWs9UEJ", + "formattedUrl": "https://www.feynmanlectures.caltech.edu/", + "htmlFormattedUrl": "https://www.feynman\u003cb\u003electures\u003c/b\u003e.caltech.edu/", + "pagemap": { + "metatags": [ + { + "viewport": "width=device-width, initial-scale=1.0" + } + ] + } + }, + { + "kind": "customsearch#result", + "title": "Video Lectures", + "htmlTitle": "Video \u003cb\u003eLectures\u003c/b\u003e", + "link": "https://www.reddit.com/r/lectures/", + "displayLink": "www.reddit.com", + "snippet": "r/lectures: This subreddit is all about video lectures, talks and interesting public speeches. The topics include mathematics, physics, computer…", + "htmlSnippet": "r/\u003cb\u003electures\u003c/b\u003e: This subreddit is all about video \u003cb\u003electures\u003c/b\u003e, talks and interesting public speeches. The topics include mathematics, physics, computer…", + "formattedUrl": "https://www.reddit.com/r/lectures/", + "htmlFormattedUrl": "https://www.reddit.com/r/\u003cb\u003electures\u003c/b\u003e/", + "pagemap": { + "cse_thumbnail": [ + { + "src": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTZtOjhfkgUKQbL3DZxe5F6OVsgeDNffleObjJ7n9RllKQTSsimax7VIaY&s", + "width": "192", + "height": "192" + } + ], + "metatags": [ + { + "og:image": "https://www.redditstatic.com/shreddit/assets/favicon/192x192.png", + "theme-color": "#000000", + "og:image:width": "256", + "og:type": "website", + "twitter:card": "summary", + "twitter:title": "r/lectures", + "og:site_name": "Reddit", + "og:title": "r/lectures", + "og:image:height": "256", + "bingbot": "noarchive", + "msapplication-navbutton-color": "#000000", + "og:description": "This subreddit is all about video lectures, talks and interesting public speeches.\n\nThe topics include mathematics, physics, computer science, programming, engineering, biology, medicine, economics, politics, social sciences, and any other subjects!", + "twitter:image": "https://www.redditstatic.com/shreddit/assets/favicon/192x192.png", + "apple-mobile-web-app-status-bar-style": "black", + "twitter:site": "@reddit", + "viewport": "width=device-width, initial-scale=1, viewport-fit=cover", + "apple-mobile-web-app-capable": "yes", + "og:ttl": "600", + "og:url": "https://www.reddit.com/r/lectures/" + } + ], + "cse_image": [ + { + "src": "https://www.redditstatic.com/shreddit/assets/favicon/192x192.png" + } + ] + } + }, + { + "kind": "customsearch#result", + "title": "Lectures & Discussions | Flint Institute of Arts", + "htmlTitle": "\u003cb\u003eLectures\u003c/b\u003e & Discussions | Flint Institute of Arts", + "link": "https://flintarts.org/events/lectures", + "displayLink": "flintarts.org", + "snippet": "It will trace the intricate relationship between jewelry, attire, and the expression of personal identity, social hierarchy, and spiritual belief systems that ...", + "htmlSnippet": "It will trace the intricate relationship between jewelry, attire, and the expression of personal identity, social hierarchy, and spiritual belief systems that ...", + "cacheId": "jvpb9DxrfxoJ", + "formattedUrl": "https://flintarts.org/events/lectures", + "htmlFormattedUrl": "https://flintarts.org/events/\u003cb\u003electures\u003c/b\u003e", + "pagemap": { + "cse_thumbnail": [ + { + "src": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS23tMtAeNhJbOWdGxShYsmnyzFdzOC9Hb7lRykA9Pw72z1IlKTkjTdZw&s", + "width": "447", + "height": "113" + } + ], + "metatags": [ + { + "og:image": "https://flintarts.org/uploads/images/page-headers/_headerImage/nightshot.jpg", + "og:type": "website", + "viewport": "width=device-width, initial-scale=1", + "og:title": "Lectures & Discussions | Flint Institute of Arts", + "og:description": "The Flint Institute of Arts is the second largest art museum in Michigan and one of the largest museum art schools in the nation." + } + ], + "cse_image": [ + { + "src": "https://flintarts.org/uploads/images/page-headers/_headerImage/nightshot.jpg" + } + ] + } + }, + { + "kind": "customsearch#result", + "title": "Mandel Lectures | Mandel Center for the Humanities ... - Waltham", + "htmlTitle": "Mandel \u003cb\u003eLectures\u003c/b\u003e | Mandel Center for the Humanities ... - Waltham", + "link": "https://www.brandeis.edu/mandel-center-humanities/mandel-lectures.html", + "displayLink": "www.brandeis.edu", + "snippet": "Past Lectures · Lecture 1: \"Invisible Music: The Sonic Idea of Black Revolution From Captivity to Reconstruction\" · Lecture 2: \"Solidarity in Sound: Grassroots ...", + "htmlSnippet": "Past \u003cb\u003eLectures\u003c/b\u003e · \u003cb\u003eLecture\u003c/b\u003e 1: "Invisible Music: The Sonic Idea of Black Revolution From Captivity to Reconstruction" · \u003cb\u003eLecture\u003c/b\u003e 2: "Solidarity in Sound: Grassroots ...", + "cacheId": "cQLOZr0kgEEJ", + "formattedUrl": "https://www.brandeis.edu/mandel-center-humanities/mandel-lectures.html", + "htmlFormattedUrl": "https://www.brandeis.edu/mandel-center-humanities/mandel-\u003cb\u003electures\u003c/b\u003e.html", + "pagemap": { + "cse_thumbnail": [ + { + "src": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQWlU7bcJ5pIHk7RBCk2QKE-48ejF7hyPV0pr-20_cBt2BGdfKtiYXBuyw&s", + "width": "275", + "height": "183" + } + ], + "metatags": [ + { + "og:image": "https://www.brandeis.edu/mandel-center-humanities/events/events-images/mlhzumba", + "twitter:card": "summary_large_image", + "viewport": "width=device-width,initial-scale=1,minimum-scale=1", + "og:title": "Mandel Lectures in the Humanities", + "og:url": "https://www.brandeis.edu/mandel-center-humanities/mandel-lectures.html", + "og:description": "Annual Lecture Series", + "twitter:image": "https://www.brandeis.edu/mandel-center-humanities/events/events-images/mlhzumba" + } + ], + "cse_image": [ + { + "src": "https://www.brandeis.edu/mandel-center-humanities/events/events-images/mlhzumba" + } + ] + } + }, + { + "kind": "customsearch#result", + "title": "Brian Douglas - YouTube", + "htmlTitle": "Brian Douglas - YouTube", + "link": "https://www.youtube.com/channel/UCq0imsn84ShAe9PBOFnoIrg", + "displayLink": "www.youtube.com", + "snippet": "Welcome to Control Systems Lectures! This collection of videos is intended to supplement a first year controls class, not replace it.", + "htmlSnippet": "Welcome to Control Systems \u003cb\u003eLectures\u003c/b\u003e! This collection of videos is intended to supplement a first year controls class, not replace it.", + "cacheId": "NEROyBHolL0J", + "formattedUrl": "https://www.youtube.com/channel/UCq0imsn84ShAe9PBOFnoIrg", + "htmlFormattedUrl": "https://www.youtube.com/channel/UCq0imsn84ShAe9PBOFnoIrg", + "pagemap": { + "hcard": [ + { + "fn": "Brian Douglas", + "url": "https://www.youtube.com/channel/UCq0imsn84ShAe9PBOFnoIrg" + } + ], + "cse_thumbnail": [ + { + "src": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR7G0CeCBz_wVTZgjnhEr2QbiKP7f3uYzKitZYn74Mi32cDmVxvsegJoLI&s", + "width": "225", + "height": "225" + } + ], + "imageobject": [ + { + "width": "900", + "url": "https://yt3.googleusercontent.com/ytc/AIdro_nLo68wetImbwGUYP3stve_iKmAEccjhqB-q4o79xdInN4=s900-c-k-c0x00ffffff-no-rj", + "height": "900" + } + ], + "person": [ + { + "name": "Brian Douglas", + "url": "https://www.youtube.com/channel/UCq0imsn84ShAe9PBOFnoIrg" + } + ], + "metatags": [ + { + "apple-itunes-app": "app-id=544007664, app-argument=https://m.youtube.com/channel/UCq0imsn84ShAe9PBOFnoIrg?referring_app=com.apple.mobilesafari-smartbanner, affiliate-data=ct=smart_app_banner_polymer&pt=9008", + "og:image": "https://yt3.googleusercontent.com/ytc/AIdro_nLo68wetImbwGUYP3stve_iKmAEccjhqB-q4o79xdInN4=s900-c-k-c0x00ffffff-no-rj", + "twitter:app:url:iphone": "vnd.youtube://www.youtube.com/channel/UCq0imsn84ShAe9PBOFnoIrg", + "twitter:app:id:googleplay": "com.google.android.youtube", + "theme-color": "rgb(255, 255, 255)", + "og:image:width": "900", + "twitter:card": "summary", + "og:site_name": "YouTube", + "twitter:url": "https://www.youtube.com/channel/UCq0imsn84ShAe9PBOFnoIrg", + "twitter:app:url:ipad": "vnd.youtube://www.youtube.com/channel/UCq0imsn84ShAe9PBOFnoIrg", + "al:android:package": "com.google.android.youtube", + "twitter:app:name:googleplay": "YouTube", + "al:ios:url": "vnd.youtube://www.youtube.com/channel/UCq0imsn84ShAe9PBOFnoIrg", + "twitter:app:id:iphone": "544007664", + "og:description": "Welcome to Control Systems Lectures! This collection of videos is intended to supplement a first year controls class, not replace it. My goal is to take specific concepts in controls and expand on them in order to provide an intuitive understanding which will ultimately make you a better controls engineer. \n\nI'm glad you made it to my channel and I hope you find it useful.\n\nShoot me a message at controlsystemlectures@gmail.com, leave a comment or question and I'll get back to you if I can. Don't forget to subscribe!\n \nTwitter: @BrianBDouglas for engineering tweets and announcement of new videos.\nWebpage: http://engineeringmedia.com\n\nHere is the hardware/software I use: http://www.youtube.com/watch?v=m-M5_mIyHe4\n\nHere's a list of my favorite references: http://bit.ly/2skvmWd\n\n--Brian", + "al:ios:app_store_id": "544007664", + "twitter:image": "https://yt3.googleusercontent.com/ytc/AIdro_nLo68wetImbwGUYP3stve_iKmAEccjhqB-q4o79xdInN4=s900-c-k-c0x00ffffff-no-rj", + "twitter:site": "@youtube", + "og:type": "profile", + "twitter:title": "Brian Douglas", + "al:ios:app_name": "YouTube", + "og:title": "Brian Douglas", + "og:image:height": "900", + "twitter:app:id:ipad": "544007664", + "al:web:url": "https://www.youtube.com/channel/UCq0imsn84ShAe9PBOFnoIrg?feature=applinks", + "al:android:url": "https://www.youtube.com/channel/UCq0imsn84ShAe9PBOFnoIrg?feature=applinks", + "fb:app_id": "87741124305", + "twitter:app:url:googleplay": "https://www.youtube.com/channel/UCq0imsn84ShAe9PBOFnoIrg", + "twitter:app:name:ipad": "YouTube", + "viewport": "width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no,", + "twitter:description": "Welcome to Control Systems Lectures! This collection of videos is intended to supplement a first year controls class, not replace it. My goal is to take specific concepts in controls and expand on them in order to provide an intuitive understanding which will ultimately make you a better controls engineer. \n\nI'm glad you made it to my channel and I hope you find it useful.\n\nShoot me a message at controlsystemlectures@gmail.com, leave a comment or question and I'll get back to you if I can. Don't forget to subscribe!\n \nTwitter: @BrianBDouglas for engineering tweets and announcement of new videos.\nWebpage: http://engineeringmedia.com\n\nHere is the hardware/software I use: http://www.youtube.com/watch?v=m-M5_mIyHe4\n\nHere's a list of my favorite references: http://bit.ly/2skvmWd\n\n--Brian", + "og:url": "https://www.youtube.com/channel/UCq0imsn84ShAe9PBOFnoIrg", + "al:android:app_name": "YouTube", + "twitter:app:name:iphone": "YouTube" + } + ], + "cse_image": [ + { + "src": "https://yt3.googleusercontent.com/ytc/AIdro_nLo68wetImbwGUYP3stve_iKmAEccjhqB-q4o79xdInN4=s900-c-k-c0x00ffffff-no-rj" + } + ] + } + }, + { + "kind": "customsearch#result", + "title": "Lecture - Wikipedia", + "htmlTitle": "\u003cb\u003eLecture\u003c/b\u003e - Wikipedia", + "link": "https://en.wikipedia.org/wiki/Lecture", + "displayLink": "en.wikipedia.org", + "snippet": "Lecture ... For the academic rank, see Lecturer. A lecture (from Latin: lēctūra 'reading') is an oral presentation intended to present information or teach people ...", + "htmlSnippet": "\u003cb\u003eLecture\u003c/b\u003e ... For the academic rank, see \u003cb\u003eLecturer\u003c/b\u003e. A \u003cb\u003electure\u003c/b\u003e (from Latin: lēctūra 'reading') is an oral presentation intended to present information or teach people ...", + "cacheId": "d9Pjta02fmgJ", + "formattedUrl": "https://en.wikipedia.org/wiki/Lecture", + "htmlFormattedUrl": "https://en.wikipedia.org/wiki/Lecture", + "pagemap": { + "metatags": [ + { + "referrer": "origin", + "og:image": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/26/ADFA_Lecture_Theatres.jpg/1200px-ADFA_Lecture_Theatres.jpg", + "theme-color": "#eaecf0", + "og:image:width": "1200", + "og:type": "website", + "viewport": "width=device-width, initial-scale=1.0, user-scalable=yes, minimum-scale=0.25, maximum-scale=5.0", + "og:title": "Lecture - Wikipedia", + "og:image:height": "799", + "format-detection": "telephone=no" + } + ] + } + }, + { + "kind": "customsearch#result", + "title": "Mount Wilson Observatory | Lectures", + "htmlTitle": "Mount Wilson Observatory | \u003cb\u003eLectures\u003c/b\u003e", + "link": "https://www.mtwilson.edu/lectures/", + "displayLink": "www.mtwilson.edu", + "snippet": "Talks & Telescopes: August 24, 2024 – Panel: The Triumph of Hubble ... Compelling talks followed by picnicking and convivial stargazing through both the big ...", + "htmlSnippet": "Talks & Telescopes: August 24, 2024 – Panel: The Triumph of Hubble ... Compelling talks followed by picnicking and convivial stargazing through both the big ...", + "cacheId": "wdXI0azqx5UJ", + "formattedUrl": "https://www.mtwilson.edu/lectures/", + "htmlFormattedUrl": "https://www.mtwilson.edu/\u003cb\u003electures\u003c/b\u003e/", + "pagemap": { + "metatags": [ + { + "viewport": "width=device-width,initial-scale=1,user-scalable=no" + } + ], + "webpage": [ + { + "image": "http://www.mtwilson.edu/wp-content/uploads/2016/09/Logo.jpg", + "url": "https://www.facebook.com/WilsonObs" + } + ] + } + }, + { + "kind": "customsearch#result", + "title": "Lectures | NBER", + "htmlTitle": "\u003cb\u003eLectures\u003c/b\u003e | NBER", + "link": "https://www.nber.org/research/lectures", + "displayLink": "www.nber.org", + "snippet": "Results 1 - 50 of 354 ... Among featured events at the NBER Summer Institute are the Martin Feldstein Lecture, which examines a current issue involving economic ...", + "htmlSnippet": "Results 1 - 50 of 354 \u003cb\u003e...\u003c/b\u003e Among featured events at the NBER Summer Institute are the Martin Feldstein \u003cb\u003eLecture\u003c/b\u003e, which examines a current issue involving economic ...", + "cacheId": "CvvP3U3nb44J", + "formattedUrl": "https://www.nber.org/research/lectures", + "htmlFormattedUrl": "https://www.nber.org/research/\u003cb\u003electures\u003c/b\u003e", + "pagemap": { + "cse_thumbnail": [ + { + "src": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTmeViEZyV1YmFEFLhcA6WdgAG3v3RV6tB93ncyxSJ5JPst_p2aWrL7D1k&s", + "width": "310", + "height": "163" + } + ], + "metatags": [ + { + "og:image": "https://www.nber.org/sites/default/files/2022-06/NBER-FB-Share-Tile-1200.jpg", + "og:site_name": "NBER", + "handheldfriendly": "true", + "viewport": "width=device-width, initial-scale=1.0", + "og:title": "Lectures", + "mobileoptimized": "width", + "og:url": "https://www.nber.org/research/lectures" + } + ], + "cse_image": [ + { + "src": "https://www.nber.org/sites/default/files/2022-06/NBER-FB-Share-Tile-1200.jpg" + } + ] + } + }, + { + "kind": "customsearch#result", + "title": "STUDENTS CANNOT ACCESS RECORDED LECTURES ... - Solved", + "htmlTitle": "STUDENTS CANNOT ACCESS RECORDED LECTURES ... - Solved", + "link": "https://community.canvaslms.com/t5/Canvas-Question-Forum/STUDENTS-CANNOT-ACCESS-RECORDED-LECTURES/td-p/190358", + "displayLink": "community.canvaslms.com", + "snippet": "Mar 19, 2020 ... I believe the issue is that students were not invited. Are you trying to capture your screen? If not, there is an option to just record your web ...", + "htmlSnippet": "Mar 19, 2020 \u003cb\u003e...\u003c/b\u003e I believe the issue is that students were not invited. Are you trying to capture your screen? If not, there is an option to just record your web ...", + "cacheId": "wqrynQXX61sJ", + "formattedUrl": "https://community.canvaslms.com/t5/Canvas...LECTURES/td-p/190358", + "htmlFormattedUrl": "https://community.canvaslms.com/t5/Canvas...\u003cb\u003eLECTURES\u003c/b\u003e/td-p/190358", + "pagemap": { + "cse_thumbnail": [ + { + "src": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRUqXau3N8LfKgSD7OJOvV7xzGarLKRU-ckWXy1ZQ1p4CLPsedvLKmLMhk&s", + "width": "310", + "height": "163" + } + ], + "metatags": [ + { + "og:image": "https://community.canvaslms.com/html/@6A1FDD4D5FF35E4BBB4083A1022FA0DB/assets/CommunityPreview23.png", + "og:type": "article", + "article:section": "Canvas Question Forum", + "article:published_time": "2020-03-19T15:50:03.409Z", + "og:site_name": "Instructure Community", + "article:modified_time": "2020-03-19T13:55:53-07:00", + "viewport": "width=device-width, initial-scale=1.0, user-scalable=yes", + "og:title": "STUDENTS CANNOT ACCESS RECORDED LECTURES", + "og:url": "https://community.canvaslms.com/t5/Canvas-Question-Forum/STUDENTS-CANNOT-ACCESS-RECORDED-LECTURES/m-p/190358#M93667", + "og:description": "I can access and see my recorded lectures but my students can't. They have an error message when they try to open the recorded presentation or notes.", + "article:author": "https://community.canvaslms.com/t5/user/viewprofilepage/user-id/794287", + "twitter:image": "https://community.canvaslms.com/html/@6A1FDD4D5FF35E4BBB4083A1022FA0DB/assets/CommunityPreview23.png" + } + ], + "cse_image": [ + { + "src": "https://community.canvaslms.com/html/@6A1FDD4D5FF35E4BBB4083A1022FA0DB/assets/CommunityPreview23.png" + } + ] + } + }, + { + "kind": "customsearch#result", + "title": "Public Lecture Series - Sam Fox School of Design & Visual Arts", + "htmlTitle": "Public \u003cb\u003eLecture\u003c/b\u003e Series - Sam Fox School of Design & Visual Arts", + "link": "https://samfoxschool.wustl.edu/calendar/series/2-public-lecture-series", + "displayLink": "samfoxschool.wustl.edu", + "snippet": "The Sam Fox School's Spring 2024 Public Lecture Series highlights design and art as catalysts for change. Renowned speakers will delve into themes like ...", + "htmlSnippet": "The Sam Fox School's Spring 2024 Public \u003cb\u003eLecture\u003c/b\u003e Series highlights design and art as catalysts for change. Renowned speakers will delve into themes like ...", + "cacheId": "B-cgQG0j6tUJ", + "formattedUrl": "https://samfoxschool.wustl.edu/calendar/series/2-public-lecture-series", + "htmlFormattedUrl": "https://samfoxschool.wustl.edu/calendar/series/2-public-lecture-series", + "pagemap": { + "cse_thumbnail": [ + { + "src": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQSmHaGianm-64m-qauYjkPK_Q0JKWe-7yom4m1ogFYTmpWArA7k6dmk0sR&s", + "width": "307", + "height": "164" + } + ], + "website": [ + { + "name": "Public Lecture Series - Sam Fox School of Design & Visual Arts — Washington University in St. Louis" + } + ], + "metatags": [ + { + "og:image": "https://dvsp0hlm0xrn3.cloudfront.net/assets/default_og_image-44e73dee4b9d1e2c6a6295901371270c8ec5899eaed48ee8167a9b12f1b0f8b3.jpg", + "og:type": "website", + "og:site_name": "Sam Fox School of Design & Visual Arts — Washington University in St. Louis", + "viewport": "width=device-width, initial-scale=1.0", + "og:title": "Public Lecture Series - Sam Fox School of Design & Visual Arts — Washington University in St. Louis", + "csrf-token": "jBQsfZGY3RH8NVs0-KVDBYB-2N2kib4UYZHYdrShfTdLkvzfSvGeOaMrRKTRdYBPRKzdcGIuP7zwm9etqX_uvg", + "csrf-param": "authenticity_token", + "og:description": "The Sam Fox School's Spring 2024 Public Lecture Series highlights design and art as catalysts for change. Renowned speakers will delve into themes like social equity, resilient cities, and the impact of emerging technologies on contemporary life. Speakers include artists, architects, designers, and critics of the highest caliber, widely recognized for their research-based practices and multidisciplinary approaches to their fields." + } + ], + "cse_image": [ + { + "src": "https://dvsp0hlm0xrn3.cloudfront.net/assets/default_og_image-44e73dee4b9d1e2c6a6295901371270c8ec5899eaed48ee8167a9b12f1b0f8b3.jpg" + } + ] + } + } + ] +} diff --git a/backend/open_webui/retrieval/web/testdata/searchapi.json b/backend/open_webui/retrieval/web/testdata/searchapi.json new file mode 100644 index 0000000..fa3d1c3 --- /dev/null +++ b/backend/open_webui/retrieval/web/testdata/searchapi.json @@ -0,0 +1,357 @@ +{ + "search_metadata": { + "id": "search_VW19X7MebbAtdMwoQe68NbDz", + "status": "Success", + "created_at": "2024-08-27T13:43:20Z", + "request_time_taken": 0.6, + "parsing_time_taken": 0.72, + "total_time_taken": 1.32, + "request_url": "https://www.google.com/search?q=chatgpt&oq=chatgpt&gl=us&hl=en&ie=UTF-8", + "html_url": "https://www.searchapi.io/api/v1/searches/search_VW19X7MebbAtdMwoQe68NbDz.html", + "json_url": "https://www.searchapi.io/api/v1/searches/search_VW19X7MebbAtdMwoQe68NbDz" + }, + "search_parameters": { + "engine": "google", + "q": "chatgpt", + "device": "desktop", + "google_domain": "google.com", + "hl": "en", + "gl": "us" + }, + "search_information": { + "query_displayed": "chatgpt", + "total_results": 1010000000, + "time_taken_displayed": 0.37, + "detected_location": "United States" + }, + "knowledge_graph": { + "kgmid": "/g/11khcfz0y2", + "knowledge_graph_type": "Kp3 verticals", + "title": "ChatGPT", + "type": "Software", + "description": "ChatGPT is a chatbot and virtual assistant developed by OpenAI and launched on November 30, 2022. Based on large language models, it enables users to refine and steer a conversation towards a desired length, format, style, level of detail, and language.", + "source": { + "name": "Wikipedia", + "link": "https://en.wikipedia.org/wiki/ChatGPT" + }, + "developer": "OpenAI, Microsoft", + "developer_links": [ + { + "text": "OpenAI", + "link": "https://www.google.com/search?sca_esv=acb05f42373aaad6&gl=us&hl=en&q=OpenAI&si=ACC90nwLLwns5sISZcdzuISy7t-NHozt8Cbt6G3WNQfC9ekAgItjbuK5dmA2L3ta2Ero3Ypd_sib6W4Pr5sCi7O_W3yzdqxwyrjzsYeYOtNg2ogL1xVq9TKwgD48tL7rygfkRfNyy4k-R5yQgywoFukoCUths6NdRX69gl50cvd6dpZcMzVelCxT7mxXlRchl6XkueG326znDiZL-ODNOysdnCc4XoeAQUFtbaVjja6Vc7WkQF4X8rUdbDKPVU9WyLOV765d8Y777kMI7-nXGGyD7xXJX5E3HA%3D%3D&sa=X&ved=2ahUKEwi17_rnppWIAxX2rokEHfAoEzYQmxMoAHoECD0QAg" + }, + { + "text": "Microsoft", + "link": "https://www.google.com/search?sca_esv=acb05f42373aaad6&gl=us&hl=en&q=Microsoft&si=ACC90nyvvWro6QmnyY1IfSdgk5wwjB1r8BGd_IWRjXqmKPQqm-SdjhIP74XAMBYys4zy1Z9yzXEom04F9Qy-tMOt2d-L6jIC5cXse6I528G870-4sF-DZYAPj0F1HoGTUOqpWuP7jbEPm3w_-mCH0wVgBHBGCgxRrCaUn8_k2-aga9V9JD6hkq2kM8zVmERCqCM8rqo3bNfbPdJ-baTq4w8Pkxdan3K--CfOtXX--lTjJtO6BnfG2RdpY_jBfy3uZZ7DeAE4-P4rvKuty6UL6le4dqqDt-kLQA%3D%3D&sa=X&ved=2ahUKEwi17_rnppWIAxX2rokEHfAoEzYQmxMoAXoECD0QAw" + } + ], + "initial_release_date": "November 30, 2022", + "programming_language": "Python", + "programming_language_links": [ + { + "text": "Python", + "link": "https://www.google.com/search?sca_esv=acb05f42373aaad6&gl=us&hl=en&q=Python&si=ACC90nyvvWro6QmnyY1IfSdgk5wwjB1r8BGd_IWRjXqmKPQqmwbtPHPEcZi5JOYKaqe_iu1m4TVPotntrDVKbuXCkoFhx-K-Dp6PbewOILPFWjhDofHha-WRuSQCgY7LnBkzXtVH7pxiRdHONv3wpVsflGBg_EdTHCxOnyWt1nDgBmCjsfchXU7DKtJq159-V0-seE_cp7VV&sa=X&ved=2ahUKEwi17_rnppWIAxX2rokEHfAoEzYQmxMoAHoECDYQAg" + } + ], + "engine": "GPT-4; GPT-4o; GPT-4o mini", + "engine_links": [ + { + "text": "GPT-4", + "link": "https://www.google.com/search?sca_esv=acb05f42373aaad6&gl=us&hl=en&q=GPT-4&stick=H4sIAAAAAAAAAONgVuLVT9c3NMy2TI_PNUtOX8TK6h4QomsCAKiBOxkZAAAA&sa=X&ved=2ahUKEwi17_rnppWIAxX2rokEHfAoEzYQmxMoAHoECDUQAg" + }, + { + "text": "GPT-4o", + "link": "https://www.google.com/search?sca_esv=acb05f42373aaad6&gl=us&hl=en&q=GPT-4o&stick=H4sIAAAAAAAAAONgVuLVT9c3NCyryEg3rMooWMTK5h4QomuSDwC3NAfvGgAAAA&sa=X&ved=2ahUKEwi17_rnppWIAxX2rokEHfAoEzYQmxMoAXoECDUQAw" + }, + { + "text": "GPT-4o", + "link": "https://www.google.com/search?sca_esv=acb05f42373aaad6&gl=us&hl=en&q=GPT-4o&stick=H4sIAAAAAAAAAONgVuLVT9c3NCyryEg3rMooWMTK5h4QomuSDwC3NAfvGgAAAA&sa=X&ved=2ahUKEwi17_rnppWIAxX2rokEHfAoEzYQmxMoAnoECDUQBA" + } + ], + "license": "Proprietary", + "platform": "Cloud computing platforms", + "platform_links": [ + { + "text": "Cloud computing", + "link": "https://www.google.com/search?sca_esv=acb05f42373aaad6&gl=us&hl=en&q=Cloud+computing&stick=H4sIAAAAAAAAAONgVuLSz9U3MKqMt8w1XsTK75yTX5qikJyfW1BakpmXDgB-4JvxIAAAAA&sa=X&ved=2ahUKEwi17_rnppWIAxX2rokEHfAoEzYQmxMoAHoECDcQAg" + } + ], + "stable_release": "July 18, 2024; 40 days ago", + "image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALoAAAC6CAMAAAAu0KfDAAAAaVBMVEX///8AAAD7+/uysrJ5eXmoqKiYmJhZWVn4+PiVlZXw8PDj4+P09PTr6+vNzc2vr6/V1dWMjIxmZmY7OzvExMSCgoIgICBMTEygoKBUVFQUFBQxMTG4uLhDQ0O+vr7b29snJydubm4LCwtts+PWAAAPGElEQVR4nM1d6YKiMAxWBKlcIocoooDv/5CrjjpNmrTlcNz82x2Oz5KmX46mi8VMIoI42ZbZ+VRfl9e6891108aRM9fjPyVOmHhZvVSl2hVp8G10Gom3uyMB+yldf0i+jZCRcOdfeeAPOfUr8W2YqoTZ3oD7IfXJ+zZSKE7Y2+B+SvMfKX24oWYmL8fL/2JvPM3cpKV2w2+DvkvgmiYnJefLt3EvFsl5BPC77L6tNNuRwG/Sf1VpxFqHrd53WoN5TL+HPNgxoPb9ZnspiiRJiqLx2CU2/9rqGpUkoNMhDQN50RRxeMlo7MV/hHxfxszlTUUY/y5ZOEIEaXJZeQfvkrRRJD4/fR0CuX/QUZTEPamfyCsr+D9VuUrC6KPQ1RlaHUxvTGgVUxWp9JLP8bQVft11Z2HsxKWioBJy6g8fMp6J8u0LOx0NXEvsd/SfAB/76DVH+3sLa+y3ydPOPmk38A373YB720HUoZx53Urg4+uD/diEh2EEedkdOHM7SpCia00iFM92mkriz7hwHeCj7bWlPY0hyMvrYS7kYQce7Frf14/B/ZBqJqWB60pmqS3hwcrvZqSbZbamwEKcW6ubxErnBea+65al2x9VpvDGPodbBTS9totNJBmr5P4hScM4iKIoiOMwLdbMb9xPxx4CG5HZ3OL0DPBrVqjBSEc0NPpmKvQLGAqL6RN4NO668thpEmwoIzrRSArgNJjtIjeEy2ylXceiA+YaN5nmVQXgWUZenTChjvxi/F7hocN3WdoEUkTRy49aGy4PSsZkrK04oULyltk4++6EG0ScrnoAYsvQlcyazB7wrSOiN6L1VMK3061GIs1p4Mchsy3BDxlqZsRlp+jdTXSWNmV8ObMXCKXFSjMsTHxxyS9f8ZMm2jFDbqfksmCFt6ZMNwl9hnyU7C0rxpuo4hFOTwCnem2tMoKLcN1oOn2Hw0VQzyOXlBg+z7ezMk7BfPibnOgFomWU/LweHZ5I4bhbsfdooyGqZ+rXxx41n+/e64TVZNEAGGeL+aIuCbJQQYAtt+on0zx7+CW3xutTveuukkbnzKxBxeRQFvyEpnFoDK67Qr1C+rpuMxX3TVLwSIOR2Zr8MUxgBKle+1Kv5CIpisTCZoCg2Vl7qRJTvEsuT3XsH12o35oZDGJR3u6qs8aoUS14um6iFoS25KtQ/u14sihU6WY/Ddnd+MUs697kNjtgfdH4CQrrufu1An62FbpHjVrvDHxDDoRdS8PcAwFaPsSphgXz9f3JzgDoe8OqJwq8Aug/EXg3sxzeVqIeI3db9XY99MzgwCdEsNq/6FTek/0tbkXFtGX/CipaQz+t9EMebshFt3Y13mcsKzFD/VL0wNN7AG2hl4almnBbXu/SzA/Z+NKenoOMnEQZ7KD7BrpC2ABJui2nNXJQhE65IuZ3lp5kBd3XmgonNGZkzikNPpYvohZUlCU6yl9mOvRwbRM03dFWXr6EoGARHJQKPGQy9ANill1PY89JlZdnyFp9C0xSofjqROgpZjl+G4XMjM0JjZBVuVS88wgm85H5nARdyQzsf/jNhQkznRWtkXlVr3wWmODq0V+10F9ZPRp6jIOm53fuLMKhqffIIlMla8RRsY7gk17xLxsNXQ2abmRYbUlHJrstANhKf8rx0gHsjwJutMIkuFg2Q2bZKRhf0pdVXvZlThg6sOmVok7jRl30yCB2BFcRDY29Pv5i1EF3ALNQF6wx0APM4zsuPlzSwYRl+RpCHXTgjqpzeAR0pRTj5PI0oaUDhMvTU+Vl6FjXZWRXRdNHQFcKYPQRMMEUWi2zh8rL5g9lUkHcRbU+g6EHO8Vkn3Z6Nhxvaa2p7x9Lng4Z1IlCfhPFiIdB90i6YkpXxkzgr96BehAXrqbyhNpTDGgAdKEW+7wfbSiOCo+0ytfyyrUBxgAEdU/UQ+2hc5mB55AZUnErbcTwIZA5xvIcwRxgEPRgg7yJHP3bqPIen3L/EcgL25z90xDomRo03cQxqltaVoaYZ6gvzkMhAUC9SBfRCnqHE83VwwSHyn8b/MBWVxDhQ7MOqDr5NCvoGOGbhTQYPFuJ+hRNNQeyf3JBdzUT9Fyu3IoPSOX3nh58wGXTsCMh20Y6TzYYOnYyUxzi8Q1WXrnhR5Cqg4AkHRMfCL1ScxlOgrTm6usDpXTmGMUchS6MOwI6lyVUUg6uQeWJSD9iMKKX/ka/dgD0nM/mC6zBV6PKK8QGUhgAnaCNg6AzkZSnqCqvDZTejJ/CKEF9wowKczSVcIsE2T1TbkBZ0sDrAXR64ttBr7cWFQwRrjjpDMn/Ffa8JZVx5B9GB4GtoB8tSy8ivOBc9dsicS5UJoiyXSfZlyX9skOOAic/t2oTrDjXIvm4cnApnwDdMjHtUMxWO71TuCacfq+dicNMgr7M1xp9Q+5L+f5GgDnSWYPPQ79nLPl74Fyt33QA6BJp2D8DPeuRsTnz2xxgru3toAIviax4/Qz0w6JBH+DKlqA4cG16aTvgX93fQV8TdPjMqTysoXgbQjmOXFOeL4COVXIKdMKh85nEK4wDvtYlMIHJxU1+Ps7TT4N+3w2BwNOVnAGw7i9yHsgqV1E3AiZxhgvIVOg3dotTBCQdATa8e/1vaboPjQzYNDQd+iJeo5GnWCCwJvUrhglKSciEMNqQfFr/XjQDdCX0pCQA7gJSO2+yBSg9GZRVUkLvgZkF+kIUQGuoWDwIi/gvSwRcADWr8bgRs/6unRP6AuUYqTvJ8hJYWM9UbihB8J+GBrNBl5WStHNAr99TsgeYmAILsUamIL/vDZ0NuqyTtP8h6/XbB4YFJRmHot0gn+W4fa8VfwAdxHVfhgKVCLA7GhwcQqyzF5I/gC57Fr/7NxLA4qiE0ku4BPkfQJfTu9c3YxHQsOq6FERY5f8MOigv+bXhqOK60nlcLRUR/AvoMs+UaCAq+tOWXFMJ8sFu9QjovXSJbMJRlEy/j0k0OD4yOJgxArqs1XJCDK5LN+Ohmat3wRHBoSGkEdDlS0BZqrLfb6MPZ6Y4QT4scDcCumwdXRB9VFJQuAgEI1G4wZBw6UToPRimQAms6kon7xLjEGLObxXDQeo5R/2GRN3uuTdkC2Ncv2idGhgBXWZoJRojKneWM6WTL2l9BMomITMOuuxoohwEk+A3dYHwsJU3psFGQpe/sCaZJwtdOvkrMa7G0CcfR0OXlQIpMp/lPhqMvFITokn5jocu3w790FBXGXE0JcgtE+3H10o2HHokPwdVC+jrIkwd6mzKG26+ycsCD4cu76rP4UgyhXtv6UzZQlNRSb4JpjBHeZaimIu5/ZtvUHl9Kc/DUk2ALisFtI2OzHuZuVUbVF5TQHX6YTjjoYPtVdA2Br30p/Vix2zGMyXI6bK196o8Hrr8RU/QwAAK09xLJ+lS//3WlCAnigXfC8No6LFsBXy40IAdwQ/bw5ZO6hPkBXZeS8mSjYa+krUAhcdC2R78GMJ4S6uuLkEe4sZwR/BDx0IH6ow5Xii/8mXDudLJPbexfY3LKVAHgbHQQaKxQwSPhM6XTi6JnUTigoDvXXzRSOgBMHl43BjoCyXT9hIfd4lL0NyoCTdrJHS45mA7AXatgEWfVXmwraLF+zd9aivsOOhwX4MSOAE+EhouMmp0k/PmpcnOQUkJ0anvUdB78GTlW4I5rKz43Eb35y7DAq8BXH/AUdChI5Gpm5NkekPsBW6Y6sNzGCmNRfiCujHQYS8EakuGzFCpYk2FGb5HGNmVo6ZJxAjo6IO7RKgKzGLyvUzpJJS9vqXKYOgx9APIXcqAr9PeqDD0dri/NtRv3xwKPUBvJNdCQFg5Zu6smM04P2LqH/w7Kyyh442Ge/Kx5vKShxDM8CVnQ62uXM1gB11JojD+gsxXzpr4RULvJOo2eu81Xsk4bKBHa/wizgDI5rPWRezEheAGpq0YiEJbQE975R0c24blJdrZFmAfvDO0VIlxbyUjdLFRFPPIf1bZDLGtEp7ilNLHrA3tfoju4QboolF9tFwTQQQv2JgSW+mr8Kwz7GEIGmJi4x8LtgCEK2L163SDCUqs9sY+Rk5zV999aWqpQvmJSn9M0AaCsmGGrpTgt/Idvt4S31vU6HNIbUl650rzU9NC3Zma8oCr52gOTbfJIJ5t6JHQmdqHCWBH66m4BdOJuj6rX0q/i01jW14C03hDmk6r4mCH742DYhnaE0ZseutCyjCpX2u7o0NQdNSVa4rwuINo2kAIdEjy0d3ShOLwPYXpTYVjCZJUls1LUa+148jzdpQI2FPOXAM2ZkPcTewbjqMsYTXi7AKHyGL+AGeD3IIxMB2xTZ0X9JDhPU9D5rSTfMcPA+3CdO6wjooxut++XepDxIEZcm0Ok8qonDaWJxn8Cm65pq3rwVIwRk6fOY5UffEbvadIiqp3hjzMryiVnE+p2VZHP9Ki6ysvGNdPUe3o2FspPKfkp9I010A82Z3SBjJV8xKG7N1N4gsdprma3Cc8vaadf0Zwj8zTBylW3Kpv7h8IjVpvsegPxH71efDCo07ouYtnMYYpKCSbfLIDnf/NCketGIkKrrv9tbfSWvC9LDiiETvTqivzkjaMgyASURCHbeIxinLvbm9HPiBtmuOcQh0h8nu3LMs+04XxjpYnPcJt1KY+A3aSakN0Btnbnh6EdnFOcxHeEms76mnF/uQgqG/dXEfHOLtxR6ic7L86WrlnPJGTa2+lk8r+/bhtN73hdaTESsTSIPWAI7IE/qozH5FH9RvlxVRoJYuDI8amAxgGi5MOOQ/U3hOPlO13sx7v9JSwN/XL+RXXjj4JpROzLho6Cfwa5+lYqWyOj01VNZx8WgwrUeGVloa+NE23eK0+abZDqWj0YbJ10eJflUTzpdzVffwIdwS9y0zLqE4cEUVtUjTbbXNJQiGEs0gIVaorjryGZGGW2trzb4Q5VqEvwhgU9wdhwkTztEekfFTY/sHHndc8Tmu9f6cNe2qVJkLzcUm1J93tO/0huQMOA/yAcGEMGzGf3fBZUXepWMqgCNWHpBl1mPW3TAuUdvgR4gMI8mdFXIYd3F4bqgr+VJQEvE76EQHRj8q6s1Kb/cDg95+I2Bopcu3bHF/8FUnWuDeyLP6u+YRTMZfE6aWkjGXXr5L/dcB/RURxu1q7WV5fl9f6VPW7bRIHs/Gsf2zY1viSH96vAAAAAElFTkSuQmCC" + }, + "organic_results": [ + { + "position": 1, + "title": "ChatGPT | OpenAI", + "link": "https://openai.com/chatgpt/", + "source": "OpenAI", + "domain": "openai.com", + "displayed_link": "https://openai.com › chatgpt", + "snippet": "ChatGPT helps you get answers, find inspiration and be more productive. It is free to use and easy to try. Just ask and ChatGPT can help with writing, ...", + "snippet_highlighted_words": ["ChatGPT", "ChatGPT"], + "sitelinks": { + "expanded": [ + { + "title": "Introducing ChatGPT", + "link": "https://openai.com/index/chatgpt/", + "snippet": "We've trained a model called ChatGPT which interacts in a ..." + }, + { + "title": "Download ChatGPT", + "link": "https://openai.com/chatgpt/download/", + "snippet": "Download ChatGPT Use ChatGPT your way. Talk to type or have a ..." + }, + { + "title": "Pricing", + "link": "https://openai.com/chatgpt/pricing/", + "snippet": "Pricing · $25per user / month billed annually · $30per user / month ..." + }, + { + "title": "“What is ChatGPT?” article", + "link": "https://help.openai.com/en/articles/6783457-what-is-chatgpt", + "snippet": "How does ChatGPT work? ChatGPT is fine-tuned from ..." + }, + { + "title": "For Teams", + "link": "https://openai.com/chatgpt/team/", + "snippet": "ChatGPT simplifies lead qualification and forecasting ..." + } + ] + }, + "favicon": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAAAAABWESUoAAABQElEQVR4Ac3PIYyDMBiG4VefPDtxEj0xM39qZl40mcPhMzONOjWNrqxA4UgmqklweBQKVfFdGhbSZZvfY5qmb35++DAbO4XQF7xjpN42s1oyXtlr2gN4SRpynnTaANtesy1tkOOR8aoAJ12J6ngmGkknCqn5gv0y8Jv03eYy+PEAu07jCQ66sDqqpohBCVb2PMtvSbeoxRJcLlIFVFKVBuOwBDdNxkzjEbKbVDwHvgZw8j+Qq2fVhhjkxB2g7JwqKJMRhUqo5Lol8OTxMbSsehXw45e9ao+J92EkGaFbBscxLqnbPRhYOVXr/53L+wTVaUDmNZ+tLNyDWgdWl3gxo7otHMYY5DYdwLc6gB18tVLBSVJD6qr6fsoBVt7wyCm4PxfiRyBTx5N8kCQP8DtrzysZrebG9ZLhnaILYbIbPss/4c/row+G/FAAAAAASUVORK5CYII=" + }, + { + "position": 2, + "title": "ChatGPT", + "link": "https://chatgpt.com/", + "source": "ChatGPT", + "domain": "chatgpt.com", + "displayed_link": "https://chatgpt.com", + "snippet": "ChatGPT helps you get answers, find inspiration and be more productive. It is free to use and easy to try. Just ask and ChatGPT can help with writing, learning,", + "snippet_highlighted_words": ["ChatGPT", "ChatGPT"], + "favicon": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAAAAABXZoBIAAABGElEQVR4Aa3SIWzCUBSF4d8rDA6LnMfiMPjU18xiJjHPCxzBVePqaqsrK6sqK5qgnmjybzShzQKb4tjv3mvuwX/yHhya9i8cDgCXlziwKm99TnIM5RN+rlQvkO5Z97+wP1FpAbkadwwzWgAOW4L2rcppxoZLjc2i1xMEzZYzblMrbBILzpaQV0wYqUfcbNNk3+kZPibsaEek1oqjxj3DA6W8Y5uobs7kuggTphvNOKWq6/HQlQl70sF4oNaS2NNaMzxQ4Krt9rBPliMW82akubKqDFSuR9x9TiiF8QsybfnBLtDNePhQm3ifSOyAyhlvpKoZy0pzsuiM2kKSwlWNhKd/FiHsFsXtVrB5XbAAEHyN2jTv7+1TvgE1rn+XcUk3JAAAAABJRU5ErkJggg==" + }, + { + "position": 3, + "title": "OpenAI", + "link": "https://openai.com/", + "source": "OpenAI", + "domain": "openai.com", + "displayed_link": "https://openai.com", + "snippet": "ChatGPT on your desktop. Chat about email, screenshots, files, and anything on your screen. Chat about email, screenshots, files ...", + "snippet_highlighted_words": ["ChatGPT"], + "sitelinks": { + "inline": [ + { + "title": "ChatGPT", + "link": "https://openai.com/chatgpt/" + }, + { + "title": "Introducing ChatGPT", + "link": "https://openai.com/index/chatgpt/" + }, + { + "title": "Download ChatGPT", + "link": "https://openai.com/chatgpt/download/" + }, + { + "title": "ChatGPT for teams", + "link": "https://openai.com/chatgpt/team/" + } + ] + }, + "favicon": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAAAAABWESUoAAABQElEQVR4Ac3PIYyDMBiG4VefPDtxEj0xM39qZl40mcPhMzONOjWNrqxA4UgmqklweBQKVfFdGhbSZZvfY5qmb35++DAbO4XQF7xjpN42s1oyXtlr2gN4SRpynnTaANtesy1tkOOR8aoAJ12J6ngmGkknCqn5gv0y8Jv03eYy+PEAu07jCQ66sDqqpohBCVb2PMtvSbeoxRJcLlIFVFKVBuOwBDdNxkzjEbKbVDwHvgZw8j+Qq2fVhhjkxB2g7JwqKJMRhUqo5Lol8OTxMbSsehXw45e9ao+J92EkGaFbBscxLqnbPRhYOVXr/53L+wTVaUDmNZ+tLNyDWgdWl3gxo7otHMYY5DYdwLc6gB18tVLBSVJD6qr6fsoBVt7wyCm4PxfiRyBTx5N8kCQP8DtrzysZrebG9ZLhnaILYbIbPss/4c/row+G/FAAAAAASUVORK5CYII=" + }, + { + "position": 4, + "title": "ChatGPT - Apps on Google Play", + "link": "https://play.google.com/store/apps/details?id=com.openai.chatgpt&hl=en_US", + "source": "Google Play", + "domain": "play.google.com", + "displayed_link": "https://play.google.com › store › apps › details › id=com...", + "snippet": "With the official ChatGPT app, get instant answers and inspiration wherever you are. This app is free and brings you the newest model improvements from ...", + "snippet_highlighted_words": ["ChatGPT"], + "rich_snippet": { + "detected_extensions": { + "rating": 4.8, + "reviews": 3113820 + }, + "extensions": ["Rating: 4.8", "3,113,820 votes", "Free", "Android", "Business/Productivity"] + }, + "favicon": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAADNklEQVR4AcXUA4wdURiG4VPbtu32mmvUtm3bts2gnNq2bbtBbSzn3n79M8nZrvdcZZO8yUTzPUMGIFmLOlBJTXhtqcPUUaoDxRwp16aObORuHcNpxmwnUjM5/uICam0PyKza2miJSmoGOlH0HlIGjwPUm9tOqrXdD6qt9RANEb39VEGPAXym/5YMK9ehxu5ahKgbH4I3m0rjdoDfBEj+EwDDyrUiiO9UR7ffAd8pMvzHAyJ3Ivr74R7AtD8SIRATURO1ttWBakuCCN4BqrDLAApRiAmAcflm1NilJUSwCAJqqcm8nBs7pRu4y+gCIAoRqdwJ07LtdCfUSSLUlEZqjBQbevwctVvX1QUA7zd8pkYIIfh41o2d0Xh7ICJOpAFOsic0ZHYBIIZQKynjaLQtCPLJVKCrRyQhaAjUYaqIMCBxxA5CqAgRRIjmUMapzBu7oHG0cZmPx2welU4AkARi6T7U3KWHanuAgshCV952hy/sJ1MmNs77Q5mcAHBEuIKwLD6Mmrv1yCS1QMftfsApJjLO+0A1cxjAEb5TwxRE/uX30PmkFrjAgJPRn7lQklMAXwL4TAtB8UVA927PIA8sBNxikC+mhHzMgwA+7j0tFEWXAN1GXkGksSzkMpXxdWBZ/L3LYLvMRBHfqLbCAD7uNT0MJRYDfYedQ4S5FOymonjvbcD7Slb86Fsa9psM9itJIuxUsPhLGG282BJg8ODjgL4QbKbieO+nxyc/NT55a/CughXfu5dLCrGGyir2GcYzPoTGYSiESFNJGtfhk69aSUH4qPG+YoKIc1Q58R+R+Hj8iJ5lYbuUArazKd/QkL9Tv2Lfqb9hpfGiSYzHh3hXxjv05/Di/e23GB8TB/Bxy4xw5YUbMfAwjRdJajw6Yun7KpaM37uWY/YbBDjpIICP023HxH47AV0ehJtLi4wfp0pR7H01M6OvwnGA/9Rf0v/xHTSeF2GWMviQ+PhzykoxJVcA1eZBKh5jvGxi47+oHnzULYCacyFN7is0Po9KRzG3Am7XbzopxFoeoZZyCY0foIrwIbcDZFPxzN+9qy2JZ/whZeADngJEP0k76gB1kOooOuwKIFn7B3LHHIJtp64TAAAAAElFTkSuQmCC", + "thumbnail": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBwgHBgkIBwgKCgkLDRYPDQwMDRsUFRAWIB0iIiAdHx8kKDQsJCYxJx8fLT0tMTU3Ojo6Iys/RD84QzQ5OjcBCgoKDQwNGg8PGjclHyU3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3N//AABEIAFwAXAMBIgACEQEDEQH/xAAbAAABBQEBAAAAAAAAAAAAAAAAAgMEBQYBB//EADQQAAIBAwMDAgQEBAcAAAAAAAECAwAEEQUSIQYTMSJBFCMyUTNhgZFCUnHSFTRTVGJysf/EABkBAQADAQEAAAAAAAAAAAAAAAABAgMEBf/EACURAAICAAQFBQAAAAAAAAAAAAABAhEDEhMhIjFRUoFBYcHh8P/aAAwDAQACEQMRAD8A8sooorc8s0+l6ppbaRp1tqF3qNlNplxNNH8CvqnEgHh8jY4K43c8Grew6u0sx2UGoid4LWGwEfyEcxyRKwlbJ859PPuB7cVzo3pe21jpW9ke2jkvLh3W2nPcIhCBM5K8KctkL5cAiq/o/TkudMubmDT4b++F5FC0c8DzLbwMGJk7aEE+oBc+35VxT03m9vk64uaSLxuutNhuFltxMwWe0nkjW3C/EMgdJDksSDyjAknOwA481BseoOn9JtoILY3F40XxO6SSBkE3ciZQHXuHLZI3MNvHjxVje6Z05odvIur21msTXt1GQI5ZZWARCixSAjbgt5aqS+Syvun9FJttF0qW9inkmue1IvMcu0KuC2Mjzke3tVIxw5ck6+izc16ogw9RiebUZb+GKIS6K2m20VtGQkY3KVHJJxw3OTUrovqXT+m7aZ5rWe4uLi4jEoRwii3UHI5B3ZJOV4zgc1anpHSptJ0w28q3Dqly872MyyTXrJGj9uMcgEEsPGcAZGTWS6m0yPR9Xks4XkZBHG+2bHcjLIG2PjjcM4Nax0sS4L9RlJzjxMuX6pt7GwsbDR4I2WGK4tnuriI94QvMzAL6scoVzkHnPNUfUl7DqXUGo39tu7NzcvKm8YOCcjIqtoreOFGLtGcsSUlTCiiitDMKKKKAUruoIVmAJBIBxzXUZw2ULA4wSpxxXFXJp1Fz44pQboTtJ+piR/Wu7RgDJOPHNPrH9h+ppez/AJAUKOZFAIIKswKnKkHwfypDK2SSc5OSfvUwxk/Y006UolTsi0U4y5596boWCiiigCiilL5oBaj2qRGv7UzH71IHipM5sft0E1xFE0ixK7qpkbwgJxk/kK37QaN0wz20+LcveSJI17Zx3Us8KKgwFyBGjlnIb7Ac159BKYZ4pgquY3D7WGQ2DnB/Kt4uqaFrqqZjGiw3Bl7er3mwW0bnLrAEX5gGOFY/YBearKzTArfqUvV2i2mlJA9tHcW0jyvG1vcSrIXUYKyoygZRgft5BrNMM/1rQ9U6/barEttYxz9lby4ue5ORnMjcKij6UAA48kk5rO5qY3Rni1n4RiQc5phxzmpUnJqO3ihaLG6KKKFgpS+aTXV80A8nvV/0qmktqZm16VFsIYyzRszZlYkKFAX1H6t3A/h54rPKcGtBp+mG9jYW6WG+NYsLcSyK8pePecYYDjn9BRiMW5WWT2WiW+rW9vHcWVyqafKQ7XHyZrlWkCdxgRtBAU+QPHIzUqXTem7oRRteWlnc7i0ht70GH8SFSuXBPh3YHwNp+oc1XHprUBjNnpWSSAPjGOcDP+pjxSX6fu07bG303Y8ywlhJL6WL7PBbPk1XyaqL7S5TR+lBG8IvY3f6e82pQowy0ByM+n0q0wzyDtYecYhDSOmorSV/8UW5lNs5hBuo4w8mzcDjymGyu1/q8ik3fTEkd0sNqtjL3ACm8TKSTkY4c8cYz4JKjyRTMfTV60gR4NJjJGctcv8AoOH8nn9qjyS4vtMw58VHPipd2UKwSJGI+5HuKqSQDuYcZJPsPeoh8VcwSoRRRRQkKKKKAUDUxb3KqJbaCRlULuYNkgDA8EewA/SoVGaAnC6j/wBlbfs/91KF2i+LO3Hvxv8A7qghjXd1BbLCbUWnk7txDFLJ/PI0jN+5amjdRY/yVr+z/wB1Qy1czmlC2PXE5nZSURFVdqqg4AyT/wCkn9aYJozXKAKKKKAKKK7QFpHoVydCk1iXK2wC9rau7eS5Q5/lA2nk/dceeIkGn39yiPbWN3Mj52NFAzBsecEDnHvWv6mJXobTFHhfg88fVut3fn+ngY9sZzgYXply9j0dp93B+NbyzXClmYhnVJtmRnwp5AGBkknOTmmbY6NNZqMX8FeB4ozaXIeb8Jey2ZP+ox6v0rq2N42zbZ3LdyQxJiFjuceVHHLDB4816DDqD3g0SSeJGkkgGXDOCO8q274O70+hARjGGyacj6gur97dZooQLzUZ7GXZvHywJgNvq9LfPf1DngfnlmZKwY9TzcW1wySOtvMUjYI7CMkIxOACccHPsa7LZ3cIlM1pcRiFgkpeJl7bHwGyOCfsa9CXqK5srW+1OC3txcfFx3JBDFC8sy7sjdz+CmPcc85NNa/rVxFpms2sccOyxmis4S4MmUKxElwxIc/KXlgfJ+9TmZGjGuZidG05tV1KKxVzG82VVthbDAEjIHOOOT7eccUzf2c+n3b2l2mydApdc5xuUMB+xFWel302rdaWd/cduOa81OJn7Uaqql5BnC4x7++c+TkkmpnX57mq2U2MGWxRio8D5ki8Z5/hzySck1N7lHFZbMxRRRUmR//Z" + }, + { + "position": 5, + "title": "ChatGPT on the App Store - Apple", + "link": "https://apps.apple.com/us/app/chatgpt/id6448311069", + "source": "Apple", + "domain": "apps.apple.com", + "displayed_link": "https://apps.apple.com › app › chatgpt", + "snippet": "This official app is free, syncs your history across devices, and brings you the newest model improvements from OpenAI. With ChatGPT in your pocket ...", + "snippet_highlighted_words": ["ChatGPT"], + "rich_snippet": { + "detected_extensions": { + "rating": 4.9, + "reviews": 1026513 + }, + "extensions": ["Rating: 4.9", "1,026,513 reviews", "Free", "iOS", "Business/Productivity"] + }, + "favicon": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAC5UlEQVR4Aa1XQ3hkQRjc+ynX2OZtbfu+tm3b1nlt27a9O4qNS5xxbdd+cTKvXydT31fJoPuvmvf6/ejw86dBlX6CwwQXCq6t5cLaz/xV4+ld6F8r9NdgsCAjIwf5+UUoLCwBydf8jN+JNQbBddzjDQM+gocErRSyWm2QgWu4lntq9/q01UAfwYKCgmK43W6ognu4lzEE+6oamCboLC0tR3vBGIwlOF2vgZm5uQWoqamBXrhcLpw5cxZ79uxFKxCxrGBMxpYZ6Eu33KAXNDp+/AQEBgbzv8Y6Kxi7+e1ofuAKVS/7zp27KE7i6dNnem5HAbVaM3CYh0YF/PWRkdEUpxHoQe3BPNTcQJCgTc9pT0tLh8VigdPpBLFv3368evVKBC7A16/fkJmZKX06qCXo39jAej67Wnjx4iVGjBiJ0NBwBAeHYsCAgTh48BCuXLmCKVOmIioqBrwS4eGRGDduPMxmMzyBWtRsbMCglWSePXuOkJAwCuhmnz79YLVaPSUrGjDWGQhgCvWEyspKdOrURUk8JiYO799/0Exg1KQ2DQxjHveEO3fuKomTPBcyUJPaNLCQxcQTNm3arGzAYDBABmoK7UU0sE7rAC5dukxJPCgoRPy6DMhATWpLDWzbtl35Cty//0DBgOQW3LhxU9nAsGEj4HA4dN0CySHkwvy6bKfECRMmISsrS34IZY8hMXnyFAZV5rFjx6WPoa5E9PnzZ2XxpKQUlJaWaiUik1IqXrBgkZKB06fPwBOKiv4fwA3Ni5FdK3NVVFSgd+++usRnzJilXIzII7JynJOTAxaa7t17Yt68+bh37z6+fPmKCxcuYvToMejVqzdWrVrNMi0rx4cVGxIFKDQkCi2ZAhRaMklTavWqeF6epCltxuneasvLyurb8lmqg0lfLw4m/dozmh0RtBUV6R/NuJZ7avf6eGs4ZeIwMoVmZrYcTvkZv+MarlUZTlUZIDi8diRfX8uFtZ8FqMb7Bx+2VJbBTrlcAAAAAElFTkSuQmCC" + }, + { + "position": 6, + "title": "What is ChatGPT and why does it matter? Here's what you ...", + "link": "https://www.zdnet.com/article/what-is-chatgpt-and-why-does-it-matter-heres-everything-you-need-to-know/", + "source": "ZDNET", + "domain": "www.zdnet.com", + "displayed_link": "https://www.zdnet.com › ... › Artificial Intelligence", + "snippet": "ChatGPT is an AI chatbot with natural language processing (NLP) that allows you to have human-like conversations to complete various tasks. The ...", + "snippet_highlighted_words": ["ChatGPT"], + "date": "Jun 17, 2024", + "favicon": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAMAAABF0y+mAAAAMFBMVEXQ/0rQ/0vM+0oDAxDV/0yixjxlfCpTZiV/nDK75USTtTg7SR/F8Uiu1UAfJhhyjC65DF56AAAAAXRSTlP3Yz+/2QAAANRJREFUKJHdkkGSxCAIRaOAAore/7YDJNPVSVfPAeYtdPEK5FMex1/U8pV/JutMatwVH9JaouTH1ok3SWsEjWGNBXve5JQ5qS+XJLJB8V3iZK8AZhBEAb5JBVjNEFPaU65tIibR1saiZ2XgbzpDH1H2ZtWttB316SSpZ5TeWymNtSfK501X2wFWo23mVR7DE49f2VYrkdPONVaEXmq9JHVIGUQSl/ia1jxFyOYT2YeUletTIyJ5SEIf4WoLfJNCE73EhJKoJHv9hHjFyQNzeefp8jvHD3ZbC4DWezICAAAAAElFTkSuQmCC" + } + ], + "inline_images": { + "images": [ + { + "title": "upload.wikimedia.org/wikipedia/commons/e/ef/ChatGP...", + "source": { + "name": "en.wikipedia.org", + "link": "https://en.wikipedia.org/wiki/ChatGPT" + }, + "original": { + "link": "https://upload.wikimedia.org/wikipedia/commons/e/ef/ChatGPT-Logo.svg", + "height": 800, + "width": 800, + "size": "1KB" + }, + "thumbnail": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALoAAAC6CAMAAAAu0KfDAAAAaVBMVEX///8AAAD7+/uysrJ5eXmoqKiYmJhZWVn4+PiVlZXw8PDj4+P09PTr6+vNzc2vr6/V1dWMjIxmZmY7OzvExMSCgoIgICBMTEygoKBUVFQUFBQxMTG4uLhDQ0O+vr7b29snJydubm4LCwtts+PWAAAPGElEQVR4nM1d6YKiMAxWBKlcIocoooDv/5CrjjpNmrTlcNz82x2Oz5KmX46mi8VMIoI42ZbZ+VRfl9e6891108aRM9fjPyVOmHhZvVSl2hVp8G10Gom3uyMB+yldf0i+jZCRcOdfeeAPOfUr8W2YqoTZ3oD7IfXJ+zZSKE7Y2+B+SvMfKX24oWYmL8fL/2JvPM3cpKV2w2+DvkvgmiYnJefLt3EvFsl5BPC77L6tNNuRwG/Sf1VpxFqHrd53WoN5TL+HPNgxoPb9ZnspiiRJiqLx2CU2/9rqGpUkoNMhDQN50RRxeMlo7MV/hHxfxszlTUUY/y5ZOEIEaXJZeQfvkrRRJD4/fR0CuX/QUZTEPamfyCsr+D9VuUrC6KPQ1RlaHUxvTGgVUxWp9JLP8bQVft11Z2HsxKWioBJy6g8fMp6J8u0LOx0NXEvsd/SfAB/76DVH+3sLa+y3ydPOPmk38A373YB720HUoZx53Urg4+uD/diEh2EEedkdOHM7SpCia00iFM92mkriz7hwHeCj7bWlPY0hyMvrYS7kYQce7Frf14/B/ZBqJqWB60pmqS3hwcrvZqSbZbamwEKcW6ubxErnBea+65al2x9VpvDGPodbBTS9totNJBmr5P4hScM4iKIoiOMwLdbMb9xPxx4CG5HZ3OL0DPBrVqjBSEc0NPpmKvQLGAqL6RN4NO668thpEmwoIzrRSArgNJjtIjeEy2ylXceiA+YaN5nmVQXgWUZenTChjvxi/F7hocN3WdoEUkTRy49aGy4PSsZkrK04oULyltk4++6EG0ScrnoAYsvQlcyazB7wrSOiN6L1VMK3061GIs1p4Mchsy3BDxlqZsRlp+jdTXSWNmV8ObMXCKXFSjMsTHxxyS9f8ZMm2jFDbqfksmCFt6ZMNwl9hnyU7C0rxpuo4hFOTwCnem2tMoKLcN1oOn2Hw0VQzyOXlBg+z7ezMk7BfPibnOgFomWU/LweHZ5I4bhbsfdooyGqZ+rXxx41n+/e64TVZNEAGGeL+aIuCbJQQYAtt+on0zx7+CW3xutTveuukkbnzKxBxeRQFvyEpnFoDK67Qr1C+rpuMxX3TVLwSIOR2Zr8MUxgBKle+1Kv5CIpisTCZoCg2Vl7qRJTvEsuT3XsH12o35oZDGJR3u6qs8aoUS14um6iFoS25KtQ/u14sihU6WY/Ddnd+MUs697kNjtgfdH4CQrrufu1An62FbpHjVrvDHxDDoRdS8PcAwFaPsSphgXz9f3JzgDoe8OqJwq8Aug/EXg3sxzeVqIeI3db9XY99MzgwCdEsNq/6FTek/0tbkXFtGX/CipaQz+t9EMebshFt3Y13mcsKzFD/VL0wNN7AG2hl4almnBbXu/SzA/Z+NKenoOMnEQZ7KD7BrpC2ABJui2nNXJQhE65IuZ3lp5kBd3XmgonNGZkzikNPpYvohZUlCU6yl9mOvRwbRM03dFWXr6EoGARHJQKPGQy9ANill1PY89JlZdnyFp9C0xSofjqROgpZjl+G4XMjM0JjZBVuVS88wgm85H5nARdyQzsf/jNhQkznRWtkXlVr3wWmODq0V+10F9ZPRp6jIOm53fuLMKhqffIIlMla8RRsY7gk17xLxsNXQ2abmRYbUlHJrstANhKf8rx0gHsjwJutMIkuFg2Q2bZKRhf0pdVXvZlThg6sOmVok7jRl30yCB2BFcRDY29Pv5i1EF3ALNQF6wx0APM4zsuPlzSwYRl+RpCHXTgjqpzeAR0pRTj5PI0oaUDhMvTU+Vl6FjXZWRXRdNHQFcKYPQRMMEUWi2zh8rL5g9lUkHcRbU+g6EHO8Vkn3Z6Nhxvaa2p7x9Lng4Z1IlCfhPFiIdB90i6YkpXxkzgr96BehAXrqbyhNpTDGgAdKEW+7wfbSiOCo+0ytfyyrUBxgAEdU/UQ+2hc5mB55AZUnErbcTwIZA5xvIcwRxgEPRgg7yJHP3bqPIen3L/EcgL25z90xDomRo03cQxqltaVoaYZ6gvzkMhAUC9SBfRCnqHE83VwwSHyn8b/MBWVxDhQ7MOqDr5NCvoGOGbhTQYPFuJ+hRNNQeyf3JBdzUT9Fyu3IoPSOX3nh58wGXTsCMh20Y6TzYYOnYyUxzi8Q1WXrnhR5Cqg4AkHRMfCL1ScxlOgrTm6usDpXTmGMUchS6MOwI6lyVUUg6uQeWJSD9iMKKX/ka/dgD0nM/mC6zBV6PKK8QGUhgAnaCNg6AzkZSnqCqvDZTejJ/CKEF9wowKczSVcIsE2T1TbkBZ0sDrAXR64ttBr7cWFQwRrjjpDMn/Ffa8JZVx5B9GB4GtoB8tSy8ivOBc9dsicS5UJoiyXSfZlyX9skOOAic/t2oTrDjXIvm4cnApnwDdMjHtUMxWO71TuCacfq+dicNMgr7M1xp9Q+5L+f5GgDnSWYPPQ79nLPl74Fyt33QA6BJp2D8DPeuRsTnz2xxgru3toAIviax4/Qz0w6JBH+DKlqA4cG16aTvgX93fQV8TdPjMqTysoXgbQjmOXFOeL4COVXIKdMKh85nEK4wDvtYlMIHJxU1+Ps7TT4N+3w2BwNOVnAGw7i9yHsgqV1E3AiZxhgvIVOg3dotTBCQdATa8e/1vaboPjQzYNDQd+iJeo5GnWCCwJvUrhglKSciEMNqQfFr/XjQDdCX0pCQA7gJSO2+yBSg9GZRVUkLvgZkF+kIUQGuoWDwIi/gvSwRcADWr8bgRs/6unRP6AuUYqTvJ8hJYWM9UbihB8J+GBrNBl5WStHNAr99TsgeYmAILsUamIL/vDZ0NuqyTtP8h6/XbB4YFJRmHot0gn+W4fa8VfwAdxHVfhgKVCLA7GhwcQqyzF5I/gC57Fr/7NxLA4qiE0ku4BPkfQJfTu9c3YxHQsOq6FERY5f8MOigv+bXhqOK60nlcLRUR/AvoMs+UaCAq+tOWXFMJ8sFu9QjovXSJbMJRlEy/j0k0OD4yOJgxArqs1XJCDK5LN+Ohmat3wRHBoSGkEdDlS0BZqrLfb6MPZ6Y4QT4scDcCumwdXRB9VFJQuAgEI1G4wZBw6UToPRimQAms6kon7xLjEGLObxXDQeo5R/2GRN3uuTdkC2Ncv2idGhgBXWZoJRojKneWM6WTL2l9BMomITMOuuxoohwEk+A3dYHwsJU3psFGQpe/sCaZJwtdOvkrMa7G0CcfR0OXlQIpMp/lPhqMvFITokn5jocu3w790FBXGXE0JcgtE+3H10o2HHokPwdVC+jrIkwd6mzKG26+ycsCD4cu76rP4UgyhXtv6UzZQlNRSb4JpjBHeZaimIu5/ZtvUHl9Kc/DUk2ALisFtI2OzHuZuVUbVF5TQHX6YTjjoYPtVdA2Br30p/Vix2zGMyXI6bK196o8Hrr8RU/QwAAK09xLJ+lS//3WlCAnigXfC8No6LFsBXy40IAdwQ/bw5ZO6hPkBXZeS8mSjYa+krUAhcdC2R78GMJ4S6uuLkEe4sZwR/BDx0IH6ow5Xii/8mXDudLJPbexfY3LKVAHgbHQQaKxQwSPhM6XTi6JnUTigoDvXXzRSOgBMHl43BjoCyXT9hIfd4lL0NyoCTdrJHS45mA7AXatgEWfVXmwraLF+zd9aivsOOhwX4MSOAE+EhouMmp0k/PmpcnOQUkJ0anvUdB78GTlW4I5rKz43Eb35y7DAq8BXH/AUdChI5Gpm5NkekPsBW6Y6sNzGCmNRfiCujHQYS8EakuGzFCpYk2FGb5HGNmVo6ZJxAjo6IO7RKgKzGLyvUzpJJS9vqXKYOgx9APIXcqAr9PeqDD0dri/NtRv3xwKPUBvJNdCQFg5Zu6smM04P2LqH/w7Kyyh442Ge/Kx5vKShxDM8CVnQ62uXM1gB11JojD+gsxXzpr4RULvJOo2eu81Xsk4bKBHa/wizgDI5rPWRezEheAGpq0YiEJbQE975R0c24blJdrZFmAfvDO0VIlxbyUjdLFRFPPIf1bZDLGtEp7ilNLHrA3tfoju4QboolF9tFwTQQQv2JgSW+mr8Kwz7GEIGmJi4x8LtgCEK2L163SDCUqs9sY+Rk5zV999aWqpQvmJSn9M0AaCsmGGrpTgt/Idvt4S31vU6HNIbUl650rzU9NC3Zma8oCr52gOTbfJIJ5t6JHQmdqHCWBH66m4BdOJuj6rX0q/i01jW14C03hDmk6r4mCH742DYhnaE0ZseutCyjCpX2u7o0NQdNSVa4rwuINo2kAIdEjy0d3ShOLwPYXpTYVjCZJUls1LUa+148jzdpQI2FPOXAM2ZkPcTewbjqMsYTXi7AKHyGL+AGeD3IIxMB2xTZ0X9JDhPU9D5rSTfMcPA+3CdO6wjooxut++XepDxIEZcm0Ok8qonDaWJxn8Cm65pq3rwVIwRk6fOY5UffEbvadIiqp3hjzMryiVnE+p2VZHP9Ki6ysvGNdPUe3o2FspPKfkp9I010A82Z3SBjJV8xKG7N1N4gsdprma3Cc8vaadf0Zwj8zTBylW3Kpv7h8IjVpvsegPxH71efDCo07ouYtnMYYpKCSbfLIDnf/NCketGIkKrrv9tbfSWvC9LDiiETvTqivzkjaMgyASURCHbeIxinLvbm9HPiBtmuOcQh0h8nu3LMs+04XxjpYnPcJt1KY+A3aSakN0Btnbnh6EdnFOcxHeEms76mnF/uQgqG/dXEfHOLtxR6ic7L86WrlnPJGTa2+lk8r+/bhtN73hdaTESsTSIPWAI7IE/qozH5FH9RvlxVRoJYuDI8amAxgGi5MOOQ/U3hOPlO13sx7v9JSwN/XL+RXXjj4JpROzLho6Cfwa5+lYqWyOj01VNZx8WgwrUeGVloa+NE23eK0+abZDqWj0YbJ10eJflUTzpdzVffwIdwS9y0zLqE4cEUVtUjTbbXNJQiGEs0gIVaorjryGZGGW2trzb4Q5VqEvwhgU9wdhwkTztEekfFTY/sHHndc8Tmu9f6cNe2qVJkLzcUm1J93tO/0huQMOA/yAcGEMGzGf3fBZUXepWMqgCNWHpBl1mPW3TAuUdvgR4gMI8mdFXIYd3F4bqgr+VJQEvE76EQHRj8q6s1Kb/cDg95+I2Bopcu3bHF/8FUnWuDeyLP6u+YRTMZfE6aWkjGXXr5L/dcB/RURxu1q7WV5fl9f6VPW7bRIHs/Gsf2zY1viSH96vAAAAAElFTkSuQmCC" + }, + { + "title": "Introducing ChatGPT | OpenAI", + "source": { + "name": "OpenAI", + "link": "https://openai.com/index/chatgpt/" + }, + "original": { + "link": "https://images.ctfassets.net/kftzwdyauwt9/40in10B8KtAGrQvwRv5cop/8241bb17c283dced48ea034a41d7464a/chatgpt_diagram_light.png?w=3840&q=90&fm=webp", + "height": 1153, + "width": 1940, + "size": "93KB" + }, + "thumbnail": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALgAAABtCAMAAAAlHltpAAAAwFBMVEX////P6t38/Pz4+Pj09PTe8Ofr6+vw8PDJyczExMTk5OTY2NjMzMz1+vjM6dvV1dW7u7ve3t61tbWtra2lpaXg4OQAAACfn5/W7eGNjY3p9O+VlZV3d3fI4dSCgoJiYmKpvLO1yb9ra2tXV1dJSUmisqrB2MzR0ddBQUFrbXU0NDSPkJaIlo9venSQn5fb9+klKCZJUExZYl5+i4N3eIJQUVs5PEdARlOUlKWioa9YW2esrLk3PU7BwMkiKT6BgomhiaRPAAAOkElEQVR4nO1ci3bbNhKlAAQwgKnxjBmWsmI5kRPXjpPdJn2k7eb//2oHpB58SSalxGnPKWxRMs3BXAKDwZ0BqCw7upDjRZP0aeJZZhzWIfgxqtOBGU4IcdPlK+DEcIrazRHaM+mtzbk6QrICriAEa/R0+Qo4lTL6QO0R2jNGmVBHdXslQxiljgg6XZqstXNO2BHaTyjf2cZTc/MKRqsqQte176+//o8mGSftu6Cbt/XJwQattXFeq9peQsXmE6tU7O+MYCxEb3xU0ctgJUQ8eluClYHm1ke7T7bSrKWWBUhbcCm9jNLiG75kJDH4YIU0uSn3AmcSFcgQAS/lEquQNkgwylqw3gMOv0LKPeMH0fqwyBG+LfAYvQ0IOs8Ru8HbyUPhDgFXKJ8HlFIIFj/KcuFCIUtpZF7YuUv/C3uBU8Sdm9xDLhcuiduYW2lhEfJFrsocdJSFHlZPGSOEEsFwoKBrwherXuk3EzT9+xDwTJAkj1fhOCNECTzS9Gkti5XRA6bChMMLKFaQFLokzBQjwooEAq+hGT0wGBxHM2u54mqgp1slbq/DqCrEG85afVn7ZEX5I66iPTj1+sgSiiRJJR4keGP3NHi2yMuFl3M/L6O6dvMcXubF3JcF/ixMXOSxiMUwhkqzmdt5EXUBi6K4xv4tc/kyLopwvdhnYU3gIl4XKDMPZSzLIs7RWENRxqIIMA9zWdp5sPmeCiwoabhUAQSP3IJZGKmdwrFpJFgADSYOD4+6ry0Pkimv8DojrTPAU4UgwR32d7WNo2JrrDFGC5A4zgwi8EblORqLVQb7b2+LH1++sx8/QfVp0hVX0RqcidppZRwoUMbjm8EfCdxQMKCctsFzeMTwpqk+TbqycftygePJXnv/amHn87iwMF+8Qn+6mIcFvI45vtky5otwDA3cp/o06ZrqVIVWvxldf6LVKbDoqiOvT5JDTnGy6tOk/9E2/n3Kv8CfuvwL/BsU8myw/Fj/81HxH4bFn40EflD74fLsfFNmWLZ/nP84Dviw+Gz2wzjgbfFNDbPzHx4H/mK2Kcv7+3fvt381gG9ZL2neTA3r2UbjbLV6uNpKn++At3ln52Z22mezq8uO9pHA3z/M3i9nbdFac+QepMSAK3CwVgPyQgzdgLaBP6DqIeDIQjBe00YmKRvanKQB/N3Fh/+8u2yIpyBCMMGV4FoIxgTlXDFOQQjFG6IvVsvZuyHgyEu91kYjZIUvBA/GOoBOiz+8mN1f9oFToxXeKVIq5FY6ANdmAPjl/X8v3r172xLHYBmM93i/MSAVxpv23uRBY6xqDW3c8+X91WoI+MGyA37182onfj5k4wO1NbRjd93ctIFjjMeZIgwwWhSCc8YdtjgVPMWcjc56/35nZA3gQjptkH1qriwwAIZ/boncDvj72Yud+A44QUIrMfhQGMhoJ+Ue4Jezhu4N8IqVZSlIJpwwTgSe4DvRm9XN1dXyCg/4drPEw3LZMhVXJSSQNYNHQ5Ua7X1rp89m56vlcrVKgisUT9KryyZwa71Kxm25dLAH+Orn1f1qdXX/sFoPkxq4tXjLvspjRK6jt1HGuBO9vFo+oNIK/VV1WN60TaXipSkaFylSrzhoo8WvUCWCrwSX6cNVE3iG7YV9nnJCFasdBH5+ieUGf2bLZos7Zwg4rpmyDvs5FaX4VvQGJZaXeLy8XKYKzm9uWsCpUk6hoQgzkA14NkPpVC5vZrV4qqU5OEFzivEOViFMLyRfA8e7Xl5drlLzNYEfLC/Qfz9gk2OjLx+wux8esOOvmsCVjyCDDcEMhCjPZlcP99hPxQ2qXd3cr36+XN0vG8BZSnQZrCKitYiu+Bp46unKVpfL8cDPN6OjktgOj0aLcxzJGj2qGshhPJs1xTdvTVMRhGMNPDkF1rvzjfbmRLR1DYfLj7PB8qI1S04Xnzzlt8qLx3EjTRostc4R9G5YvOrqMezwgPiE0ksQPCWtJc+P1/SmV9koMXGX7y6Ej7CVnga8p318ORL43ZdPZ5vP4hf761Z6EnD62/TFmnV5/ntXdJxm+fl2m3qkX7582UpPa/Gzx6/ZU+gfvcrGqdQN82Swo+/ThsjRDY793IP0uAwDA+m3YrnGSKPwc+2v/+bBMpEAWtfsnDLGEqGpG28ScB0lHJs87K/hjtLMEbYaunK9sqyqg6jXPZCpDZsEd0i2J4DdFWWVkKYNYBRw6pAO7AWeYbgUeB68dmmtLpee24GWTSs99KgWFzILBVPQOvk1JiDFnMXQhUjuBHJ5ACEHAF4jzw4vj9HiM35x4TNodeRIr3LWCCP5jgLWplItADfTBUOVMgd5bhuraGRs6wudkeu3DunzdOD+9vOWLNDb4rYN3EifHE0qPh1UAOhVkdaiDEZXWzh//IYG5bhyGmN8JJeaO8dxHGjHjeIN98dMVrye/4TebTrwePvnVor9mn9qAafSSLRukB40hm5Oc4Duci55ZWlW5hjmvd2eo9lZivKD9D4EBxjFYQyo8dZDem8I2+yni4sLLltYxwGnoRFJqnLrm3bukGy2DJBsZziNYjzg/XB8a5w8S2EyVywNfSZSdJ+oPVOJ2TcuEyDLwqv2hphRflxxjO1qk7RoCqnHPdkCJ05wlwI3jBZBpBjQDKxDaxWsDG3tZ2gqhDBFGWcUQ/yMoYnwPiQusebORp5RLa6Ucaq2Oup0Arm2wdpUMDYHnFykDGjcIG3keR84KT2aRXsrw1mGguByn1JBEidlGaT2Q76e96aRccBBm7X/r+JqBM52wDPBFE6n1aQqhGCEiqF13YBmq9u2f5YpnCJU6k7hNMXOwhGihqYvknd3Tk3340zKLa4TucpZ2g5DKxSPrGBb2Tv1aO2H9l2cDNzakNKrEg6vmRN/ROj2XNFNyVLyZ13eVJt/pgHvTjlnGWicZtHf6H2bBihnhCUrzFjKU4mGG3tc3fNNefNm+/H5zquMLr2Yc0RgATHyKK2x6ACQEsF25E7SrLpxyMTQ7Y/O5aMiIsZ1Jgh6TEFFo88maX5+GnDy+1Tgypq0ZpBWDLhPmdkdl5ikuZen+tamosApQDqD9EUgl9GA/HOTpp2iuQ/lVK9ygupJV/dyBPUERI+pK3s64GnfUttYauDohTUDB84oCsoZZAUWu/fxCicA75H38cCJZcJk7ZmiBq65jBwplHWel947nFOQfTTmusau3Za+CcCHM1nIJQW6+LQAQwiStEyIvvUanr3FAEo2zWVzFU4NaSM3slONU3i1+7FJEHXi2lrinSHrbmy9PBm4WKiQI5v3XuTRh7RPNcTugho6og8XAZliFzhRCp0sQztRe6IxhZGNcCmuwU9IkTdVjwfO/hpkh4xXbBXjpkwZZPFaCNUlDxjxqTKGjDX/UQOPUoE3Hm934m6x8cD5b90z7RupMyLDdg9kjgGUM81k2LrFGRGMK41BzDTHcrKpKGlyJKvYcviGQ8ta6G/NdDr/8OEn14r8vrcf50aakFbwmUFLxAlKgulD0tY5097PPRF49+rRwIngvUl7imLobgP/9uywLiaYbvKw0uwkkgEwJuzJA7OIKlhAv0LrTxuNJ65IjAbOXC8fWbtDjN1T+G4HM5tZ9uXuT27uPv7PubvbX7S7u/u0dh9TVySOobVZSpfiYTDpSVp/9Ur55ROn+cdPCg+f0+Hl2uKeqMXDK070RTu3P0ozk3p9oNtDLf00g9PwPC9Je5L4zrR2M3Fsk1+kXyVBcgfKgG8/jnCS5knAlbUd13CWyWikMukxGB64SFujVOh64vmCZPAa5S+ayL8CcAI7PPXzV2zwyR/R86ZnGU4c0qUERRA27XXBEK2XQqEgXdXiLelpbqHLRTYrEr7gZR5sDBaQq4WY99PMQysSI22cafAxZ9OTntuyBzin3JGUSNNccZpSdK63updlL5FFxPaKxFkWNZIfT3FKVmnbibPaM4eEvu21/bVj5qcjvMoWeJcybmy8P3H19rgLBXm07X0lZ5n31rOAh6CiZU5JHAd4B52HEqocLxyxeLWtoEsuaxuXENLAx6jHCul8/cRZ916shPTIS8uAJ5As1evs8bLYan91pSvgSMp0WsDFl5K8WlLRHddAX1uSlSXi/9A4e5aeqGQCOTFnzIgqw68EGyAeIu919hTgvWc2189IjKjH2fWKRBMA2nhexjJYi28LXuQL8D7PfV88HpGtPVTqPVlpg2jQWhgm08NLw5dqHpMltxoumQrvjYahJ3nFcYn9daGqm8paL15p4OiBkwV7iaR+WLoIxoWideqp8iouhk6Prb0Ky+pHCGnG+xsPNyWluF3bCkYB1zj008vJ0PTkf/8UnBZgNUbjou2SJmiWAb3SonXqKYAbinF4WsNVvOkSJ2j2Od5zeUrM2Z1Px+XHTXrY0YDAaaCpOh0o3yLYj0RpiCZv72F4qphzqLJ0EOCNoR7DeK6dSHtzcQrpOBBIO9oDcbYZmD7FisSeUre4Q0qMPMFXcae1QSL4DsErIs/ky4zBdcPNfusViUOV7SCkvddkvShP+7wJjJUMef9Q0nOkrq9uKmkPtWNKpLVdJbhSUpi0H6OdxAQZooU2m//OmSyVvgIAXSVyI29zGzTGIdaa3LYoWV5gCPWqBbUmWQGUokpxgfesFU1v477742TgBFkZzURyLmklPn2oHrBgbd+XjKTD5itxDAJSBBRjETxEnfuy9AMhUK+4p1sD6klPEm8/K+72fa3DSNVjLjK3dzj1poO7vSPZ83SopSuSVX/fhko7TdKowLE9vMC97+H8o8oo4Lf+kzEf45/g5vkncB/D7brtalobvbGLvCx8ASEvdRl9HgZshah9xPGbAfefP2fEfv5M8XDLMnl7KxrAM8qIMBjK0LT4w4jBscEGV1V68dwJZZyRVptfdge+AdAMlln6IoTThsyU8hUGJ5U++rRKGOIRX0N0tOrTpOtgWRlhPCOcdAnONyzfNZA4SfVp0v8Cn676NOl/KvBTy/8BsqneOZjJbOsAAAAASUVORK5CYII=" + }, + { + "title": "What Is ChatGPT? Everything You Need to Know | TechTarget", + "source": { + "name": "TechTarget", + "link": "https://www.techtarget.com/whatis/definition/ChatGPT" + }, + "original": { + "link": "https://cdn.ttgtmedia.com/rms/onlineimages/chatgpt_screenshot-f_mobile.jpg", + "height": 252, + "width": 559, + "size": "12KB" + }, + "thumbnail": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBwgHBgkIBwgKCgkLDRYPDQwMDRsUFRAWIB0iIiAdHx8kKDQsJCYxJx8fLT0tMTU3Ojo6Iys/RD84QzQ5OjcBCgoKDQwNGg8PGjclHyU3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3N//AABEIAFwAzAMBIgACEQEDEQH/xAAcAAEAAgMBAQEAAAAAAAAAAAAAAwQBAgcIBgX/xABBEAABAgQCBAoGBwkBAAAAAAABAAIDBBESITETFEFRBQciNmF0gaGy0SMkMnGR8AZSVGKSscEVQkNEU3KCouEz/8QAFwEBAQEBAAAAAAAAAAAAAAAAAAEDAv/EABsRAQACAgMAAAAAAAAAAAAAAAABEQJBEyFR/9oADAMBAAIRAxEAPwDmMJzGua6JB0gDiXC4tuFMq7FvEfBdDc2HLOa40tcYpNOynzVTwp2CxkNroLXFuZNRd0Lcz8scpUD/ACd5rpH51rli11cu5fp/tCU+xj8bvNYbPy7X3GXBF1aVNKUySh3LiN5hQutx/EugLn3Es+76DQ3NwBm4/jX3d7t6ipkUN7t6Xu3qD8v6RjhayD+x7rqu0ltnRT2u1X6TdkPRmCHWi68HPsVbhThaHwaIZjMivMS6mjAOWeZG9WNchAML4rWXtDmhxpgrpljEcmUxPfjJbPZNdLUpmWuz+PuWSJ63B0tXH913ZtWNbhUrp2U31CxrsE5TEM7PaCjVmk9X2pbH7rsO9bUm/rQMsqHP5oo9egCtZhmGeIWwnINK6wyn9wQbMbOXN0joFv7wa0+asqmJ2C6lJhhrliMUM7BH8xD/ABBBcRUxOQjSkdhqaDEJrsEgETDCD94ILiKprcM5RmYGhxQTkEkDTsqcsRigtooDEo4NL8TlgjYhcKgmnSEE6KG929L3b0EyKG929L3b0HkDaibUVQQ5IhyQegeJHmFB61H8a+9XwXEjzCg9aj+NfeooiIgrzkjKTwaJyXhxg2tt4rSua0miIdGMjNggMwrCuoAraqzbnAgMix2YZQoV1e4olRdohFLhc2ba4bfQHE9HetdNgQZlhycPVzln8VtpH3O9YmwTiGmBliMsMUue1xrMTZG7QfraisOmDUgTbWkF2BgHGmzsWNMQL9ba3AAky5zph+q2cYrWD1maJBpXQAn4UWXOeORrMy0jC7QZmvu6UGrYjza0zUK53s+rkCtUEyCQTNtpQV9XOa2D3gubrM0SRWur5dyGI4EERpugOWr16fq9iDR8UtFHzjeSaOpLkrbWKHGbZS3CkE49KzV5qNYmwbqD0GXdj71qYrqYzM20DGplqfm1AEY0I1xl2dTLmtKblu1zosQMhTLCa1oYOGGeKwHuMeG3WJoH6pg0DqZ40VxgLWAOcXEZk7UBgcGARHBzt4FFsiICIiAiIg8g7UTaiIIckRB6C4kGk/QGFT7XH8a++scvg+IzmDC63H8a6CoqKxyWOUqIIrHJY5SogiscmjO4KVEEVjkscpUQRWO6Esd0KVEEVjk0blKiCKx3QljlKiCKxyWOUqIIrHJY5SogiscljlKiDx1tRDnmE7QqgidoTtCD0JxGcwYXW4/jXQVz7iN5hQutx/GugqKIiICIiAiIgIiICIiAiIgIiICIiAiIgIiIPIkKNNNhQmQ4QcxsVzmcgGrqCvvw2LcxZkEuMlDx3yopl7lFCZGOjdDjNYXOIb6W20gZ9HvVh8KfcHF06x1uJ9caTls5W7BVEUzGjhphR5aFCNP6AaezBWODvo5wzwnK61wfwfEjy5cWh7XsFSMwAXAn4L858R8SmkiOfTAXEmitS3CvCUnA0EpwhNQIOJ0cOK5ranPAKTelh3jiM5gwqfao/jXQVz7iM5gwutx/GugoCIiAiIgIiICItHutpgTiBgg3RVROA/wY46NEcFnWxWmijYiv/mUFlFrDde0OoRXY4UK2QEREBERAREQEREHkBjZctbpIr2uLzfRlQ1v640UhgyVR6287/Qf9ViRlIMcyjYjT6WK8OIOwB1PyCscOcGS0jLh8APuMcs5Tq4Cvkqj8mO2CxwECI6I2mJcy0hRoiD0JxGcwYXW4/jXQVz7iM5gwutx/GugqKIiINIhOFBXL81m1qpPjRNO5t2AJwoFpp4to5QrX6oQfoWtS1qpse90MOL8SDsHksh78eX3DyQW7Wpa35KqGI8QwQ7Gh2BHOeGe33DyQW7W/JS1vyVUc54pyzj0DyS9+PL7h5ILdrfkpa1VL309vZuHklz6e3/qPJBbtalrVWufaTecxsHktQ593tn4DyQWYnJY4saHOAwBNKrZip3vuIv2DYPJSQXvMQAuqN1AgtIiICIiD/9k=" + }, + { + "title": "ChatGPT Tutorial - A Crash Course on Chat GPT for Beginners", + "source": { + "name": "YouTube", + "link": "https://m.youtube.com/watch?v=JTxsNm9IdYU" + }, + "original": { + "link": "https://i.ytimg.com/vi/JTxsNm9IdYU/maxresdefault.jpg", + "height": 720, + "width": 1280, + "size": "134KB" + }, + "thumbnail": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRIDD6PSH-o5_a4uY4vMZypbGD47mIWLL6VsTXNuADpOw&s" + }, + { + "title": "Introducing ChatGPT and Whisper APIs | OpenAI", + "source": { + "name": "OpenAI", + "link": "https://openai.com/index/introducing-chatgpt-and-whisper-apis/" + }, + "original": { + "link": "https://images.ctfassets.net/kftzwdyauwt9/44fefabe-41f8-4dbf-d80656c1f876/8dec20d14a894ae52ae07449452a89c5/introducing-chatgpt-and-whisper-apis.jpg?w=3840&q=90&fm=webp", + "height": 2048, + "width": 2048, + "size": "93KB" + }, + "thumbnail": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ_IQLO0924Gl1jYnj0yWaeKwSWj8tbTbk0Jc6cAvQv6A&s" + } + ] + }, + "inline_videos": [ + { + "position": 1, + "title": "2 MINUTES AGO: OpenAI Just Released the Most Powerful ...", + "link": "https://www.youtube.com/watch?v=7idowVzHZ9g", + "source": "YouTube", + "channel": "AI Uncovered", + "date": "1 day ago", + "image": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBwgHBgkIBwgKCgkLDRYPDQwMDRsUFRAWIB0iIiAdHx8kKDQsJCYxJx8fLT0tMTU3Ojo6Iys/RD84QzQ5OjcBCgoKDQwNGg8PGjclHyU3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3N//AABEIAFMAlAMBIgACEQEDEQH/xAAbAAABBQEBAAAAAAAAAAAAAAAAAgMEBQYHAf/EADgQAAEDAgQEAwYFBAIDAAAAAAECAwQAEQUGEiETMUFRFCKRBzJSYXGBFiNCobEVwdHwYsIzcpL/xAAZAQADAQEBAAAAAAAAAAAAAAAAAQIDBAX/xAAkEQACAQMEAgIDAAAAAAAAAAAAAQIDERIEFCExQVEyUhMi8P/aAAwDAQACEQMRAD8A4hatfh0cQsneIt+ZNdUb90pNgPpe9ZK1b7GUpZyhggQk6lRUkC3cmrghNmGWfOSefWrPBITsyU220nU4s2HyqHIirYcSh4WVbUodq6N7PILDbfiVutF5z9OoXSKmbxRcVdmsy9lmPEZYWHEeLadQ5ckcwb2+lbDEcNYxXDXI0+CH2lo82koIHzBJqHChx1XdWVKIOrTq2va3L6Vo4jbQQOGAFWt9rk/3NTTlKxFVPLo4U1HeyvjsjBJQUWffjqXbds/4rF5qiJjYw7oACHPMK7D7ZMMUIcHFkjzRpAbWQP0L2/kiuVZqPHahyD7xBSa18CTuZu1FhS7V5ppFCKLUu1FqAG6LVYYThMrFpRYiBsFKdS3HXAhDabgXJPzIHck1rMTyFHjQnHhNfiFh7hKemMlTT3TiflhRaRflr5gg/KkBgrUGpEyK7ClvxJKdD7DimnE3vZSSQR6imKAE2ry1LtXhFIBs0V6edFADlq6zliO3jDGFYVOUlbsRJWCAf/Gi10knqL27WFcq03BHeuhZYmON4iiY2gFC4irrH6VFCwR63/f7VdpoaipQk/KMnmV0KxaQ5YFOvl/anYmHScQjeJRhxaQlN0rYQbk/QG/3t0NTsHjxpmKOonpCm1kix610nL2VsEhJ48dpSjzCFLNqzqSSfJpTi2uCg9mmMTfGjCZTjq9Q1ILir+Ujoe24NXftBxjEIuIogwn5qefkiAhSu+43pgltjPMF5ASHF3SQkAWFdDxHL0PGwhcgLStN9LrStKhfmL9qxU/CNZU18mcMxjHYy8NmwJQnmWWtSHVylqBIIO4OxFUmJL4mFM9w8f4NdazrkXDYOXcZmcZ+TKEVS0LeXq0afNYdq488rVhbXzdP8VvTfZhUK/TRal2pIUg7BSfWtDMTavLU62W9aC4RwyoX35jrWjcdyih2MpuM+pPHCXkOKc0qbsvzAhQOq5QLf8b9TQBGyXLjRcQlNzC1wpEUoSh5zhtqcSpK0BS/07p2PK9r7XrqOJ4uP6a/ILr8JbkNLwmLUXYsY2IToUkFJUoqAIbvq0m4AukczjO5W8JEEqOpuVpWX1qLpa1EHSLBVykG3Ig8ue9lrdym9FRHaW83dbxSTxVcG5c0KUNVjtwvdHRV6kZTZilR5+PYhMhpUGH5C3EahYm5uTbpc3Nul7VWkVqVOZRD7auG4I916kK4vFH5t03OrSRw9tt786J7uTlQJpgNSG5BQkx+KpZso2JSPNbbcEnnsR1FO4jKkV5anPKQSFCw570m6SbBQ9aAGiN6KcKd6KAJATWkyxP4ALDly2pKuXMG19vrVAE1Mgu8BwLtyJP7H/NUibnSM25djYXlmHLw0hxyyH+MOuqx/g03lXGy80QsgHqO1Ly8XsdyO0yErddgFUc6VAHQmykEi4vsSLC/u1jIji4GIutFZa1AlJIvY1nWjdXNKErNlw5GzJiGb+PhkY2bXqQ4SAlKQN73+9dxwkYgzhpVibjKpJUb8H3bdK4DgmISXpC+Ni05p5J8vBZuL9q6rluVOEUlzEVSo36eOyULH71y85HdJJU73K/2sY0uLlp+I0fzpygzf/gd1ftcfeuNSUcOJGa+qj+1bPPuKJxbHUx2llTUYlPy19fSw/esfiBCpFh7qEgCu5RsjznK/JZZAjMSs74IxKbS4yuWnUhYuFWBIB+4FTcbzJmnEyYWMKeELxSboVBS0kEL2GoIB/eq1nCXWsD/AKwh9xp9EkJabQhSV7AHWFdLX5j1vXuIZmx7EovhcQxiZJY1JVw3XCRcG4P2NSuehvjs6NIw/BEe0DNL7GLLdxAwZeuCYJSlv8oXs5qsbbdOtVfs3gt4LlV7Hp0Rh9jEZAiv8ZaUlqELh1xIO58xFwOib1lGW8VfQ7jjeJOmTKSUSFg/mELcDVib7hW//wA2pUjBZk6W1hkueVIgsjhiQkaWWiTewCiAAdI576vlV/ikYvU0le76EJexfImap8GBK4TzTvh1rLSF8RrUFJPmBG40m471Z+1nGsRmZpxLCZD6VQIUq8dkNIToOgdQLn3jzNUU9udMxxqLPmLdl3aYLrhuUGwGn56SbfanJECTPdenYrPUh9xpLzjklPmUpWqyTdQN7I6A/TuKDY3WgvJq8oSX8KyTBk4fIdgmXizzc2XHgJlOBKWroTpIO17epNTnGcUi5rxGevNjjHDwVmW7OXhDalllShZHCuACL3vz6VlMKGOYP4ZvBsYmRfGrQHEtakJBKAvVa5CrJ5nY7WqLMexFx/GXsQxqUuRwgh9RBX4loqSEgkq2SSUm1qX45Aq9N9P+6LjN2bWnxgb+F4orEMXw9x1xeJrw5EfZVtKOHuDbfnUjPWa8bfy5gEdcxJaxTCuJMSGGxxVcQi99O2wHK1Y7FMLXhojFxSjx29YBQBbl2Ub8/lUaRKkSW47ch9x1EZvhspUbhtF76R2FzSxsXGakrogqTvRTpG9FMZKCaUBagKR8Q9a91I+JPrTuSarDJMqB7PsTlwnVtOR57B1oNj5goH/p6VSz8YRinEXKCI8xl0J8SE+RwG+6kjkduY2+laRDkKFk6RgUh1BkyQZMgJWDoUQNCfqEpST8ya5vIbdYWWyUqSuytuRHT6VMmOJ1PJ2cWMJU23MYRu4ga0eZCwVDe49auM953bdirZwIfmqA1vkW0BVx5e58tcnixvCJZlNJIeT5hrKVJ325W++/7VdsxC/lSRjC30lbs9KeFsNKUoI1fcqT6VMUkVKWXJDgWSpxw7htBJJ6kmoqSOMlaxcagVD7082tKYjoCk3UpI59N6Z1J+JPrWhJuH5MdmGHw07LugLLigG0aCCT1KieXasJptT/AImVYNeJVwdGyL7W5elN3T3HrUQp4dl1KmdhPmta5ta1r16tS1qKlrUokWJUq5tXupPcetF09x61pczEWN73N73vQsrWSVrUonmVG96Xt3HrXm3cUXAQVLUEhS1kJFkgqJsOwpNj3PID7U5t3FFh8qLgIVqUEpUtRCRZIJuEj5Ugop2vDSGMFO9FOkb0UcAWwy5F7D0pwZdhgXUAB8xVO5jcsYopDDyXGS6EoSEixF+htepuaMQiKirhNuqL4WNQCdtuhP8AjtXbudPZ2gLF+ycMuQ+iU+lLGXInwj0qtyliDq1Ox5LwLTbadF7DTbaw/wB6VF/EU2JPkFRQ+2XCEpJ8oSD+m3y60bqhZPAMX7L38NxPgHpXv4aiXvoTf6UziuML/orUiEoMyHSk6SQVJTvew/3aoUDNS3ElmWhCDwyEvpvsq3Mj69qb1ND6CxZPcyvFUbpVoPyFM/h0Mq8yEOt9wLEVFy5mFDDLzeJuurULrStR1bW9369qaxnMAnwGjFU5FdS9uhLm5FtjcVD1FFq6hyPFlzDyjPkKKDhz4cYKhJQU2KEb6fryGwvXv4bifCn0qEvM6WUwklhtwuNpU6pKvcv2+fWokrHkRsdXLZU5IZU0EBsnSBy5fz9zRHUU49xuLFlwctRPhT6V5+GYnwj0qnnY6nEXIrjJei8F7zDXcKTtvtbfblTsPNYTPkeMKlRN+EEI8wsdvUd6vc0b/AMWWYyzE+FPpQcsRLck+lZ5OY5cfEX3m3i8yteyHL2032sOhtT+OZi8ayz4B2RH0qPERfSTysbj70t3Qt8B4P2XH4YifCn0rw5Yi/Cn0qtjZpkCE+X20KeSkFoi4B3A3/mohzDNkty9UgMktAtpTtZQKb2PzGo091Q+gsZF0csR+gTSDlljsKoVZhnKVHUXCCz71iQHf/YU/NzC/KhAIcLD6XQfyyRqTY/36UbnTc/oPGXsthldk9vWiq05slAJDbSOQvqvuaKe40n1DGRnlc6DubkkmiivKND0gWrznz3oooAdC1kC61GwsLnpSLUUVohBbY0miipGKVva9JtRRSYhaORpCqKKb6GAFOJSNNeUU4gB3NulJIsdq9opMBFza19qORoopAKtfnRRRQB//9k=" + }, + { + "position": 2, + "title": "OpenAI Secretly Released a NEW ChatGPT Model and It’s ...", + "link": "https://www.youtube.com/watch?v=uh4baKXL6K4", + "source": "YouTube", + "channel": "Unveiling AI News", + "date": "21 hours ago", + "image": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBwgHBgkIBwgKCgkLDRYPDQwMDRsUFRAWIB0iIiAdHx8kKDQsJCYxJx8fLT0tMTU3Ojo6Iys/RD84QzQ5OjcBCgoKDQwNGg8PGjclHyU3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3N//AABEIAFMAlAMBIgACEQEDEQH/xAAbAAABBQEBAAAAAAAAAAAAAAAGAAIDBAUBB//EADYQAAIBAwMCAwYFAwQDAAAAAAECAwAEEQUSIQYxE0FRFCIyYXGBQpGhscEjYnIHFlLwFTOC/8QAGgEAAgMBAQAAAAAAAAAAAAAAAgQAAQMFBv/EACkRAAICAQQBAQgDAAAAAAAAAAABAhEDBBIhMUFRBRMiMnGh0fAzYZH/2gAMAwEAAhEDEQA/APJJDU0EWxdxHvH9KjRd8yqe2c1eVUz75GcE4IOPvVisSuFmnbbCNi+cjfwPOro0SAKpuJp5GYZBDADFMaW4RhIjbSoGCF5+lQzXFyyLJk7QCBxwKzcmNRh6l9NLsYoxzOAT73vZ2/PtWXr+lXFmFmWRJrRvgdDyP8h5VH7dMMNubag4GfOprXVpFlXeVCtw4PIP1qk5BNR8GDSrYu1t0nYQhRGeVB8h6VWZUP4VrQAogkHI71Nv3L+9OdUHkBUR2jtjmoQaeK7mmkj1pZqFDs13NNzXQahKHU4VHkeop4PlUBZIlWI6rqyjuQPvViLnGKsykWVHFKur2pVZhZy0GZ2YjIRSTWtpVq093vlGQVzgeX3qvp8aRl1fksvPzq1FO8NyFQ4JA3DyrOY1iXJr2FkuqTMkUAeNfiHY961LHpcSPiVO3ljgfLFaX+nyNEJGdC2Rgue3/eaML24trRN8rxx57FiBSk2zpQS9Dzu+6QgEp8BAuTnFYOodMojf+sJx5DvXo8+rWk91EltLFK/Jbw2zxig3U+o7GS9KmRs84jA+GghKW7g1lGFcgBrVsbbw0f4kZ0J+QwR+9ZdG3VEcLWceoRHKOwV/kw4/Yj8qGJdqjLDj6U+ujnNU6NnoLwvatT8bZj2Ndu/Hf2iHt9s0Ua9eWqWfU+t6PLFa3630cMscWAVkWRx4ifJ1OT/cG9RQZ07pdvrV7NbyTeAqW7Sh9owCCAM/LmteDo6EK/tbXIljtopHijMakOzOpGWIGBt9aJRbFsmqxY3UnyEUmuy/7n1prvULgW9rokbwtAVLRuy2xYpnjcTnP3pt/NPd2hu+mZJJNYuLG1ZJiEW7kh3TiUjb+PcIgdvO0D50N2PSdpfoZIbmdI1M0bB9pKyqyhF4453Dt9qoDp6NuoItJFwy7YBJcuVzsOzewA88dqm1lLVYm2r67DZm1Q6fqH/iGH+4Rb2IvjbFQxk3T7s44zs8Pd8+/NZ/UGnNrWnXVlosFvc6hFfwyXcdoUCh2tkWRlxxs8UPkjgH5UO2mhadqonOk3VwxS2aURXCqhVwwABb4cEHPB4q1a9IJJqiWlzcPHELOKWWQbW2ySEAKMcEZPf0FTayS1eKN26oKdRmvbq7E3Rc1v4LancnUZEZPDP9TCGX1h2dvw/F51WsrrTLTQ5XvIra4tJNOWKYQKB7rahcAtGDyCBhl+goXTRNOOmNLLJereJdCyaPamwTEHz77cj61Yl6as/EaO3mvGaC8jtZ5niXw2ZmCttI5GNw796m1lPVY7oLbu0a0jjtun7nxtSigsUkn0/aZntNjbmhyfNthODn4c8ZoU6zt1t+oHxKsjSwxSyMqovvlBuyEJXdnvg4zmp7jpbTba7tYLiW+j9puTbojpHuzkAP/gc/WsS/itbe9lhsjMY42KkygAlgSD28qumgI6iGX5RL2pUl7UqgA57hormEICxLDgdznjFalxYXFjOBcJtZuQQQQR9RxWJLKYNQgm4/pujjPyOf4r2a70uG7hezigVLe3gz4oH485GP1/KsMsttHR0+NStmjpaBNJg8GP4YwQvqaFtZ0bVtWc3F47JHvwkCjOU+fzPpRhp06qiKQFAUDAq9K6CMkNxilV6j9eAV6K6Xj0yaW7kQqWO1UfnA+lDvVfS9rFrk0iRYE+JUOcDPmKM11SUQzzRWs08aDEaQ4y7feg3qXqK4lu7eG5szA4ALLkNtPOeRwfKri3douSXTMq/0uReltTjUDaoWYDPYq2Tj7bqCISJYSjeXH2r0m5vFktJYsZSSJlI9cggivOLeMRQ734JH6U1ibcbEsySlwR2t1PYtcCEgGaFoJMjPunGf2rVHU+pOreP7NcBoo4XE8AcMqElcg+eSeay7lOzj71CnB+tapsWljhLmSNW01nUhIbayESe0XUcqwxRhV8RSNoA7AZAqZoeoINUutXMEi3UFxiZ8AgO/G3b55zjAz3rP02ZLXU7O5lzshnSRsDJwGBOKMZurrIxs1tBK0rSxTOGUAOyuvz/4oPvV8eWL5VOM0sWO77/foZl6nU2Utn0+KFLlGtY4YERUGTuYAA+6xxnn0pA9WIY7CGJ4ZGhTa0JVS0cQ2j3wcYGeefOren6tp2mXLPbNdzpc3guJTJGAYwA3A55OW703TtZ03TYI7FDPJbLHPumkt1b3pNoA2ZwVGOcnmpuj6gSxZ1H+L7P9/Jlay+ueDctqEKxo10k8rJt4lKkL2PmM01+qNSkBz7MHdkeSRYFDSshDKWI7nIq9Lf6JPZXdlLczRpNNHKrwWKoAVUgjYDjzHNDLhRIwjJZATtJGCRUYeOEZqpw6/r6FuK+nTUhqAI9oE3jZxxuznt6ZrrStNK8r/E7Fmx6mqi1OlUaOKRaU8V2o1PFKrMqHX8W9NwHbg/SvQen+v9Pj6e8HU5ZE1CKPw8bCRNgYU5H65oGicSrg43eYqrPZ85i7elBKKkuRnHlcHwe0Wd0Lq0hni4EqBgD5ZqxNI7QHc+0fib0FB/RWpSSaH4UwO6zbw2/w/C37j/5oklmM0e2Mggjn6UjOO10dCGTdGyOPVLmS0C2emS+Go90uVTI9QM80Ma1c3nhqj6csabi3vSKzE/nRncQXE1qqRssYxgMPKgnWNN8CUFr1pWPbK4/mih2G5raZssjHTpnlG0tGw257ZGP5oRun3NsXsO/1rf1y4MVuIA2Xc+XoKH1QscDvTkVSOdOVsfF78RB8uKrlMHB8qvbQiY8hVZhuJNEDuGqM4rd6esDeXCxRwmWZyFjT1JrGjWiroy6Wy1a2uJDiNJV8QkZ9wnDfoTS+p+Q7PsRKWouraTr/AAK4Ok7DwzHMZHm8MHxrYo6FyiuFVce8u10y7Oi5YAH1G+qNBGmxLlTtkTfGzxGJxg4Ksp7EEHzI7EE16GIfBgilC3YggYiMowZZv6aoqnbu8b3UXbhV4zuweSLdfT2/hCyhlWV7Zn4TO2BTt/pD1wwY8cDdgUq4qNNHoIZZ5d0Zcpp3x1S+3g8wlXaxFMAqece+ajxXQj0eJytKbo4KlSmAU5aIyZODxXKaDxXagFFgqVOVODU0MhdirDnHepZI6jhikaZfCRnb0UVZjGYWf6fLMdUulWMtAYMSt5Kcjbn68/rRLc2E0Mu62baP+PlTdBiGn9OaaYlCrPPmdh+JyWXB+mBW867/AC7UrlXxD+GXwgdf6xqULm3KhPQt/FDmpXM+4vPNub5Uaa1bvcTLGF4HnjtWVL02kRFxqHNuoyEB5kPkPp61UOXQU5cGHf29vP0/psdxhblzLIr+ag7cZ+WAPzoc9me3ciZcN5fT5Vt6tO1xfAD4IxgAeX/eKsxFvZ9pOR5ZFN7aQlKdvgF5Pe4HambKJ1MUhxcW0cnzK811tL0+Ye4skJ9VbI/I1e0H3gMhMCrNrO8DZU/WtWTQZMZt545f7T7pP8frWdNZzQNtmiZD/cKCcFJUzbBrJ4JqcHTLttrl5a7/AGWeSHeMP4Tsu4ehweapXN7JLHs4C/Ko/CrnhVktPBeDo5PbuqyRcXLvsqMuTmm7KuGKmGOtqOX7y3ZV20sVYMdMK1CbhlKnYpVC7N5UV5kVhkFgDW94McERSJAi/KlSrSBzW+At6ekaPpU7Dx4xGCM8cetasBy7JxtC9sV2lWWXyO4W6RRviVKbSRuYg4rI1QYgcc/F60qVTH0iZHywQMaeOfdHxH96vxRJ4ZG3ilSrfwJ2yMxpub3R3rqoo8qVKrBseow3HFTFiwKNyvoe1KlVA2Dd2ipcyoi4UOQBUJA9KVKszdDSBTGA9KVKqDRGwFRMBSpVDSJGaVKlUCP/2Q==" + }, + { + "position": 3, + "title": "OpenAI's ChatGPT Does Research… And Breaks Itself!", + "link": "https://www.youtube.com/watch?v=iC-wRBsAhEs", + "source": "YouTube", + "channel": "Two Minute Papers", + "date": "2 days ago", + "image": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBwgHBgkIBwgKCgkLDRYPDQwMDRsUFRAWIB0iIiAdHx8kKDQsJCYxJx8fLT0tMTU3Ojo6Iys/RD84QzQ5OjcBCgoKDQwNGg8PGjclHyU3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3N//AABEIAFMAlAMBIgACEQEDEQH/xAAcAAACAgMBAQAAAAAAAAAAAAAEBQMGAAECBwj/xAA+EAACAQMCBAMEBwYEBwAAAAABAgMABBEFEgYTITEiQVFhcZGhBxSBkrHB0RUjMjNCYhZScoNzgpOiwuHw/8QAGwEAAgMBAQEAAAAAAAAAAAAAAgQBAwUGAAf/xAAsEQACAgEDAgUDBAMAAAAAAAABAgADEQQhMRJBBRMiUZEUMkJxgcHRFVJh/9oADAMBAAIRAxEAPwCsoGA7CpEVicEYqYReA49KVcLcNrrPCfEGry313HNpUIeKKMjbIdpOGz18vKsjT1+bnBjdjdMtUMMkSqGBHTvW74MY+/lVd/w8q/R6eJWu7s3AvBbC3HVSCwGfXPWrA3AGkW93ZaJrHEl1bcQ3kQaOKGLfDGTnCsfPqCO65x5dK16mIG8TdczvQI2+uwHPXePxr2b93PbmOTBBGCDXz7BwVcpofEk8t3cftfQ7pYjbKw5cqHb4s9+oLEe4e2rZN9HPI4n03Sm1O75F1Zyzyy5GVaMqGA8sZdPnRs+YKpiWXVtOOnz+XKY+FvyoWMBuxBrx+4eKaRooruZld2EZzk7euCfsq2fQ8qniG7gvGaWPl7cFjjIJpivXZPSRFtR4KyoLQdj+/wA+0vG01mKf6lovKHNtQzIe69ytJmjwadSxXGRMW2l6mw0hxmtFaLtrdp5UjUdWOBTC80KWFC8TCVQOuO4+yvNYqnBM8tLupZRsIjK1rFTvESpA6Ejv6VHBbmONUZy5H9R7mizA6RjOd5xtruAYnjPtphbaXc3C7ooyV9ewqW60e4swkj7WXIyVPagNicZlqUWfdjaJp9Eiutd+v3CgrGPAD6+tb4k1KTTNNkngTc4GAPStcR65HprxQIMzSMAB6VDxbHv0RjjJIpGbQE8gvbu6vbl7iZ2Z2PU5rKbQaHcSJvOEyegNZVfmCNDT2EcRqQRG3THTzrX0Za/HofB3FTRahb2uptEjWSSOm+RwrY2q38XXHTBqG6iaUjaxBrjTuFrSTxSRgBcE4JGBkD19SKxabtPRX1AnJ5EZdLXbBG0eanxZLq/0Y51TUrafWY9RR1gYokhVXBB2Ljp7cUz1OXhzX+KtJ4vbiXT7O2gWKSezuJAs4eMlgoXueuB09Omc1ltwTojACeBnX/iMCPnUXEXAeiW1gs1skmSem5yfzprS6qu84QyqyspzBuCOL9MvvpE4ludQnhtdM1eIFGupBGDyiqoDnzKljin/APjmwuOHOIbuW7t11K2kvINPRpVDyxvgoUHcjO0f8tU3ROEdOur6GKRDtZgDgn9avMf0b8PyZ2hmwcEiRunzp0iUg5nhVpLy4Z9jpGyrtGe/2Vc/onVjq0rLnwqCce+rDrv0aWGm2s10h3JuyAScgfGj/o90e00m4Nyi/wA4FCMk9B1qAMHMse4sip2E9UiYMoHspRqWlGW6VoEAEn8XoDTOGZWAx06VKTt3OWJU+XpRq7IciL2VrauGgtjp0VtGAUVpAc78daG1KeWyYcoArID38jRSXqOTtIwDjrQOsTLM0caEHbknFWVgs+WlVxWuohNojZMmu7eyluZOXCwVz2LdhT2z0pOWHuM5P9PpRjCG1DTOyJEo6ZAG2rrNSMECK0aJshmk6BYkVFwAowBVY4u1vkW4SDDAyBCR65pPf65Nc67Fy5GWFiVCA9MVH9VF1ZOs7MMTluvc9aVTB3mlapT0mL+INJm1HVLV41GEALOewqXiC4/dxwA5XHWmd3eRW9vzLqQQxAeZ6mkvEKtfaUt1YMAAuV6dxUvkjaeoKq4LcRI80aNhnUH0JrKFsNKjltw902+UnqSa3VPkmOHXL7SRIx6L8abaNbm6uWtBtDTxMiEt/WPEv/copWq0fpzPFdRSRna6OGU+hHauRFgVgTxHCpIwJcIbO7EEcvIZkKg7o/EPlQPFFyg0+ODcOZ32nvTqRJGiGqaWziKYlpokPWN/6unpnv8AHsaovFcg1K/2uxklzgsp6gYrV0CJTewGcYz+o/5FrA1qiTcMZXVLYv0BbOTR1ldS2XE9xcLeMbOSQl0HUA1XdOE1ruVnZtgO0kYrvS5S9vnPdjWh4heaVDVyjTVdZw0vGp6iNZ0e4hiULMpyFJ/iANc8LoW0tjJECgYjcO6mkulIHSUOzYC5yKN0DUZYbF4IlyGDsW9Kq0Ore/qDdpOopFeMRsutpHNyUJO04z61ZBzJbH9ywLMK8hvtTa2k3Rgc1mPX0x7Ptoix4y1G16R3BA8wUU/lW/VpLLUDjAmLdrK6XKEEz0G4tZosGQEZ86YaZZhBzpMEnsPSqHHx9dSJsnWCQepUg01suNkmIh2pGzdh5H7aK3T3hNx8Sqi/TeZnJ/eXOWQL2NI+KZkfTo0H8bSqo9maHXVZZbWWdXQFThapWq8Wm6cxiIPErZVm7k+uB+FZ1hRB6pvaSi3UP6BxC9VENvqtkkJBKthqMvbyU21x9RTmXCHaAe2aqh1pWkDmJd4OQdgPWi4OIShYgJ4jlspjPwxVH1AAOOZoWeE3MROuKbeXUbG3iJHPQeMZ86MtbiKLRYrORxzQgXHqaBF8L7fJtCndggUs1SV0MLIcESDrSFPiFxvFbgRW/RisEdxGdlp11HEw8IBckVlF20VzLCr81uvsrdboVscTJNiA4zFSrR1iv75ffXSabJ5zQfeo20shHKpe5gAz18VfPnbI2nRgiHaNJe6Jqtzewy8+yuSGmsyMMGAxuU9s4H2/CncuicM8Vs95akC5U4kltn2SI396+vvFA7LVQCL2A59DVTvOFbqbWZtR0/VY7WRmyssUpRx7Mg9q1PD9a6Dy7/tHErKKW6kbBno0PDEMdtyJZ+euMBpIxux7SK6veE9Lu4QDFyJtoBmgwhJ9SOxqoWtxxdZLg8T2Nwo7C5twxH2rg06i4zGnaWv7Xlhu9SZ2CR2cbKrjyJznHfv8q2k1Wnt2BidiWA5JkUnD11o9vcyB4bqLYcu3gZR7c9PnVNs9WSxRWMmN2cAdc05u3uOIWMuuXciw947OBSEX0z6n2n5UHJw/ZyQLAMyRjtvGCPdij0aV/UM2DgxfUs/lYU7yr3V8PrsV2kUdyEYOYpBhX8WSp99LxdiSWRnEULu7PyUbpGCchR7BU+pwJZX8tpHnbEdoyaWT2MU8xlfuRg104BrQPWM7cTAHTY5S04yeYwa4WJeY4LIvVgPTzoyO8trnUTLpqTJaGQ8kTEb9oHnjp3zSK1sFguOaHOAMBc9Kc6ZY3uoTtHpygyxpv6vtwMgd/tosu6l29OxGIJWut+hfVvnP8S5QXnL0udGbxLE7Y+w1Q4tReKOa1a0jdZihW5Y9YsZyB78j/wC7WzUdOudL0UXWo9biX9zhD4PFkDr7B1qiXEIubZomOM4wfSuauyjYadr4anmVFlz2Px2jBXBqVtTZbb9nJYRs8kyyC7OdyoO6+mO/x92EA019uFxn/V0pnYQ/VLZYt24jJJ9tL4VN+Zq5t1GFYFcb5jvT54khZGciRjkD5U5fTrazjWfVG3OOqQg/jQGi6aZPq93G8Ql7KJUYqDuPXtim1zw5f3UjSS39m7HvmQ/pTWi0ulqIv1DAE8DM5rxvVW23NVplO3J/qJ7nWbhpTym5aDoFXyrKYHg6+JyLmz/6v/qsrc/yWk7WCcv9Bqf9DIFiizjmZPoJP0FbFuFPikY+zdj8qiAkJG4x7fRutTJjPdcegFYf0tA/AfE6HzXP5TsRR46Nj/cP6VJEFVsB8/7proSZx5++o3uYkYBpcN5KDk/CpXT0k7IPieZ3A5hgAVclEHtbLH8K6DIXGAGI7ELj8qEWbf8A1Ig9XcE/AfrU8EqIMfWQfbuA/CmlRV4EoLE8mGb2QFXTDAdtrAn4ipYH65xj4n8qCNzbxRl5LhFUf31pBcXy5PMt7U+WcSSe/wDyj5+6jGYBlf46hW/vbc2c9tzVBSYlwpU9MFie/u7+yj14e4alRQuozxuAASkwIJ9eqmpLqwh3AJDGqr2AUYFaSIKOiL92rQ7gYBlfQh3Ilf4s0y20W3gmsL+S65jlWVkHhGM56fpV14M02Cx0sTrMr3N3GjSElSE89o6+3vVe1eFXtJGZBlFJU47HFPOHbmOK2RRNGqFQR46lrLCvSTBFVYOQI/nEF5by2tzGGjOC8UoDKfQjyPXzrznjPSorLUrZ7KLlQTsBJyznDZ9M4GR28ulegyXcIjyLqLPoZBVT150uG8XLnRTnYJOo/wBPX5UtZX1jGI7pb2pfqBixdA0/cR+15VHkeUrf+QpNJbNFxCNNacywlwFmRcFlI/iAP2/A07i0+3u4edbeNB0JBOVPoR5VCdHCSiQSOHHY7u1UNQvtNGrxG8cvmW+wuY7GC3t4lVoIlIwRhjn1JyO/WiP2hFv6xgIR1zhjn7CtVmOJSuHLFvNg5U/EVJh0OUmyP8snX5j881eACMETMbqzkneWNmil8aSIinyMTfqfxrKrpuCOhRyf7WUj5kfhWVHlV+0jqb3gcSgkEjJ9tGRAZrVZQjeGdpxIeZLy36p3xUn1eA4zDGfeorVZRn7oH4yaO3gHaGP7ooqG3hJ6wx/dFarKsEAwJYo59YZZY1IhGY8Ljb8KblfD/E/3zWVlT3g9oDcIM92++aFaMerfeNZWUcAxTrWVMIVnAOcgMetXDSUURphQOg8qysqPeePaNJQNnYUjvANx6DvWVlRCEWrBENVs5OWpYzJnIyG6+Y7H7adcb6bZWuqMtvbRxqUDEKOmTWVlVNzGElZjgi3fy0+FF/V4cfyY/uitVleWFZODbw5/kx/dFZWVlFKp/9k=" + } + ], + "inline_videos_more_link": "https://www.google.com/search?sca_esv=acb05f42373aaad6&gl=us&hl=en&tbm=vid&q=chatgpt&sa=X&ved=2ahUKEwi17_rnppWIAxX2rokEHfAoEzYQ8ccDegQIIhAH", + "related_searches": [ + { + "query": "ChatGPT login", + "link": "https://www.google.com/search?sca_esv=acb05f42373aaad6&gl=us&hl=en&q=ChatGPT+login&sa=X&ved=2ahUKEwi17_rnppWIAxX2rokEHfAoEzYQ1QJ6BAhUEAE" + }, + { + "query": "ChatGPT free", + "link": "https://www.google.com/search?sca_esv=acb05f42373aaad6&gl=us&hl=en&q=ChatGPT+free&sa=X&ved=2ahUKEwi17_rnppWIAxX2rokEHfAoEzYQ1QJ6BAhXEAE" + }, + { + "query": "ChatGPT 4", + "link": "https://www.google.com/search?sca_esv=acb05f42373aaad6&gl=us&hl=en&q=ChatGPT+4&sa=X&ved=2ahUKEwi17_rnppWIAxX2rokEHfAoEzYQ1QJ6BAhREAE" + }, + { + "query": "ChatGPT app", + "link": "https://www.google.com/search?sca_esv=acb05f42373aaad6&gl=us&hl=en&q=ChatGPT+app&sa=X&ved=2ahUKEwi17_rnppWIAxX2rokEHfAoEzYQ1QJ6BAhQEAE" + }, + { + "query": "ChatGPT download", + "link": "https://www.google.com/search?sca_esv=acb05f42373aaad6&gl=us&hl=en&q=ChatGPT+download&sa=X&ved=2ahUKEwi17_rnppWIAxX2rokEHfAoEzYQ1QJ6BAhPEAE" + }, + { + "query": "ChatGPT OpenAI", + "link": "https://www.google.com/search?sca_esv=acb05f42373aaad6&gl=us&hl=en&q=ChatGPT+OpenAI&sa=X&ved=2ahUKEwi17_rnppWIAxX2rokEHfAoEzYQ1QJ6BAhOEAE" + }, + { + "query": "ChatGPT website", + "link": "https://www.google.com/search?sca_esv=acb05f42373aaad6&gl=us&hl=en&q=ChatGPT+website&sa=X&ved=2ahUKEwi17_rnppWIAxX2rokEHfAoEzYQ1QJ6BAhVEAE" + }, + { + "query": "ChatGPT free online", + "link": "https://www.google.com/search?sca_esv=acb05f42373aaad6&gl=us&hl=en&q=ChatGPT+free+online&sa=X&ved=2ahUKEwi17_rnppWIAxX2rokEHfAoEzYQ1QJ6BAhWEAE" + } + ], + "pagination": { + "current": 1, + "next": "https://www.google.com/search?q=chatgpt&oq=chatgpt&gl=us&hl=en&start=10&ie=UTF-8" + } +} diff --git a/backend/open_webui/retrieval/web/testdata/searxng.json b/backend/open_webui/retrieval/web/testdata/searxng.json new file mode 100644 index 0000000..0e6952b --- /dev/null +++ b/backend/open_webui/retrieval/web/testdata/searxng.json @@ -0,0 +1,476 @@ +{ + "query": "python", + "number_of_results": 116000000, + "results": [ + { + "url": "https://www.python.org/", + "title": "Welcome to Python.org", + "content": "Python is a versatile and powerful language that lets you work quickly and integrate systems more effectively. Learn how to get started, download the latest version, access documentation, find jobs, and join the Python community.", + "engine": "bing", + "parsed_url": ["https", "www.python.org", "/", "", "", ""], + "template": "default.html", + "engines": ["bing", "qwant", "duckduckgo"], + "positions": [1, 1, 1], + "score": 9.0, + "category": "general" + }, + { + "url": "https://wiki.nerdvpn.de/wiki/Python_(programming_language)", + "title": "Python (programming language) - Wikipedia", + "content": "Python is a high-level, general-purpose programming language. Its design philosophy emphasizes code readability with the use of significant indentation. Python is dynamically typed and garbage-collected. It supports multiple programming paradigms, including structured (particularly procedural), object-oriented and functional programming.", + "engine": "bing", + "parsed_url": ["https", "wiki.nerdvpn.de", "/wiki/Python_(programming_language)", "", "", ""], + "template": "default.html", + "engines": ["bing", "qwant", "duckduckgo"], + "positions": [4, 3, 2], + "score": 3.25, + "category": "general" + }, + { + "url": "https://docs.python.org/3/tutorial/index.html", + "title": "The Python Tutorial \u2014 Python 3.12.3 documentation", + "content": "3 days ago \u00b7 Python is an easy to learn, powerful programming language. It has efficient high-level data structures and a simple but effective approach to object-oriented programming. Python\u2019s elegant syntax and dynamic typing, together with its interpreted nature, make it an ideal language for scripting and rapid application development in many \u2026", + "engine": "bing", + "parsed_url": ["https", "docs.python.org", "/3/tutorial/index.html", "", "", ""], + "template": "default.html", + "engines": ["bing", "qwant", "duckduckgo"], + "positions": [5, 5, 3], + "score": 2.2, + "category": "general" + }, + { + "url": "https://www.python.org/downloads/", + "title": "Download Python | Python.org", + "content": "Python is a popular programming language for various purposes. Find the latest version of Python for different operating systems, download release notes, and learn about the development process.", + "engine": "bing", + "parsed_url": ["https", "www.python.org", "/downloads/", "", "", ""], + "template": "default.html", + "engines": ["bing", "duckduckgo"], + "positions": [2, 2], + "score": 2.0, + "category": "general" + }, + { + "url": "https://www.python.org/about/gettingstarted/", + "title": "Python For Beginners | Python.org", + "content": "Learn the basics of Python, a popular and easy-to-use programming language, from installing it to using it for various purposes. Find out how to access online documentation, tutorials, books, code samples, and more resources to help you get started with Python.", + "engine": "bing", + "parsed_url": ["https", "www.python.org", "/about/gettingstarted/", "", "", ""], + "template": "default.html", + "engines": ["bing", "qwant", "duckduckgo"], + "positions": [9, 4, 4], + "score": 1.8333333333333333, + "category": "general" + }, + { + "url": "https://www.python.org/shell/", + "title": "Welcome to Python.org", + "content": "Python is a versatile and easy-to-use programming language that lets you work quickly. Learn more about Python, download the latest version, access documentation, find jobs, and join the community.", + "engine": "bing", + "parsed_url": ["https", "www.python.org", "/shell/", "", "", ""], + "template": "default.html", + "engines": ["bing", "qwant", "duckduckgo"], + "positions": [3, 10, 8], + "score": 1.675, + "category": "general" + }, + { + "url": "https://realpython.com/", + "title": "Python Tutorials \u2013 Real Python", + "content": "Real Python offers comprehensive and up-to-date tutorials, books, and courses for Python developers of all skill levels. Whether you want to learn Python basics, web development, data science, machine learning, or more, you can find clear and practical guides and code examples here.", + "engine": "bing", + "parsed_url": ["https", "realpython.com", "/", "", "", ""], + "template": "default.html", + "engines": ["bing", "qwant", "duckduckgo"], + "positions": [6, 6, 5], + "score": 1.6, + "category": "general" + }, + { + "url": "https://wiki.nerdvpn.de/wiki/Python", + "title": "Python", + "content": "Topics referred to by the same term", + "engine": "wikipedia", + "parsed_url": ["https", "wiki.nerdvpn.de", "/wiki/Python", "", "", ""], + "template": "default.html", + "engines": ["wikipedia"], + "positions": [1], + "score": 1.0, + "category": "general" + }, + { + "title": "Online Python - IDE, Editor, Compiler, Interpreter", + "content": "Online Python IDE is a free online tool that lets you write, execute, and share Python code in the web browser. Learn about Python, its features, and its popularity as a general-purpose programming language for web development, data science, and more.", + "url": "https://www.online-python.com/", + "engine": "duckduckgo", + "parsed_url": ["https", "www.online-python.com", "/", "", "", ""], + "template": "default.html", + "engines": ["qwant", "duckduckgo"], + "positions": [8, 6], + "score": 0.5833333333333333, + "category": "general" + }, + { + "url": "https://micropython.org/", + "title": "MicroPython - Python for microcontrollers", + "content": "MicroPython is a full Python compiler and runtime that runs on the bare-metal. You get an interactive prompt (the REPL) to execute commands immediately, along ...", + "img_src": null, + "engine": "google", + "parsed_url": ["https", "micropython.org", "/", "", "", ""], + "template": "default.html", + "engines": ["google"], + "positions": [1], + "score": 1.0, + "category": "general" + }, + { + "url": "https://dictionary.cambridge.org/uk/dictionary/english/python", + "title": "PYTHON | \u0417\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u0432 \u0430\u043d\u0433\u043b\u0456\u0439\u0441\u044c\u043a\u0456\u0439 \u043c\u043e\u0432\u0456 - Cambridge Dictionary", + "content": "Apr 17, 2024 \u2014 \u0412\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f PYTHON: 1. a very large snake that kills animals for food by wrapping itself around them and crushing them\u2026. \u0414\u0456\u0437\u043d\u0430\u0439\u0442\u0435\u0441\u044f \u0431\u0456\u043b\u044c\u0448\u0435.", + "img_src": null, + "engine": "google", + "parsed_url": [ + "https", + "dictionary.cambridge.org", + "/uk/dictionary/english/python", + "", + "", + "" + ], + "template": "default.html", + "engines": ["google"], + "positions": [2], + "score": 0.5, + "category": "general" + }, + { + "url": "https://www.codetoday.co.uk/code", + "title": "Web-based Python Editor (with Turtle graphics)", + "content": "Quick way of starting to write Python code, including drawing with Turtle, provided by CodeToday using Trinket.io Ideal for young children to start ...", + "img_src": null, + "engine": "google", + "parsed_url": ["https", "www.codetoday.co.uk", "/code", "", "", ""], + "template": "default.html", + "engines": ["google"], + "positions": [3], + "score": 0.3333333333333333, + "category": "general" + }, + { + "url": "https://snapcraft.io/docs/python-plugin", + "title": "The python plugin | Snapcraft documentation", + "content": "The python plugin can be used by either Python 2 or Python 3 based parts using a setup.py script for building the project, or using a package published to ...", + "img_src": null, + "engine": "google", + "parsed_url": ["https", "snapcraft.io", "/docs/python-plugin", "", "", ""], + "template": "default.html", + "engines": ["google"], + "positions": [4], + "score": 0.25, + "category": "general" + }, + { + "url": "https://www.developer-tech.com/categories/developer-languages/developer-languages-python/", + "title": "Latest Python Developer News", + "content": "Python's status as the primary language for AI and machine learning projects, from its extensive data-handling capabilities to its flexibility and ...", + "img_src": null, + "engine": "google", + "parsed_url": [ + "https", + "www.developer-tech.com", + "/categories/developer-languages/developer-languages-python/", + "", + "", + "" + ], + "template": "default.html", + "engines": ["google"], + "positions": [5], + "score": 0.2, + "category": "general" + }, + { + "url": "https://subjectguides.york.ac.uk/coding/python", + "title": "Coding: a Practical Guide - Python - Subject Guides", + "content": "Python is a coding language used for a wide range of things, including working with data, building systems and software, and even creating games.", + "img_src": null, + "engine": "google", + "parsed_url": ["https", "subjectguides.york.ac.uk", "/coding/python", "", "", ""], + "template": "default.html", + "engines": ["google"], + "positions": [6], + "score": 0.16666666666666666, + "category": "general" + }, + { + "url": "https://hub.salford.ac.uk/psytech/python/getting-started-python/", + "title": "Getting Started - Python - Salford PsyTech Home - The Hub", + "content": "Python in itself is a very friendly programming language, when we get to grips with writing code, once you grasp the logic, it will become very intuitive.", + "img_src": null, + "engine": "google", + "parsed_url": [ + "https", + "hub.salford.ac.uk", + "/psytech/python/getting-started-python/", + "", + "", + "" + ], + "template": "default.html", + "engines": ["google"], + "positions": [7], + "score": 0.14285714285714285, + "category": "general" + }, + { + "url": "https://snapcraft.io/docs/python-apps", + "title": "Python apps | Snapcraft documentation", + "content": "Snapcraft can be used to package and distribute Python applications in a way that enables convenient installation by users. The process of creating a snap ...", + "img_src": null, + "engine": "google", + "parsed_url": ["https", "snapcraft.io", "/docs/python-apps", "", "", ""], + "template": "default.html", + "engines": ["google"], + "positions": [8], + "score": 0.125, + "category": "general" + }, + { + "url": "https://anvil.works/", + "title": "Anvil | Build Web Apps with Nothing but Python", + "content": "Anvil is a free Python-based drag-and-drop web app builder.\u200eSign Up \u00b7 \u200eSign in \u00b7 \u200ePricing \u00b7 \u200eForum", + "img_src": null, + "engine": "google", + "parsed_url": ["https", "anvil.works", "/", "", "", ""], + "template": "default.html", + "engines": ["google"], + "positions": [9], + "score": 0.1111111111111111, + "category": "general" + }, + { + "url": "https://docs.python.org/", + "title": "Python 3.12.3 documentation", + "content": "3 days ago \u00b7 This is the official documentation for Python 3.12.3. Documentation sections: What's new in Python 3.12? Or all \"What's new\" documents since Python 2.0. Tutorial. Start here: a tour of Python's syntax and features. Library reference. Standard library and builtins. Language reference.", + "engine": "bing", + "parsed_url": ["https", "docs.python.org", "/", "", "", ""], + "template": "default.html", + "engines": ["bing", "duckduckgo"], + "positions": [7, 13], + "score": 0.43956043956043955, + "category": "general" + }, + { + "title": "How to Use Python: Your First Steps - Real Python", + "content": "Learn the basics of Python syntax, installation, error handling, and more in this tutorial. You'll also code your first Python program and test your knowledge with a quiz.", + "url": "https://realpython.com/python-first-steps/", + "engine": "duckduckgo", + "parsed_url": ["https", "realpython.com", "/python-first-steps/", "", "", ""], + "template": "default.html", + "engines": ["qwant", "duckduckgo"], + "positions": [14, 7], + "score": 0.42857142857142855, + "category": "general" + }, + { + "title": "The Python Tutorial \u2014 Python 3.11.8 documentation", + "content": "This tutorial introduces the reader informally to the basic concepts and features of the Python language and system. It helps to have a Python interpreter handy for hands-on experience, but all examples are self-contained, so the tutorial can be read off-line as well. For a description of standard objects and modules, see The Python Standard ...", + "url": "https://docs.python.org/3.11/tutorial/", + "engine": "duckduckgo", + "parsed_url": ["https", "docs.python.org", "/3.11/tutorial/", "", "", ""], + "template": "default.html", + "engines": ["duckduckgo"], + "positions": [7], + "score": 0.14285714285714285, + "category": "general" + }, + { + "url": "https://realpython.com/python-introduction/", + "title": "Introduction to Python 3 \u2013 Real Python", + "content": "Python programming language, including a brief history of the development of Python and reasons why you might select Python as your language of choice.", + "engine": "bing", + "parsed_url": ["https", "realpython.com", "/python-introduction/", "", "", ""], + "template": "default.html", + "engines": ["bing"], + "positions": [8], + "score": 0.125, + "category": "general" + }, + { + "title": "Our Documentation | Python.org", + "content": "Find online or download Python's documentation, tutorials, and guides for beginners and advanced users. Learn how to port from Python 2 to Python 3, contribute to Python, and access Python videos and books.", + "url": "https://www.python.org/doc/", + "engine": "duckduckgo", + "parsed_url": ["https", "www.python.org", "/doc/", "", "", ""], + "template": "default.html", + "engines": ["duckduckgo"], + "positions": [9], + "score": 0.1111111111111111, + "category": "general" + }, + { + "title": "Welcome to Python.org", + "url": "http://www.get-python.org/shell/", + "content": "The mission of the Python Software Foundation is to promote, protect, and advance the Python programming language, and to support and facilitate the growth of a diverse and international community of Python programmers. Learn more. Become a Member Donate to the PSF.", + "engine": "qwant", + "parsed_url": ["http", "www.get-python.org", "/shell/", "", "", ""], + "template": "default.html", + "engines": ["qwant"], + "positions": [9], + "score": 0.1111111111111111, + "category": "general" + }, + { + "title": "About Python\u2122 | Python.org", + "content": "Python is a powerful, fast, and versatile programming language that runs on various platforms and is easy to learn. Learn how to get started, explore the applications, and join the community of Python programmers and users.", + "url": "https://www.python.org/about/", + "engine": "duckduckgo", + "parsed_url": ["https", "www.python.org", "/about/", "", "", ""], + "template": "default.html", + "engines": ["duckduckgo"], + "positions": [11], + "score": 0.09090909090909091, + "category": "general" + }, + { + "title": "Online Python Compiler (Interpreter) - Programiz", + "content": "Write and run Python code using this online tool. You can use Python Shell like IDLE, and take inputs from the user in our Python compiler.", + "url": "https://www.programiz.com/python-programming/online-compiler/", + "engine": "duckduckgo", + "parsed_url": [ + "https", + "www.programiz.com", + "/python-programming/online-compiler/", + "", + "", + "" + ], + "template": "default.html", + "engines": ["duckduckgo"], + "positions": [12], + "score": 0.08333333333333333, + "category": "general" + }, + { + "title": "Welcome to Python.org", + "content": "Python is a versatile and powerful language that lets you work quickly and integrate systems more effectively. Download the latest version, read the documentation, find jobs, events, success stories, and more on Python.org.", + "url": "https://www.python.org/?downloads", + "engine": "duckduckgo", + "parsed_url": ["https", "www.python.org", "/", "", "downloads", ""], + "template": "default.html", + "engines": ["duckduckgo"], + "positions": [15], + "score": 0.06666666666666667, + "category": "general" + }, + { + "url": "https://www.matillion.com/blog/the-importance-of-python-and-its-growing-influence-on-data-productivty-a-matillion-perspective", + "title": "The Importance of Python and its Growing Influence on ...", + "content": "Jan 30, 2024 \u2014 The synergy of low-code functionality with Python's versatility empowers data professionals to orchestrate complex transformations seamlessly.", + "img_src": null, + "engine": "google", + "parsed_url": [ + "https", + "www.matillion.com", + "/blog/the-importance-of-python-and-its-growing-influence-on-data-productivty-a-matillion-perspective", + "", + "", + "" + ], + "template": "default.html", + "engines": ["google"], + "positions": [10], + "score": 0.1, + "category": "general" + }, + { + "title": "BeginnersGuide - Python Wiki", + "content": "This is the program that reads Python programs and carries out their instructions; you need it before you can do any Python programming. Mac and Linux distributions may include an outdated version of Python (Python 2), but you should install an updated one (Python 3). See BeginnersGuide/Download for instructions to download the correct version ...", + "url": "https://wiki.python.org/moin/BeginnersGuide", + "engine": "duckduckgo", + "parsed_url": ["https", "wiki.python.org", "/moin/BeginnersGuide", "", "", ""], + "template": "default.html", + "engines": ["duckduckgo"], + "positions": [16], + "score": 0.0625, + "category": "general" + }, + { + "title": "Learn Python - Free Interactive Python Tutorial", + "content": "Learn Python from scratch or improve your skills with this website that offers tutorials, exercises, tests and certification. Explore topics such as basics, data science, advanced features and more with DataCamp.", + "url": "https://www.learnpython.org/", + "engine": "duckduckgo", + "parsed_url": ["https", "www.learnpython.org", "/", "", "", ""], + "template": "default.html", + "engines": ["duckduckgo"], + "positions": [17], + "score": 0.058823529411764705, + "category": "general" + } + ], + "answers": [], + "corrections": [], + "infoboxes": [ + { + "infobox": "Python", + "id": "https://en.wikipedia.org/wiki/Python_(programming_language)", + "content": "general-purpose programming language", + "img_src": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/6f/.PY_file_recreation.png/500px-.PY_file_recreation.png", + "urls": [ + { + "title": "Official website", + "url": "https://www.python.org/", + "official": true + }, + { + "title": "Wikipedia (en)", + "url": "https://en.wikipedia.org/wiki/Python_(programming_language)" + }, + { + "title": "Wikidata", + "url": "http://www.wikidata.org/entity/Q28865" + } + ], + "attributes": [ + { + "label": "Inception", + "value": "Wednesday, February 20, 1991", + "entity": "P571" + }, + { + "label": "Developer", + "value": "Python Software Foundation, Guido van Rossum", + "entity": "P178" + }, + { + "label": "Copyright license", + "value": "Python Software Foundation License", + "entity": "P275" + }, + { + "label": "Programmed in", + "value": "C, Python", + "entity": "P277" + }, + { + "label": "Software version identifier", + "value": "3.12.3, 3.13.0a6", + "entity": "P348" + } + ], + "engine": "wikidata", + "engines": ["wikidata"] + } + ], + "suggestions": [ + "python turtle", + "micro python tutorial", + "python docs", + "python compiler", + "snapcraft python", + "micropython vs python", + "python online", + "python download" + ], + "unresponsive_engines": [] +} diff --git a/backend/open_webui/retrieval/web/testdata/serper.json b/backend/open_webui/retrieval/web/testdata/serper.json new file mode 100644 index 0000000..b269eaf --- /dev/null +++ b/backend/open_webui/retrieval/web/testdata/serper.json @@ -0,0 +1,190 @@ +{ + "searchParameters": { + "q": "apple inc", + "gl": "us", + "hl": "en", + "autocorrect": true, + "page": 1, + "type": "search" + }, + "knowledgeGraph": { + "title": "Apple", + "type": "Technology company", + "website": "http://www.apple.com/", + "imageUrl": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQwGQRv5TjjkycpctY66mOg_e2-npacrmjAb6_jAWhzlzkFE3OTjxyzbA&s=0", + "description": "Apple Inc. is an American multinational technology company specializing in consumer electronics, software and online services headquartered in Cupertino, California, United States.", + "descriptionSource": "Wikipedia", + "descriptionLink": "https://en.wikipedia.org/wiki/Apple_Inc.", + "attributes": { + "Headquarters": "Cupertino, CA", + "CEO": "Tim Cook (Aug 24, 2011–)", + "Founded": "April 1, 1976, Los Altos, CA", + "Sales": "1 (800) 692-7753", + "Products": "iPhone, Apple Watch, iPad, and more", + "Founders": "Steve Jobs, Steve Wozniak, and Ronald Wayne", + "Subsidiaries": "Apple Store, Beats Electronics, Beddit, and more" + } + }, + "organic": [ + { + "title": "Apple", + "link": "https://www.apple.com/", + "snippet": "Discover the innovative world of Apple and shop everything iPhone, iPad, Apple Watch, Mac, and Apple TV, plus explore accessories, entertainment, ...", + "sitelinks": [ + { + "title": "Support", + "link": "https://support.apple.com/" + }, + { + "title": "iPhone", + "link": "https://www.apple.com/iphone/" + }, + { + "title": "Apple makes business better.", + "link": "https://www.apple.com/business/" + }, + { + "title": "Mac", + "link": "https://www.apple.com/mac/" + } + ], + "position": 1 + }, + { + "title": "Apple Inc. - Wikipedia", + "link": "https://en.wikipedia.org/wiki/Apple_Inc.", + "snippet": "Apple Inc. is an American multinational technology company specializing in consumer electronics, software and online services headquartered in Cupertino, ...", + "attributes": { + "Products": "AirPods; Apple Watch; iPad; iPhone; Mac", + "Founders": "Steve Jobs; Steve Wozniak; Ronald Wayne", + "Founded": "April 1, 1976; 46 years ago in Los Altos, California, U.S", + "Industry": "Consumer electronics; Software services; Online services" + }, + "sitelinks": [ + { + "title": "History", + "link": "https://en.wikipedia.org/wiki/History_of_Apple_Inc." + }, + { + "title": "Timeline of Apple Inc. products", + "link": "https://en.wikipedia.org/wiki/Timeline_of_Apple_Inc._products" + }, + { + "title": "List of software by Apple Inc.", + "link": "https://en.wikipedia.org/wiki/List_of_software_by_Apple_Inc." + }, + { + "title": "Apple Store", + "link": "https://en.wikipedia.org/wiki/Apple_Store" + } + ], + "position": 2 + }, + { + "title": "Apple Inc. | History, Products, Headquarters, & Facts | Britannica", + "link": "https://www.britannica.com/topic/Apple-Inc", + "snippet": "Apple Inc., formerly Apple Computer, Inc., American manufacturer of personal computers, smartphones, tablet computers, computer peripherals, ...", + "date": "Aug 31, 2022", + "attributes": { + "Related People": "Steve Jobs Steve Wozniak Jony Ive Tim Cook Angela Ahrendts", + "Date": "1976 - present", + "Areas Of Involvement": "peripheral device" + }, + "position": 3 + }, + { + "title": "AAPL: Apple Inc Stock Price Quote - NASDAQ GS - Bloomberg.com", + "link": "https://www.bloomberg.com/quote/AAPL:US", + "snippet": "Stock analysis for Apple Inc (AAPL:NASDAQ GS) including stock price, stock chart, company news, key statistics, fundamentals and company profile.", + "position": 4 + }, + { + "title": "Apple Inc. (AAPL) Company Profile & Facts - Yahoo Finance", + "link": "https://finance.yahoo.com/quote/AAPL/profile/", + "snippet": "Apple Inc. designs, manufactures, and markets smartphones, personal computers, tablets, wearables, and accessories worldwide. It also sells various related ...", + "position": 5 + }, + { + "title": "AAPL | Apple Inc. Stock Price & News - WSJ", + "link": "https://www.wsj.com/market-data/quotes/AAPL", + "snippet": "Apple, Inc. engages in the design, manufacture, and sale of smartphones, personal computers, tablets, wearables and accessories, and other varieties of ...", + "position": 6 + }, + { + "title": "Apple Inc Company Profile - Apple Inc Overview - GlobalData", + "link": "https://www.globaldata.com/company-profile/apple-inc/", + "snippet": "Apple Inc (Apple) designs, manufactures, and markets smartphones, tablets, personal computers (PCs), portable and wearable devices. The company also offers ...", + "position": 7 + }, + { + "title": "Apple Inc (AAPL) Stock Price & News - Google Finance", + "link": "https://www.google.com/finance/quote/AAPL:NASDAQ?hl=en", + "snippet": "Get the latest Apple Inc (AAPL) real-time quote, historical performance, charts, and other financial information to help you make more informed trading and ...", + "position": 8 + } + ], + "peopleAlsoAsk": [ + { + "question": "What does Apple Inc mean?", + "snippet": "Apple Inc., formerly Apple Computer, Inc., American manufacturer of personal\ncomputers, smartphones, tablet computers, computer peripherals, and computer\nsoftware. It was the first successful personal computer company and the\npopularizer of the graphical user interface.\nAug 31, 2022", + "title": "Apple Inc. | History, Products, Headquarters, & Facts | Britannica", + "link": "https://www.britannica.com/topic/Apple-Inc" + }, + { + "question": "Is Apple and Apple Inc same?", + "snippet": "Apple was founded as Apple Computer Company on April 1, 1976, by Steve Jobs,\nSteve Wozniak and Ronald Wayne to develop and sell Wozniak's Apple I personal\ncomputer. It was incorporated by Jobs and Wozniak as Apple Computer, Inc.", + "title": "Apple Inc. - Wikipedia", + "link": "https://en.wikipedia.org/wiki/Apple_Inc." + }, + { + "question": "Who owns Apple Inc?", + "snippet": "Apple Inc. is owned by two main institutional investors (Vanguard Group and\nBlackRock, Inc). While its major individual shareholders comprise people like\nArt Levinson, Tim Cook, Bruce Sewell, Al Gore, Johny Sroujli, and others.", + "title": "Who Owns Apple In 2022? - FourWeekMBA", + "link": "https://fourweekmba.com/who-owns-apple/" + }, + { + "question": "What products does Apple Inc offer?", + "snippet": "APPLE FOOTER\nStore.\nMac.\niPad.\niPhone.\nWatch.\nAirPods.\nTV & Home.\nAirTag.", + "title": "More items...", + "link": "https://www.apple.com/business/" + } + ], + "relatedSearches": [ + { + "query": "Who invented the iPhone" + }, + { + "query": "Apple Inc competitors" + }, + { + "query": "Apple iPad" + }, + { + "query": "iPhones" + }, + { + "query": "Apple Inc us" + }, + { + "query": "Apple company history" + }, + { + "query": "Apple Store" + }, + { + "query": "Apple customer service" + }, + { + "query": "Apple Watch" + }, + { + "query": "Apple Inc Industry" + }, + { + "query": "Apple Inc registered address" + }, + { + "query": "Apple Inc Bloomberg" + } + ] +} diff --git a/backend/open_webui/retrieval/web/testdata/serply.json b/backend/open_webui/retrieval/web/testdata/serply.json new file mode 100644 index 0000000..0fc2a31 --- /dev/null +++ b/backend/open_webui/retrieval/web/testdata/serply.json @@ -0,0 +1,206 @@ +{ + "ads": [], + "ads_count": 0, + "answers": [], + "results": [ + { + "title": "Apple", + "link": "https://www.apple.com/", + "description": "Discover the innovative world of Apple and shop everything iPhone, iPad, Apple Watch, Mac, and Apple TV, plus explore accessories, entertainment, ...", + "additional_links": [ + { + "text": "AppleApplehttps://www.apple.com", + "href": "https://www.apple.com/" + } + ], + "cite": {}, + "subdomains": [ + { + "title": "Support", + "link": "https://support.apple.com/", + "description": "SupportContact - iPhone Support - Billing and Subscriptions - Apple Repair" + }, + { + "title": "Store", + "link": "https://www.apple.com/store", + "description": "StoreShop iPhone - Shop iPad - App Store - Shop Mac - ..." + }, + { + "title": "Mac", + "link": "https://www.apple.com/mac/", + "description": "MacMacBook Air - MacBook Pro - iMac - Compare Mac models - Mac mini" + }, + { + "title": "iPad", + "link": "https://www.apple.com/ipad/", + "description": "iPadShop iPad - iPad Pro - iPad Air - Compare iPad models - ..." + }, + { + "title": "Watch", + "link": "https://www.apple.com/watch/", + "description": "WatchShop Apple Watch - Series 9 - SE - Ultra 2 - Nike - Hermès - ..." + } + ], + "realPosition": 1 + }, + { + "title": "Apple", + "link": "https://www.apple.com/", + "description": "Discover the innovative world of Apple and shop everything iPhone, iPad, Apple Watch, Mac, and Apple TV, plus explore accessories, entertainment, ...", + "additional_links": [ + { + "text": "AppleApplehttps://www.apple.com", + "href": "https://www.apple.com/" + } + ], + "cite": {}, + "realPosition": 2 + }, + { + "title": "Apple Inc.", + "link": "https://en.wikipedia.org/wiki/Apple_Inc.", + "description": "Apple Inc. (formerly Apple Computer, Inc.) is an American multinational corporation and technology company headquartered in Cupertino, California, ...", + "additional_links": [ + { + "text": "Apple Inc.Wikipediahttps://en.wikipedia.org › wiki › Apple_Inc", + "href": "https://en.wikipedia.org/wiki/Apple_Inc." + }, + { + "text": "", + "href": "https://en.wikipedia.org/wiki/Apple_Inc." + }, + { + "text": "History", + "href": "https://en.wikipedia.org/wiki/History_of_Apple_Inc." + }, + { + "text": "List of Apple products", + "href": "https://en.wikipedia.org/wiki/List_of_Apple_products" + }, + { + "text": "Litigation involving Apple Inc.", + "href": "https://en.wikipedia.org/wiki/Litigation_involving_Apple_Inc." + }, + { + "text": "Apple Park", + "href": "https://en.wikipedia.org/wiki/Apple_Park" + } + ], + "cite": { + "domain": "https://en.wikipedia.org › wiki › Apple_Inc", + "span": " › wiki › Apple_Inc" + }, + "realPosition": 3 + }, + { + "title": "Apple Inc. (AAPL) Company Profile & Facts", + "link": "https://finance.yahoo.com/quote/AAPL/profile/", + "description": "Apple Inc. designs, manufactures, and markets smartphones, personal computers, tablets, wearables, and accessories worldwide. The company offers iPhone, a line ...", + "additional_links": [ + { + "text": "Apple Inc. (AAPL) Company Profile & FactsYahoo Financehttps://finance.yahoo.com › quote › AAPL › profile", + "href": "https://finance.yahoo.com/quote/AAPL/profile/" + } + ], + "cite": { + "domain": "https://finance.yahoo.com › quote › AAPL › profile", + "span": " › quote › AAPL › profile" + }, + "realPosition": 4 + }, + { + "title": "Apple Inc - Company Profile and News", + "link": "https://www.bloomberg.com/profile/company/AAPL:US", + "description": "Apple Inc. Apple Inc. designs, manufactures, and markets smartphones, personal computers, tablets, wearables and accessories, and sells a variety of related ...", + "additional_links": [ + { + "text": "Apple Inc - Company Profile and NewsBloomberghttps://www.bloomberg.com › company › AAPL:US", + "href": "https://www.bloomberg.com/profile/company/AAPL:US" + }, + { + "text": "", + "href": "https://www.bloomberg.com/profile/company/AAPL:US" + } + ], + "cite": { + "domain": "https://www.bloomberg.com › company › AAPL:US", + "span": " › company › AAPL:US" + }, + "realPosition": 5 + }, + { + "title": "Apple Inc. | History, Products, Headquarters, & Facts", + "link": "https://www.britannica.com/money/Apple-Inc", + "description": "May 22, 2024 — Apple Inc. is an American multinational technology company that revolutionized the technology sector through its innovation of computer ...", + "additional_links": [ + { + "text": "Apple Inc. | History, Products, Headquarters, & FactsBritannicahttps://www.britannica.com › money › Apple-Inc", + "href": "https://www.britannica.com/money/Apple-Inc" + }, + { + "text": "", + "href": "https://www.britannica.com/money/Apple-Inc" + } + ], + "cite": { + "domain": "https://www.britannica.com › money › Apple-Inc", + "span": " › money › Apple-Inc" + }, + "realPosition": 6 + } + ], + "shopping_ads": [], + "places": [ + { + "title": "Apple Inc." + }, + { + "title": "Apple Inc" + }, + { + "title": "Apple Inc" + } + ], + "related_searches": { + "images": [], + "text": [ + { + "title": "apple inc full form", + "link": "https://www.google.com/search?sca_esv=6b6df170a5c9891b&sca_upv=1&q=Apple+Inc+full+form&sa=X&ved=2ahUKEwjLxuSJwM-GAxUHODQIHYuJBhgQ1QJ6BAhPEAE" + }, + { + "title": "apple company history", + "link": "https://www.google.com/search?sca_esv=6b6df170a5c9891b&sca_upv=1&q=Apple+company+history&sa=X&ved=2ahUKEwjLxuSJwM-GAxUHODQIHYuJBhgQ1QJ6BAhOEAE" + }, + { + "title": "apple store", + "link": "https://www.google.com/search?sca_esv=6b6df170a5c9891b&sca_upv=1&q=Apple+Store&sa=X&ved=2ahUKEwjLxuSJwM-GAxUHODQIHYuJBhgQ1QJ6BAhQEAE" + }, + { + "title": "apple id", + "link": "https://www.google.com/search?sca_esv=6b6df170a5c9891b&sca_upv=1&q=Apple+id&sa=X&ved=2ahUKEwjLxuSJwM-GAxUHODQIHYuJBhgQ1QJ6BAhSEAE" + }, + { + "title": "apple inc industry", + "link": "https://www.google.com/search?sca_esv=6b6df170a5c9891b&sca_upv=1&q=Apple+Inc+industry&sa=X&ved=2ahUKEwjLxuSJwM-GAxUHODQIHYuJBhgQ1QJ6BAhREAE" + }, + { + "title": "apple login", + "link": "https://www.google.com/search?sca_esv=6b6df170a5c9891b&sca_upv=1&q=Apple+login&sa=X&ved=2ahUKEwjLxuSJwM-GAxUHODQIHYuJBhgQ1QJ6BAhTEAE" + } + ] + }, + "image_results": [], + "carousel": [], + "total": 2450000000, + "knowledge_graph": "", + "related_questions": [ + "What does the Apple Inc do?", + "Why did Apple change to Apple Inc?", + "Who owns Apple Inc.?", + "What is Apple Inc best known for?" + ], + "carousel_count": 0, + "ts": 2.491065263748169, + "device_type": null +} diff --git a/backend/open_webui/retrieval/web/testdata/serpstack.json b/backend/open_webui/retrieval/web/testdata/serpstack.json new file mode 100644 index 0000000..a82f689 --- /dev/null +++ b/backend/open_webui/retrieval/web/testdata/serpstack.json @@ -0,0 +1,276 @@ +{ + "request": { + "success": true, + "total_time_taken": 3.4, + "processed_timestamp": 1714968442, + "search_url": "http://www.google.com/search?q=mcdonalds\u0026gl=us\u0026hl=en\u0026safe=0\u0026num=10" + }, + "search_parameters": { + "engine": "google", + "type": "web", + "device": "desktop", + "auto_location": "1", + "google_domain": "google.com", + "gl": "us", + "hl": "en", + "safe": "0", + "news_type": "all", + "exclude_autocorrected_results": "0", + "images_color": "any", + "page": "1", + "num": "10", + "output": "json", + "csv_fields": "search_parameters.query,organic_results.position,organic_results.title,organic_results.url,organic_results.domain", + "query": "mcdonalds", + "action": "search", + "access_key": "aac48e007e15c532bb94ffb34532a4b2", + "error": {} + }, + "search_information": { + "total_results": 1170000000, + "time_taken_displayed": 0.49, + "detected_location": {}, + "did_you_mean": {}, + "no_results_for_original_query": false, + "showing_results_for": {} + }, + "organic_results": [ + { + "position": 1, + "title": "Our Full McDonald\u0027s Food Menu", + "snippet": "", + "prerender": false, + "cached_page_url": {}, + "related_pages_url": {}, + "url": "https://www.mcdonalds.com/us/en-us/full-menu.html", + "domain": "www.mcdonalds.com", + "displayed_url": "https://www.mcdonalds.com \u203a en-us \u203a full-menu" + }, + { + "position": 2, + "title": "McDonald\u0027s", + "snippet": "McDonald\u0027s is the world\u0027s largest fast food restaurant chain, serving over 69 million customers daily in over 100 countries in more than 40,000 outlets as of\u00a0...", + "prerender": false, + "cached_page_url": {}, + "related_pages_url": {}, + "url": "https://en.wikipedia.org/wiki/McDonald%27s", + "domain": "en.wikipedia.org", + "displayed_url": "https://en.wikipedia.org \u203a wiki \u203a McDonald\u0027s" + }, + { + "position": 3, + "title": "Restaurants Near Me: Nearby McDonald\u0027s Locations", + "snippet": "", + "prerender": false, + "cached_page_url": {}, + "related_pages_url": {}, + "url": "https://www.mcdonalds.com/us/en-us/restaurant-locator.html", + "domain": "www.mcdonalds.com", + "displayed_url": "https://www.mcdonalds.com \u203a en-us \u203a restaurant-locator" + }, + { + "position": 4, + "title": "Download the McDonald\u0027s App: Deals, Promotions \u0026 ...", + "snippet": "Download the McDonald\u0027s app for Mobile Order \u0026 Pay, exclusive deals and coupons, menu information and special promotions.", + "prerender": false, + "cached_page_url": {}, + "related_pages_url": {}, + "url": "https://www.mcdonalds.com/us/en-us/download-app.html", + "domain": "www.mcdonalds.com", + "displayed_url": "https://www.mcdonalds.com \u203a en-us \u203a download-app" + }, + { + "position": 5, + "title": "McDonald\u0027s Restaurant Careers in the US", + "snippet": "McDonald\u0027s restaurant jobs are one-of-a-kind \u2013 just like you. Restaurants are hiring across all levels, from Crew team to Management. Apply today!", + "prerender": false, + "cached_page_url": {}, + "related_pages_url": {}, + "url": "https://jobs.mchire.com/", + "domain": "jobs.mchire.com", + "displayed_url": "https://jobs.mchire.com" + } + ], + "inline_images": [ + { + "image_url": "https://serpstack-assets.apilayer.net/2418910010831954152.png", + "title": "" + } + ], + "local_results": [ + { + "position": 1, + "title": "McDonald\u0027s", + "coordinates": { + "latitude": 0, + "longitude": 0 + }, + "address": "", + "rating": 0, + "reviews": 0, + "type": "", + "price": {}, + "url": 0 + }, + { + "position": 2, + "title": "McDonald\u0027s", + "coordinates": { + "latitude": 0, + "longitude": 0 + }, + "address": "", + "rating": 0, + "reviews": 0, + "type": "", + "price": {}, + "url": 0 + }, + { + "position": 3, + "title": "McDonald\u0027s", + "coordinates": { + "latitude": 0, + "longitude": 0 + }, + "address": "", + "rating": 0, + "reviews": 0, + "type": "", + "price": {}, + "url": 0 + } + ], + "top_stories": [ + { + "block_position": 1, + "title": "Menu nutrition", + "url": "/search?safe=0\u0026sca_esv=c9c7fd42856085e2\u0026sca_upv=1\u0026gl=us\u0026hl=en\u0026q=mcdonald%27s+double+quarter+pounder+with+cheese\u0026stick=H4sIAAAAAAAAAONgFuLUz9U3ME-vLDBX4tVP1zc0TCsuNE0ytjTTUs5OttJPy89P0c9NzSuNLyjKL8tMSS2yAvNS80qKMlOLF7Hq5ian5Ocl5qSoFyuk5Jcm5aQqFJYmFpWkFikU5JfmATUolGeWZCgkZ6SmFqcCAM4ilJtxAAAA\u0026sa=X\u0026ved=2ahUKEwjF55alk_iFAxXlamwGHbqgAs4Qri56BAh0EAM", + "source": "", + "uploaded": "", + "uploaded_utc": "2024-05-06T04:07:22.082Z" + }, + { + "block_position": 2, + "title": "Profiles", + "url": "https://www.instagram.com/McDonalds", + "source": "", + "uploaded": "", + "uploaded_utc": "2024-05-06T04:07:22.082Z" + }, + { + "block_position": 3, + "title": "People also search for", + "url": "/search?safe=0\u0026sca_esv=c9c7fd42856085e2\u0026sca_upv=1\u0026gl=us\u0026hl=en\u0026si=ACC90nzx_D3_zUKRnpAjmO0UBLNxnt7EyN4YYdru6U3bxLI-L5Wg8IL2sxPFxxcDEhVbocy-LJPZIvZySijw0ho2hfZ-KtV-sSEEJ9lw7JuEkXHDnRK5y4Dm8aqbiLwugbLbslwjG3hO_gpDTFZK2VoUGZPy2nrmOBCy0G3PoOfoiEtct2GSZlUz0uufG-xP8emtNzQKQpvjkAm5Zmi57iVZueiD62upz7-x2N3dAbwtm6FkInAPRw1yR91zuT7F3lEaPblTW3LaRwCDC0bvaRCh9x4N9zHgY1OOQa_rzts2jf5WpXcuw4Y%3D\u0026q=Burger+King\u0026sa=X\u0026ved=2ahUKEwjF55alk_iFAxXlamwGHbqgAs4Qs9oBKAB6BAhzEAI", + "source": "", + "uploaded": "", + "uploaded_utc": "2024-05-06T04:07:22.082Z" + } + ], + "related_questions": [ + { + "question": "What\u0027s a number 7 at McDonald\u0027s?What\u0027s a number 7 at McDonald\u0027s?What\u0027s a number 7 at McDonald\u0027s?", + "answer": "", + "title": "", + "displayed_url": "" + }, + { + "question": "Why is McDonald\u0027s changing their name?Why is McDonald\u0027s changing their name?Why is McDonald\u0027s changing their name?", + "answer": "", + "title": "", + "displayed_url": "" + }, + { + "question": "What is the oldest still running Mcdonalds?What is the oldest still running Mcdonalds?What is the oldest still running Mcdonalds?", + "answer": "", + "title": "", + "displayed_url": "" + }, + { + "question": "Why is McDonald\u0027s now WcDonald\u0027s?Why is McDonald\u0027s now WcDonald\u0027s?Why is McDonald\u0027s now WcDonald\u0027s?", + "answer": "", + "title": "", + "displayed_url": "" + } + ], + "knowledge_graph": { + "title": "", + "type": "Fast-food restaurant company", + "image_urls": ["https://serpstack-assets.apilayer.net/2418910010831954152.png"], + "description": "McDonald\u0027s Corporation is an American multinational fast food chain, founded in 1940 as a restaurant operated by Richard and Maurice McDonald, in San Bernardino, California, United States.", + "source": { + "name": "Wikipedia", + "url": "https://en.wikipedia.org/wiki/McDonald\u0027s" + }, + "people_also_search_for": [], + "known_attributes": [ + { + "attribute": "kc:/business/business_operation:founder", + "link": "http://www.google.com/search?safe=0\u0026sca_esv=c9c7fd42856085e2\u0026sca_upv=1\u0026gl=us\u0026hl=en\u0026q=Ray+Kroc\u0026si=ACC90nzx_D3_zUKRnpAjmO0UBLNxnt7EyN4YYdru6U3bxLI-LxARWRdbk5SkoY2sDn5Qq7yOmqYGei6qZ7sfJhsjZXBPgjMlLbS7824rpJOm69GzqVWMdoNIZiFX2T4A2td14sZOn4a1BexZLtZXHU7NZdF6VsWbGMVuiSYtXdev7uaUjEJKumiwlqTAATTebOriYTEBuSzC\u0026sa=X\u0026ved=2ahUKEwjF55alk_iFAxXlamwGHbqgAs4QmxMoAHoECHgQAg", + "name": "Founder: ", + "value": "Ray Kroc" + }, + { + "attribute": "kc:/organization/organization:ceo", + "link": "http://www.google.com/search?safe=0\u0026sca_esv=c9c7fd42856085e2\u0026sca_upv=1\u0026gl=us\u0026hl=en\u0026q=Chris+Kempczinski\u0026si=ACC90nwLLwns5sISZcdzuISy7t-NHozt8Cbt6G3WNQfC9ekAgKFbjdEFCDgxLbt57EDZGosYDGiZuq1AcBhA6IhTOSZxfVSySuGQ3VDwmmTA7Z93n3K3596jAuZH9VVv5h8PyvKJSuGuSsQWviJTl3eKj2UL1ZIWuDgkjyVMnC47rN7j0G9PlHRCCLdQF7VDQ1gubTiC4onXqLRBTbwAj6a--PD6Jv_NoA%3D%3D\u0026sa=X\u0026ved=2ahUKEwjF55alk_iFAxXlamwGHbqgAs4QmxMoAHoECHUQAg", + "name": "CEO: ", + "value": "Chris Kempczinski (Nov 1, 2019\u2013)" + }, + { + "attribute": "kc:/business/employer:revenue", + "link": "", + "name": "Revenue: ", + "value": "25.49\u00a0billion USD (2023)" + }, + { + "attribute": "kc:/organization/organization:founded", + "link": "http://www.google.com/search?safe=0\u0026sca_esv=c9c7fd42856085e2\u0026sca_upv=1\u0026gl=us\u0026hl=en\u0026q=Des+Plaines\u0026si=ACC90nyvvWro6QmnyY1IfSdgk5wwjB1r8BGd_IWRjXqmKPQqm_yqLtI_DBi5PXGOtg_Z3qrzzEP6mcih1nN7h5A7v6OefnEJiC7a8dBR-v9LxlRubfyR6vlMr3fZ3TmVKWwz9FRpvZb1eYNt-RM7KIDKQlwGEIgINvzhxjUrv6uxSmceduzxd8W7Pkz71XGwxF0F8OlSzHlx\u0026sa=X\u0026ved=2ahUKEwjF55alk_iFAxXlamwGHbqgAs4QmxMoAHoECG4QAg", + "name": "Founded: ", + "value": "April 15, 1955, Des Plaines, IL" + }, + { + "attribute": "kc:/organization/organization:headquarters", + "link": "http://www.google.com/search?safe=0\u0026sca_esv=c9c7fd42856085e2\u0026sca_upv=1\u0026gl=us\u0026hl=en\u0026q=Chicago\u0026si=ACC90nyvvWro6QmnyY1IfSdgk5wwjB1r8BGd_IWRjXqmKPQqm-46AEJ_kJbUIEvsvEEZqteiYJvXVXs2ScRNDvFFpjfeAaW3dxtpTGCgcsf5RMdi6IdzOdtjJMN3ZaFwqZOmdi7tC6r0Mh1O9bnP3HrVDB9hH02m7aA6f70dCAfTdpOFnGxDU6wVMAI5MxWBE3wTugtUDOK-\u0026sa=X\u0026ved=2ahUKEwjF55alk_iFAxXlamwGHbqgAs4QmxMoAHoECHYQAg", + "name": "Headquarters: ", + "value": "Chicago, IL" + }, + { + "attribute": "kc:/organization/organization:president", + "link": "http://www.google.com/search?safe=0\u0026sca_esv=c9c7fd42856085e2\u0026sca_upv=1\u0026gl=us\u0026hl=en\u0026q=Chris+Kempczinski\u0026si=ACC90nwLLwns5sISZcdzuISy7t-NHozt8Cbt6G3WNQfC9ekAgKFbjdEFCDgxLbt57EDZGosYDGiZuq1AcBhA6IhTOSZxfVSySuGQ3VDwmmTA7Z93n3K3596jAuZH9VVv5h8PyvKJSuGuSsQWviJTl3eKj2UL1ZIWuDgkjyVMnC47rN7j0G9PlHRCCLdQF7VDQ1gubTiC4onXqLRBTbwAj6a--PD6Jv_NoA%3D%3D\u0026sa=X\u0026ved=2ahUKEwjF55alk_iFAxXlamwGHbqgAs4QmxMoAHoECHEQAg", + "name": "President: ", + "value": "Chris Kempczinski" + } + ], + "website": "https://www.mcdonalds.com/us/en-us.html", + "profiles": [ + { + "name": "Instagram", + "url": "https://www.instagram.com/McDonalds" + }, + { + "name": "X (Twitter)", + "url": "https://twitter.com/McDonalds" + }, + { + "name": "Facebook", + "url": "https://www.facebook.com/McDonaldsUS" + }, + { + "name": "YouTube", + "url": "https://www.youtube.com/user/McDonaldsUS" + }, + { + "name": "Pinterest", + "url": "https://www.pinterest.com/mcdonalds" + } + ], + "founded": "April 15, 1955, Des Plaines, IL", + "headquarters": "Chicago, IL", + "founders": [ + { + "name": "Ray Kroc", + "link": "http://www.google.com/search?safe=0\u0026sca_esv=c9c7fd42856085e2\u0026sca_upv=1\u0026gl=us\u0026hl=en\u0026q=Ray+Kroc\u0026si=ACC90nzx_D3_zUKRnpAjmO0UBLNxnt7EyN4YYdru6U3bxLI-LxARWRdbk5SkoY2sDn5Qq7yOmqYGei6qZ7sfJhsjZXBPgjMlLbS7824rpJOm69GzqVWMdoNIZiFX2T4A2td14sZOn4a1BexZLtZXHU7NZdF6VsWbGMVuiSYtXdev7uaUjEJKumiwlqTAATTebOriYTEBuSzC\u0026sa=X\u0026ved=2ahUKEwjF55alk_iFAxXlamwGHbqgAs4QmxMoAHoECHgQAg" + } + ] + } +} diff --git a/backend/open_webui/retrieval/web/utils.py b/backend/open_webui/retrieval/web/utils.py new file mode 100644 index 0000000..fd94a1a --- /dev/null +++ b/backend/open_webui/retrieval/web/utils.py @@ -0,0 +1,538 @@ +import asyncio +import logging +import socket +import ssl +import urllib.parse +import urllib.request +from collections import defaultdict +from datetime import datetime, time, timedelta +from typing import ( + Any, + AsyncIterator, + Dict, + Iterator, + List, + Optional, + Sequence, + Union, + Literal, +) +import aiohttp +import certifi +import validators +from langchain_community.document_loaders import PlaywrightURLLoader, WebBaseLoader +from langchain_community.document_loaders.firecrawl import FireCrawlLoader +from langchain_community.document_loaders.base import BaseLoader +from langchain_core.documents import Document +from open_webui.constants import ERROR_MESSAGES +from open_webui.config import ( + ENABLE_RAG_LOCAL_WEB_FETCH, + PLAYWRIGHT_WS_URI, + RAG_WEB_LOADER_ENGINE, + FIRECRAWL_API_BASE_URL, + FIRECRAWL_API_KEY, +) +from open_webui.env import SRC_LOG_LEVELS + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["RAG"]) + + +def validate_url(url: Union[str, Sequence[str]]): + if isinstance(url, str): + if isinstance(validators.url(url), validators.ValidationError): + raise ValueError(ERROR_MESSAGES.INVALID_URL) + if not ENABLE_RAG_LOCAL_WEB_FETCH: + # Local web fetch is disabled, filter out any URLs that resolve to private IP addresses + parsed_url = urllib.parse.urlparse(url) + # Get IPv4 and IPv6 addresses + ipv4_addresses, ipv6_addresses = resolve_hostname(parsed_url.hostname) + # Check if any of the resolved addresses are private + # This is technically still vulnerable to DNS rebinding attacks, as we don't control WebBaseLoader + for ip in ipv4_addresses: + if validators.ipv4(ip, private=True): + raise ValueError(ERROR_MESSAGES.INVALID_URL) + for ip in ipv6_addresses: + if validators.ipv6(ip, private=True): + raise ValueError(ERROR_MESSAGES.INVALID_URL) + return True + elif isinstance(url, Sequence): + return all(validate_url(u) for u in url) + else: + return False + + +def safe_validate_urls(url: Sequence[str]) -> Sequence[str]: + valid_urls = [] + for u in url: + try: + if validate_url(u): + valid_urls.append(u) + except ValueError: + continue + return valid_urls + + +def resolve_hostname(hostname): + # Get address information + addr_info = socket.getaddrinfo(hostname, None) + + # Extract IP addresses from address information + ipv4_addresses = [info[4][0] for info in addr_info if info[0] == socket.AF_INET] + ipv6_addresses = [info[4][0] for info in addr_info if info[0] == socket.AF_INET6] + + return ipv4_addresses, ipv6_addresses + + +def extract_metadata(soup, url): + metadata = {"source": url} + if title := soup.find("title"): + metadata["title"] = title.get_text() + if description := soup.find("meta", attrs={"name": "description"}): + metadata["description"] = description.get("content", "No description found.") + if html := soup.find("html"): + metadata["language"] = html.get("lang", "No language found.") + return metadata + + +def verify_ssl_cert(url: str) -> bool: + """Verify SSL certificate for the given URL.""" + if not url.startswith("https://"): + return True + + try: + hostname = url.split("://")[-1].split("/")[0] + context = ssl.create_default_context(cafile=certifi.where()) + with context.wrap_socket(ssl.socket(), server_hostname=hostname) as s: + s.connect((hostname, 443)) + return True + except ssl.SSLError: + return False + except Exception as e: + log.warning(f"SSL verification failed for {url}: {str(e)}") + return False + + +class SafeFireCrawlLoader(BaseLoader): + def __init__( + self, + web_paths, + verify_ssl: bool = True, + trust_env: bool = False, + requests_per_second: Optional[float] = None, + continue_on_failure: bool = True, + api_key: Optional[str] = None, + api_url: Optional[str] = None, + mode: Literal["crawl", "scrape", "map"] = "crawl", + proxy: Optional[Dict[str, str]] = None, + params: Optional[Dict] = None, + ): + """Concurrent document loader for FireCrawl operations. + + Executes multiple FireCrawlLoader instances concurrently using thread pooling + to improve bulk processing efficiency. + Args: + web_paths: List of URLs/paths to process. + verify_ssl: If True, verify SSL certificates. + trust_env: If True, use proxy settings from environment variables. + requests_per_second: Number of requests per second to limit to. + continue_on_failure (bool): If True, continue loading other URLs on failure. + api_key: API key for FireCrawl service. Defaults to None + (uses FIRE_CRAWL_API_KEY environment variable if not provided). + api_url: Base URL for FireCrawl API. Defaults to official API endpoint. + mode: Operation mode selection: + - 'crawl': Website crawling mode (default) + - 'scrape': Direct page scraping + - 'map': Site map generation + proxy: Proxy override settings for the FireCrawl API. + params: The parameters to pass to the Firecrawl API. + Examples include crawlerOptions. + For more details, visit: https://github.com/mendableai/firecrawl-py + """ + proxy_server = proxy.get("server") if proxy else None + if trust_env and not proxy_server: + env_proxies = urllib.request.getproxies() + env_proxy_server = env_proxies.get("https") or env_proxies.get("http") + if env_proxy_server: + if proxy: + proxy["server"] = env_proxy_server + else: + proxy = {"server": env_proxy_server} + self.web_paths = web_paths + self.verify_ssl = verify_ssl + self.requests_per_second = requests_per_second + self.last_request_time = None + self.trust_env = trust_env + self.continue_on_failure = continue_on_failure + self.api_key = api_key + self.api_url = api_url + self.mode = mode + self.params = params + + def lazy_load(self) -> Iterator[Document]: + """Load documents concurrently using FireCrawl.""" + for url in self.web_paths: + try: + self._safe_process_url_sync(url) + loader = FireCrawlLoader( + url=url, + api_key=self.api_key, + api_url=self.api_url, + mode=self.mode, + params=self.params, + ) + yield from loader.lazy_load() + except Exception as e: + if self.continue_on_failure: + log.exception(e, "Error loading %s", url) + continue + raise e + + async def alazy_load(self): + """Async version of lazy_load.""" + for url in self.web_paths: + try: + await self._safe_process_url(url) + loader = FireCrawlLoader( + url=url, + api_key=self.api_key, + api_url=self.api_url, + mode=self.mode, + params=self.params, + ) + async for document in loader.alazy_load(): + yield document + except Exception as e: + if self.continue_on_failure: + log.exception(e, "Error loading %s", url) + continue + raise e + + def _verify_ssl_cert(self, url: str) -> bool: + return verify_ssl_cert(url) + + async def _wait_for_rate_limit(self): + """Wait to respect the rate limit if specified.""" + if self.requests_per_second and self.last_request_time: + min_interval = timedelta(seconds=1.0 / self.requests_per_second) + time_since_last = datetime.now() - self.last_request_time + if time_since_last < min_interval: + await asyncio.sleep((min_interval - time_since_last).total_seconds()) + self.last_request_time = datetime.now() + + def _sync_wait_for_rate_limit(self): + """Synchronous version of rate limit wait.""" + if self.requests_per_second and self.last_request_time: + min_interval = timedelta(seconds=1.0 / self.requests_per_second) + time_since_last = datetime.now() - self.last_request_time + if time_since_last < min_interval: + time.sleep((min_interval - time_since_last).total_seconds()) + self.last_request_time = datetime.now() + + async def _safe_process_url(self, url: str) -> bool: + """Perform safety checks before processing a URL.""" + if self.verify_ssl and not self._verify_ssl_cert(url): + raise ValueError(f"SSL certificate verification failed for {url}") + await self._wait_for_rate_limit() + return True + + def _safe_process_url_sync(self, url: str) -> bool: + """Synchronous version of safety checks.""" + if self.verify_ssl and not self._verify_ssl_cert(url): + raise ValueError(f"SSL certificate verification failed for {url}") + self._sync_wait_for_rate_limit() + return True + + +class SafePlaywrightURLLoader(PlaywrightURLLoader): + """Load HTML pages safely with Playwright, supporting SSL verification, rate limiting, and remote browser connection. + + Attributes: + web_paths (List[str]): List of URLs to load. + verify_ssl (bool): If True, verify SSL certificates. + trust_env (bool): If True, use proxy settings from environment variables. + requests_per_second (Optional[float]): Number of requests per second to limit to. + continue_on_failure (bool): If True, continue loading other URLs on failure. + headless (bool): If True, the browser will run in headless mode. + proxy (dict): Proxy override settings for the Playwright session. + playwright_ws_url (Optional[str]): WebSocket endpoint URI for remote browser connection. + """ + + def __init__( + self, + web_paths: List[str], + verify_ssl: bool = True, + trust_env: bool = False, + requests_per_second: Optional[float] = None, + continue_on_failure: bool = True, + headless: bool = True, + remove_selectors: Optional[List[str]] = None, + proxy: Optional[Dict[str, str]] = None, + playwright_ws_url: Optional[str] = None, + ): + """Initialize with additional safety parameters and remote browser support.""" + + proxy_server = proxy.get("server") if proxy else None + if trust_env and not proxy_server: + env_proxies = urllib.request.getproxies() + env_proxy_server = env_proxies.get("https") or env_proxies.get("http") + if env_proxy_server: + if proxy: + proxy["server"] = env_proxy_server + else: + proxy = {"server": env_proxy_server} + + # We'll set headless to False if using playwright_ws_url since it's handled by the remote browser + super().__init__( + urls=web_paths, + continue_on_failure=continue_on_failure, + headless=headless if playwright_ws_url is None else False, + remove_selectors=remove_selectors, + proxy=proxy, + ) + self.verify_ssl = verify_ssl + self.requests_per_second = requests_per_second + self.last_request_time = None + self.playwright_ws_url = playwright_ws_url + self.trust_env = trust_env + + def lazy_load(self) -> Iterator[Document]: + """Safely load URLs synchronously with support for remote browser.""" + from playwright.sync_api import sync_playwright + + with sync_playwright() as p: + # Use remote browser if ws_endpoint is provided, otherwise use local browser + if self.playwright_ws_url: + browser = p.chromium.connect(self.playwright_ws_url) + else: + browser = p.chromium.launch(headless=self.headless, proxy=self.proxy) + + for url in self.urls: + try: + self._safe_process_url_sync(url) + page = browser.new_page() + response = page.goto(url) + if response is None: + raise ValueError(f"page.goto() returned None for url {url}") + + text = self.evaluator.evaluate(page, browser, response) + metadata = {"source": url} + yield Document(page_content=text, metadata=metadata) + except Exception as e: + if self.continue_on_failure: + log.exception(e, "Error loading %s", url) + continue + raise e + browser.close() + + async def alazy_load(self) -> AsyncIterator[Document]: + """Safely load URLs asynchronously with support for remote browser.""" + from playwright.async_api import async_playwright + + async with async_playwright() as p: + # Use remote browser if ws_endpoint is provided, otherwise use local browser + if self.playwright_ws_url: + browser = await p.chromium.connect(self.playwright_ws_url) + else: + browser = await p.chromium.launch( + headless=self.headless, proxy=self.proxy + ) + + for url in self.urls: + try: + await self._safe_process_url(url) + page = await browser.new_page() + response = await page.goto(url) + if response is None: + raise ValueError(f"page.goto() returned None for url {url}") + + text = await self.evaluator.evaluate_async(page, browser, response) + metadata = {"source": url} + yield Document(page_content=text, metadata=metadata) + except Exception as e: + if self.continue_on_failure: + log.exception(e, "Error loading %s", url) + continue + raise e + await browser.close() + + def _verify_ssl_cert(self, url: str) -> bool: + return verify_ssl_cert(url) + + async def _wait_for_rate_limit(self): + """Wait to respect the rate limit if specified.""" + if self.requests_per_second and self.last_request_time: + min_interval = timedelta(seconds=1.0 / self.requests_per_second) + time_since_last = datetime.now() - self.last_request_time + if time_since_last < min_interval: + await asyncio.sleep((min_interval - time_since_last).total_seconds()) + self.last_request_time = datetime.now() + + def _sync_wait_for_rate_limit(self): + """Synchronous version of rate limit wait.""" + if self.requests_per_second and self.last_request_time: + min_interval = timedelta(seconds=1.0 / self.requests_per_second) + time_since_last = datetime.now() - self.last_request_time + if time_since_last < min_interval: + time.sleep((min_interval - time_since_last).total_seconds()) + self.last_request_time = datetime.now() + + async def _safe_process_url(self, url: str) -> bool: + """Perform safety checks before processing a URL.""" + if self.verify_ssl and not self._verify_ssl_cert(url): + raise ValueError(f"SSL certificate verification failed for {url}") + await self._wait_for_rate_limit() + return True + + def _safe_process_url_sync(self, url: str) -> bool: + """Synchronous version of safety checks.""" + if self.verify_ssl and not self._verify_ssl_cert(url): + raise ValueError(f"SSL certificate verification failed for {url}") + self._sync_wait_for_rate_limit() + return True + + +class SafeWebBaseLoader(WebBaseLoader): + """WebBaseLoader with enhanced error handling for URLs.""" + + def __init__(self, trust_env: bool = False, *args, **kwargs): + """Initialize SafeWebBaseLoader + Args: + trust_env (bool, optional): set to True if using proxy to make web requests, for example + using http(s)_proxy environment variables. Defaults to False. + """ + super().__init__(*args, **kwargs) + self.trust_env = trust_env + + async def _fetch( + self, url: str, retries: int = 3, cooldown: int = 2, backoff: float = 1.5 + ) -> str: + async with aiohttp.ClientSession(trust_env=self.trust_env) as session: + for i in range(retries): + try: + kwargs: Dict = dict( + headers=self.session.headers, + cookies=self.session.cookies.get_dict(), + ) + if not self.session.verify: + kwargs["ssl"] = False + + async with session.get( + url, **(self.requests_kwargs | kwargs) + ) as response: + if self.raise_for_status: + response.raise_for_status() + return await response.text() + except aiohttp.ClientConnectionError as e: + if i == retries - 1: + raise + else: + log.warning( + f"Error fetching {url} with attempt " + f"{i + 1}/{retries}: {e}. Retrying..." + ) + await asyncio.sleep(cooldown * backoff**i) + raise ValueError("retry count exceeded") + + def _unpack_fetch_results( + self, results: Any, urls: List[str], parser: Union[str, None] = None + ) -> List[Any]: + """Unpack fetch results into BeautifulSoup objects.""" + from bs4 import BeautifulSoup + + final_results = [] + for i, result in enumerate(results): + url = urls[i] + if parser is None: + if url.endswith(".xml"): + parser = "xml" + else: + parser = self.default_parser + self._check_parser(parser) + final_results.append(BeautifulSoup(result, parser, **self.bs_kwargs)) + return final_results + + async def ascrape_all( + self, urls: List[str], parser: Union[str, None] = None + ) -> List[Any]: + """Async fetch all urls, then return soups for all results.""" + results = await self.fetch_all(urls) + return self._unpack_fetch_results(results, urls, parser=parser) + + def lazy_load(self) -> Iterator[Document]: + """Lazy load text from the url(s) in web_path with error handling.""" + for path in self.web_paths: + try: + soup = self._scrape(path, bs_kwargs=self.bs_kwargs) + text = soup.get_text(**self.bs_get_text_kwargs) + + # Build metadata + metadata = extract_metadata(soup, path) + + yield Document(page_content=text, metadata=metadata) + except Exception as e: + # Log the error and continue with the next URL + log.exception(e, "Error loading %s", path) + + async def alazy_load(self) -> AsyncIterator[Document]: + """Async lazy load text from the url(s) in web_path.""" + results = await self.ascrape_all(self.web_paths) + for path, soup in zip(self.web_paths, results): + text = soup.get_text(**self.bs_get_text_kwargs) + metadata = {"source": path} + if title := soup.find("title"): + metadata["title"] = title.get_text() + if description := soup.find("meta", attrs={"name": "description"}): + metadata["description"] = description.get( + "content", "No description found." + ) + if html := soup.find("html"): + metadata["language"] = html.get("lang", "No language found.") + yield Document(page_content=text, metadata=metadata) + + async def aload(self) -> list[Document]: + """Load data into Document objects.""" + return [document async for document in self.alazy_load()] + + +RAG_WEB_LOADER_ENGINES = defaultdict(lambda: SafeWebBaseLoader) +RAG_WEB_LOADER_ENGINES["playwright"] = SafePlaywrightURLLoader +RAG_WEB_LOADER_ENGINES["safe_web"] = SafeWebBaseLoader +RAG_WEB_LOADER_ENGINES["firecrawl"] = SafeFireCrawlLoader + + +def get_web_loader( + urls: Union[str, Sequence[str]], + verify_ssl: bool = True, + requests_per_second: int = 2, + trust_env: bool = False, +): + # Check if the URLs are valid + safe_urls = safe_validate_urls([urls] if isinstance(urls, str) else urls) + + web_loader_args = { + "web_paths": safe_urls, + "verify_ssl": verify_ssl, + "requests_per_second": requests_per_second, + "continue_on_failure": True, + "trust_env": trust_env, + } + + if PLAYWRIGHT_WS_URI.value: + web_loader_args["playwright_ws_url"] = PLAYWRIGHT_WS_URI.value + + if RAG_WEB_LOADER_ENGINE.value == "firecrawl": + web_loader_args["api_key"] = FIRECRAWL_API_KEY.value + web_loader_args["api_url"] = FIRECRAWL_API_BASE_URL.value + + # Create the appropriate WebLoader based on the configuration + WebLoaderClass = RAG_WEB_LOADER_ENGINES[RAG_WEB_LOADER_ENGINE.value] + web_loader = WebLoaderClass(**web_loader_args) + + log.debug( + "Using RAG_WEB_LOADER_ENGINE %s for %s URLs", + web_loader.__class__.__name__, + len(safe_urls), + ) + + return web_loader diff --git a/backend/open_webui/routers/audio.py b/backend/open_webui/routers/audio.py new file mode 100644 index 0000000..c949e65 --- /dev/null +++ b/backend/open_webui/routers/audio.py @@ -0,0 +1,828 @@ +import hashlib +import json +import logging +import os +import uuid +from functools import lru_cache +from pathlib import Path +from pydub import AudioSegment +from pydub.silence import split_on_silence + +import aiohttp +import aiofiles +import requests +import mimetypes + +from fastapi import ( + Depends, + FastAPI, + File, + HTTPException, + Request, + UploadFile, + status, + APIRouter, +) +from fastapi.middleware.cors import CORSMiddleware +from fastapi.responses import FileResponse +from pydantic import BaseModel + + +from open_webui.utils.auth import get_admin_user, get_verified_user +from open_webui.config import ( + WHISPER_MODEL_AUTO_UPDATE, + WHISPER_MODEL_DIR, + CACHE_DIR, +) + +from open_webui.constants import ERROR_MESSAGES +from open_webui.env import ( + AIOHTTP_CLIENT_TIMEOUT, + ENV, + SRC_LOG_LEVELS, + DEVICE_TYPE, + ENABLE_FORWARD_USER_INFO_HEADERS, +) + + +router = APIRouter() + +# Constants +MAX_FILE_SIZE_MB = 25 +MAX_FILE_SIZE = MAX_FILE_SIZE_MB * 1024 * 1024 # Convert MB to bytes + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["AUDIO"]) + +SPEECH_CACHE_DIR = Path(CACHE_DIR).joinpath("./audio/speech/") +SPEECH_CACHE_DIR.mkdir(parents=True, exist_ok=True) + + +########################################## +# +# Utility functions +# +########################################## + +from pydub import AudioSegment +from pydub.utils import mediainfo + + +def is_mp4_audio(file_path): + """Check if the given file is an MP4 audio file.""" + if not os.path.isfile(file_path): + log.error(f"File not found: {file_path}") + return False + + info = mediainfo(file_path) + if ( + info.get("codec_name") == "aac" + and info.get("codec_type") == "audio" + and info.get("codec_tag_string") == "mp4a" + ): + return True + return False + + +def convert_mp4_to_wav(file_path, output_path): + """Convert MP4 audio file to WAV format.""" + audio = AudioSegment.from_file(file_path, format="mp4") + audio.export(output_path, format="wav") + log.info(f"Converted {file_path} to {output_path}") + + +def set_faster_whisper_model(model: str, auto_update: bool = False): + whisper_model = None + if model: + from faster_whisper import WhisperModel + + faster_whisper_kwargs = { + "model_size_or_path": model, + "device": DEVICE_TYPE if DEVICE_TYPE and DEVICE_TYPE == "cuda" else "cpu", + "compute_type": "int8", + "download_root": WHISPER_MODEL_DIR, + "local_files_only": not auto_update, + } + + try: + whisper_model = WhisperModel(**faster_whisper_kwargs) + except Exception: + log.warning( + "WhisperModel initialization failed, attempting download with local_files_only=False" + ) + faster_whisper_kwargs["local_files_only"] = False + whisper_model = WhisperModel(**faster_whisper_kwargs) + return whisper_model + + +########################################## +# +# Audio API +# +########################################## + + +class TTSConfigForm(BaseModel): + OPENAI_API_BASE_URL: str + OPENAI_API_KEY: str + API_KEY: str + ENGINE: str + MODEL: str + VOICE: str + SPLIT_ON: str + AZURE_SPEECH_REGION: str + AZURE_SPEECH_OUTPUT_FORMAT: str + + +class STTConfigForm(BaseModel): + OPENAI_API_BASE_URL: str + OPENAI_API_KEY: str + ENGINE: str + MODEL: str + WHISPER_MODEL: str + DEEPGRAM_API_KEY: str + + +class AudioConfigUpdateForm(BaseModel): + tts: TTSConfigForm + stt: STTConfigForm + + +@router.get("/config") +async def get_audio_config(request: Request, user=Depends(get_admin_user)): + return { + "tts": { + "OPENAI_API_BASE_URL": request.app.state.config.TTS_OPENAI_API_BASE_URL, + "OPENAI_API_KEY": request.app.state.config.TTS_OPENAI_API_KEY, + "API_KEY": request.app.state.config.TTS_API_KEY, + "ENGINE": request.app.state.config.TTS_ENGINE, + "MODEL": request.app.state.config.TTS_MODEL, + "VOICE": request.app.state.config.TTS_VOICE, + "SPLIT_ON": request.app.state.config.TTS_SPLIT_ON, + "AZURE_SPEECH_REGION": request.app.state.config.TTS_AZURE_SPEECH_REGION, + "AZURE_SPEECH_OUTPUT_FORMAT": request.app.state.config.TTS_AZURE_SPEECH_OUTPUT_FORMAT, + }, + "stt": { + "OPENAI_API_BASE_URL": request.app.state.config.STT_OPENAI_API_BASE_URL, + "OPENAI_API_KEY": request.app.state.config.STT_OPENAI_API_KEY, + "ENGINE": request.app.state.config.STT_ENGINE, + "MODEL": request.app.state.config.STT_MODEL, + "WHISPER_MODEL": request.app.state.config.WHISPER_MODEL, + "DEEPGRAM_API_KEY": request.app.state.config.DEEPGRAM_API_KEY, + }, + } + + +@router.post("/config/update") +async def update_audio_config( + request: Request, form_data: AudioConfigUpdateForm, user=Depends(get_admin_user) +): + request.app.state.config.TTS_OPENAI_API_BASE_URL = form_data.tts.OPENAI_API_BASE_URL + request.app.state.config.TTS_OPENAI_API_KEY = form_data.tts.OPENAI_API_KEY + request.app.state.config.TTS_API_KEY = form_data.tts.API_KEY + request.app.state.config.TTS_ENGINE = form_data.tts.ENGINE + request.app.state.config.TTS_MODEL = form_data.tts.MODEL + request.app.state.config.TTS_VOICE = form_data.tts.VOICE + request.app.state.config.TTS_SPLIT_ON = form_data.tts.SPLIT_ON + request.app.state.config.TTS_AZURE_SPEECH_REGION = form_data.tts.AZURE_SPEECH_REGION + request.app.state.config.TTS_AZURE_SPEECH_OUTPUT_FORMAT = ( + form_data.tts.AZURE_SPEECH_OUTPUT_FORMAT + ) + + request.app.state.config.STT_OPENAI_API_BASE_URL = form_data.stt.OPENAI_API_BASE_URL + request.app.state.config.STT_OPENAI_API_KEY = form_data.stt.OPENAI_API_KEY + request.app.state.config.STT_ENGINE = form_data.stt.ENGINE + request.app.state.config.STT_MODEL = form_data.stt.MODEL + request.app.state.config.WHISPER_MODEL = form_data.stt.WHISPER_MODEL + request.app.state.config.DEEPGRAM_API_KEY = form_data.stt.DEEPGRAM_API_KEY + + if request.app.state.config.STT_ENGINE == "": + request.app.state.faster_whisper_model = set_faster_whisper_model( + form_data.stt.WHISPER_MODEL, WHISPER_MODEL_AUTO_UPDATE + ) + + return { + "tts": { + "OPENAI_API_BASE_URL": request.app.state.config.TTS_OPENAI_API_BASE_URL, + "OPENAI_API_KEY": request.app.state.config.TTS_OPENAI_API_KEY, + "API_KEY": request.app.state.config.TTS_API_KEY, + "ENGINE": request.app.state.config.TTS_ENGINE, + "MODEL": request.app.state.config.TTS_MODEL, + "VOICE": request.app.state.config.TTS_VOICE, + "SPLIT_ON": request.app.state.config.TTS_SPLIT_ON, + "AZURE_SPEECH_REGION": request.app.state.config.TTS_AZURE_SPEECH_REGION, + "AZURE_SPEECH_OUTPUT_FORMAT": request.app.state.config.TTS_AZURE_SPEECH_OUTPUT_FORMAT, + }, + "stt": { + "OPENAI_API_BASE_URL": request.app.state.config.STT_OPENAI_API_BASE_URL, + "OPENAI_API_KEY": request.app.state.config.STT_OPENAI_API_KEY, + "ENGINE": request.app.state.config.STT_ENGINE, + "MODEL": request.app.state.config.STT_MODEL, + "WHISPER_MODEL": request.app.state.config.WHISPER_MODEL, + "DEEPGRAM_API_KEY": request.app.state.config.DEEPGRAM_API_KEY, + }, + } + + +def load_speech_pipeline(request): + from transformers import pipeline + from datasets import load_dataset + + if request.app.state.speech_synthesiser is None: + request.app.state.speech_synthesiser = pipeline( + "text-to-speech", "microsoft/speecht5_tts" + ) + + if request.app.state.speech_speaker_embeddings_dataset is None: + request.app.state.speech_speaker_embeddings_dataset = load_dataset( + "Matthijs/cmu-arctic-xvectors", split="validation" + ) + + +@router.post("/speech") +async def speech(request: Request, user=Depends(get_verified_user)): + body = await request.body() + name = hashlib.sha256( + body + + str(request.app.state.config.TTS_ENGINE).encode("utf-8") + + str(request.app.state.config.TTS_MODEL).encode("utf-8") + ).hexdigest() + + file_path = SPEECH_CACHE_DIR.joinpath(f"{name}.mp3") + file_body_path = SPEECH_CACHE_DIR.joinpath(f"{name}.json") + + # Check if the file already exists in the cache + if file_path.is_file(): + return FileResponse(file_path) + + payload = None + try: + payload = json.loads(body.decode("utf-8")) + except Exception as e: + log.exception(e) + raise HTTPException(status_code=400, detail="Invalid JSON payload") + + if request.app.state.config.TTS_ENGINE == "openai": + payload["model"] = request.app.state.config.TTS_MODEL + + try: + timeout = aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT) + async with aiohttp.ClientSession( + timeout=timeout, trust_env=True + ) as session: + async with session.post( + url=f"{request.app.state.config.TTS_OPENAI_API_BASE_URL}/audio/speech", + json=payload, + headers={ + "Content-Type": "application/json", + "Authorization": f"Bearer {request.app.state.config.TTS_OPENAI_API_KEY}", + **( + { + "X-OpenWebUI-User-Name": user.name, + "X-OpenWebUI-User-Id": user.id, + "X-OpenWebUI-User-Email": user.email, + "X-OpenWebUI-User-Role": user.role, + } + if ENABLE_FORWARD_USER_INFO_HEADERS + else {} + ), + }, + ) as r: + r.raise_for_status() + + async with aiofiles.open(file_path, "wb") as f: + await f.write(await r.read()) + + async with aiofiles.open(file_body_path, "w") as f: + await f.write(json.dumps(payload)) + + return FileResponse(file_path) + + except Exception as e: + log.exception(e) + detail = None + + try: + if r.status != 200: + res = await r.json() + + if "error" in res: + detail = f"External: {res['error'].get('message', '')}" + except Exception: + detail = f"External: {e}" + + raise HTTPException( + status_code=getattr(r, "status", 500), + detail=detail if detail else "Open WebUI: Server Connection Error", + ) + + elif request.app.state.config.TTS_ENGINE == "elevenlabs": + voice_id = payload.get("voice", "") + + if voice_id not in get_available_voices(request): + raise HTTPException( + status_code=400, + detail="Invalid voice id", + ) + + try: + timeout = aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT) + async with aiohttp.ClientSession( + timeout=timeout, trust_env=True + ) as session: + async with session.post( + f"https://api.elevenlabs.io/v1/text-to-speech/{voice_id}", + json={ + "text": payload["input"], + "model_id": request.app.state.config.TTS_MODEL, + "voice_settings": {"stability": 0.5, "similarity_boost": 0.5}, + }, + headers={ + "Accept": "audio/mpeg", + "Content-Type": "application/json", + "xi-api-key": request.app.state.config.TTS_API_KEY, + }, + ) as r: + r.raise_for_status() + + async with aiofiles.open(file_path, "wb") as f: + await f.write(await r.read()) + + async with aiofiles.open(file_body_path, "w") as f: + await f.write(json.dumps(payload)) + + return FileResponse(file_path) + + except Exception as e: + log.exception(e) + detail = None + + try: + if r.status != 200: + res = await r.json() + if "error" in res: + detail = f"External: {res['error'].get('message', '')}" + except Exception: + detail = f"External: {e}" + + raise HTTPException( + status_code=getattr(r, "status", 500), + detail=detail if detail else "Open WebUI: Server Connection Error", + ) + + elif request.app.state.config.TTS_ENGINE == "azure": + try: + payload = json.loads(body.decode("utf-8")) + except Exception as e: + log.exception(e) + raise HTTPException(status_code=400, detail="Invalid JSON payload") + + region = request.app.state.config.TTS_AZURE_SPEECH_REGION + language = request.app.state.config.TTS_VOICE + locale = "-".join(request.app.state.config.TTS_VOICE.split("-")[:1]) + output_format = request.app.state.config.TTS_AZURE_SPEECH_OUTPUT_FORMAT + + try: + data = f""" + {payload["input"]} + """ + timeout = aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT) + async with aiohttp.ClientSession( + timeout=timeout, trust_env=True + ) as session: + async with session.post( + f"https://{region}.tts.speech.microsoft.com/cognitiveservices/v1", + headers={ + "Ocp-Apim-Subscription-Key": request.app.state.config.TTS_API_KEY, + "Content-Type": "application/ssml+xml", + "X-Microsoft-OutputFormat": output_format, + }, + data=data, + ) as r: + r.raise_for_status() + + async with aiofiles.open(file_path, "wb") as f: + await f.write(await r.read()) + + async with aiofiles.open(file_body_path, "w") as f: + await f.write(json.dumps(payload)) + + return FileResponse(file_path) + + except Exception as e: + log.exception(e) + detail = None + + try: + if r.status != 200: + res = await r.json() + if "error" in res: + detail = f"External: {res['error'].get('message', '')}" + except Exception: + detail = f"External: {e}" + + raise HTTPException( + status_code=getattr(r, "status", 500), + detail=detail if detail else "Open WebUI: Server Connection Error", + ) + + elif request.app.state.config.TTS_ENGINE == "transformers": + payload = None + try: + payload = json.loads(body.decode("utf-8")) + except Exception as e: + log.exception(e) + raise HTTPException(status_code=400, detail="Invalid JSON payload") + + import torch + import soundfile as sf + + load_speech_pipeline(request) + + embeddings_dataset = request.app.state.speech_speaker_embeddings_dataset + + speaker_index = 6799 + try: + speaker_index = embeddings_dataset["filename"].index( + request.app.state.config.TTS_MODEL + ) + except Exception: + pass + + speaker_embedding = torch.tensor( + embeddings_dataset[speaker_index]["xvector"] + ).unsqueeze(0) + + speech = request.app.state.speech_synthesiser( + payload["input"], + forward_params={"speaker_embeddings": speaker_embedding}, + ) + + sf.write(file_path, speech["audio"], samplerate=speech["sampling_rate"]) + + async with aiofiles.open(file_body_path, "w") as f: + await f.write(json.dumps(payload)) + + return FileResponse(file_path) + + +def transcribe(request: Request, file_path): + log.info(f"transcribe: {file_path}") + filename = os.path.basename(file_path) + file_dir = os.path.dirname(file_path) + id = filename.split(".")[0] + + if request.app.state.config.STT_ENGINE == "": + if request.app.state.faster_whisper_model is None: + request.app.state.faster_whisper_model = set_faster_whisper_model( + request.app.state.config.WHISPER_MODEL + ) + + model = request.app.state.faster_whisper_model + segments, info = model.transcribe(file_path, beam_size=5) + log.info( + "Detected language '%s' with probability %f" + % (info.language, info.language_probability) + ) + + transcript = "".join([segment.text for segment in list(segments)]) + data = {"text": transcript.strip()} + + # save the transcript to a json file + transcript_file = f"{file_dir}/{id}.json" + with open(transcript_file, "w") as f: + json.dump(data, f) + + log.debug(data) + return data + elif request.app.state.config.STT_ENGINE == "openai": + if is_mp4_audio(file_path): + os.rename(file_path, file_path.replace(".wav", ".mp4")) + # Convert MP4 audio file to WAV format + convert_mp4_to_wav(file_path.replace(".wav", ".mp4"), file_path) + + r = None + try: + r = requests.post( + url=f"{request.app.state.config.STT_OPENAI_API_BASE_URL}/audio/transcriptions", + headers={ + "Authorization": f"Bearer {request.app.state.config.STT_OPENAI_API_KEY}" + }, + files={"file": (filename, open(file_path, "rb"))}, + data={"model": request.app.state.config.STT_MODEL}, + ) + + r.raise_for_status() + data = r.json() + + # save the transcript to a json file + transcript_file = f"{file_dir}/{id}.json" + with open(transcript_file, "w") as f: + json.dump(data, f) + + return data + except Exception as e: + log.exception(e) + + detail = None + if r is not None: + try: + res = r.json() + if "error" in res: + detail = f"External: {res['error'].get('message', '')}" + except Exception: + detail = f"External: {e}" + + raise Exception(detail if detail else "Open WebUI: Server Connection Error") + + elif request.app.state.config.STT_ENGINE == "deepgram": + try: + # Determine the MIME type of the file + mime, _ = mimetypes.guess_type(file_path) + if not mime: + mime = "audio/wav" # fallback to wav if undetectable + + # Read the audio file + with open(file_path, "rb") as f: + file_data = f.read() + + # Build headers and parameters + headers = { + "Authorization": f"Token {request.app.state.config.DEEPGRAM_API_KEY}", + "Content-Type": mime, + } + + # Add model if specified + params = {} + if request.app.state.config.STT_MODEL: + params["model"] = request.app.state.config.STT_MODEL + + # Make request to Deepgram API + r = requests.post( + "https://api.deepgram.com/v1/listen", + headers=headers, + params=params, + data=file_data, + ) + r.raise_for_status() + response_data = r.json() + + # Extract transcript from Deepgram response + try: + transcript = response_data["results"]["channels"][0]["alternatives"][ + 0 + ].get("transcript", "") + except (KeyError, IndexError) as e: + log.error(f"Malformed response from Deepgram: {str(e)}") + raise Exception( + "Failed to parse Deepgram response - unexpected response format" + ) + data = {"text": transcript.strip()} + + # Save transcript + transcript_file = f"{file_dir}/{id}.json" + with open(transcript_file, "w") as f: + json.dump(data, f) + + return data + + except Exception as e: + log.exception(e) + detail = None + if r is not None: + try: + res = r.json() + if "error" in res: + detail = f"External: {res['error'].get('message', '')}" + except Exception: + detail = f"External: {e}" + raise Exception(detail if detail else "Open WebUI: Server Connection Error") + + +def compress_audio(file_path): + if os.path.getsize(file_path) > MAX_FILE_SIZE: + file_dir = os.path.dirname(file_path) + audio = AudioSegment.from_file(file_path) + audio = audio.set_frame_rate(16000).set_channels(1) # Compress audio + compressed_path = f"{file_dir}/{id}_compressed.opus" + audio.export(compressed_path, format="opus", bitrate="32k") + log.debug(f"Compressed audio to {compressed_path}") + + if ( + os.path.getsize(compressed_path) > MAX_FILE_SIZE + ): # Still larger than MAX_FILE_SIZE after compression + raise Exception(ERROR_MESSAGES.FILE_TOO_LARGE(size=f"{MAX_FILE_SIZE_MB}MB")) + return compressed_path + else: + return file_path + + +@router.post("/transcriptions") +def transcription( + request: Request, + file: UploadFile = File(...), + user=Depends(get_verified_user), +): + log.info(f"file.content_type: {file.content_type}") + + if file.content_type not in ["audio/mpeg", "audio/wav", "audio/ogg", "audio/x-m4a"]: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.FILE_NOT_SUPPORTED, + ) + + try: + ext = file.filename.split(".")[-1] + id = uuid.uuid4() + + filename = f"{id}.{ext}" + contents = file.file.read() + + file_dir = f"{CACHE_DIR}/audio/transcriptions" + os.makedirs(file_dir, exist_ok=True) + file_path = f"{file_dir}/{filename}" + + with open(file_path, "wb") as f: + f.write(contents) + + try: + try: + file_path = compress_audio(file_path) + except Exception as e: + log.exception(e) + + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT(e), + ) + + data = transcribe(request, file_path) + file_path = file_path.split("/")[-1] + return {**data, "filename": file_path} + except Exception as e: + log.exception(e) + + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT(e), + ) + + except Exception as e: + log.exception(e) + + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT(e), + ) + + +def get_available_models(request: Request) -> list[dict]: + available_models = [] + if request.app.state.config.TTS_ENGINE == "openai": + # Use custom endpoint if not using the official OpenAI API URL + if not request.app.state.config.TTS_OPENAI_API_BASE_URL.startswith( + "https://api.openai.com" + ): + try: + response = requests.get( + f"{request.app.state.config.TTS_OPENAI_API_BASE_URL}/audio/models" + ) + response.raise_for_status() + data = response.json() + available_models = data.get("models", []) + except Exception as e: + log.error(f"Error fetching models from custom endpoint: {str(e)}") + available_models = [{"id": "tts-1"}, {"id": "tts-1-hd"}] + else: + available_models = [{"id": "tts-1"}, {"id": "tts-1-hd"}] + elif request.app.state.config.TTS_ENGINE == "elevenlabs": + try: + response = requests.get( + "https://api.elevenlabs.io/v1/models", + headers={ + "xi-api-key": request.app.state.config.TTS_API_KEY, + "Content-Type": "application/json", + }, + timeout=5, + ) + response.raise_for_status() + models = response.json() + + available_models = [ + {"name": model["name"], "id": model["model_id"]} for model in models + ] + except requests.RequestException as e: + log.error(f"Error fetching voices: {str(e)}") + return available_models + + +@router.get("/models") +async def get_models(request: Request, user=Depends(get_verified_user)): + return {"models": get_available_models(request)} + + +def get_available_voices(request) -> dict: + """Returns {voice_id: voice_name} dict""" + available_voices = {} + if request.app.state.config.TTS_ENGINE == "openai": + # Use custom endpoint if not using the official OpenAI API URL + if not request.app.state.config.TTS_OPENAI_API_BASE_URL.startswith( + "https://api.openai.com" + ): + try: + response = requests.get( + f"{request.app.state.config.TTS_OPENAI_API_BASE_URL}/audio/voices" + ) + response.raise_for_status() + data = response.json() + voices_list = data.get("voices", []) + available_voices = {voice["id"]: voice["name"] for voice in voices_list} + except Exception as e: + log.error(f"Error fetching voices from custom endpoint: {str(e)}") + available_voices = { + "alloy": "alloy", + "echo": "echo", + "fable": "fable", + "onyx": "onyx", + "nova": "nova", + "shimmer": "shimmer", + } + else: + available_voices = { + "alloy": "alloy", + "echo": "echo", + "fable": "fable", + "onyx": "onyx", + "nova": "nova", + "shimmer": "shimmer", + } + elif request.app.state.config.TTS_ENGINE == "elevenlabs": + try: + available_voices = get_elevenlabs_voices( + api_key=request.app.state.config.TTS_API_KEY + ) + except Exception: + # Avoided @lru_cache with exception + pass + elif request.app.state.config.TTS_ENGINE == "azure": + try: + region = request.app.state.config.TTS_AZURE_SPEECH_REGION + url = f"https://{region}.tts.speech.microsoft.com/cognitiveservices/voices/list" + headers = { + "Ocp-Apim-Subscription-Key": request.app.state.config.TTS_API_KEY + } + + response = requests.get(url, headers=headers) + response.raise_for_status() + voices = response.json() + + for voice in voices: + available_voices[voice["ShortName"]] = ( + f"{voice['DisplayName']} ({voice['ShortName']})" + ) + except requests.RequestException as e: + log.error(f"Error fetching voices: {str(e)}") + + return available_voices + + +@lru_cache +def get_elevenlabs_voices(api_key: str) -> dict: + """ + Note, set the following in your .env file to use Elevenlabs: + AUDIO_TTS_ENGINE=elevenlabs + AUDIO_TTS_API_KEY=sk_... # Your Elevenlabs API key + AUDIO_TTS_VOICE=EXAVITQu4vr4xnSDxMaL # From https://api.elevenlabs.io/v1/voices + AUDIO_TTS_MODEL=eleven_multilingual_v2 + """ + + try: + # TODO: Add retries + response = requests.get( + "https://api.elevenlabs.io/v1/voices", + headers={ + "xi-api-key": api_key, + "Content-Type": "application/json", + }, + ) + response.raise_for_status() + voices_data = response.json() + + voices = {} + for voice in voices_data.get("voices", []): + voices[voice["voice_id"]] = voice["name"] + except requests.RequestException as e: + # Avoid @lru_cache with exception + log.error(f"Error fetching voices: {str(e)}") + raise RuntimeError(f"Error fetching voices: {str(e)}") + + return voices + + +@router.get("/voices") +async def get_voices(request: Request, user=Depends(get_verified_user)): + return { + "voices": [ + {"id": k, "name": v} for k, v in get_available_voices(request).items() + ] + } diff --git a/backend/open_webui/routers/auths.py b/backend/open_webui/routers/auths.py new file mode 100644 index 0000000..f01b5bd --- /dev/null +++ b/backend/open_webui/routers/auths.py @@ -0,0 +1,850 @@ +import re +import uuid +import time +import datetime +import logging +from aiohttp import ClientSession + +from open_webui.models.auths import ( + AddUserForm, + ApiKey, + Auths, + Token, + LdapForm, + SigninForm, + SigninResponse, + SignupForm, + UpdatePasswordForm, + UpdateProfileForm, + UserResponse, +) +from open_webui.models.users import Users + +from open_webui.constants import ERROR_MESSAGES, WEBHOOK_MESSAGES +from open_webui.env import ( + WEBUI_AUTH, + WEBUI_AUTH_TRUSTED_EMAIL_HEADER, + WEBUI_AUTH_TRUSTED_NAME_HEADER, + WEBUI_AUTH_COOKIE_SAME_SITE, + WEBUI_AUTH_COOKIE_SECURE, + SRC_LOG_LEVELS, +) +from fastapi import APIRouter, Depends, HTTPException, Request, status +from fastapi.responses import RedirectResponse, Response +from open_webui.config import OPENID_PROVIDER_URL, ENABLE_OAUTH_SIGNUP, ENABLE_LDAP +from pydantic import BaseModel +from open_webui.utils.misc import parse_duration, validate_email_format +from open_webui.utils.auth import ( + create_api_key, + create_token, + get_admin_user, + get_verified_user, + get_current_user, + get_password_hash, +) +from open_webui.utils.webhook import post_webhook +from open_webui.utils.access_control import get_permissions + +from typing import Optional, List + +from ssl import CERT_REQUIRED, PROTOCOL_TLS + +if ENABLE_LDAP.value: + from ldap3 import Server, Connection, NONE, Tls + from ldap3.utils.conv import escape_filter_chars + +router = APIRouter() + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MAIN"]) + +############################ +# GetSessionUser +############################ + + +class SessionUserResponse(Token, UserResponse): + expires_at: Optional[int] = None + permissions: Optional[dict] = None + + +@router.get("/", response_model=SessionUserResponse) +async def get_session_user( + request: Request, response: Response, user=Depends(get_current_user) +): + expires_delta = parse_duration(request.app.state.config.JWT_EXPIRES_IN) + expires_at = None + if expires_delta: + expires_at = int(time.time()) + int(expires_delta.total_seconds()) + + token = create_token( + data={"id": user.id}, + expires_delta=expires_delta, + ) + + datetime_expires_at = ( + datetime.datetime.fromtimestamp(expires_at, datetime.timezone.utc) + if expires_at + else None + ) + + # Set the cookie token + response.set_cookie( + key="token", + value=token, + expires=datetime_expires_at, + httponly=True, # Ensures the cookie is not accessible via JavaScript + samesite=WEBUI_AUTH_COOKIE_SAME_SITE, + secure=WEBUI_AUTH_COOKIE_SECURE, + ) + + user_permissions = get_permissions( + user.id, request.app.state.config.USER_PERMISSIONS + ) + + return { + "token": token, + "token_type": "Bearer", + "expires_at": expires_at, + "id": user.id, + "email": user.email, + "name": user.name, + "role": user.role, + "profile_image_url": user.profile_image_url, + "permissions": user_permissions, + } + + +############################ +# Update Profile +############################ + + +@router.post("/update/profile", response_model=UserResponse) +async def update_profile( + form_data: UpdateProfileForm, session_user=Depends(get_verified_user) +): + if session_user: + user = Users.update_user_by_id( + session_user.id, + {"profile_image_url": form_data.profile_image_url, "name": form_data.name}, + ) + if user: + return user + else: + raise HTTPException(400, detail=ERROR_MESSAGES.DEFAULT()) + else: + raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED) + + +############################ +# Update Password +############################ + + +@router.post("/update/password", response_model=bool) +async def update_password( + form_data: UpdatePasswordForm, session_user=Depends(get_current_user) +): + if WEBUI_AUTH_TRUSTED_EMAIL_HEADER: + raise HTTPException(400, detail=ERROR_MESSAGES.ACTION_PROHIBITED) + if session_user: + user = Auths.authenticate_user(session_user.email, form_data.password) + + if user: + hashed = get_password_hash(form_data.new_password) + return Auths.update_user_password_by_id(user.id, hashed) + else: + raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_PASSWORD) + else: + raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED) + + +############################ +# LDAP Authentication +############################ +@router.post("/ldap", response_model=SessionUserResponse) +async def ldap_auth(request: Request, response: Response, form_data: LdapForm): + ENABLE_LDAP = request.app.state.config.ENABLE_LDAP + LDAP_SERVER_LABEL = request.app.state.config.LDAP_SERVER_LABEL + LDAP_SERVER_HOST = request.app.state.config.LDAP_SERVER_HOST + LDAP_SERVER_PORT = request.app.state.config.LDAP_SERVER_PORT + LDAP_ATTRIBUTE_FOR_MAIL = request.app.state.config.LDAP_ATTRIBUTE_FOR_MAIL + LDAP_ATTRIBUTE_FOR_USERNAME = request.app.state.config.LDAP_ATTRIBUTE_FOR_USERNAME + LDAP_SEARCH_BASE = request.app.state.config.LDAP_SEARCH_BASE + LDAP_SEARCH_FILTERS = request.app.state.config.LDAP_SEARCH_FILTERS + LDAP_APP_DN = request.app.state.config.LDAP_APP_DN + LDAP_APP_PASSWORD = request.app.state.config.LDAP_APP_PASSWORD + LDAP_USE_TLS = request.app.state.config.LDAP_USE_TLS + LDAP_CA_CERT_FILE = request.app.state.config.LDAP_CA_CERT_FILE + LDAP_CIPHERS = ( + request.app.state.config.LDAP_CIPHERS + if request.app.state.config.LDAP_CIPHERS + else "ALL" + ) + + if not ENABLE_LDAP: + raise HTTPException(400, detail="LDAP authentication is not enabled") + + try: + tls = Tls( + validate=CERT_REQUIRED, + version=PROTOCOL_TLS, + ca_certs_file=LDAP_CA_CERT_FILE, + ciphers=LDAP_CIPHERS, + ) + except Exception as e: + log.error(f"An error occurred on TLS: {str(e)}") + raise HTTPException(400, detail=str(e)) + + try: + server = Server( + host=LDAP_SERVER_HOST, + port=LDAP_SERVER_PORT, + get_info=NONE, + use_ssl=LDAP_USE_TLS, + tls=tls, + ) + connection_app = Connection( + server, + LDAP_APP_DN, + LDAP_APP_PASSWORD, + auto_bind="NONE", + authentication="SIMPLE", + ) + if not connection_app.bind(): + raise HTTPException(400, detail="Application account bind failed") + + search_success = connection_app.search( + search_base=LDAP_SEARCH_BASE, + search_filter=f"(&({LDAP_ATTRIBUTE_FOR_USERNAME}={escape_filter_chars(form_data.user.lower())}){LDAP_SEARCH_FILTERS})", + attributes=[ + f"{LDAP_ATTRIBUTE_FOR_USERNAME}", + f"{LDAP_ATTRIBUTE_FOR_MAIL}", + "cn", + ], + ) + + if not search_success: + raise HTTPException(400, detail="User not found in the LDAP server") + + entry = connection_app.entries[0] + username = str(entry[f"{LDAP_ATTRIBUTE_FOR_USERNAME}"]).lower() + mail = str(entry[f"{LDAP_ATTRIBUTE_FOR_MAIL}"]) + if not mail or mail == "" or mail == "[]": + raise HTTPException(400, f"User {form_data.user} does not have mail.") + cn = str(entry["cn"]) + user_dn = entry.entry_dn + + if username == form_data.user.lower(): + connection_user = Connection( + server, + user_dn, + form_data.password, + auto_bind="NONE", + authentication="SIMPLE", + ) + if not connection_user.bind(): + raise HTTPException(400, f"Authentication failed for {form_data.user}") + + user = Users.get_user_by_email(mail) + if not user: + try: + user_count = Users.get_num_users() + + role = ( + "admin" + if user_count == 0 + else request.app.state.config.DEFAULT_USER_ROLE + ) + + user = Auths.insert_new_auth( + email=mail, password=str(uuid.uuid4()), name=cn, role=role + ) + + if not user: + raise HTTPException( + 500, detail=ERROR_MESSAGES.CREATE_USER_ERROR + ) + + except HTTPException: + raise + except Exception as err: + raise HTTPException(500, detail=ERROR_MESSAGES.DEFAULT(err)) + + user = Auths.authenticate_user_by_trusted_header(mail) + + if user: + token = create_token( + data={"id": user.id}, + expires_delta=parse_duration( + request.app.state.config.JWT_EXPIRES_IN + ), + ) + + # Set the cookie token + response.set_cookie( + key="token", + value=token, + httponly=True, # Ensures the cookie is not accessible via JavaScript + ) + + user_permissions = get_permissions( + user.id, request.app.state.config.USER_PERMISSIONS + ) + + return { + "token": token, + "token_type": "Bearer", + "id": user.id, + "email": user.email, + "name": user.name, + "role": user.role, + "profile_image_url": user.profile_image_url, + "permissions": user_permissions, + } + else: + raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED) + else: + raise HTTPException( + 400, + f"User {form_data.user} does not match the record. Search result: {str(entry[f'{LDAP_ATTRIBUTE_FOR_USERNAME}'])}", + ) + except Exception as e: + raise HTTPException(400, detail=str(e)) + + +############################ +# SignIn +############################ + + +@router.post("/signin", response_model=SessionUserResponse) +async def signin(request: Request, response: Response, form_data: SigninForm): + if WEBUI_AUTH_TRUSTED_EMAIL_HEADER: + if WEBUI_AUTH_TRUSTED_EMAIL_HEADER not in request.headers: + raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_TRUSTED_HEADER) + + trusted_email = request.headers[WEBUI_AUTH_TRUSTED_EMAIL_HEADER].lower() + trusted_name = trusted_email + if WEBUI_AUTH_TRUSTED_NAME_HEADER: + trusted_name = request.headers.get( + WEBUI_AUTH_TRUSTED_NAME_HEADER, trusted_email + ) + if not Users.get_user_by_email(trusted_email.lower()): + await signup( + request, + response, + SignupForm( + email=trusted_email, password=str(uuid.uuid4()), name=trusted_name + ), + ) + user = Auths.authenticate_user_by_trusted_header(trusted_email) + elif WEBUI_AUTH == False: + admin_email = "admin@localhost" + admin_password = "admin" + + if Users.get_user_by_email(admin_email.lower()): + user = Auths.authenticate_user(admin_email.lower(), admin_password) + else: + if Users.get_num_users() != 0: + raise HTTPException(400, detail=ERROR_MESSAGES.EXISTING_USERS) + + await signup( + request, + response, + SignupForm(email=admin_email, password=admin_password, name="User"), + ) + + user = Auths.authenticate_user(admin_email.lower(), admin_password) + else: + user = Auths.authenticate_user(form_data.email.lower(), form_data.password) + + if user: + + expires_delta = parse_duration(request.app.state.config.JWT_EXPIRES_IN) + expires_at = None + if expires_delta: + expires_at = int(time.time()) + int(expires_delta.total_seconds()) + + token = create_token( + data={"id": user.id}, + expires_delta=expires_delta, + ) + + datetime_expires_at = ( + datetime.datetime.fromtimestamp(expires_at, datetime.timezone.utc) + if expires_at + else None + ) + + # Set the cookie token + response.set_cookie( + key="token", + value=token, + expires=datetime_expires_at, + httponly=True, # Ensures the cookie is not accessible via JavaScript + samesite=WEBUI_AUTH_COOKIE_SAME_SITE, + secure=WEBUI_AUTH_COOKIE_SECURE, + ) + + user_permissions = get_permissions( + user.id, request.app.state.config.USER_PERMISSIONS + ) + + return { + "token": token, + "token_type": "Bearer", + "expires_at": expires_at, + "id": user.id, + "email": user.email, + "name": user.name, + "role": user.role, + "profile_image_url": user.profile_image_url, + "permissions": user_permissions, + } + else: + raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED) + + +############################ +# SignUp +############################ + + +@router.post("/signup", response_model=SessionUserResponse) +async def signup(request: Request, response: Response, form_data: SignupForm): + + if WEBUI_AUTH: + if ( + not request.app.state.config.ENABLE_SIGNUP + or not request.app.state.config.ENABLE_LOGIN_FORM + ): + raise HTTPException( + status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.ACCESS_PROHIBITED + ) + else: + if Users.get_num_users() != 0: + raise HTTPException( + status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.ACCESS_PROHIBITED + ) + + user_count = Users.get_num_users() + if not validate_email_format(form_data.email.lower()): + raise HTTPException( + status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.INVALID_EMAIL_FORMAT + ) + + if Users.get_user_by_email(form_data.email.lower()): + raise HTTPException(400, detail=ERROR_MESSAGES.EMAIL_TAKEN) + + try: + role = ( + "admin" if user_count == 0 else request.app.state.config.DEFAULT_USER_ROLE + ) + + if user_count == 0: + # Disable signup after the first user is created + request.app.state.config.ENABLE_SIGNUP = False + + hashed = get_password_hash(form_data.password) + user = Auths.insert_new_auth( + form_data.email.lower(), + hashed, + form_data.name, + form_data.profile_image_url, + role, + ) + + if user: + expires_delta = parse_duration(request.app.state.config.JWT_EXPIRES_IN) + expires_at = None + if expires_delta: + expires_at = int(time.time()) + int(expires_delta.total_seconds()) + + token = create_token( + data={"id": user.id}, + expires_delta=expires_delta, + ) + + datetime_expires_at = ( + datetime.datetime.fromtimestamp(expires_at, datetime.timezone.utc) + if expires_at + else None + ) + + # Set the cookie token + response.set_cookie( + key="token", + value=token, + expires=datetime_expires_at, + httponly=True, # Ensures the cookie is not accessible via JavaScript + samesite=WEBUI_AUTH_COOKIE_SAME_SITE, + secure=WEBUI_AUTH_COOKIE_SECURE, + ) + + if request.app.state.config.WEBHOOK_URL: + post_webhook( + request.app.state.WEBUI_NAME, + request.app.state.config.WEBHOOK_URL, + WEBHOOK_MESSAGES.USER_SIGNUP(user.name), + { + "action": "signup", + "message": WEBHOOK_MESSAGES.USER_SIGNUP(user.name), + "user": user.model_dump_json(exclude_none=True), + }, + ) + + user_permissions = get_permissions( + user.id, request.app.state.config.USER_PERMISSIONS + ) + + return { + "token": token, + "token_type": "Bearer", + "expires_at": expires_at, + "id": user.id, + "email": user.email, + "name": user.name, + "role": user.role, + "profile_image_url": user.profile_image_url, + "permissions": user_permissions, + } + else: + raise HTTPException(500, detail=ERROR_MESSAGES.CREATE_USER_ERROR) + except Exception as err: + raise HTTPException(500, detail=ERROR_MESSAGES.DEFAULT(err)) + + +@router.get("/signout") +async def signout(request: Request, response: Response): + response.delete_cookie("token") + + if ENABLE_OAUTH_SIGNUP.value: + oauth_id_token = request.cookies.get("oauth_id_token") + if oauth_id_token: + try: + async with ClientSession() as session: + async with session.get(OPENID_PROVIDER_URL.value) as resp: + if resp.status == 200: + openid_data = await resp.json() + logout_url = openid_data.get("end_session_endpoint") + if logout_url: + response.delete_cookie("oauth_id_token") + return RedirectResponse( + headers=response.headers, + url=f"{logout_url}?id_token_hint={oauth_id_token}", + ) + else: + raise HTTPException( + status_code=resp.status, + detail="Failed to fetch OpenID configuration", + ) + except Exception as e: + raise HTTPException(status_code=500, detail=str(e)) + + return {"status": True} + + +############################ +# AddUser +############################ + + +@router.post("/add", response_model=SigninResponse) +async def add_user(form_data: AddUserForm, user=Depends(get_admin_user)): + if not validate_email_format(form_data.email.lower()): + raise HTTPException( + status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.INVALID_EMAIL_FORMAT + ) + + if Users.get_user_by_email(form_data.email.lower()): + raise HTTPException(400, detail=ERROR_MESSAGES.EMAIL_TAKEN) + + try: + hashed = get_password_hash(form_data.password) + user = Auths.insert_new_auth( + form_data.email.lower(), + hashed, + form_data.name, + form_data.profile_image_url, + form_data.role, + ) + + if user: + token = create_token(data={"id": user.id}) + return { + "token": token, + "token_type": "Bearer", + "id": user.id, + "email": user.email, + "name": user.name, + "role": user.role, + "profile_image_url": user.profile_image_url, + } + else: + raise HTTPException(500, detail=ERROR_MESSAGES.CREATE_USER_ERROR) + except Exception as err: + raise HTTPException(500, detail=ERROR_MESSAGES.DEFAULT(err)) + + +############################ +# GetAdminDetails +############################ + + +@router.get("/admin/details") +async def get_admin_details(request: Request, user=Depends(get_current_user)): + if request.app.state.config.SHOW_ADMIN_DETAILS: + admin_email = request.app.state.config.ADMIN_EMAIL + admin_name = None + + log.info(f"Admin details - Email: {admin_email}, Name: {admin_name}") + + if admin_email: + admin = Users.get_user_by_email(admin_email) + if admin: + admin_name = admin.name + else: + admin = Users.get_first_user() + if admin: + admin_email = admin.email + admin_name = admin.name + + return { + "name": admin_name, + "email": admin_email, + } + else: + raise HTTPException(400, detail=ERROR_MESSAGES.ACTION_PROHIBITED) + + +############################ +# ToggleSignUp +############################ + + +@router.get("/admin/config") +async def get_admin_config(request: Request, user=Depends(get_admin_user)): + return { + "SHOW_ADMIN_DETAILS": request.app.state.config.SHOW_ADMIN_DETAILS, + "WEBUI_URL": request.app.state.config.WEBUI_URL, + "ENABLE_SIGNUP": request.app.state.config.ENABLE_SIGNUP, + "ENABLE_API_KEY": request.app.state.config.ENABLE_API_KEY, + "ENABLE_API_KEY_ENDPOINT_RESTRICTIONS": request.app.state.config.ENABLE_API_KEY_ENDPOINT_RESTRICTIONS, + "API_KEY_ALLOWED_ENDPOINTS": request.app.state.config.API_KEY_ALLOWED_ENDPOINTS, + "ENABLE_CHANNELS": request.app.state.config.ENABLE_CHANNELS, + "DEFAULT_USER_ROLE": request.app.state.config.DEFAULT_USER_ROLE, + "JWT_EXPIRES_IN": request.app.state.config.JWT_EXPIRES_IN, + "ENABLE_COMMUNITY_SHARING": request.app.state.config.ENABLE_COMMUNITY_SHARING, + "ENABLE_MESSAGE_RATING": request.app.state.config.ENABLE_MESSAGE_RATING, + } + + +class AdminConfig(BaseModel): + SHOW_ADMIN_DETAILS: bool + WEBUI_URL: str + ENABLE_SIGNUP: bool + ENABLE_API_KEY: bool + ENABLE_API_KEY_ENDPOINT_RESTRICTIONS: bool + API_KEY_ALLOWED_ENDPOINTS: str + ENABLE_CHANNELS: bool + DEFAULT_USER_ROLE: str + JWT_EXPIRES_IN: str + ENABLE_COMMUNITY_SHARING: bool + ENABLE_MESSAGE_RATING: bool + + +@router.post("/admin/config") +async def update_admin_config( + request: Request, form_data: AdminConfig, user=Depends(get_admin_user) +): + request.app.state.config.SHOW_ADMIN_DETAILS = form_data.SHOW_ADMIN_DETAILS + request.app.state.config.WEBUI_URL = form_data.WEBUI_URL + request.app.state.config.ENABLE_SIGNUP = form_data.ENABLE_SIGNUP + + request.app.state.config.ENABLE_API_KEY = form_data.ENABLE_API_KEY + request.app.state.config.ENABLE_API_KEY_ENDPOINT_RESTRICTIONS = ( + form_data.ENABLE_API_KEY_ENDPOINT_RESTRICTIONS + ) + request.app.state.config.API_KEY_ALLOWED_ENDPOINTS = ( + form_data.API_KEY_ALLOWED_ENDPOINTS + ) + + request.app.state.config.ENABLE_CHANNELS = form_data.ENABLE_CHANNELS + + if form_data.DEFAULT_USER_ROLE in ["pending", "user", "admin"]: + request.app.state.config.DEFAULT_USER_ROLE = form_data.DEFAULT_USER_ROLE + + pattern = r"^(-1|0|(-?\d+(\.\d+)?)(ms|s|m|h|d|w))$" + + # Check if the input string matches the pattern + if re.match(pattern, form_data.JWT_EXPIRES_IN): + request.app.state.config.JWT_EXPIRES_IN = form_data.JWT_EXPIRES_IN + + request.app.state.config.ENABLE_COMMUNITY_SHARING = ( + form_data.ENABLE_COMMUNITY_SHARING + ) + request.app.state.config.ENABLE_MESSAGE_RATING = form_data.ENABLE_MESSAGE_RATING + + return { + "SHOW_ADMIN_DETAILS": request.app.state.config.SHOW_ADMIN_DETAILS, + "WEBUI_URL": request.app.state.config.WEBUI_URL, + "ENABLE_SIGNUP": request.app.state.config.ENABLE_SIGNUP, + "ENABLE_API_KEY": request.app.state.config.ENABLE_API_KEY, + "ENABLE_API_KEY_ENDPOINT_RESTRICTIONS": request.app.state.config.ENABLE_API_KEY_ENDPOINT_RESTRICTIONS, + "API_KEY_ALLOWED_ENDPOINTS": request.app.state.config.API_KEY_ALLOWED_ENDPOINTS, + "ENABLE_CHANNELS": request.app.state.config.ENABLE_CHANNELS, + "DEFAULT_USER_ROLE": request.app.state.config.DEFAULT_USER_ROLE, + "JWT_EXPIRES_IN": request.app.state.config.JWT_EXPIRES_IN, + "ENABLE_COMMUNITY_SHARING": request.app.state.config.ENABLE_COMMUNITY_SHARING, + "ENABLE_MESSAGE_RATING": request.app.state.config.ENABLE_MESSAGE_RATING, + } + + +class LdapServerConfig(BaseModel): + label: str + host: str + port: Optional[int] = None + attribute_for_mail: str = "mail" + attribute_for_username: str = "uid" + app_dn: str + app_dn_password: str + search_base: str + search_filters: str = "" + use_tls: bool = True + certificate_path: Optional[str] = None + ciphers: Optional[str] = "ALL" + + +@router.get("/admin/config/ldap/server", response_model=LdapServerConfig) +async def get_ldap_server(request: Request, user=Depends(get_admin_user)): + return { + "label": request.app.state.config.LDAP_SERVER_LABEL, + "host": request.app.state.config.LDAP_SERVER_HOST, + "port": request.app.state.config.LDAP_SERVER_PORT, + "attribute_for_mail": request.app.state.config.LDAP_ATTRIBUTE_FOR_MAIL, + "attribute_for_username": request.app.state.config.LDAP_ATTRIBUTE_FOR_USERNAME, + "app_dn": request.app.state.config.LDAP_APP_DN, + "app_dn_password": request.app.state.config.LDAP_APP_PASSWORD, + "search_base": request.app.state.config.LDAP_SEARCH_BASE, + "search_filters": request.app.state.config.LDAP_SEARCH_FILTERS, + "use_tls": request.app.state.config.LDAP_USE_TLS, + "certificate_path": request.app.state.config.LDAP_CA_CERT_FILE, + "ciphers": request.app.state.config.LDAP_CIPHERS, + } + + +@router.post("/admin/config/ldap/server") +async def update_ldap_server( + request: Request, form_data: LdapServerConfig, user=Depends(get_admin_user) +): + required_fields = [ + "label", + "host", + "attribute_for_mail", + "attribute_for_username", + "app_dn", + "app_dn_password", + "search_base", + ] + for key in required_fields: + value = getattr(form_data, key) + if not value: + raise HTTPException(400, detail=f"Required field {key} is empty") + + if form_data.use_tls and not form_data.certificate_path: + raise HTTPException( + 400, detail="TLS is enabled but certificate file path is missing" + ) + + request.app.state.config.LDAP_SERVER_LABEL = form_data.label + request.app.state.config.LDAP_SERVER_HOST = form_data.host + request.app.state.config.LDAP_SERVER_PORT = form_data.port + request.app.state.config.LDAP_ATTRIBUTE_FOR_MAIL = form_data.attribute_for_mail + request.app.state.config.LDAP_ATTRIBUTE_FOR_USERNAME = ( + form_data.attribute_for_username + ) + request.app.state.config.LDAP_APP_DN = form_data.app_dn + request.app.state.config.LDAP_APP_PASSWORD = form_data.app_dn_password + request.app.state.config.LDAP_SEARCH_BASE = form_data.search_base + request.app.state.config.LDAP_SEARCH_FILTERS = form_data.search_filters + request.app.state.config.LDAP_USE_TLS = form_data.use_tls + request.app.state.config.LDAP_CA_CERT_FILE = form_data.certificate_path + request.app.state.config.LDAP_CIPHERS = form_data.ciphers + + return { + "label": request.app.state.config.LDAP_SERVER_LABEL, + "host": request.app.state.config.LDAP_SERVER_HOST, + "port": request.app.state.config.LDAP_SERVER_PORT, + "attribute_for_mail": request.app.state.config.LDAP_ATTRIBUTE_FOR_MAIL, + "attribute_for_username": request.app.state.config.LDAP_ATTRIBUTE_FOR_USERNAME, + "app_dn": request.app.state.config.LDAP_APP_DN, + "app_dn_password": request.app.state.config.LDAP_APP_PASSWORD, + "search_base": request.app.state.config.LDAP_SEARCH_BASE, + "search_filters": request.app.state.config.LDAP_SEARCH_FILTERS, + "use_tls": request.app.state.config.LDAP_USE_TLS, + "certificate_path": request.app.state.config.LDAP_CA_CERT_FILE, + "ciphers": request.app.state.config.LDAP_CIPHERS, + } + + +@router.get("/admin/config/ldap") +async def get_ldap_config(request: Request, user=Depends(get_admin_user)): + return {"ENABLE_LDAP": request.app.state.config.ENABLE_LDAP} + + +class LdapConfigForm(BaseModel): + enable_ldap: Optional[bool] = None + + +@router.post("/admin/config/ldap") +async def update_ldap_config( + request: Request, form_data: LdapConfigForm, user=Depends(get_admin_user) +): + request.app.state.config.ENABLE_LDAP = form_data.enable_ldap + return {"ENABLE_LDAP": request.app.state.config.ENABLE_LDAP} + + +############################ +# API Key +############################ + + +# create api key +@router.post("/api_key", response_model=ApiKey) +async def generate_api_key(request: Request, user=Depends(get_current_user)): + if not request.app.state.config.ENABLE_API_KEY: + raise HTTPException( + status.HTTP_403_FORBIDDEN, + detail=ERROR_MESSAGES.API_KEY_CREATION_NOT_ALLOWED, + ) + + api_key = create_api_key() + success = Users.update_user_api_key_by_id(user.id, api_key) + + if success: + return { + "api_key": api_key, + } + else: + raise HTTPException(500, detail=ERROR_MESSAGES.CREATE_API_KEY_ERROR) + + +# delete api key +@router.delete("/api_key", response_model=bool) +async def delete_api_key(user=Depends(get_current_user)): + success = Users.update_user_api_key_by_id(user.id, None) + return success + + +# get api key +@router.get("/api_key", response_model=ApiKey) +async def get_api_key(user=Depends(get_current_user)): + api_key = Users.get_user_api_key_by_id(user.id) + if api_key: + return { + "api_key": api_key, + } + else: + raise HTTPException(404, detail=ERROR_MESSAGES.API_KEY_NOT_FOUND) diff --git a/backend/open_webui/routers/channels.py b/backend/open_webui/routers/channels.py new file mode 100644 index 0000000..6da3f04 --- /dev/null +++ b/backend/open_webui/routers/channels.py @@ -0,0 +1,712 @@ +import json +import logging +from typing import Optional + + +from fastapi import APIRouter, Depends, HTTPException, Request, status, BackgroundTasks +from pydantic import BaseModel + + +from open_webui.socket.main import sio, get_user_ids_from_room +from open_webui.models.users import Users, UserNameResponse + +from open_webui.models.channels import Channels, ChannelModel, ChannelForm +from open_webui.models.messages import ( + Messages, + MessageModel, + MessageResponse, + MessageForm, +) + + +from open_webui.config import ENABLE_ADMIN_CHAT_ACCESS, ENABLE_ADMIN_EXPORT +from open_webui.constants import ERROR_MESSAGES +from open_webui.env import SRC_LOG_LEVELS + + +from open_webui.utils.auth import get_admin_user, get_verified_user +from open_webui.utils.access_control import has_access, get_users_with_access +from open_webui.utils.webhook import post_webhook + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MODELS"]) + +router = APIRouter() + +############################ +# GetChatList +############################ + + +@router.get("/", response_model=list[ChannelModel]) +async def get_channels(user=Depends(get_verified_user)): + if user.role == "admin": + return Channels.get_channels() + else: + return Channels.get_channels_by_user_id(user.id) + + +############################ +# CreateNewChannel +############################ + + +@router.post("/create", response_model=Optional[ChannelModel]) +async def create_new_channel(form_data: ChannelForm, user=Depends(get_admin_user)): + try: + channel = Channels.insert_new_channel(None, form_data, user.id) + return ChannelModel(**channel.model_dump()) + except Exception as e: + log.exception(e) + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT() + ) + + +############################ +# GetChannelById +############################ + + +@router.get("/{id}", response_model=Optional[ChannelModel]) +async def get_channel_by_id(id: str, user=Depends(get_verified_user)): + channel = Channels.get_channel_by_id(id) + if not channel: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND + ) + + if user.role != "admin" and not has_access( + user.id, type="read", access_control=channel.access_control + ): + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.DEFAULT() + ) + + return ChannelModel(**channel.model_dump()) + + +############################ +# UpdateChannelById +############################ + + +@router.post("/{id}/update", response_model=Optional[ChannelModel]) +async def update_channel_by_id( + id: str, form_data: ChannelForm, user=Depends(get_admin_user) +): + channel = Channels.get_channel_by_id(id) + if not channel: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND + ) + + try: + channel = Channels.update_channel_by_id(id, form_data) + return ChannelModel(**channel.model_dump()) + except Exception as e: + log.exception(e) + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT() + ) + + +############################ +# DeleteChannelById +############################ + + +@router.delete("/{id}/delete", response_model=bool) +async def delete_channel_by_id(id: str, user=Depends(get_admin_user)): + channel = Channels.get_channel_by_id(id) + if not channel: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND + ) + + try: + Channels.delete_channel_by_id(id) + return True + except Exception as e: + log.exception(e) + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT() + ) + + +############################ +# GetChannelMessages +############################ + + +class MessageUserResponse(MessageResponse): + user: UserNameResponse + + +@router.get("/{id}/messages", response_model=list[MessageUserResponse]) +async def get_channel_messages( + id: str, skip: int = 0, limit: int = 50, user=Depends(get_verified_user) +): + channel = Channels.get_channel_by_id(id) + if not channel: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND + ) + + if user.role != "admin" and not has_access( + user.id, type="read", access_control=channel.access_control + ): + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.DEFAULT() + ) + + message_list = Messages.get_messages_by_channel_id(id, skip, limit) + users = {} + + messages = [] + for message in message_list: + if message.user_id not in users: + user = Users.get_user_by_id(message.user_id) + users[message.user_id] = user + + replies = Messages.get_replies_by_message_id(message.id) + latest_reply_at = replies[0].created_at if replies else None + + messages.append( + MessageUserResponse( + **{ + **message.model_dump(), + "reply_count": len(replies), + "latest_reply_at": latest_reply_at, + "reactions": Messages.get_reactions_by_message_id(message.id), + "user": UserNameResponse(**users[message.user_id].model_dump()), + } + ) + ) + + return messages + + +############################ +# PostNewMessage +############################ + + +async def send_notification(name, webui_url, channel, message, active_user_ids): + users = get_users_with_access("read", channel.access_control) + + for user in users: + if user.id in active_user_ids: + continue + else: + if user.settings: + webhook_url = user.settings.ui.get("notifications", {}).get( + "webhook_url", None + ) + + if webhook_url: + post_webhook( + name, + webhook_url, + f"#{channel.name} - {webui_url}/channels/{channel.id}\n\n{message.content}", + { + "action": "channel", + "message": message.content, + "title": channel.name, + "url": f"{webui_url}/channels/{channel.id}", + }, + ) + + +@router.post("/{id}/messages/post", response_model=Optional[MessageModel]) +async def post_new_message( + request: Request, + id: str, + form_data: MessageForm, + background_tasks: BackgroundTasks, + user=Depends(get_verified_user), +): + channel = Channels.get_channel_by_id(id) + if not channel: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND + ) + + if user.role != "admin" and not has_access( + user.id, type="read", access_control=channel.access_control + ): + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.DEFAULT() + ) + + try: + message = Messages.insert_new_message(form_data, channel.id, user.id) + + if message: + event_data = { + "channel_id": channel.id, + "message_id": message.id, + "data": { + "type": "message", + "data": MessageUserResponse( + **{ + **message.model_dump(), + "reply_count": 0, + "latest_reply_at": None, + "reactions": Messages.get_reactions_by_message_id( + message.id + ), + "user": UserNameResponse(**user.model_dump()), + } + ).model_dump(), + }, + "user": UserNameResponse(**user.model_dump()).model_dump(), + "channel": channel.model_dump(), + } + + await sio.emit( + "channel-events", + event_data, + to=f"channel:{channel.id}", + ) + + if message.parent_id: + # If this message is a reply, emit to the parent message as well + parent_message = Messages.get_message_by_id(message.parent_id) + + if parent_message: + await sio.emit( + "channel-events", + { + "channel_id": channel.id, + "message_id": parent_message.id, + "data": { + "type": "message:reply", + "data": MessageUserResponse( + **{ + **parent_message.model_dump(), + "user": UserNameResponse( + **Users.get_user_by_id( + parent_message.user_id + ).model_dump() + ), + } + ).model_dump(), + }, + "user": UserNameResponse(**user.model_dump()).model_dump(), + "channel": channel.model_dump(), + }, + to=f"channel:{channel.id}", + ) + + active_user_ids = get_user_ids_from_room(f"channel:{channel.id}") + + background_tasks.add_task( + send_notification, + request.app.state.WEBUI_NAME, + request.app.state.config.WEBUI_URL, + channel, + message, + active_user_ids, + ) + + return MessageModel(**message.model_dump()) + except Exception as e: + log.exception(e) + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT() + ) + + +############################ +# GetChannelMessage +############################ + + +@router.get("/{id}/messages/{message_id}", response_model=Optional[MessageUserResponse]) +async def get_channel_message( + id: str, message_id: str, user=Depends(get_verified_user) +): + channel = Channels.get_channel_by_id(id) + if not channel: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND + ) + + if user.role != "admin" and not has_access( + user.id, type="read", access_control=channel.access_control + ): + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.DEFAULT() + ) + + message = Messages.get_message_by_id(message_id) + if not message: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND + ) + + if message.channel_id != id: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT() + ) + + return MessageUserResponse( + **{ + **message.model_dump(), + "user": UserNameResponse( + **Users.get_user_by_id(message.user_id).model_dump() + ), + } + ) + + +############################ +# GetChannelThreadMessages +############################ + + +@router.get( + "/{id}/messages/{message_id}/thread", response_model=list[MessageUserResponse] +) +async def get_channel_thread_messages( + id: str, + message_id: str, + skip: int = 0, + limit: int = 50, + user=Depends(get_verified_user), +): + channel = Channels.get_channel_by_id(id) + if not channel: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND + ) + + if user.role != "admin" and not has_access( + user.id, type="read", access_control=channel.access_control + ): + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.DEFAULT() + ) + + message_list = Messages.get_messages_by_parent_id(id, message_id, skip, limit) + users = {} + + messages = [] + for message in message_list: + if message.user_id not in users: + user = Users.get_user_by_id(message.user_id) + users[message.user_id] = user + + messages.append( + MessageUserResponse( + **{ + **message.model_dump(), + "reply_count": 0, + "latest_reply_at": None, + "reactions": Messages.get_reactions_by_message_id(message.id), + "user": UserNameResponse(**users[message.user_id].model_dump()), + } + ) + ) + + return messages + + +############################ +# UpdateMessageById +############################ + + +@router.post( + "/{id}/messages/{message_id}/update", response_model=Optional[MessageModel] +) +async def update_message_by_id( + id: str, message_id: str, form_data: MessageForm, user=Depends(get_verified_user) +): + channel = Channels.get_channel_by_id(id) + if not channel: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND + ) + + if user.role != "admin" and not has_access( + user.id, type="read", access_control=channel.access_control + ): + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.DEFAULT() + ) + + message = Messages.get_message_by_id(message_id) + if not message: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND + ) + + if message.channel_id != id: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT() + ) + + try: + message = Messages.update_message_by_id(message_id, form_data) + message = Messages.get_message_by_id(message_id) + + if message: + await sio.emit( + "channel-events", + { + "channel_id": channel.id, + "message_id": message.id, + "data": { + "type": "message:update", + "data": MessageUserResponse( + **{ + **message.model_dump(), + "user": UserNameResponse( + **user.model_dump() + ).model_dump(), + } + ).model_dump(), + }, + "user": UserNameResponse(**user.model_dump()).model_dump(), + "channel": channel.model_dump(), + }, + to=f"channel:{channel.id}", + ) + + return MessageModel(**message.model_dump()) + except Exception as e: + log.exception(e) + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT() + ) + + +############################ +# AddReactionToMessage +############################ + + +class ReactionForm(BaseModel): + name: str + + +@router.post("/{id}/messages/{message_id}/reactions/add", response_model=bool) +async def add_reaction_to_message( + id: str, message_id: str, form_data: ReactionForm, user=Depends(get_verified_user) +): + channel = Channels.get_channel_by_id(id) + if not channel: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND + ) + + if user.role != "admin" and not has_access( + user.id, type="read", access_control=channel.access_control + ): + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.DEFAULT() + ) + + message = Messages.get_message_by_id(message_id) + if not message: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND + ) + + if message.channel_id != id: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT() + ) + + try: + Messages.add_reaction_to_message(message_id, user.id, form_data.name) + message = Messages.get_message_by_id(message_id) + + await sio.emit( + "channel-events", + { + "channel_id": channel.id, + "message_id": message.id, + "data": { + "type": "message:reaction:add", + "data": { + **message.model_dump(), + "user": UserNameResponse( + **Users.get_user_by_id(message.user_id).model_dump() + ).model_dump(), + "name": form_data.name, + }, + }, + "user": UserNameResponse(**user.model_dump()).model_dump(), + "channel": channel.model_dump(), + }, + to=f"channel:{channel.id}", + ) + + return True + except Exception as e: + log.exception(e) + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT() + ) + + +############################ +# RemoveReactionById +############################ + + +@router.post("/{id}/messages/{message_id}/reactions/remove", response_model=bool) +async def remove_reaction_by_id_and_user_id_and_name( + id: str, message_id: str, form_data: ReactionForm, user=Depends(get_verified_user) +): + channel = Channels.get_channel_by_id(id) + if not channel: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND + ) + + if user.role != "admin" and not has_access( + user.id, type="read", access_control=channel.access_control + ): + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.DEFAULT() + ) + + message = Messages.get_message_by_id(message_id) + if not message: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND + ) + + if message.channel_id != id: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT() + ) + + try: + Messages.remove_reaction_by_id_and_user_id_and_name( + message_id, user.id, form_data.name + ) + + message = Messages.get_message_by_id(message_id) + + await sio.emit( + "channel-events", + { + "channel_id": channel.id, + "message_id": message.id, + "data": { + "type": "message:reaction:remove", + "data": { + **message.model_dump(), + "user": UserNameResponse( + **Users.get_user_by_id(message.user_id).model_dump() + ).model_dump(), + "name": form_data.name, + }, + }, + "user": UserNameResponse(**user.model_dump()).model_dump(), + "channel": channel.model_dump(), + }, + to=f"channel:{channel.id}", + ) + + return True + except Exception as e: + log.exception(e) + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT() + ) + + +############################ +# DeleteMessageById +############################ + + +@router.delete("/{id}/messages/{message_id}/delete", response_model=bool) +async def delete_message_by_id( + id: str, message_id: str, user=Depends(get_verified_user) +): + channel = Channels.get_channel_by_id(id) + if not channel: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND + ) + + if user.role != "admin" and not has_access( + user.id, type="read", access_control=channel.access_control + ): + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.DEFAULT() + ) + + message = Messages.get_message_by_id(message_id) + if not message: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND + ) + + if message.channel_id != id: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT() + ) + + try: + Messages.delete_message_by_id(message_id) + await sio.emit( + "channel-events", + { + "channel_id": channel.id, + "message_id": message.id, + "data": { + "type": "message:delete", + "data": { + **message.model_dump(), + "user": UserNameResponse(**user.model_dump()).model_dump(), + }, + }, + "user": UserNameResponse(**user.model_dump()).model_dump(), + "channel": channel.model_dump(), + }, + to=f"channel:{channel.id}", + ) + + if message.parent_id: + # If this message is a reply, emit to the parent message as well + parent_message = Messages.get_message_by_id(message.parent_id) + + if parent_message: + await sio.emit( + "channel-events", + { + "channel_id": channel.id, + "message_id": parent_message.id, + "data": { + "type": "message:reply", + "data": MessageUserResponse( + **{ + **parent_message.model_dump(), + "user": UserNameResponse( + **Users.get_user_by_id( + parent_message.user_id + ).model_dump() + ), + } + ).model_dump(), + }, + "user": UserNameResponse(**user.model_dump()).model_dump(), + "channel": channel.model_dump(), + }, + to=f"channel:{channel.id}", + ) + + return True + except Exception as e: + log.exception(e) + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT() + ) diff --git a/backend/open_webui/routers/chats.py b/backend/open_webui/routers/chats.py new file mode 100644 index 0000000..2efd043 --- /dev/null +++ b/backend/open_webui/routers/chats.py @@ -0,0 +1,698 @@ +import json +import logging +from typing import Optional + +from open_webui.models.chats import ( + ChatForm, + ChatImportForm, + ChatResponse, + Chats, + ChatTitleIdResponse, +) +from open_webui.models.tags import TagModel, Tags +from open_webui.models.folders import Folders + +from open_webui.config import ENABLE_ADMIN_CHAT_ACCESS, ENABLE_ADMIN_EXPORT +from open_webui.constants import ERROR_MESSAGES +from open_webui.env import SRC_LOG_LEVELS +from fastapi import APIRouter, Depends, HTTPException, Request, status +from pydantic import BaseModel + + +from open_webui.utils.auth import get_admin_user, get_verified_user +from open_webui.utils.access_control import has_permission + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MODELS"]) + +router = APIRouter() + +############################ +# GetChatList +############################ + + +@router.get("/", response_model=list[ChatTitleIdResponse]) +@router.get("/list", response_model=list[ChatTitleIdResponse]) +async def get_session_user_chat_list( + user=Depends(get_verified_user), page: Optional[int] = None +): + if page is not None: + limit = 60 + skip = (page - 1) * limit + + return Chats.get_chat_title_id_list_by_user_id(user.id, skip=skip, limit=limit) + else: + return Chats.get_chat_title_id_list_by_user_id(user.id) + + +############################ +# DeleteAllChats +############################ + + +@router.delete("/", response_model=bool) +async def delete_all_user_chats(request: Request, user=Depends(get_verified_user)): + + if user.role == "user" and not has_permission( + user.id, "chat.delete", request.app.state.config.USER_PERMISSIONS + ): + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + ) + + result = Chats.delete_chats_by_user_id(user.id) + return result + + +############################ +# GetUserChatList +############################ + + +@router.get("/list/user/{user_id}", response_model=list[ChatTitleIdResponse]) +async def get_user_chat_list_by_user_id( + user_id: str, + user=Depends(get_admin_user), + skip: int = 0, + limit: int = 50, +): + if not ENABLE_ADMIN_CHAT_ACCESS: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + ) + return Chats.get_chat_list_by_user_id( + user_id, include_archived=True, skip=skip, limit=limit + ) + + +############################ +# CreateNewChat +############################ + + +@router.post("/new", response_model=Optional[ChatResponse]) +async def create_new_chat(form_data: ChatForm, user=Depends(get_verified_user)): + try: + chat = Chats.insert_new_chat(user.id, form_data) + return ChatResponse(**chat.model_dump()) + except Exception as e: + log.exception(e) + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT() + ) + + +############################ +# ImportChat +############################ + + +@router.post("/import", response_model=Optional[ChatResponse]) +async def import_chat(form_data: ChatImportForm, user=Depends(get_verified_user)): + try: + chat = Chats.import_chat(user.id, form_data) + if chat: + tags = chat.meta.get("tags", []) + for tag_id in tags: + tag_id = tag_id.replace(" ", "_").lower() + tag_name = " ".join([word.capitalize() for word in tag_id.split("_")]) + if ( + tag_id != "none" + and Tags.get_tag_by_name_and_user_id(tag_name, user.id) is None + ): + Tags.insert_new_tag(tag_name, user.id) + + return ChatResponse(**chat.model_dump()) + except Exception as e: + log.exception(e) + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT() + ) + + +############################ +# GetChats +############################ + + +@router.get("/search", response_model=list[ChatTitleIdResponse]) +async def search_user_chats( + text: str, page: Optional[int] = None, user=Depends(get_verified_user) +): + if page is None: + page = 1 + + limit = 60 + skip = (page - 1) * limit + + chat_list = [ + ChatTitleIdResponse(**chat.model_dump()) + for chat in Chats.get_chats_by_user_id_and_search_text( + user.id, text, skip=skip, limit=limit + ) + ] + + # Delete tag if no chat is found + words = text.strip().split(" ") + if page == 1 and len(words) == 1 and words[0].startswith("tag:"): + tag_id = words[0].replace("tag:", "") + if len(chat_list) == 0: + if Tags.get_tag_by_name_and_user_id(tag_id, user.id): + log.debug(f"deleting tag: {tag_id}") + Tags.delete_tag_by_name_and_user_id(tag_id, user.id) + + return chat_list + + +############################ +# GetChatsByFolderId +############################ + + +@router.get("/folder/{folder_id}", response_model=list[ChatResponse]) +async def get_chats_by_folder_id(folder_id: str, user=Depends(get_verified_user)): + folder_ids = [folder_id] + children_folders = Folders.get_children_folders_by_id_and_user_id( + folder_id, user.id + ) + if children_folders: + folder_ids.extend([folder.id for folder in children_folders]) + + return [ + ChatResponse(**chat.model_dump()) + for chat in Chats.get_chats_by_folder_ids_and_user_id(folder_ids, user.id) + ] + + +############################ +# GetPinnedChats +############################ + + +@router.get("/pinned", response_model=list[ChatResponse]) +async def get_user_pinned_chats(user=Depends(get_verified_user)): + return [ + ChatResponse(**chat.model_dump()) + for chat in Chats.get_pinned_chats_by_user_id(user.id) + ] + + +############################ +# GetChats +############################ + + +@router.get("/all", response_model=list[ChatResponse]) +async def get_user_chats(user=Depends(get_verified_user)): + return [ + ChatResponse(**chat.model_dump()) + for chat in Chats.get_chats_by_user_id(user.id) + ] + + +############################ +# GetArchivedChats +############################ + + +@router.get("/all/archived", response_model=list[ChatResponse]) +async def get_user_archived_chats(user=Depends(get_verified_user)): + return [ + ChatResponse(**chat.model_dump()) + for chat in Chats.get_archived_chats_by_user_id(user.id) + ] + + +############################ +# GetAllTags +############################ + + +@router.get("/all/tags", response_model=list[TagModel]) +async def get_all_user_tags(user=Depends(get_verified_user)): + try: + tags = Tags.get_tags_by_user_id(user.id) + return tags + except Exception as e: + log.exception(e) + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT() + ) + + +############################ +# GetAllChatsInDB +############################ + + +@router.get("/all/db", response_model=list[ChatResponse]) +async def get_all_user_chats_in_db(user=Depends(get_admin_user)): + if not ENABLE_ADMIN_EXPORT: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + ) + return [ChatResponse(**chat.model_dump()) for chat in Chats.get_chats()] + + +############################ +# GetArchivedChats +############################ + + +@router.get("/archived", response_model=list[ChatTitleIdResponse]) +async def get_archived_session_user_chat_list( + user=Depends(get_verified_user), skip: int = 0, limit: int = 50 +): + return Chats.get_archived_chat_list_by_user_id(user.id, skip, limit) + + +############################ +# ArchiveAllChats +############################ + + +@router.post("/archive/all", response_model=bool) +async def archive_all_chats(user=Depends(get_verified_user)): + return Chats.archive_all_chats_by_user_id(user.id) + + +############################ +# GetSharedChatById +############################ + + +@router.get("/share/{share_id}", response_model=Optional[ChatResponse]) +async def get_shared_chat_by_id(share_id: str, user=Depends(get_verified_user)): + if user.role == "pending": + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.NOT_FOUND + ) + + if user.role == "user" or (user.role == "admin" and not ENABLE_ADMIN_CHAT_ACCESS): + chat = Chats.get_chat_by_share_id(share_id) + elif user.role == "admin" and ENABLE_ADMIN_CHAT_ACCESS: + chat = Chats.get_chat_by_id(share_id) + + if chat: + return ChatResponse(**chat.model_dump()) + + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.NOT_FOUND + ) + + +############################ +# GetChatsByTags +############################ + + +class TagForm(BaseModel): + name: str + + +class TagFilterForm(TagForm): + skip: Optional[int] = 0 + limit: Optional[int] = 50 + + +@router.post("/tags", response_model=list[ChatTitleIdResponse]) +async def get_user_chat_list_by_tag_name( + form_data: TagFilterForm, user=Depends(get_verified_user) +): + chats = Chats.get_chat_list_by_user_id_and_tag_name( + user.id, form_data.name, form_data.skip, form_data.limit + ) + if len(chats) == 0: + Tags.delete_tag_by_name_and_user_id(form_data.name, user.id) + + return chats + + +############################ +# GetChatById +############################ + + +@router.get("/{id}", response_model=Optional[ChatResponse]) +async def get_chat_by_id(id: str, user=Depends(get_verified_user)): + chat = Chats.get_chat_by_id_and_user_id(id, user.id) + + if chat: + return ChatResponse(**chat.model_dump()) + + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.NOT_FOUND + ) + + +############################ +# UpdateChatById +############################ + + +@router.post("/{id}", response_model=Optional[ChatResponse]) +async def update_chat_by_id( + id: str, form_data: ChatForm, user=Depends(get_verified_user) +): + chat = Chats.get_chat_by_id_and_user_id(id, user.id) + if chat: + updated_chat = {**chat.chat, **form_data.chat} + chat = Chats.update_chat_by_id(id, updated_chat) + return ChatResponse(**chat.model_dump()) + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + ) + + +############################ +# DeleteChatById +############################ + + +@router.delete("/{id}", response_model=bool) +async def delete_chat_by_id(request: Request, id: str, user=Depends(get_verified_user)): + if user.role == "admin": + chat = Chats.get_chat_by_id(id) + for tag in chat.meta.get("tags", []): + if Chats.count_chats_by_tag_name_and_user_id(tag, user.id) == 1: + Tags.delete_tag_by_name_and_user_id(tag, user.id) + + result = Chats.delete_chat_by_id(id) + + return result + else: + if not has_permission( + user.id, "chat.delete", request.app.state.config.USER_PERMISSIONS + ): + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + ) + + chat = Chats.get_chat_by_id(id) + for tag in chat.meta.get("tags", []): + if Chats.count_chats_by_tag_name_and_user_id(tag, user.id) == 1: + Tags.delete_tag_by_name_and_user_id(tag, user.id) + + result = Chats.delete_chat_by_id_and_user_id(id, user.id) + return result + + +############################ +# GetPinnedStatusById +############################ + + +@router.get("/{id}/pinned", response_model=Optional[bool]) +async def get_pinned_status_by_id(id: str, user=Depends(get_verified_user)): + chat = Chats.get_chat_by_id_and_user_id(id, user.id) + if chat: + return chat.pinned + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.DEFAULT() + ) + + +############################ +# PinChatById +############################ + + +@router.post("/{id}/pin", response_model=Optional[ChatResponse]) +async def pin_chat_by_id(id: str, user=Depends(get_verified_user)): + chat = Chats.get_chat_by_id_and_user_id(id, user.id) + if chat: + chat = Chats.toggle_chat_pinned_by_id(id) + return chat + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.DEFAULT() + ) + + +############################ +# CloneChat +############################ + + +class CloneForm(BaseModel): + title: Optional[str] = None + + +@router.post("/{id}/clone", response_model=Optional[ChatResponse]) +async def clone_chat_by_id( + form_data: CloneForm, id: str, user=Depends(get_verified_user) +): + chat = Chats.get_chat_by_id_and_user_id(id, user.id) + if chat: + updated_chat = { + **chat.chat, + "originalChatId": chat.id, + "branchPointMessageId": chat.chat["history"]["currentId"], + "title": form_data.title if form_data.title else f"Clone of {chat.title}", + } + + chat = Chats.insert_new_chat(user.id, ChatForm(**{"chat": updated_chat})) + return ChatResponse(**chat.model_dump()) + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.DEFAULT() + ) + + +############################ +# CloneSharedChatById +############################ + + +@router.post("/{id}/clone/shared", response_model=Optional[ChatResponse]) +async def clone_shared_chat_by_id(id: str, user=Depends(get_verified_user)): + chat = Chats.get_chat_by_share_id(id) + if chat: + updated_chat = { + **chat.chat, + "originalChatId": chat.id, + "branchPointMessageId": chat.chat["history"]["currentId"], + "title": f"Clone of {chat.title}", + } + + chat = Chats.insert_new_chat(user.id, ChatForm(**{"chat": updated_chat})) + return ChatResponse(**chat.model_dump()) + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.DEFAULT() + ) + + +############################ +# ArchiveChat +############################ + + +@router.post("/{id}/archive", response_model=Optional[ChatResponse]) +async def archive_chat_by_id(id: str, user=Depends(get_verified_user)): + chat = Chats.get_chat_by_id_and_user_id(id, user.id) + if chat: + chat = Chats.toggle_chat_archive_by_id(id) + + # Delete tags if chat is archived + if chat.archived: + for tag_id in chat.meta.get("tags", []): + if Chats.count_chats_by_tag_name_and_user_id(tag_id, user.id) == 0: + log.debug(f"deleting tag: {tag_id}") + Tags.delete_tag_by_name_and_user_id(tag_id, user.id) + else: + for tag_id in chat.meta.get("tags", []): + tag = Tags.get_tag_by_name_and_user_id(tag_id, user.id) + if tag is None: + log.debug(f"inserting tag: {tag_id}") + tag = Tags.insert_new_tag(tag_id, user.id) + + return ChatResponse(**chat.model_dump()) + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.DEFAULT() + ) + + +############################ +# ShareChatById +############################ + + +@router.post("/{id}/share", response_model=Optional[ChatResponse]) +async def share_chat_by_id(id: str, user=Depends(get_verified_user)): + chat = Chats.get_chat_by_id_and_user_id(id, user.id) + if chat: + if chat.share_id: + shared_chat = Chats.update_shared_chat_by_chat_id(chat.id) + return ChatResponse(**shared_chat.model_dump()) + + shared_chat = Chats.insert_shared_chat_by_chat_id(chat.id) + if not shared_chat: + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=ERROR_MESSAGES.DEFAULT(), + ) + return ChatResponse(**shared_chat.model_dump()) + + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + ) + + +############################ +# DeletedSharedChatById +############################ + + +@router.delete("/{id}/share", response_model=Optional[bool]) +async def delete_shared_chat_by_id(id: str, user=Depends(get_verified_user)): + chat = Chats.get_chat_by_id_and_user_id(id, user.id) + if chat: + if not chat.share_id: + return False + + result = Chats.delete_shared_chat_by_chat_id(id) + update_result = Chats.update_chat_share_id_by_id(id, None) + + return result and update_result != None + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + ) + + +############################ +# UpdateChatFolderIdById +############################ + + +class ChatFolderIdForm(BaseModel): + folder_id: Optional[str] = None + + +@router.post("/{id}/folder", response_model=Optional[ChatResponse]) +async def update_chat_folder_id_by_id( + id: str, form_data: ChatFolderIdForm, user=Depends(get_verified_user) +): + chat = Chats.get_chat_by_id_and_user_id(id, user.id) + if chat: + chat = Chats.update_chat_folder_id_by_id_and_user_id( + id, user.id, form_data.folder_id + ) + return ChatResponse(**chat.model_dump()) + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.DEFAULT() + ) + + +############################ +# GetChatTagsById +############################ + + +@router.get("/{id}/tags", response_model=list[TagModel]) +async def get_chat_tags_by_id(id: str, user=Depends(get_verified_user)): + chat = Chats.get_chat_by_id_and_user_id(id, user.id) + if chat: + tags = chat.meta.get("tags", []) + return Tags.get_tags_by_ids_and_user_id(tags, user.id) + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.NOT_FOUND + ) + + +############################ +# AddChatTagById +############################ + + +@router.post("/{id}/tags", response_model=list[TagModel]) +async def add_tag_by_id_and_tag_name( + id: str, form_data: TagForm, user=Depends(get_verified_user) +): + chat = Chats.get_chat_by_id_and_user_id(id, user.id) + if chat: + tags = chat.meta.get("tags", []) + tag_id = form_data.name.replace(" ", "_").lower() + + if tag_id == "none": + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("Tag name cannot be 'None'"), + ) + + if tag_id not in tags: + Chats.add_chat_tag_by_id_and_user_id_and_tag_name( + id, user.id, form_data.name + ) + + chat = Chats.get_chat_by_id_and_user_id(id, user.id) + tags = chat.meta.get("tags", []) + return Tags.get_tags_by_ids_and_user_id(tags, user.id) + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.DEFAULT() + ) + + +############################ +# DeleteChatTagById +############################ + + +@router.delete("/{id}/tags", response_model=list[TagModel]) +async def delete_tag_by_id_and_tag_name( + id: str, form_data: TagForm, user=Depends(get_verified_user) +): + chat = Chats.get_chat_by_id_and_user_id(id, user.id) + if chat: + Chats.delete_tag_by_id_and_user_id_and_tag_name(id, user.id, form_data.name) + + if Chats.count_chats_by_tag_name_and_user_id(form_data.name, user.id) == 0: + Tags.delete_tag_by_name_and_user_id(form_data.name, user.id) + + chat = Chats.get_chat_by_id_and_user_id(id, user.id) + tags = chat.meta.get("tags", []) + return Tags.get_tags_by_ids_and_user_id(tags, user.id) + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.NOT_FOUND + ) + + +############################ +# DeleteAllTagsById +############################ + + +@router.delete("/{id}/tags/all", response_model=Optional[bool]) +async def delete_all_tags_by_id(id: str, user=Depends(get_verified_user)): + chat = Chats.get_chat_by_id_and_user_id(id, user.id) + if chat: + Chats.delete_all_tags_by_id_and_user_id(id, user.id) + + for tag in chat.meta.get("tags", []): + if Chats.count_chats_by_tag_name_and_user_id(tag, user.id) == 0: + Tags.delete_tag_by_name_and_user_id(tag, user.id) + + return True + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.NOT_FOUND + ) diff --git a/backend/open_webui/routers/configs.py b/backend/open_webui/routers/configs.py new file mode 100644 index 0000000..388c44f --- /dev/null +++ b/backend/open_webui/routers/configs.py @@ -0,0 +1,246 @@ +from fastapi import APIRouter, Depends, Request +from pydantic import BaseModel + +from typing import Optional + +from open_webui.utils.auth import get_admin_user, get_verified_user +from open_webui.config import get_config, save_config +from open_webui.config import BannerModel + + +router = APIRouter() + + +############################ +# ImportConfig +############################ + + +class ImportConfigForm(BaseModel): + config: dict + + +@router.post("/import", response_model=dict) +async def import_config(form_data: ImportConfigForm, user=Depends(get_admin_user)): + save_config(form_data.config) + return get_config() + + +############################ +# ExportConfig +############################ + + +@router.get("/export", response_model=dict) +async def export_config(user=Depends(get_admin_user)): + return get_config() + + +############################ +# Direct Connections Config +############################ + + +class DirectConnectionsConfigForm(BaseModel): + ENABLE_DIRECT_CONNECTIONS: bool + + +@router.get("/direct_connections", response_model=DirectConnectionsConfigForm) +async def get_direct_connections_config(request: Request, user=Depends(get_admin_user)): + return { + "ENABLE_DIRECT_CONNECTIONS": request.app.state.config.ENABLE_DIRECT_CONNECTIONS, + } + + +@router.post("/direct_connections", response_model=DirectConnectionsConfigForm) +async def set_direct_connections_config( + request: Request, + form_data: DirectConnectionsConfigForm, + user=Depends(get_admin_user), +): + request.app.state.config.ENABLE_DIRECT_CONNECTIONS = ( + form_data.ENABLE_DIRECT_CONNECTIONS + ) + return { + "ENABLE_DIRECT_CONNECTIONS": request.app.state.config.ENABLE_DIRECT_CONNECTIONS, + } + + +############################ +# CodeInterpreterConfig +############################ +class CodeInterpreterConfigForm(BaseModel): + CODE_EXECUTION_ENGINE: str + CODE_EXECUTION_JUPYTER_URL: Optional[str] + CODE_EXECUTION_JUPYTER_AUTH: Optional[str] + CODE_EXECUTION_JUPYTER_AUTH_TOKEN: Optional[str] + CODE_EXECUTION_JUPYTER_AUTH_PASSWORD: Optional[str] + CODE_EXECUTION_JUPYTER_TIMEOUT: Optional[int] + ENABLE_CODE_INTERPRETER: bool + CODE_INTERPRETER_ENGINE: str + CODE_INTERPRETER_PROMPT_TEMPLATE: Optional[str] + CODE_INTERPRETER_JUPYTER_URL: Optional[str] + CODE_INTERPRETER_JUPYTER_AUTH: Optional[str] + CODE_INTERPRETER_JUPYTER_AUTH_TOKEN: Optional[str] + CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD: Optional[str] + CODE_INTERPRETER_JUPYTER_TIMEOUT: Optional[int] + + +@router.get("/code_execution", response_model=CodeInterpreterConfigForm) +async def get_code_execution_config(request: Request, user=Depends(get_admin_user)): + return { + "CODE_EXECUTION_ENGINE": request.app.state.config.CODE_EXECUTION_ENGINE, + "CODE_EXECUTION_JUPYTER_URL": request.app.state.config.CODE_EXECUTION_JUPYTER_URL, + "CODE_EXECUTION_JUPYTER_AUTH": request.app.state.config.CODE_EXECUTION_JUPYTER_AUTH, + "CODE_EXECUTION_JUPYTER_AUTH_TOKEN": request.app.state.config.CODE_EXECUTION_JUPYTER_AUTH_TOKEN, + "CODE_EXECUTION_JUPYTER_AUTH_PASSWORD": request.app.state.config.CODE_EXECUTION_JUPYTER_AUTH_PASSWORD, + "CODE_EXECUTION_JUPYTER_TIMEOUT": request.app.state.config.CODE_EXECUTION_JUPYTER_TIMEOUT, + "ENABLE_CODE_INTERPRETER": request.app.state.config.ENABLE_CODE_INTERPRETER, + "CODE_INTERPRETER_ENGINE": request.app.state.config.CODE_INTERPRETER_ENGINE, + "CODE_INTERPRETER_PROMPT_TEMPLATE": request.app.state.config.CODE_INTERPRETER_PROMPT_TEMPLATE, + "CODE_INTERPRETER_JUPYTER_URL": request.app.state.config.CODE_INTERPRETER_JUPYTER_URL, + "CODE_INTERPRETER_JUPYTER_AUTH": request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH, + "CODE_INTERPRETER_JUPYTER_AUTH_TOKEN": request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_TOKEN, + "CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD": request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD, + "CODE_INTERPRETER_JUPYTER_TIMEOUT": request.app.state.config.CODE_INTERPRETER_JUPYTER_TIMEOUT, + } + + +@router.post("/code_execution", response_model=CodeInterpreterConfigForm) +async def set_code_execution_config( + request: Request, form_data: CodeInterpreterConfigForm, user=Depends(get_admin_user) +): + + request.app.state.config.CODE_EXECUTION_ENGINE = form_data.CODE_EXECUTION_ENGINE + request.app.state.config.CODE_EXECUTION_JUPYTER_URL = ( + form_data.CODE_EXECUTION_JUPYTER_URL + ) + request.app.state.config.CODE_EXECUTION_JUPYTER_AUTH = ( + form_data.CODE_EXECUTION_JUPYTER_AUTH + ) + request.app.state.config.CODE_EXECUTION_JUPYTER_AUTH_TOKEN = ( + form_data.CODE_EXECUTION_JUPYTER_AUTH_TOKEN + ) + request.app.state.config.CODE_EXECUTION_JUPYTER_AUTH_PASSWORD = ( + form_data.CODE_EXECUTION_JUPYTER_AUTH_PASSWORD + ) + request.app.state.config.CODE_EXECUTION_JUPYTER_TIMEOUT = ( + form_data.CODE_EXECUTION_JUPYTER_TIMEOUT + ) + + request.app.state.config.ENABLE_CODE_INTERPRETER = form_data.ENABLE_CODE_INTERPRETER + request.app.state.config.CODE_INTERPRETER_ENGINE = form_data.CODE_INTERPRETER_ENGINE + request.app.state.config.CODE_INTERPRETER_PROMPT_TEMPLATE = ( + form_data.CODE_INTERPRETER_PROMPT_TEMPLATE + ) + + request.app.state.config.CODE_INTERPRETER_JUPYTER_URL = ( + form_data.CODE_INTERPRETER_JUPYTER_URL + ) + + request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH = ( + form_data.CODE_INTERPRETER_JUPYTER_AUTH + ) + + request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_TOKEN = ( + form_data.CODE_INTERPRETER_JUPYTER_AUTH_TOKEN + ) + request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD = ( + form_data.CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD + ) + request.app.state.config.CODE_INTERPRETER_JUPYTER_TIMEOUT = ( + form_data.CODE_INTERPRETER_JUPYTER_TIMEOUT + ) + + return { + "CODE_EXECUTION_ENGINE": request.app.state.config.CODE_EXECUTION_ENGINE, + "CODE_EXECUTION_JUPYTER_URL": request.app.state.config.CODE_EXECUTION_JUPYTER_URL, + "CODE_EXECUTION_JUPYTER_AUTH": request.app.state.config.CODE_EXECUTION_JUPYTER_AUTH, + "CODE_EXECUTION_JUPYTER_AUTH_TOKEN": request.app.state.config.CODE_EXECUTION_JUPYTER_AUTH_TOKEN, + "CODE_EXECUTION_JUPYTER_AUTH_PASSWORD": request.app.state.config.CODE_EXECUTION_JUPYTER_AUTH_PASSWORD, + "CODE_EXECUTION_JUPYTER_TIMEOUT": request.app.state.config.CODE_EXECUTION_JUPYTER_TIMEOUT, + "ENABLE_CODE_INTERPRETER": request.app.state.config.ENABLE_CODE_INTERPRETER, + "CODE_INTERPRETER_ENGINE": request.app.state.config.CODE_INTERPRETER_ENGINE, + "CODE_INTERPRETER_PROMPT_TEMPLATE": request.app.state.config.CODE_INTERPRETER_PROMPT_TEMPLATE, + "CODE_INTERPRETER_JUPYTER_URL": request.app.state.config.CODE_INTERPRETER_JUPYTER_URL, + "CODE_INTERPRETER_JUPYTER_AUTH": request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH, + "CODE_INTERPRETER_JUPYTER_AUTH_TOKEN": request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_TOKEN, + "CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD": request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD, + "CODE_INTERPRETER_JUPYTER_TIMEOUT": request.app.state.config.CODE_INTERPRETER_JUPYTER_TIMEOUT, + } + + +############################ +# SetDefaultModels +############################ +class ModelsConfigForm(BaseModel): + DEFAULT_MODELS: Optional[str] + MODEL_ORDER_LIST: Optional[list[str]] + + +@router.get("/models", response_model=ModelsConfigForm) +async def get_models_config(request: Request, user=Depends(get_admin_user)): + return { + "DEFAULT_MODELS": request.app.state.config.DEFAULT_MODELS, + "MODEL_ORDER_LIST": request.app.state.config.MODEL_ORDER_LIST, + } + + +@router.post("/models", response_model=ModelsConfigForm) +async def set_models_config( + request: Request, form_data: ModelsConfigForm, user=Depends(get_admin_user) +): + request.app.state.config.DEFAULT_MODELS = form_data.DEFAULT_MODELS + request.app.state.config.MODEL_ORDER_LIST = form_data.MODEL_ORDER_LIST + return { + "DEFAULT_MODELS": request.app.state.config.DEFAULT_MODELS, + "MODEL_ORDER_LIST": request.app.state.config.MODEL_ORDER_LIST, + } + + +class PromptSuggestion(BaseModel): + title: list[str] + content: str + + +class SetDefaultSuggestionsForm(BaseModel): + suggestions: list[PromptSuggestion] + + +@router.post("/suggestions", response_model=list[PromptSuggestion]) +async def set_default_suggestions( + request: Request, + form_data: SetDefaultSuggestionsForm, + user=Depends(get_admin_user), +): + data = form_data.model_dump() + request.app.state.config.DEFAULT_PROMPT_SUGGESTIONS = data["suggestions"] + return request.app.state.config.DEFAULT_PROMPT_SUGGESTIONS + + +############################ +# SetBanners +############################ + + +class SetBannersForm(BaseModel): + banners: list[BannerModel] + + +@router.post("/banners", response_model=list[BannerModel]) +async def set_banners( + request: Request, + form_data: SetBannersForm, + user=Depends(get_admin_user), +): + data = form_data.model_dump() + request.app.state.config.BANNERS = data["banners"] + return request.app.state.config.BANNERS + + +@router.get("/banners", response_model=list[BannerModel]) +async def get_banners( + request: Request, + user=Depends(get_verified_user), +): + return request.app.state.config.BANNERS diff --git a/backend/open_webui/routers/evaluations.py b/backend/open_webui/routers/evaluations.py new file mode 100644 index 0000000..f0c4a6b --- /dev/null +++ b/backend/open_webui/routers/evaluations.py @@ -0,0 +1,159 @@ +from typing import Optional +from fastapi import APIRouter, Depends, HTTPException, status, Request +from pydantic import BaseModel + +from open_webui.models.users import Users, UserModel +from open_webui.models.feedbacks import ( + FeedbackModel, + FeedbackResponse, + FeedbackForm, + Feedbacks, +) + +from open_webui.constants import ERROR_MESSAGES +from open_webui.utils.auth import get_admin_user, get_verified_user + +router = APIRouter() + + +############################ +# GetConfig +############################ + + +@router.get("/config") +async def get_config(request: Request, user=Depends(get_admin_user)): + return { + "ENABLE_EVALUATION_ARENA_MODELS": request.app.state.config.ENABLE_EVALUATION_ARENA_MODELS, + "EVALUATION_ARENA_MODELS": request.app.state.config.EVALUATION_ARENA_MODELS, + } + + +############################ +# UpdateConfig +############################ + + +class UpdateConfigForm(BaseModel): + ENABLE_EVALUATION_ARENA_MODELS: Optional[bool] = None + EVALUATION_ARENA_MODELS: Optional[list[dict]] = None + + +@router.post("/config") +async def update_config( + request: Request, + form_data: UpdateConfigForm, + user=Depends(get_admin_user), +): + config = request.app.state.config + if form_data.ENABLE_EVALUATION_ARENA_MODELS is not None: + config.ENABLE_EVALUATION_ARENA_MODELS = form_data.ENABLE_EVALUATION_ARENA_MODELS + if form_data.EVALUATION_ARENA_MODELS is not None: + config.EVALUATION_ARENA_MODELS = form_data.EVALUATION_ARENA_MODELS + return { + "ENABLE_EVALUATION_ARENA_MODELS": config.ENABLE_EVALUATION_ARENA_MODELS, + "EVALUATION_ARENA_MODELS": config.EVALUATION_ARENA_MODELS, + } + + +class FeedbackUserResponse(FeedbackResponse): + user: Optional[UserModel] = None + + +@router.get("/feedbacks/all", response_model=list[FeedbackUserResponse]) +async def get_all_feedbacks(user=Depends(get_admin_user)): + feedbacks = Feedbacks.get_all_feedbacks() + return [ + FeedbackUserResponse( + **feedback.model_dump(), user=Users.get_user_by_id(feedback.user_id) + ) + for feedback in feedbacks + ] + + +@router.delete("/feedbacks/all") +async def delete_all_feedbacks(user=Depends(get_admin_user)): + success = Feedbacks.delete_all_feedbacks() + return success + + +@router.get("/feedbacks/all/export", response_model=list[FeedbackModel]) +async def get_all_feedbacks(user=Depends(get_admin_user)): + feedbacks = Feedbacks.get_all_feedbacks() + return [ + FeedbackModel( + **feedback.model_dump(), user=Users.get_user_by_id(feedback.user_id) + ) + for feedback in feedbacks + ] + + +@router.get("/feedbacks/user", response_model=list[FeedbackUserResponse]) +async def get_feedbacks(user=Depends(get_verified_user)): + feedbacks = Feedbacks.get_feedbacks_by_user_id(user.id) + return feedbacks + + +@router.delete("/feedbacks", response_model=bool) +async def delete_feedbacks(user=Depends(get_verified_user)): + success = Feedbacks.delete_feedbacks_by_user_id(user.id) + return success + + +@router.post("/feedback", response_model=FeedbackModel) +async def create_feedback( + request: Request, + form_data: FeedbackForm, + user=Depends(get_verified_user), +): + feedback = Feedbacks.insert_new_feedback(user_id=user.id, form_data=form_data) + if not feedback: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT(), + ) + + return feedback + + +@router.get("/feedback/{id}", response_model=FeedbackModel) +async def get_feedback_by_id(id: str, user=Depends(get_verified_user)): + feedback = Feedbacks.get_feedback_by_id_and_user_id(id=id, user_id=user.id) + + if not feedback: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND + ) + + return feedback + + +@router.post("/feedback/{id}", response_model=FeedbackModel) +async def update_feedback_by_id( + id: str, form_data: FeedbackForm, user=Depends(get_verified_user) +): + feedback = Feedbacks.update_feedback_by_id_and_user_id( + id=id, user_id=user.id, form_data=form_data + ) + + if not feedback: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND + ) + + return feedback + + +@router.delete("/feedback/{id}") +async def delete_feedback_by_id(id: str, user=Depends(get_verified_user)): + if user.role == "admin": + success = Feedbacks.delete_feedback_by_id(id=id) + else: + success = Feedbacks.delete_feedback_by_id_and_user_id(id=id, user_id=user.id) + + if not success: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND + ) + + return success diff --git a/backend/open_webui/routers/files.py b/backend/open_webui/routers/files.py new file mode 100644 index 0000000..95b7f64 --- /dev/null +++ b/backend/open_webui/routers/files.py @@ -0,0 +1,392 @@ +import logging +import os +import uuid +from pathlib import Path +from typing import Optional +from urllib.parse import quote + +from fastapi import APIRouter, Depends, File, HTTPException, Request, UploadFile, status +from fastapi.responses import FileResponse, StreamingResponse +from open_webui.constants import ERROR_MESSAGES +from open_webui.env import SRC_LOG_LEVELS +from open_webui.models.files import ( + FileForm, + FileModel, + FileModelResponse, + Files, +) +from open_webui.routers.retrieval import ProcessFileForm, process_file +from open_webui.routers.audio import transcribe +from open_webui.storage.provider import Storage +from open_webui.utils.auth import get_admin_user, get_verified_user +from pydantic import BaseModel + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MODELS"]) + + +router = APIRouter() + +############################ +# Upload File +############################ + + +@router.post("/", response_model=FileModelResponse) +def upload_file( + request: Request, + file: UploadFile = File(...), + user=Depends(get_verified_user), + file_metadata: dict = {}, +): + log.info(f"file.content_type: {file.content_type}") + try: + unsanitized_filename = file.filename + filename = os.path.basename(unsanitized_filename) + + # replace filename with uuid + id = str(uuid.uuid4()) + name = filename + filename = f"{id}_{filename}" + contents, file_path = Storage.upload_file(file.file, filename) + + file_item = Files.insert_new_file( + user.id, + FileForm( + **{ + "id": id, + "filename": name, + "path": file_path, + "meta": { + "name": name, + "content_type": file.content_type, + "size": len(contents), + "data": file_metadata, + }, + } + ), + ) + + try: + if file.content_type in [ + "audio/mpeg", + "audio/wav", + "audio/ogg", + "audio/x-m4a", + ]: + file_path = Storage.get_file(file_path) + result = transcribe(request, file_path) + process_file( + request, + ProcessFileForm(file_id=id, content=result.get("text", "")), + user=user, + ) + else: + process_file(request, ProcessFileForm(file_id=id), user=user) + + file_item = Files.get_file_by_id(id=id) + except Exception as e: + log.exception(e) + log.error(f"Error processing file: {file_item.id}") + file_item = FileModelResponse( + **{ + **file_item.model_dump(), + "error": str(e.detail) if hasattr(e, "detail") else str(e), + } + ) + + if file_item: + return file_item + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("Error uploading file"), + ) + + except Exception as e: + log.exception(e) + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT(e), + ) + + +############################ +# List Files +############################ + + +@router.get("/", response_model=list[FileModelResponse]) +async def list_files(user=Depends(get_verified_user)): + if user.role == "admin": + files = Files.get_files() + else: + files = Files.get_files_by_user_id(user.id) + return files + + +############################ +# Delete All Files +############################ + + +@router.delete("/all") +async def delete_all_files(user=Depends(get_admin_user)): + result = Files.delete_all_files() + if result: + try: + Storage.delete_all_files() + except Exception as e: + log.exception(e) + log.error("Error deleting files") + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("Error deleting files"), + ) + return {"message": "All files deleted successfully"} + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("Error deleting files"), + ) + + +############################ +# Get File By Id +############################ + + +@router.get("/{id}", response_model=Optional[FileModel]) +async def get_file_by_id(id: str, user=Depends(get_verified_user)): + file = Files.get_file_by_id(id) + + if file and (file.user_id == user.id or user.role == "admin"): + return file + else: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +############################ +# Get File Data Content By Id +############################ + + +@router.get("/{id}/data/content") +async def get_file_data_content_by_id(id: str, user=Depends(get_verified_user)): + file = Files.get_file_by_id(id) + + if file and (file.user_id == user.id or user.role == "admin"): + return {"content": file.data.get("content", "")} + else: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +############################ +# Update File Data Content By Id +############################ + + +class ContentForm(BaseModel): + content: str + + +@router.post("/{id}/data/content/update") +async def update_file_data_content_by_id( + request: Request, id: str, form_data: ContentForm, user=Depends(get_verified_user) +): + file = Files.get_file_by_id(id) + + if file and (file.user_id == user.id or user.role == "admin"): + try: + process_file( + request, + ProcessFileForm(file_id=id, content=form_data.content), + user=user, + ) + file = Files.get_file_by_id(id=id) + except Exception as e: + log.exception(e) + log.error(f"Error processing file: {file.id}") + + return {"content": file.data.get("content", "")} + else: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +############################ +# Get File Content By Id +############################ + + +@router.get("/{id}/content") +async def get_file_content_by_id(id: str, user=Depends(get_verified_user)): + file = Files.get_file_by_id(id) + if file and (file.user_id == user.id or user.role == "admin"): + try: + file_path = Storage.get_file(file.path) + file_path = Path(file_path) + + # Check if the file already exists in the cache + if file_path.is_file(): + # Handle Unicode filenames + filename = file.meta.get("name", file.filename) + encoded_filename = quote(filename) # RFC5987 encoding + + content_type = file.meta.get("content_type") + filename = file.meta.get("name", file.filename) + encoded_filename = quote(filename) + headers = {} + + if content_type == "application/pdf" or filename.lower().endswith( + ".pdf" + ): + headers["Content-Disposition"] = ( + f"inline; filename*=UTF-8''{encoded_filename}" + ) + content_type = "application/pdf" + elif content_type != "text/plain": + headers["Content-Disposition"] = ( + f"attachment; filename*=UTF-8''{encoded_filename}" + ) + + return FileResponse(file_path, headers=headers, media_type=content_type) + + else: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + except Exception as e: + log.exception(e) + log.error("Error getting file content") + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("Error getting file content"), + ) + else: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +@router.get("/{id}/content/html") +async def get_html_file_content_by_id(id: str, user=Depends(get_verified_user)): + file = Files.get_file_by_id(id) + if file and (file.user_id == user.id or user.role == "admin"): + try: + file_path = Storage.get_file(file.path) + file_path = Path(file_path) + + # Check if the file already exists in the cache + if file_path.is_file(): + log.info(f"file_path: {file_path}") + return FileResponse(file_path) + else: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + except Exception as e: + log.exception(e) + log.error("Error getting file content") + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("Error getting file content"), + ) + else: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +@router.get("/{id}/content/{file_name}") +async def get_file_content_by_id(id: str, user=Depends(get_verified_user)): + file = Files.get_file_by_id(id) + + if file and (file.user_id == user.id or user.role == "admin"): + file_path = file.path + + # Handle Unicode filenames + filename = file.meta.get("name", file.filename) + encoded_filename = quote(filename) # RFC5987 encoding + headers = { + "Content-Disposition": f"attachment; filename*=UTF-8''{encoded_filename}" + } + + if file_path: + file_path = Storage.get_file(file_path) + file_path = Path(file_path) + + # Check if the file already exists in the cache + if file_path.is_file(): + return FileResponse(file_path, headers=headers) + else: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + else: + # File path doesn’t exist, return the content as .txt if possible + file_content = file.content.get("content", "") + file_name = file.filename + + # Create a generator that encodes the file content + def generator(): + yield file_content.encode("utf-8") + + return StreamingResponse( + generator(), + media_type="text/plain", + headers=headers, + ) + else: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +############################ +# Delete File By Id +############################ + + +@router.delete("/{id}") +async def delete_file_by_id(id: str, user=Depends(get_verified_user)): + file = Files.get_file_by_id(id) + if file and (file.user_id == user.id or user.role == "admin"): + # We should add Chroma cleanup here + + result = Files.delete_file_by_id(id) + if result: + try: + Storage.delete_file(file.path) + except Exception as e: + log.exception(e) + log.error("Error deleting files") + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("Error deleting files"), + ) + return {"message": "File deleted successfully"} + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("Error deleting file"), + ) + else: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=ERROR_MESSAGES.NOT_FOUND, + ) diff --git a/backend/open_webui/routers/folders.py b/backend/open_webui/routers/folders.py new file mode 100644 index 0000000..ca2fbd2 --- /dev/null +++ b/backend/open_webui/routers/folders.py @@ -0,0 +1,251 @@ +import logging +import os +import shutil +import uuid +from pathlib import Path +from typing import Optional +from pydantic import BaseModel +import mimetypes + + +from open_webui.models.folders import ( + FolderForm, + FolderModel, + Folders, +) +from open_webui.models.chats import Chats + +from open_webui.config import UPLOAD_DIR +from open_webui.env import SRC_LOG_LEVELS +from open_webui.constants import ERROR_MESSAGES + + +from fastapi import APIRouter, Depends, File, HTTPException, UploadFile, status +from fastapi.responses import FileResponse, StreamingResponse + + +from open_webui.utils.auth import get_admin_user, get_verified_user + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MODELS"]) + + +router = APIRouter() + + +############################ +# Get Folders +############################ + + +@router.get("/", response_model=list[FolderModel]) +async def get_folders(user=Depends(get_verified_user)): + folders = Folders.get_folders_by_user_id(user.id) + + return [ + { + **folder.model_dump(), + "items": { + "chats": [ + {"title": chat.title, "id": chat.id} + for chat in Chats.get_chats_by_folder_id_and_user_id( + folder.id, user.id + ) + ] + }, + } + for folder in folders + ] + + +############################ +# Create Folder +############################ + + +@router.post("/") +def create_folder(form_data: FolderForm, user=Depends(get_verified_user)): + folder = Folders.get_folder_by_parent_id_and_user_id_and_name( + None, user.id, form_data.name + ) + + if folder: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("Folder already exists"), + ) + + try: + folder = Folders.insert_new_folder(user.id, form_data.name) + return folder + except Exception as e: + log.exception(e) + log.error("Error creating folder") + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("Error creating folder"), + ) + + +############################ +# Get Folders By Id +############################ + + +@router.get("/{id}", response_model=Optional[FolderModel]) +async def get_folder_by_id(id: str, user=Depends(get_verified_user)): + folder = Folders.get_folder_by_id_and_user_id(id, user.id) + if folder: + return folder + else: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +############################ +# Update Folder Name By Id +############################ + + +@router.post("/{id}/update") +async def update_folder_name_by_id( + id: str, form_data: FolderForm, user=Depends(get_verified_user) +): + folder = Folders.get_folder_by_id_and_user_id(id, user.id) + if folder: + existing_folder = Folders.get_folder_by_parent_id_and_user_id_and_name( + folder.parent_id, user.id, form_data.name + ) + if existing_folder: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("Folder already exists"), + ) + + try: + folder = Folders.update_folder_name_by_id_and_user_id( + id, user.id, form_data.name + ) + + return folder + except Exception as e: + log.exception(e) + log.error(f"Error updating folder: {id}") + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("Error updating folder"), + ) + else: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +############################ +# Update Folder Parent Id By Id +############################ + + +class FolderParentIdForm(BaseModel): + parent_id: Optional[str] = None + + +@router.post("/{id}/update/parent") +async def update_folder_parent_id_by_id( + id: str, form_data: FolderParentIdForm, user=Depends(get_verified_user) +): + folder = Folders.get_folder_by_id_and_user_id(id, user.id) + if folder: + existing_folder = Folders.get_folder_by_parent_id_and_user_id_and_name( + form_data.parent_id, user.id, folder.name + ) + + if existing_folder: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("Folder already exists"), + ) + + try: + folder = Folders.update_folder_parent_id_by_id_and_user_id( + id, user.id, form_data.parent_id + ) + return folder + except Exception as e: + log.exception(e) + log.error(f"Error updating folder: {id}") + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("Error updating folder"), + ) + else: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +############################ +# Update Folder Is Expanded By Id +############################ + + +class FolderIsExpandedForm(BaseModel): + is_expanded: bool + + +@router.post("/{id}/update/expanded") +async def update_folder_is_expanded_by_id( + id: str, form_data: FolderIsExpandedForm, user=Depends(get_verified_user) +): + folder = Folders.get_folder_by_id_and_user_id(id, user.id) + if folder: + try: + folder = Folders.update_folder_is_expanded_by_id_and_user_id( + id, user.id, form_data.is_expanded + ) + return folder + except Exception as e: + log.exception(e) + log.error(f"Error updating folder: {id}") + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("Error updating folder"), + ) + else: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +############################ +# Delete Folder By Id +############################ + + +@router.delete("/{id}") +async def delete_folder_by_id(id: str, user=Depends(get_verified_user)): + folder = Folders.get_folder_by_id_and_user_id(id, user.id) + if folder: + try: + result = Folders.delete_folder_by_id_and_user_id(id, user.id) + if result: + return result + else: + raise Exception("Error deleting folder") + except Exception as e: + log.exception(e) + log.error(f"Error deleting folder: {id}") + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("Error deleting folder"), + ) + else: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=ERROR_MESSAGES.NOT_FOUND, + ) diff --git a/backend/open_webui/routers/functions.py b/backend/open_webui/routers/functions.py new file mode 100644 index 0000000..ac2db93 --- /dev/null +++ b/backend/open_webui/routers/functions.py @@ -0,0 +1,411 @@ +import os +import logging +from pathlib import Path +from typing import Optional + +from open_webui.models.functions import ( + FunctionForm, + FunctionModel, + FunctionResponse, + Functions, +) +from open_webui.utils.plugin import load_function_module_by_id, replace_imports +from open_webui.config import CACHE_DIR +from open_webui.constants import ERROR_MESSAGES +from fastapi import APIRouter, Depends, HTTPException, Request, status +from open_webui.utils.auth import get_admin_user, get_verified_user +from open_webui.env import SRC_LOG_LEVELS + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MAIN"]) + + +router = APIRouter() + +############################ +# GetFunctions +############################ + + +@router.get("/", response_model=list[FunctionResponse]) +async def get_functions(user=Depends(get_verified_user)): + return Functions.get_functions() + + +############################ +# ExportFunctions +############################ + + +@router.get("/export", response_model=list[FunctionModel]) +async def get_functions(user=Depends(get_admin_user)): + return Functions.get_functions() + + +############################ +# CreateNewFunction +############################ + + +@router.post("/create", response_model=Optional[FunctionResponse]) +async def create_new_function( + request: Request, form_data: FunctionForm, user=Depends(get_admin_user) +): + if not form_data.id.isidentifier(): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="Only alphanumeric characters and underscores are allowed in the id", + ) + + form_data.id = form_data.id.lower() + + function = Functions.get_function_by_id(form_data.id) + if function is None: + try: + form_data.content = replace_imports(form_data.content) + function_module, function_type, frontmatter = load_function_module_by_id( + form_data.id, + content=form_data.content, + ) + form_data.meta.manifest = frontmatter + + FUNCTIONS = request.app.state.FUNCTIONS + FUNCTIONS[form_data.id] = function_module + + function = Functions.insert_new_function(user.id, function_type, form_data) + + function_cache_dir = Path(CACHE_DIR) / "functions" / form_data.id + function_cache_dir.mkdir(parents=True, exist_ok=True) + + if function: + return function + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("Error creating function"), + ) + except Exception as e: + log.exception(f"Failed to create a new function: {e}") + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT(e), + ) + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.ID_TAKEN, + ) + + +############################ +# GetFunctionById +############################ + + +@router.get("/id/{id}", response_model=Optional[FunctionModel]) +async def get_function_by_id(id: str, user=Depends(get_admin_user)): + function = Functions.get_function_by_id(id) + + if function: + return function + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +############################ +# ToggleFunctionById +############################ + + +@router.post("/id/{id}/toggle", response_model=Optional[FunctionModel]) +async def toggle_function_by_id(id: str, user=Depends(get_admin_user)): + function = Functions.get_function_by_id(id) + if function: + function = Functions.update_function_by_id( + id, {"is_active": not function.is_active} + ) + + if function: + return function + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("Error updating function"), + ) + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +############################ +# ToggleGlobalById +############################ + + +@router.post("/id/{id}/toggle/global", response_model=Optional[FunctionModel]) +async def toggle_global_by_id(id: str, user=Depends(get_admin_user)): + function = Functions.get_function_by_id(id) + if function: + function = Functions.update_function_by_id( + id, {"is_global": not function.is_global} + ) + + if function: + return function + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("Error updating function"), + ) + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +############################ +# UpdateFunctionById +############################ + + +@router.post("/id/{id}/update", response_model=Optional[FunctionModel]) +async def update_function_by_id( + request: Request, id: str, form_data: FunctionForm, user=Depends(get_admin_user) +): + try: + form_data.content = replace_imports(form_data.content) + function_module, function_type, frontmatter = load_function_module_by_id( + id, content=form_data.content + ) + form_data.meta.manifest = frontmatter + + FUNCTIONS = request.app.state.FUNCTIONS + FUNCTIONS[id] = function_module + + updated = {**form_data.model_dump(exclude={"id"}), "type": function_type} + log.debug(updated) + + function = Functions.update_function_by_id(id, updated) + + if function: + return function + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("Error updating function"), + ) + + except Exception as e: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT(e), + ) + + +############################ +# DeleteFunctionById +############################ + + +@router.delete("/id/{id}/delete", response_model=bool) +async def delete_function_by_id( + request: Request, id: str, user=Depends(get_admin_user) +): + result = Functions.delete_function_by_id(id) + + if result: + FUNCTIONS = request.app.state.FUNCTIONS + if id in FUNCTIONS: + del FUNCTIONS[id] + + return result + + +############################ +# GetFunctionValves +############################ + + +@router.get("/id/{id}/valves", response_model=Optional[dict]) +async def get_function_valves_by_id(id: str, user=Depends(get_admin_user)): + function = Functions.get_function_by_id(id) + if function: + try: + valves = Functions.get_function_valves_by_id(id) + return valves + except Exception as e: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT(e), + ) + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +############################ +# GetFunctionValvesSpec +############################ + + +@router.get("/id/{id}/valves/spec", response_model=Optional[dict]) +async def get_function_valves_spec_by_id( + request: Request, id: str, user=Depends(get_admin_user) +): + function = Functions.get_function_by_id(id) + if function: + if id in request.app.state.FUNCTIONS: + function_module = request.app.state.FUNCTIONS[id] + else: + function_module, function_type, frontmatter = load_function_module_by_id(id) + request.app.state.FUNCTIONS[id] = function_module + + if hasattr(function_module, "Valves"): + Valves = function_module.Valves + return Valves.schema() + return None + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +############################ +# UpdateFunctionValves +############################ + + +@router.post("/id/{id}/valves/update", response_model=Optional[dict]) +async def update_function_valves_by_id( + request: Request, id: str, form_data: dict, user=Depends(get_admin_user) +): + function = Functions.get_function_by_id(id) + if function: + if id in request.app.state.FUNCTIONS: + function_module = request.app.state.FUNCTIONS[id] + else: + function_module, function_type, frontmatter = load_function_module_by_id(id) + request.app.state.FUNCTIONS[id] = function_module + + if hasattr(function_module, "Valves"): + Valves = function_module.Valves + + try: + form_data = {k: v for k, v in form_data.items() if v is not None} + valves = Valves(**form_data) + Functions.update_function_valves_by_id(id, valves.model_dump()) + return valves.model_dump() + except Exception as e: + log.exception(f"Error updating function values by id {id}: {e}") + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT(e), + ) + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +############################ +# FunctionUserValves +############################ + + +@router.get("/id/{id}/valves/user", response_model=Optional[dict]) +async def get_function_user_valves_by_id(id: str, user=Depends(get_verified_user)): + function = Functions.get_function_by_id(id) + if function: + try: + user_valves = Functions.get_user_valves_by_id_and_user_id(id, user.id) + return user_valves + except Exception as e: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT(e), + ) + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +@router.get("/id/{id}/valves/user/spec", response_model=Optional[dict]) +async def get_function_user_valves_spec_by_id( + request: Request, id: str, user=Depends(get_verified_user) +): + function = Functions.get_function_by_id(id) + if function: + if id in request.app.state.FUNCTIONS: + function_module = request.app.state.FUNCTIONS[id] + else: + function_module, function_type, frontmatter = load_function_module_by_id(id) + request.app.state.FUNCTIONS[id] = function_module + + if hasattr(function_module, "UserValves"): + UserValves = function_module.UserValves + return UserValves.schema() + return None + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +@router.post("/id/{id}/valves/user/update", response_model=Optional[dict]) +async def update_function_user_valves_by_id( + request: Request, id: str, form_data: dict, user=Depends(get_verified_user) +): + function = Functions.get_function_by_id(id) + + if function: + if id in request.app.state.FUNCTIONS: + function_module = request.app.state.FUNCTIONS[id] + else: + function_module, function_type, frontmatter = load_function_module_by_id(id) + request.app.state.FUNCTIONS[id] = function_module + + if hasattr(function_module, "UserValves"): + UserValves = function_module.UserValves + + try: + form_data = {k: v for k, v in form_data.items() if v is not None} + user_valves = UserValves(**form_data) + Functions.update_user_valves_by_id_and_user_id( + id, user.id, user_valves.model_dump() + ) + return user_valves.model_dump() + except Exception as e: + log.exception(f"Error updating function user valves by id {id}: {e}") + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT(e), + ) + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) diff --git a/backend/open_webui/routers/groups.py b/backend/open_webui/routers/groups.py new file mode 100755 index 0000000..ae822c0 --- /dev/null +++ b/backend/open_webui/routers/groups.py @@ -0,0 +1,131 @@ +import os +from pathlib import Path +from typing import Optional +import logging + +from open_webui.models.users import Users +from open_webui.models.groups import ( + Groups, + GroupForm, + GroupUpdateForm, + GroupResponse, +) + +from open_webui.config import CACHE_DIR +from open_webui.constants import ERROR_MESSAGES +from fastapi import APIRouter, Depends, HTTPException, Request, status + +from open_webui.utils.auth import get_admin_user, get_verified_user +from open_webui.env import SRC_LOG_LEVELS + + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MAIN"]) + +router = APIRouter() + +############################ +# GetFunctions +############################ + + +@router.get("/", response_model=list[GroupResponse]) +async def get_groups(user=Depends(get_verified_user)): + if user.role == "admin": + return Groups.get_groups() + else: + return Groups.get_groups_by_member_id(user.id) + + +############################ +# CreateNewGroup +############################ + + +@router.post("/create", response_model=Optional[GroupResponse]) +async def create_new_group(form_data: GroupForm, user=Depends(get_admin_user)): + try: + group = Groups.insert_new_group(user.id, form_data) + if group: + return group + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("Error creating group"), + ) + except Exception as e: + log.exception(f"Error creating a new group: {e}") + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT(e), + ) + + +############################ +# GetGroupById +############################ + + +@router.get("/id/{id}", response_model=Optional[GroupResponse]) +async def get_group_by_id(id: str, user=Depends(get_admin_user)): + group = Groups.get_group_by_id(id) + if group: + return group + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +############################ +# UpdateGroupById +############################ + + +@router.post("/id/{id}/update", response_model=Optional[GroupResponse]) +async def update_group_by_id( + id: str, form_data: GroupUpdateForm, user=Depends(get_admin_user) +): + try: + if form_data.user_ids: + form_data.user_ids = Users.get_valid_user_ids(form_data.user_ids) + + group = Groups.update_group_by_id(id, form_data) + if group: + return group + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("Error updating group"), + ) + except Exception as e: + log.exception(f"Error updating group {id}: {e}") + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT(e), + ) + + +############################ +# DeleteGroupById +############################ + + +@router.delete("/id/{id}/delete", response_model=bool) +async def delete_group_by_id(id: str, user=Depends(get_admin_user)): + try: + result = Groups.delete_group_by_id(id) + if result: + return result + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("Error deleting group"), + ) + except Exception as e: + log.exception(f"Error deleting group {id}: {e}") + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT(e), + ) diff --git a/backend/open_webui/routers/images.py b/backend/open_webui/routers/images.py new file mode 100644 index 0000000..131fa2d --- /dev/null +++ b/backend/open_webui/routers/images.py @@ -0,0 +1,672 @@ +import asyncio +import base64 +import io +import json +import logging +import mimetypes +import re +from pathlib import Path +from typing import Optional + +import requests +from fastapi import APIRouter, Depends, HTTPException, Request, UploadFile +from open_webui.config import CACHE_DIR +from open_webui.constants import ERROR_MESSAGES +from open_webui.env import ENABLE_FORWARD_USER_INFO_HEADERS, SRC_LOG_LEVELS +from open_webui.routers.files import upload_file +from open_webui.utils.auth import get_admin_user, get_verified_user +from open_webui.utils.images.comfyui import ( + ComfyUIGenerateImageForm, + ComfyUIWorkflow, + comfyui_generate_image, +) +from pydantic import BaseModel + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["IMAGES"]) + +IMAGE_CACHE_DIR = Path(CACHE_DIR).joinpath("./image/generations/") +IMAGE_CACHE_DIR.mkdir(parents=True, exist_ok=True) + + +router = APIRouter() + + +@router.get("/config") +async def get_config(request: Request, user=Depends(get_admin_user)): + return { + "enabled": request.app.state.config.ENABLE_IMAGE_GENERATION, + "engine": request.app.state.config.IMAGE_GENERATION_ENGINE, + "prompt_generation": request.app.state.config.ENABLE_IMAGE_PROMPT_GENERATION, + "openai": { + "OPENAI_API_BASE_URL": request.app.state.config.IMAGES_OPENAI_API_BASE_URL, + "OPENAI_API_KEY": request.app.state.config.IMAGES_OPENAI_API_KEY, + }, + "automatic1111": { + "AUTOMATIC1111_BASE_URL": request.app.state.config.AUTOMATIC1111_BASE_URL, + "AUTOMATIC1111_API_AUTH": request.app.state.config.AUTOMATIC1111_API_AUTH, + "AUTOMATIC1111_CFG_SCALE": request.app.state.config.AUTOMATIC1111_CFG_SCALE, + "AUTOMATIC1111_SAMPLER": request.app.state.config.AUTOMATIC1111_SAMPLER, + "AUTOMATIC1111_SCHEDULER": request.app.state.config.AUTOMATIC1111_SCHEDULER, + }, + "comfyui": { + "COMFYUI_BASE_URL": request.app.state.config.COMFYUI_BASE_URL, + "COMFYUI_API_KEY": request.app.state.config.COMFYUI_API_KEY, + "COMFYUI_WORKFLOW": request.app.state.config.COMFYUI_WORKFLOW, + "COMFYUI_WORKFLOW_NODES": request.app.state.config.COMFYUI_WORKFLOW_NODES, + }, + "gemini": { + "GEMINI_API_BASE_URL": request.app.state.config.IMAGES_GEMINI_API_BASE_URL, + "GEMINI_API_KEY": request.app.state.config.IMAGES_GEMINI_API_KEY, + }, + } + + +class OpenAIConfigForm(BaseModel): + OPENAI_API_BASE_URL: str + OPENAI_API_KEY: str + + +class Automatic1111ConfigForm(BaseModel): + AUTOMATIC1111_BASE_URL: str + AUTOMATIC1111_API_AUTH: str + AUTOMATIC1111_CFG_SCALE: Optional[str | float | int] + AUTOMATIC1111_SAMPLER: Optional[str] + AUTOMATIC1111_SCHEDULER: Optional[str] + + +class ComfyUIConfigForm(BaseModel): + COMFYUI_BASE_URL: str + COMFYUI_API_KEY: str + COMFYUI_WORKFLOW: str + COMFYUI_WORKFLOW_NODES: list[dict] + + +class GeminiConfigForm(BaseModel): + GEMINI_API_BASE_URL: str + GEMINI_API_KEY: str + + +class ConfigForm(BaseModel): + enabled: bool + engine: str + prompt_generation: bool + openai: OpenAIConfigForm + automatic1111: Automatic1111ConfigForm + comfyui: ComfyUIConfigForm + gemini: GeminiConfigForm + + +@router.post("/config/update") +async def update_config( + request: Request, form_data: ConfigForm, user=Depends(get_admin_user) +): + request.app.state.config.IMAGE_GENERATION_ENGINE = form_data.engine + request.app.state.config.ENABLE_IMAGE_GENERATION = form_data.enabled + + request.app.state.config.ENABLE_IMAGE_PROMPT_GENERATION = ( + form_data.prompt_generation + ) + + request.app.state.config.IMAGES_OPENAI_API_BASE_URL = ( + form_data.openai.OPENAI_API_BASE_URL + ) + request.app.state.config.IMAGES_OPENAI_API_KEY = form_data.openai.OPENAI_API_KEY + + request.app.state.config.IMAGES_GEMINI_API_BASE_URL = ( + form_data.gemini.GEMINI_API_BASE_URL + ) + request.app.state.config.IMAGES_GEMINI_API_KEY = form_data.gemini.GEMINI_API_KEY + + request.app.state.config.AUTOMATIC1111_BASE_URL = ( + form_data.automatic1111.AUTOMATIC1111_BASE_URL + ) + request.app.state.config.AUTOMATIC1111_API_AUTH = ( + form_data.automatic1111.AUTOMATIC1111_API_AUTH + ) + + request.app.state.config.AUTOMATIC1111_CFG_SCALE = ( + float(form_data.automatic1111.AUTOMATIC1111_CFG_SCALE) + if form_data.automatic1111.AUTOMATIC1111_CFG_SCALE + else None + ) + request.app.state.config.AUTOMATIC1111_SAMPLER = ( + form_data.automatic1111.AUTOMATIC1111_SAMPLER + if form_data.automatic1111.AUTOMATIC1111_SAMPLER + else None + ) + request.app.state.config.AUTOMATIC1111_SCHEDULER = ( + form_data.automatic1111.AUTOMATIC1111_SCHEDULER + if form_data.automatic1111.AUTOMATIC1111_SCHEDULER + else None + ) + + request.app.state.config.COMFYUI_BASE_URL = ( + form_data.comfyui.COMFYUI_BASE_URL.strip("/") + ) + request.app.state.config.COMFYUI_API_KEY = form_data.comfyui.COMFYUI_API_KEY + + request.app.state.config.COMFYUI_WORKFLOW = form_data.comfyui.COMFYUI_WORKFLOW + request.app.state.config.COMFYUI_WORKFLOW_NODES = ( + form_data.comfyui.COMFYUI_WORKFLOW_NODES + ) + + return { + "enabled": request.app.state.config.ENABLE_IMAGE_GENERATION, + "engine": request.app.state.config.IMAGE_GENERATION_ENGINE, + "prompt_generation": request.app.state.config.ENABLE_IMAGE_PROMPT_GENERATION, + "openai": { + "OPENAI_API_BASE_URL": request.app.state.config.IMAGES_OPENAI_API_BASE_URL, + "OPENAI_API_KEY": request.app.state.config.IMAGES_OPENAI_API_KEY, + }, + "automatic1111": { + "AUTOMATIC1111_BASE_URL": request.app.state.config.AUTOMATIC1111_BASE_URL, + "AUTOMATIC1111_API_AUTH": request.app.state.config.AUTOMATIC1111_API_AUTH, + "AUTOMATIC1111_CFG_SCALE": request.app.state.config.AUTOMATIC1111_CFG_SCALE, + "AUTOMATIC1111_SAMPLER": request.app.state.config.AUTOMATIC1111_SAMPLER, + "AUTOMATIC1111_SCHEDULER": request.app.state.config.AUTOMATIC1111_SCHEDULER, + }, + "comfyui": { + "COMFYUI_BASE_URL": request.app.state.config.COMFYUI_BASE_URL, + "COMFYUI_API_KEY": request.app.state.config.COMFYUI_API_KEY, + "COMFYUI_WORKFLOW": request.app.state.config.COMFYUI_WORKFLOW, + "COMFYUI_WORKFLOW_NODES": request.app.state.config.COMFYUI_WORKFLOW_NODES, + }, + "gemini": { + "GEMINI_API_BASE_URL": request.app.state.config.IMAGES_GEMINI_API_BASE_URL, + "GEMINI_API_KEY": request.app.state.config.IMAGES_GEMINI_API_KEY, + }, + } + + +def get_automatic1111_api_auth(request: Request): + if request.app.state.config.AUTOMATIC1111_API_AUTH is None: + return "" + else: + auth1111_byte_string = request.app.state.config.AUTOMATIC1111_API_AUTH.encode( + "utf-8" + ) + auth1111_base64_encoded_bytes = base64.b64encode(auth1111_byte_string) + auth1111_base64_encoded_string = auth1111_base64_encoded_bytes.decode("utf-8") + return f"Basic {auth1111_base64_encoded_string}" + + +@router.get("/config/url/verify") +async def verify_url(request: Request, user=Depends(get_admin_user)): + if request.app.state.config.IMAGE_GENERATION_ENGINE == "automatic1111": + try: + r = requests.get( + url=f"{request.app.state.config.AUTOMATIC1111_BASE_URL}/sdapi/v1/options", + headers={"authorization": get_automatic1111_api_auth(request)}, + ) + r.raise_for_status() + return True + except Exception: + request.app.state.config.ENABLE_IMAGE_GENERATION = False + raise HTTPException(status_code=400, detail=ERROR_MESSAGES.INVALID_URL) + elif request.app.state.config.IMAGE_GENERATION_ENGINE == "comfyui": + + headers = None + if request.app.state.config.COMFYUI_API_KEY: + headers = { + "Authorization": f"Bearer {request.app.state.config.COMFYUI_API_KEY}" + } + + try: + r = requests.get( + url=f"{request.app.state.config.COMFYUI_BASE_URL}/object_info", + headers=headers, + ) + r.raise_for_status() + return True + except Exception: + request.app.state.config.ENABLE_IMAGE_GENERATION = False + raise HTTPException(status_code=400, detail=ERROR_MESSAGES.INVALID_URL) + else: + return True + + +def set_image_model(request: Request, model: str): + log.info(f"Setting image model to {model}") + request.app.state.config.IMAGE_GENERATION_MODEL = model + if request.app.state.config.IMAGE_GENERATION_ENGINE in ["", "automatic1111"]: + api_auth = get_automatic1111_api_auth(request) + r = requests.get( + url=f"{request.app.state.config.AUTOMATIC1111_BASE_URL}/sdapi/v1/options", + headers={"authorization": api_auth}, + ) + options = r.json() + if model != options["sd_model_checkpoint"]: + options["sd_model_checkpoint"] = model + r = requests.post( + url=f"{request.app.state.config.AUTOMATIC1111_BASE_URL}/sdapi/v1/options", + json=options, + headers={"authorization": api_auth}, + ) + return request.app.state.config.IMAGE_GENERATION_MODEL + + +def get_image_model(request): + if request.app.state.config.IMAGE_GENERATION_ENGINE == "openai": + return ( + request.app.state.config.IMAGE_GENERATION_MODEL + if request.app.state.config.IMAGE_GENERATION_MODEL + else "dall-e-2" + ) + elif request.app.state.config.IMAGE_GENERATION_ENGINE == "gemini": + return ( + request.app.state.config.IMAGE_GENERATION_MODEL + if request.app.state.config.IMAGE_GENERATION_MODEL + else "imagen-3.0-generate-002" + ) + elif request.app.state.config.IMAGE_GENERATION_ENGINE == "comfyui": + return ( + request.app.state.config.IMAGE_GENERATION_MODEL + if request.app.state.config.IMAGE_GENERATION_MODEL + else "" + ) + elif ( + request.app.state.config.IMAGE_GENERATION_ENGINE == "automatic1111" + or request.app.state.config.IMAGE_GENERATION_ENGINE == "" + ): + try: + r = requests.get( + url=f"{request.app.state.config.AUTOMATIC1111_BASE_URL}/sdapi/v1/options", + headers={"authorization": get_automatic1111_api_auth(request)}, + ) + options = r.json() + return options["sd_model_checkpoint"] + except Exception as e: + request.app.state.config.ENABLE_IMAGE_GENERATION = False + raise HTTPException(status_code=400, detail=ERROR_MESSAGES.DEFAULT(e)) + + +class ImageConfigForm(BaseModel): + MODEL: str + IMAGE_SIZE: str + IMAGE_STEPS: int + + +@router.get("/image/config") +async def get_image_config(request: Request, user=Depends(get_admin_user)): + return { + "MODEL": request.app.state.config.IMAGE_GENERATION_MODEL, + "IMAGE_SIZE": request.app.state.config.IMAGE_SIZE, + "IMAGE_STEPS": request.app.state.config.IMAGE_STEPS, + } + + +@router.post("/image/config/update") +async def update_image_config( + request: Request, form_data: ImageConfigForm, user=Depends(get_admin_user) +): + set_image_model(request, form_data.MODEL) + + pattern = r"^\d+x\d+$" + if re.match(pattern, form_data.IMAGE_SIZE): + request.app.state.config.IMAGE_SIZE = form_data.IMAGE_SIZE + else: + raise HTTPException( + status_code=400, + detail=ERROR_MESSAGES.INCORRECT_FORMAT(" (e.g., 512x512)."), + ) + + if form_data.IMAGE_STEPS >= 0: + request.app.state.config.IMAGE_STEPS = form_data.IMAGE_STEPS + else: + raise HTTPException( + status_code=400, + detail=ERROR_MESSAGES.INCORRECT_FORMAT(" (e.g., 50)."), + ) + + return { + "MODEL": request.app.state.config.IMAGE_GENERATION_MODEL, + "IMAGE_SIZE": request.app.state.config.IMAGE_SIZE, + "IMAGE_STEPS": request.app.state.config.IMAGE_STEPS, + } + + +@router.get("/models") +def get_models(request: Request, user=Depends(get_verified_user)): + try: + if request.app.state.config.IMAGE_GENERATION_ENGINE == "openai": + return [ + {"id": "dall-e-2", "name": "DALL·E 2"}, + {"id": "dall-e-3", "name": "DALL·E 3"}, + ] + elif request.app.state.config.IMAGE_GENERATION_ENGINE == "gemini": + return [ + {"id": "imagen-3-0-generate-002", "name": "imagen-3.0 generate-002"}, + ] + elif request.app.state.config.IMAGE_GENERATION_ENGINE == "comfyui": + # TODO - get models from comfyui + headers = { + "Authorization": f"Bearer {request.app.state.config.COMFYUI_API_KEY}" + } + r = requests.get( + url=f"{request.app.state.config.COMFYUI_BASE_URL}/object_info", + headers=headers, + ) + info = r.json() + + workflow = json.loads(request.app.state.config.COMFYUI_WORKFLOW) + model_node_id = None + + for node in request.app.state.config.COMFYUI_WORKFLOW_NODES: + if node["type"] == "model": + if node["node_ids"]: + model_node_id = node["node_ids"][0] + break + + if model_node_id: + model_list_key = None + + log.info(workflow[model_node_id]["class_type"]) + for key in info[workflow[model_node_id]["class_type"]]["input"][ + "required" + ]: + if "_name" in key: + model_list_key = key + break + + if model_list_key: + return list( + map( + lambda model: {"id": model, "name": model}, + info[workflow[model_node_id]["class_type"]]["input"][ + "required" + ][model_list_key][0], + ) + ) + else: + return list( + map( + lambda model: {"id": model, "name": model}, + info["CheckpointLoaderSimple"]["input"]["required"][ + "ckpt_name" + ][0], + ) + ) + elif ( + request.app.state.config.IMAGE_GENERATION_ENGINE == "automatic1111" + or request.app.state.config.IMAGE_GENERATION_ENGINE == "" + ): + r = requests.get( + url=f"{request.app.state.config.AUTOMATIC1111_BASE_URL}/sdapi/v1/sd-models", + headers={"authorization": get_automatic1111_api_auth(request)}, + ) + models = r.json() + return list( + map( + lambda model: {"id": model["title"], "name": model["model_name"]}, + models, + ) + ) + except Exception as e: + request.app.state.config.ENABLE_IMAGE_GENERATION = False + raise HTTPException(status_code=400, detail=ERROR_MESSAGES.DEFAULT(e)) + + +class GenerateImageForm(BaseModel): + model: Optional[str] = None + prompt: str + size: Optional[str] = None + n: int = 1 + negative_prompt: Optional[str] = None + + +def load_b64_image_data(b64_str): + try: + if "," in b64_str: + header, encoded = b64_str.split(",", 1) + mime_type = header.split(";")[0] + img_data = base64.b64decode(encoded) + else: + mime_type = "image/png" + img_data = base64.b64decode(b64_str) + return img_data, mime_type + except Exception as e: + log.exception(f"Error loading image data: {e}") + return None + + +def load_url_image_data(url, headers=None): + try: + if headers: + r = requests.get(url, headers=headers) + else: + r = requests.get(url) + + r.raise_for_status() + if r.headers["content-type"].split("/")[0] == "image": + mime_type = r.headers["content-type"] + return r.content, mime_type + else: + log.error("Url does not point to an image.") + return None + + except Exception as e: + log.exception(f"Error saving image: {e}") + return None + + +def upload_image(request, image_metadata, image_data, content_type, user): + image_format = mimetypes.guess_extension(content_type) + file = UploadFile( + file=io.BytesIO(image_data), + filename=f"generated-image{image_format}", # will be converted to a unique ID on upload_file + headers={ + "content-type": content_type, + }, + ) + file_item = upload_file(request, file, user, file_metadata=image_metadata) + url = request.app.url_path_for("get_file_content_by_id", id=file_item.id) + return url + + +@router.post("/generations") +async def image_generations( + request: Request, + form_data: GenerateImageForm, + user=Depends(get_verified_user), +): + width, height = tuple(map(int, request.app.state.config.IMAGE_SIZE.split("x"))) + + r = None + try: + if request.app.state.config.IMAGE_GENERATION_ENGINE == "openai": + headers = {} + headers["Authorization"] = ( + f"Bearer {request.app.state.config.IMAGES_OPENAI_API_KEY}" + ) + headers["Content-Type"] = "application/json" + + if ENABLE_FORWARD_USER_INFO_HEADERS: + headers["X-OpenWebUI-User-Name"] = user.name + headers["X-OpenWebUI-User-Id"] = user.id + headers["X-OpenWebUI-User-Email"] = user.email + headers["X-OpenWebUI-User-Role"] = user.role + + data = { + "model": ( + request.app.state.config.IMAGE_GENERATION_MODEL + if request.app.state.config.IMAGE_GENERATION_MODEL != "" + else "dall-e-2" + ), + "prompt": form_data.prompt, + "n": form_data.n, + "size": ( + form_data.size + if form_data.size + else request.app.state.config.IMAGE_SIZE + ), + "response_format": "b64_json", + } + + # Use asyncio.to_thread for the requests.post call + r = await asyncio.to_thread( + requests.post, + url=f"{request.app.state.config.IMAGES_OPENAI_API_BASE_URL}/images/generations", + json=data, + headers=headers, + ) + + r.raise_for_status() + res = r.json() + + images = [] + + for image in res["data"]: + image_data, content_type = load_b64_image_data(image["b64_json"]) + url = upload_image(request, data, image_data, content_type, user) + images.append({"url": url}) + return images + + elif request.app.state.config.IMAGE_GENERATION_ENGINE == "gemini": + headers = {} + headers["Content-Type"] = "application/json" + headers["x-goog-api-key"] = request.app.state.config.IMAGES_GEMINI_API_KEY + + model = get_image_model(request) + data = { + "instances": {"prompt": form_data.prompt}, + "parameters": { + "sampleCount": form_data.n, + "outputOptions": {"mimeType": "image/png"}, + }, + } + + # Use asyncio.to_thread for the requests.post call + r = await asyncio.to_thread( + requests.post, + url=f"{request.app.state.config.IMAGES_GEMINI_API_BASE_URL}/models/{model}:predict", + json=data, + headers=headers, + ) + + r.raise_for_status() + res = r.json() + + images = [] + for image in res["predictions"]: + image_data, content_type = load_b64_image_data( + image["bytesBase64Encoded"] + ) + url = upload_image(request, data, image_data, content_type, user) + images.append({"url": url}) + + return images + + elif request.app.state.config.IMAGE_GENERATION_ENGINE == "comfyui": + data = { + "prompt": form_data.prompt, + "width": width, + "height": height, + "n": form_data.n, + } + + if request.app.state.config.IMAGE_STEPS is not None: + data["steps"] = request.app.state.config.IMAGE_STEPS + + if form_data.negative_prompt is not None: + data["negative_prompt"] = form_data.negative_prompt + + form_data = ComfyUIGenerateImageForm( + **{ + "workflow": ComfyUIWorkflow( + **{ + "workflow": request.app.state.config.COMFYUI_WORKFLOW, + "nodes": request.app.state.config.COMFYUI_WORKFLOW_NODES, + } + ), + **data, + } + ) + res = await comfyui_generate_image( + request.app.state.config.IMAGE_GENERATION_MODEL, + form_data, + user.id, + request.app.state.config.COMFYUI_BASE_URL, + request.app.state.config.COMFYUI_API_KEY, + ) + log.debug(f"res: {res}") + + images = [] + + for image in res["data"]: + headers = None + if request.app.state.config.COMFYUI_API_KEY: + headers = { + "Authorization": f"Bearer {request.app.state.config.COMFYUI_API_KEY}" + } + + image_data, content_type = load_url_image_data(image["url"], headers) + url = upload_image( + request, + form_data.model_dump(exclude_none=True), + image_data, + content_type, + user, + ) + images.append({"url": url}) + return images + elif ( + request.app.state.config.IMAGE_GENERATION_ENGINE == "automatic1111" + or request.app.state.config.IMAGE_GENERATION_ENGINE == "" + ): + if form_data.model: + set_image_model(form_data.model) + + data = { + "prompt": form_data.prompt, + "batch_size": form_data.n, + "width": width, + "height": height, + } + + if request.app.state.config.IMAGE_STEPS is not None: + data["steps"] = request.app.state.config.IMAGE_STEPS + + if form_data.negative_prompt is not None: + data["negative_prompt"] = form_data.negative_prompt + + if request.app.state.config.AUTOMATIC1111_CFG_SCALE: + data["cfg_scale"] = request.app.state.config.AUTOMATIC1111_CFG_SCALE + + if request.app.state.config.AUTOMATIC1111_SAMPLER: + data["sampler_name"] = request.app.state.config.AUTOMATIC1111_SAMPLER + + if request.app.state.config.AUTOMATIC1111_SCHEDULER: + data["scheduler"] = request.app.state.config.AUTOMATIC1111_SCHEDULER + + # Use asyncio.to_thread for the requests.post call + r = await asyncio.to_thread( + requests.post, + url=f"{request.app.state.config.AUTOMATIC1111_BASE_URL}/sdapi/v1/txt2img", + json=data, + headers={"authorization": get_automatic1111_api_auth(request)}, + ) + + res = r.json() + log.debug(f"res: {res}") + + images = [] + + for image in res["images"]: + image_data, content_type = load_b64_image_data(image) + url = upload_image( + request, + {**data, "info": res["info"]}, + image_data, + content_type, + user, + ) + images.append({"url": url}) + return images + except Exception as e: + error = e + if r != None: + data = r.json() + if "error" in data: + error = data["error"]["message"] + raise HTTPException(status_code=400, detail=ERROR_MESSAGES.DEFAULT(error)) diff --git a/backend/open_webui/routers/knowledge.py b/backend/open_webui/routers/knowledge.py new file mode 100644 index 0000000..1969045 --- /dev/null +++ b/backend/open_webui/routers/knowledge.py @@ -0,0 +1,668 @@ +from typing import List, Optional +from pydantic import BaseModel +from fastapi import APIRouter, Depends, HTTPException, status, Request +import logging + +from open_webui.models.knowledge import ( + Knowledges, + KnowledgeForm, + KnowledgeResponse, + KnowledgeUserResponse, +) +from open_webui.models.files import Files, FileModel +from open_webui.retrieval.vector.connector import VECTOR_DB_CLIENT +from open_webui.routers.retrieval import ( + process_file, + ProcessFileForm, + process_files_batch, + BatchProcessFilesForm, +) +from open_webui.storage.provider import Storage + +from open_webui.constants import ERROR_MESSAGES +from open_webui.utils.auth import get_verified_user +from open_webui.utils.access_control import has_access, has_permission + + +from open_webui.env import SRC_LOG_LEVELS +from open_webui.models.models import Models, ModelForm + + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MODELS"]) + +router = APIRouter() + +############################ +# getKnowledgeBases +############################ + + +@router.get("/", response_model=list[KnowledgeUserResponse]) +async def get_knowledge(user=Depends(get_verified_user)): + knowledge_bases = [] + + if user.role == "admin": + knowledge_bases = Knowledges.get_knowledge_bases() + else: + knowledge_bases = Knowledges.get_knowledge_bases_by_user_id(user.id, "read") + + # Get files for each knowledge base + knowledge_with_files = [] + for knowledge_base in knowledge_bases: + files = [] + if knowledge_base.data: + files = Files.get_file_metadatas_by_ids( + knowledge_base.data.get("file_ids", []) + ) + + # Check if all files exist + if len(files) != len(knowledge_base.data.get("file_ids", [])): + missing_files = list( + set(knowledge_base.data.get("file_ids", [])) + - set([file.id for file in files]) + ) + if missing_files: + data = knowledge_base.data or {} + file_ids = data.get("file_ids", []) + + for missing_file in missing_files: + file_ids.remove(missing_file) + + data["file_ids"] = file_ids + Knowledges.update_knowledge_data_by_id( + id=knowledge_base.id, data=data + ) + + files = Files.get_file_metadatas_by_ids(file_ids) + + knowledge_with_files.append( + KnowledgeUserResponse( + **knowledge_base.model_dump(), + files=files, + ) + ) + + return knowledge_with_files + + +@router.get("/list", response_model=list[KnowledgeUserResponse]) +async def get_knowledge_list(user=Depends(get_verified_user)): + knowledge_bases = [] + + if user.role == "admin": + knowledge_bases = Knowledges.get_knowledge_bases() + else: + knowledge_bases = Knowledges.get_knowledge_bases_by_user_id(user.id, "write") + + # Get files for each knowledge base + knowledge_with_files = [] + for knowledge_base in knowledge_bases: + files = [] + if knowledge_base.data: + files = Files.get_file_metadatas_by_ids( + knowledge_base.data.get("file_ids", []) + ) + + # Check if all files exist + if len(files) != len(knowledge_base.data.get("file_ids", [])): + missing_files = list( + set(knowledge_base.data.get("file_ids", [])) + - set([file.id for file in files]) + ) + if missing_files: + data = knowledge_base.data or {} + file_ids = data.get("file_ids", []) + + for missing_file in missing_files: + file_ids.remove(missing_file) + + data["file_ids"] = file_ids + Knowledges.update_knowledge_data_by_id( + id=knowledge_base.id, data=data + ) + + files = Files.get_file_metadatas_by_ids(file_ids) + + knowledge_with_files.append( + KnowledgeUserResponse( + **knowledge_base.model_dump(), + files=files, + ) + ) + return knowledge_with_files + + +############################ +# CreateNewKnowledge +############################ + + +@router.post("/create", response_model=Optional[KnowledgeResponse]) +async def create_new_knowledge( + request: Request, form_data: KnowledgeForm, user=Depends(get_verified_user) +): + if user.role != "admin" and not has_permission( + user.id, "workspace.knowledge", request.app.state.config.USER_PERMISSIONS + ): + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.UNAUTHORIZED, + ) + + knowledge = Knowledges.insert_new_knowledge(user.id, form_data) + + if knowledge: + return knowledge + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.FILE_EXISTS, + ) + + +############################ +# GetKnowledgeById +############################ + + +class KnowledgeFilesResponse(KnowledgeResponse): + files: list[FileModel] + + +@router.get("/{id}", response_model=Optional[KnowledgeFilesResponse]) +async def get_knowledge_by_id(id: str, user=Depends(get_verified_user)): + knowledge = Knowledges.get_knowledge_by_id(id=id) + + if knowledge: + + if ( + user.role == "admin" + or knowledge.user_id == user.id + or has_access(user.id, "read", knowledge.access_control) + ): + + file_ids = knowledge.data.get("file_ids", []) if knowledge.data else [] + files = Files.get_files_by_ids(file_ids) + + return KnowledgeFilesResponse( + **knowledge.model_dump(), + files=files, + ) + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +############################ +# UpdateKnowledgeById +############################ + + +@router.post("/{id}/update", response_model=Optional[KnowledgeFilesResponse]) +async def update_knowledge_by_id( + id: str, + form_data: KnowledgeForm, + user=Depends(get_verified_user), +): + knowledge = Knowledges.get_knowledge_by_id(id=id) + if not knowledge: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + # Is the user the original creator, in a group with write access, or an admin + if ( + knowledge.user_id != user.id + and not has_access(user.id, "write", knowledge.access_control) + and user.role != "admin" + ): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + ) + + knowledge = Knowledges.update_knowledge_by_id(id=id, form_data=form_data) + if knowledge: + file_ids = knowledge.data.get("file_ids", []) if knowledge.data else [] + files = Files.get_files_by_ids(file_ids) + + return KnowledgeFilesResponse( + **knowledge.model_dump(), + files=files, + ) + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.ID_TAKEN, + ) + + +############################ +# AddFileToKnowledge +############################ + + +class KnowledgeFileIdForm(BaseModel): + file_id: str + + +@router.post("/{id}/file/add", response_model=Optional[KnowledgeFilesResponse]) +def add_file_to_knowledge_by_id( + request: Request, + id: str, + form_data: KnowledgeFileIdForm, + user=Depends(get_verified_user), +): + knowledge = Knowledges.get_knowledge_by_id(id=id) + + if not knowledge: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + if ( + knowledge.user_id != user.id + and not has_access(user.id, "write", knowledge.access_control) + and user.role != "admin" + ): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + ) + + file = Files.get_file_by_id(form_data.file_id) + if not file: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + if not file.data: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.FILE_NOT_PROCESSED, + ) + + # Add content to the vector database + try: + process_file( + request, + ProcessFileForm(file_id=form_data.file_id, collection_name=id), + user=user, + ) + except Exception as e: + log.debug(e) + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=str(e), + ) + + if knowledge: + data = knowledge.data or {} + file_ids = data.get("file_ids", []) + + if form_data.file_id not in file_ids: + file_ids.append(form_data.file_id) + data["file_ids"] = file_ids + + knowledge = Knowledges.update_knowledge_data_by_id(id=id, data=data) + + if knowledge: + files = Files.get_files_by_ids(file_ids) + + return KnowledgeFilesResponse( + **knowledge.model_dump(), + files=files, + ) + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("knowledge"), + ) + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("file_id"), + ) + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +@router.post("/{id}/file/update", response_model=Optional[KnowledgeFilesResponse]) +def update_file_from_knowledge_by_id( + request: Request, + id: str, + form_data: KnowledgeFileIdForm, + user=Depends(get_verified_user), +): + knowledge = Knowledges.get_knowledge_by_id(id=id) + if not knowledge: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + if ( + knowledge.user_id != user.id + and not has_access(user.id, "write", knowledge.access_control) + and user.role != "admin" + ): + + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + ) + + file = Files.get_file_by_id(form_data.file_id) + if not file: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + # Remove content from the vector database + VECTOR_DB_CLIENT.delete( + collection_name=knowledge.id, filter={"file_id": form_data.file_id} + ) + + # Add content to the vector database + try: + process_file( + request, + ProcessFileForm(file_id=form_data.file_id, collection_name=id), + user=user, + ) + except Exception as e: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=str(e), + ) + + if knowledge: + data = knowledge.data or {} + file_ids = data.get("file_ids", []) + + files = Files.get_files_by_ids(file_ids) + + return KnowledgeFilesResponse( + **knowledge.model_dump(), + files=files, + ) + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +############################ +# RemoveFileFromKnowledge +############################ + + +@router.post("/{id}/file/remove", response_model=Optional[KnowledgeFilesResponse]) +def remove_file_from_knowledge_by_id( + id: str, + form_data: KnowledgeFileIdForm, + user=Depends(get_verified_user), +): + knowledge = Knowledges.get_knowledge_by_id(id=id) + if not knowledge: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + if ( + knowledge.user_id != user.id + and not has_access(user.id, "write", knowledge.access_control) + and user.role != "admin" + ): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + ) + + file = Files.get_file_by_id(form_data.file_id) + if not file: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + # Remove content from the vector database + VECTOR_DB_CLIENT.delete( + collection_name=knowledge.id, filter={"file_id": form_data.file_id} + ) + + # Remove the file's collection from vector database + file_collection = f"file-{form_data.file_id}" + if VECTOR_DB_CLIENT.has_collection(collection_name=file_collection): + VECTOR_DB_CLIENT.delete_collection(collection_name=file_collection) + + # Delete file from database + Files.delete_file_by_id(form_data.file_id) + + if knowledge: + data = knowledge.data or {} + file_ids = data.get("file_ids", []) + + if form_data.file_id in file_ids: + file_ids.remove(form_data.file_id) + data["file_ids"] = file_ids + + knowledge = Knowledges.update_knowledge_data_by_id(id=id, data=data) + + if knowledge: + files = Files.get_files_by_ids(file_ids) + + return KnowledgeFilesResponse( + **knowledge.model_dump(), + files=files, + ) + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("knowledge"), + ) + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("file_id"), + ) + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +############################ +# DeleteKnowledgeById +############################ + + +@router.delete("/{id}/delete", response_model=bool) +async def delete_knowledge_by_id(id: str, user=Depends(get_verified_user)): + knowledge = Knowledges.get_knowledge_by_id(id=id) + if not knowledge: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + if ( + knowledge.user_id != user.id + and not has_access(user.id, "write", knowledge.access_control) + and user.role != "admin" + ): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + ) + + log.info(f"Deleting knowledge base: {id} (name: {knowledge.name})") + + # Get all models + models = Models.get_all_models() + log.info(f"Found {len(models)} models to check for knowledge base {id}") + + # Update models that reference this knowledge base + for model in models: + if model.meta and hasattr(model.meta, "knowledge"): + knowledge_list = model.meta.knowledge or [] + # Filter out the deleted knowledge base + updated_knowledge = [k for k in knowledge_list if k.get("id") != id] + + # If the knowledge list changed, update the model + if len(updated_knowledge) != len(knowledge_list): + log.info(f"Updating model {model.id} to remove knowledge base {id}") + model.meta.knowledge = updated_knowledge + # Create a ModelForm for the update + model_form = ModelForm( + id=model.id, + name=model.name, + base_model_id=model.base_model_id, + meta=model.meta, + params=model.params, + access_control=model.access_control, + is_active=model.is_active, + ) + Models.update_model_by_id(model.id, model_form) + + # Clean up vector DB + try: + VECTOR_DB_CLIENT.delete_collection(collection_name=id) + except Exception as e: + log.debug(e) + pass + result = Knowledges.delete_knowledge_by_id(id=id) + return result + + +############################ +# ResetKnowledgeById +############################ + + +@router.post("/{id}/reset", response_model=Optional[KnowledgeResponse]) +async def reset_knowledge_by_id(id: str, user=Depends(get_verified_user)): + knowledge = Knowledges.get_knowledge_by_id(id=id) + if not knowledge: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + if ( + knowledge.user_id != user.id + and not has_access(user.id, "write", knowledge.access_control) + and user.role != "admin" + ): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + ) + + try: + VECTOR_DB_CLIENT.delete_collection(collection_name=id) + except Exception as e: + log.debug(e) + pass + + knowledge = Knowledges.update_knowledge_data_by_id(id=id, data={"file_ids": []}) + + return knowledge + + +############################ +# AddFilesToKnowledge +############################ + + +@router.post("/{id}/files/batch/add", response_model=Optional[KnowledgeFilesResponse]) +def add_files_to_knowledge_batch( + request: Request, + id: str, + form_data: list[KnowledgeFileIdForm], + user=Depends(get_verified_user), +): + """ + Add multiple files to a knowledge base + """ + knowledge = Knowledges.get_knowledge_by_id(id=id) + if not knowledge: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + if ( + knowledge.user_id != user.id + and not has_access(user.id, "write", knowledge.access_control) + and user.role != "admin" + ): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + ) + + # Get files content + log.info(f"files/batch/add - {len(form_data)} files") + files: List[FileModel] = [] + for form in form_data: + file = Files.get_file_by_id(form.file_id) + if not file: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=f"File {form.file_id} not found", + ) + files.append(file) + + # Process files + try: + result = process_files_batch( + request=request, + form_data=BatchProcessFilesForm(files=files, collection_name=id), + user=user, + ) + except Exception as e: + log.error( + f"add_files_to_knowledge_batch: Exception occurred: {e}", exc_info=True + ) + raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e)) + + # Add successful files to knowledge base + data = knowledge.data or {} + existing_file_ids = data.get("file_ids", []) + + # Only add files that were successfully processed + successful_file_ids = [r.file_id for r in result.results if r.status == "completed"] + for file_id in successful_file_ids: + if file_id not in existing_file_ids: + existing_file_ids.append(file_id) + + data["file_ids"] = existing_file_ids + knowledge = Knowledges.update_knowledge_data_by_id(id=id, data=data) + + # If there were any errors, include them in the response + if result.errors: + error_details = [f"{err.file_id}: {err.error}" for err in result.errors] + return KnowledgeFilesResponse( + **knowledge.model_dump(), + files=Files.get_files_by_ids(existing_file_ids), + warnings={ + "message": "Some files failed to process", + "errors": error_details, + }, + ) + + return KnowledgeFilesResponse( + **knowledge.model_dump(), files=Files.get_files_by_ids(existing_file_ids) + ) diff --git a/backend/open_webui/routers/memories.py b/backend/open_webui/routers/memories.py new file mode 100644 index 0000000..c55a6a9 --- /dev/null +++ b/backend/open_webui/routers/memories.py @@ -0,0 +1,192 @@ +from fastapi import APIRouter, Depends, HTTPException, Request +from pydantic import BaseModel +import logging +from typing import Optional + +from open_webui.models.memories import Memories, MemoryModel +from open_webui.retrieval.vector.connector import VECTOR_DB_CLIENT +from open_webui.utils.auth import get_verified_user +from open_webui.env import SRC_LOG_LEVELS + + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MODELS"]) + +router = APIRouter() + + +@router.get("/ef") +async def get_embeddings(request: Request): + return {"result": request.app.state.EMBEDDING_FUNCTION("hello world")} + + +############################ +# GetMemories +############################ + + +@router.get("/", response_model=list[MemoryModel]) +async def get_memories(user=Depends(get_verified_user)): + return Memories.get_memories_by_user_id(user.id) + + +############################ +# AddMemory +############################ + + +class AddMemoryForm(BaseModel): + content: str + + +class MemoryUpdateModel(BaseModel): + content: Optional[str] = None + + +@router.post("/add", response_model=Optional[MemoryModel]) +async def add_memory( + request: Request, + form_data: AddMemoryForm, + user=Depends(get_verified_user), +): + memory = Memories.insert_new_memory(user.id, form_data.content) + + VECTOR_DB_CLIENT.upsert( + collection_name=f"user-memory-{user.id}", + items=[ + { + "id": memory.id, + "text": memory.content, + "vector": request.app.state.EMBEDDING_FUNCTION(memory.content, user), + "metadata": {"created_at": memory.created_at}, + } + ], + ) + + return memory + + +############################ +# QueryMemory +############################ + + +class QueryMemoryForm(BaseModel): + content: str + k: Optional[int] = 1 + + +@router.post("/query") +async def query_memory( + request: Request, form_data: QueryMemoryForm, user=Depends(get_verified_user) +): + results = VECTOR_DB_CLIENT.search( + collection_name=f"user-memory-{user.id}", + vectors=[request.app.state.EMBEDDING_FUNCTION(form_data.content, user)], + limit=form_data.k, + ) + + return results + + +############################ +# ResetMemoryFromVectorDB +############################ +@router.post("/reset", response_model=bool) +async def reset_memory_from_vector_db( + request: Request, user=Depends(get_verified_user) +): + VECTOR_DB_CLIENT.delete_collection(f"user-memory-{user.id}") + + memories = Memories.get_memories_by_user_id(user.id) + VECTOR_DB_CLIENT.upsert( + collection_name=f"user-memory-{user.id}", + items=[ + { + "id": memory.id, + "text": memory.content, + "vector": request.app.state.EMBEDDING_FUNCTION(memory.content, user), + "metadata": { + "created_at": memory.created_at, + "updated_at": memory.updated_at, + }, + } + for memory in memories + ], + ) + + return True + + +############################ +# DeleteMemoriesByUserId +############################ + + +@router.delete("/delete/user", response_model=bool) +async def delete_memory_by_user_id(user=Depends(get_verified_user)): + result = Memories.delete_memories_by_user_id(user.id) + + if result: + try: + VECTOR_DB_CLIENT.delete_collection(f"user-memory-{user.id}") + except Exception as e: + log.error(e) + return True + + return False + + +############################ +# UpdateMemoryById +############################ + + +@router.post("/{memory_id}/update", response_model=Optional[MemoryModel]) +async def update_memory_by_id( + memory_id: str, + request: Request, + form_data: MemoryUpdateModel, + user=Depends(get_verified_user), +): + memory = Memories.update_memory_by_id(memory_id, form_data.content) + if memory is None: + raise HTTPException(status_code=404, detail="Memory not found") + + if form_data.content is not None: + VECTOR_DB_CLIENT.upsert( + collection_name=f"user-memory-{user.id}", + items=[ + { + "id": memory.id, + "text": memory.content, + "vector": request.app.state.EMBEDDING_FUNCTION( + memory.content, user + ), + "metadata": { + "created_at": memory.created_at, + "updated_at": memory.updated_at, + }, + } + ], + ) + + return memory + + +############################ +# DeleteMemoryById +############################ + + +@router.delete("/{memory_id}", response_model=bool) +async def delete_memory_by_id(memory_id: str, user=Depends(get_verified_user)): + result = Memories.delete_memory_by_id_and_user_id(memory_id, user.id) + + if result: + VECTOR_DB_CLIENT.delete( + collection_name=f"user-memory-{user.id}", ids=[memory_id] + ) + return True + + return False diff --git a/backend/open_webui/routers/models.py b/backend/open_webui/routers/models.py new file mode 100644 index 0000000..0cf3308 --- /dev/null +++ b/backend/open_webui/routers/models.py @@ -0,0 +1,203 @@ +from typing import Optional + +from open_webui.models.models import ( + ModelForm, + ModelModel, + ModelResponse, + ModelUserResponse, + Models, +) +from open_webui.constants import ERROR_MESSAGES +from fastapi import APIRouter, Depends, HTTPException, Request, status + + +from open_webui.utils.auth import get_admin_user, get_verified_user +from open_webui.utils.access_control import has_access, has_permission + + +router = APIRouter() + + +########################### +# GetModels +########################### + + +@router.get("/", response_model=list[ModelUserResponse]) +async def get_models(id: Optional[str] = None, user=Depends(get_verified_user)): + if user.role == "admin": + return Models.get_models() + else: + return Models.get_models_by_user_id(user.id) + + +########################### +# GetBaseModels +########################### + + +@router.get("/base", response_model=list[ModelResponse]) +async def get_base_models(user=Depends(get_admin_user)): + return Models.get_base_models() + + +############################ +# CreateNewModel +############################ + + +@router.post("/create", response_model=Optional[ModelModel]) +async def create_new_model( + request: Request, + form_data: ModelForm, + user=Depends(get_verified_user), +): + if user.role != "admin" and not has_permission( + user.id, "workspace.models", request.app.state.config.USER_PERMISSIONS + ): + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.UNAUTHORIZED, + ) + + model = Models.get_model_by_id(form_data.id) + if model: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.MODEL_ID_TAKEN, + ) + + else: + model = Models.insert_new_model(form_data, user.id) + if model: + return model + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.DEFAULT(), + ) + + +########################### +# GetModelById +########################### + + +# Note: We're not using the typical url path param here, but instead using a query parameter to allow '/' in the id +@router.get("/model", response_model=Optional[ModelResponse]) +async def get_model_by_id(id: str, user=Depends(get_verified_user)): + model = Models.get_model_by_id(id) + if model: + if ( + user.role == "admin" + or model.user_id == user.id + or has_access(user.id, "read", model.access_control) + ): + return model + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +############################ +# ToggelModelById +############################ + + +@router.post("/model/toggle", response_model=Optional[ModelResponse]) +async def toggle_model_by_id(id: str, user=Depends(get_verified_user)): + model = Models.get_model_by_id(id) + if model: + if ( + user.role == "admin" + or model.user_id == user.id + or has_access(user.id, "write", model.access_control) + ): + model = Models.toggle_model_by_id(id) + + if model: + return model + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("Error updating function"), + ) + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.UNAUTHORIZED, + ) + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +############################ +# UpdateModelById +############################ + + +@router.post("/model/update", response_model=Optional[ModelModel]) +async def update_model_by_id( + id: str, + form_data: ModelForm, + user=Depends(get_verified_user), +): + model = Models.get_model_by_id(id) + + if not model: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + if ( + model.user_id != user.id + and not has_access(user.id, "write", model.access_control) + and user.role != "admin" + ): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + ) + + model = Models.update_model_by_id(id, form_data) + return model + + +############################ +# DeleteModelById +############################ + + +@router.delete("/model/delete", response_model=bool) +async def delete_model_by_id(id: str, user=Depends(get_verified_user)): + model = Models.get_model_by_id(id) + if not model: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + if ( + user.role != "admin" + and model.user_id != user.id + and not has_access(user.id, "write", model.access_control) + ): + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.UNAUTHORIZED, + ) + + result = Models.delete_model_by_id(id) + return result + + +@router.delete("/delete/all", response_model=bool) +async def delete_all_models(user=Depends(get_admin_user)): + result = Models.delete_all_models() + return result diff --git a/backend/open_webui/routers/ollama.py b/backend/open_webui/routers/ollama.py new file mode 100644 index 0000000..d99416c --- /dev/null +++ b/backend/open_webui/routers/ollama.py @@ -0,0 +1,1634 @@ +# TODO: Implement a more intelligent load balancing mechanism for distributing requests among multiple backend instances. +# Current implementation uses a simple round-robin approach (random.choice). Consider incorporating algorithms like weighted round-robin, +# least connections, or least response time for better resource utilization and performance optimization. + +import asyncio +import json +import logging +import os +import random +import re +import time +from typing import Optional, Union +from urllib.parse import urlparse +import aiohttp +from aiocache import cached +import requests +from open_webui.models.users import UserModel + +from open_webui.env import ( + ENABLE_FORWARD_USER_INFO_HEADERS, +) + +from fastapi import ( + Depends, + FastAPI, + File, + HTTPException, + Request, + UploadFile, + APIRouter, +) +from fastapi.middleware.cors import CORSMiddleware +from fastapi.responses import StreamingResponse +from pydantic import BaseModel, ConfigDict, validator +from starlette.background import BackgroundTask + + +from open_webui.models.models import Models +from open_webui.utils.misc import ( + calculate_sha256, +) +from open_webui.utils.payload import ( + apply_model_params_to_body_ollama, + apply_model_params_to_body_openai, + apply_model_system_prompt_to_body, +) +from open_webui.utils.auth import get_admin_user, get_verified_user +from open_webui.utils.access_control import has_access + + +from open_webui.config import ( + UPLOAD_DIR, +) +from open_webui.env import ( + ENV, + SRC_LOG_LEVELS, + AIOHTTP_CLIENT_TIMEOUT, + AIOHTTP_CLIENT_TIMEOUT_OPENAI_MODEL_LIST, + BYPASS_MODEL_ACCESS_CONTROL, +) +from open_webui.constants import ERROR_MESSAGES + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["OLLAMA"]) + + +########################################## +# +# Utility functions +# +########################################## + + +async def send_get_request(url, key=None, user: UserModel = None): + timeout = aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT_OPENAI_MODEL_LIST) + try: + async with aiohttp.ClientSession(timeout=timeout, trust_env=True) as session: + async with session.get( + url, + headers={ + "Content-Type": "application/json", + **({"Authorization": f"Bearer {key}"} if key else {}), + **( + { + "X-OpenWebUI-User-Name": user.name, + "X-OpenWebUI-User-Id": user.id, + "X-OpenWebUI-User-Email": user.email, + "X-OpenWebUI-User-Role": user.role, + } + if ENABLE_FORWARD_USER_INFO_HEADERS and user + else {} + ), + }, + ) as response: + return await response.json() + except Exception as e: + # Handle connection error here + log.error(f"Connection error: {e}") + return None + + +async def cleanup_response( + response: Optional[aiohttp.ClientResponse], + session: Optional[aiohttp.ClientSession], +): + if response: + response.close() + if session: + await session.close() + + +async def send_post_request( + url: str, + payload: Union[str, bytes], + stream: bool = True, + key: Optional[str] = None, + content_type: Optional[str] = None, + user: UserModel = None, +): + + r = None + try: + session = aiohttp.ClientSession( + trust_env=True, timeout=aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT) + ) + + r = await session.post( + url, + data=payload, + headers={ + "Content-Type": "application/json", + **({"Authorization": f"Bearer {key}"} if key else {}), + **( + { + "X-OpenWebUI-User-Name": user.name, + "X-OpenWebUI-User-Id": user.id, + "X-OpenWebUI-User-Email": user.email, + "X-OpenWebUI-User-Role": user.role, + } + if ENABLE_FORWARD_USER_INFO_HEADERS and user + else {} + ), + }, + ) + r.raise_for_status() + + if stream: + response_headers = dict(r.headers) + + if content_type: + response_headers["Content-Type"] = content_type + + return StreamingResponse( + r.content, + status_code=r.status, + headers=response_headers, + background=BackgroundTask( + cleanup_response, response=r, session=session + ), + ) + else: + res = await r.json() + await cleanup_response(r, session) + return res + + except Exception as e: + detail = None + + if r is not None: + try: + res = await r.json() + if "error" in res: + detail = f"Ollama: {res.get('error', 'Unknown error')}" + except Exception: + detail = f"Ollama: {e}" + + raise HTTPException( + status_code=r.status if r else 500, + detail=detail if detail else "Open WebUI: Server Connection Error", + ) + + +def get_api_key(idx, url, configs): + parsed_url = urlparse(url) + base_url = f"{parsed_url.scheme}://{parsed_url.netloc}" + return configs.get(str(idx), configs.get(base_url, {})).get( + "key", None + ) # Legacy support + + +########################################## +# +# API routes +# +########################################## + +router = APIRouter() + + +@router.head("/") +@router.get("/") +async def get_status(): + return {"status": True} + + +class ConnectionVerificationForm(BaseModel): + url: str + key: Optional[str] = None + + +@router.post("/verify") +async def verify_connection( + form_data: ConnectionVerificationForm, user=Depends(get_admin_user) +): + url = form_data.url + key = form_data.key + + async with aiohttp.ClientSession( + timeout=aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT_OPENAI_MODEL_LIST) + ) as session: + try: + async with session.get( + f"{url}/api/version", + headers={ + **({"Authorization": f"Bearer {key}"} if key else {}), + **( + { + "X-OpenWebUI-User-Name": user.name, + "X-OpenWebUI-User-Id": user.id, + "X-OpenWebUI-User-Email": user.email, + "X-OpenWebUI-User-Role": user.role, + } + if ENABLE_FORWARD_USER_INFO_HEADERS and user + else {} + ), + }, + ) as r: + if r.status != 200: + detail = f"HTTP Error: {r.status}" + res = await r.json() + + if "error" in res: + detail = f"External Error: {res['error']}" + raise Exception(detail) + + data = await r.json() + return data + except aiohttp.ClientError as e: + log.exception(f"Client error: {str(e)}") + raise HTTPException( + status_code=500, detail="Open WebUI: Server Connection Error" + ) + except Exception as e: + log.exception(f"Unexpected error: {e}") + error_detail = f"Unexpected error: {str(e)}" + raise HTTPException(status_code=500, detail=error_detail) + + +@router.get("/config") +async def get_config(request: Request, user=Depends(get_admin_user)): + return { + "ENABLE_OLLAMA_API": request.app.state.config.ENABLE_OLLAMA_API, + "OLLAMA_BASE_URLS": request.app.state.config.OLLAMA_BASE_URLS, + "OLLAMA_API_CONFIGS": request.app.state.config.OLLAMA_API_CONFIGS, + } + + +class OllamaConfigForm(BaseModel): + ENABLE_OLLAMA_API: Optional[bool] = None + OLLAMA_BASE_URLS: list[str] + OLLAMA_API_CONFIGS: dict + + +@router.post("/config/update") +async def update_config( + request: Request, form_data: OllamaConfigForm, user=Depends(get_admin_user) +): + request.app.state.config.ENABLE_OLLAMA_API = form_data.ENABLE_OLLAMA_API + + request.app.state.config.OLLAMA_BASE_URLS = form_data.OLLAMA_BASE_URLS + request.app.state.config.OLLAMA_API_CONFIGS = form_data.OLLAMA_API_CONFIGS + + # Remove the API configs that are not in the API URLS + keys = list(map(str, range(len(request.app.state.config.OLLAMA_BASE_URLS)))) + request.app.state.config.OLLAMA_API_CONFIGS = { + key: value + for key, value in request.app.state.config.OLLAMA_API_CONFIGS.items() + if key in keys + } + + return { + "ENABLE_OLLAMA_API": request.app.state.config.ENABLE_OLLAMA_API, + "OLLAMA_BASE_URLS": request.app.state.config.OLLAMA_BASE_URLS, + "OLLAMA_API_CONFIGS": request.app.state.config.OLLAMA_API_CONFIGS, + } + + +@cached(ttl=3) +async def get_all_models(request: Request, user: UserModel = None): + log.info("get_all_models()") + if request.app.state.config.ENABLE_OLLAMA_API: + request_tasks = [] + for idx, url in enumerate(request.app.state.config.OLLAMA_BASE_URLS): + if (str(idx) not in request.app.state.config.OLLAMA_API_CONFIGS) and ( + url not in request.app.state.config.OLLAMA_API_CONFIGS # Legacy support + ): + request_tasks.append(send_get_request(f"{url}/api/tags", user=user)) + else: + api_config = request.app.state.config.OLLAMA_API_CONFIGS.get( + str(idx), + request.app.state.config.OLLAMA_API_CONFIGS.get( + url, {} + ), # Legacy support + ) + + enable = api_config.get("enable", True) + key = api_config.get("key", None) + + if enable: + request_tasks.append( + send_get_request(f"{url}/api/tags", key, user=user) + ) + else: + request_tasks.append(asyncio.ensure_future(asyncio.sleep(0, None))) + + responses = await asyncio.gather(*request_tasks) + + for idx, response in enumerate(responses): + if response: + url = request.app.state.config.OLLAMA_BASE_URLS[idx] + api_config = request.app.state.config.OLLAMA_API_CONFIGS.get( + str(idx), + request.app.state.config.OLLAMA_API_CONFIGS.get( + url, {} + ), # Legacy support + ) + + prefix_id = api_config.get("prefix_id", None) + model_ids = api_config.get("model_ids", []) + + if len(model_ids) != 0 and "models" in response: + response["models"] = list( + filter( + lambda model: model["model"] in model_ids, + response["models"], + ) + ) + + if prefix_id: + for model in response.get("models", []): + model["model"] = f"{prefix_id}.{model['model']}" + + def merge_models_lists(model_lists): + merged_models = {} + + for idx, model_list in enumerate(model_lists): + if model_list is not None: + for model in model_list: + id = model["model"] + if id not in merged_models: + model["urls"] = [idx] + merged_models[id] = model + else: + merged_models[id]["urls"].append(idx) + + return list(merged_models.values()) + + models = { + "models": merge_models_lists( + map( + lambda response: response.get("models", []) if response else None, + responses, + ) + ) + } + + else: + models = {"models": []} + + request.app.state.OLLAMA_MODELS = { + model["model"]: model for model in models["models"] + } + return models + + +async def get_filtered_models(models, user): + # Filter models based on user access control + filtered_models = [] + for model in models.get("models", []): + model_info = Models.get_model_by_id(model["model"]) + if model_info: + if user.id == model_info.user_id or has_access( + user.id, type="read", access_control=model_info.access_control + ): + filtered_models.append(model) + return filtered_models + + +@router.get("/api/tags") +@router.get("/api/tags/{url_idx}") +async def get_ollama_tags( + request: Request, url_idx: Optional[int] = None, user=Depends(get_verified_user) +): + models = [] + + if url_idx is None: + models = await get_all_models(request, user=user) + else: + url = request.app.state.config.OLLAMA_BASE_URLS[url_idx] + key = get_api_key(url_idx, url, request.app.state.config.OLLAMA_API_CONFIGS) + + r = None + try: + r = requests.request( + method="GET", + url=f"{url}/api/tags", + headers={ + **({"Authorization": f"Bearer {key}"} if key else {}), + **( + { + "X-OpenWebUI-User-Name": user.name, + "X-OpenWebUI-User-Id": user.id, + "X-OpenWebUI-User-Email": user.email, + "X-OpenWebUI-User-Role": user.role, + } + if ENABLE_FORWARD_USER_INFO_HEADERS and user + else {} + ), + }, + ) + r.raise_for_status() + + models = r.json() + except Exception as e: + log.exception(e) + + detail = None + if r is not None: + try: + res = r.json() + if "error" in res: + detail = f"Ollama: {res['error']}" + except Exception: + detail = f"Ollama: {e}" + + raise HTTPException( + status_code=r.status_code if r else 500, + detail=detail if detail else "Open WebUI: Server Connection Error", + ) + + if user.role == "user" and not BYPASS_MODEL_ACCESS_CONTROL: + models["models"] = await get_filtered_models(models, user) + + return models + + +@router.get("/api/version") +@router.get("/api/version/{url_idx}") +async def get_ollama_versions(request: Request, url_idx: Optional[int] = None): + if request.app.state.config.ENABLE_OLLAMA_API: + if url_idx is None: + # returns lowest version + request_tasks = [ + send_get_request( + f"{url}/api/version", + request.app.state.config.OLLAMA_API_CONFIGS.get( + str(idx), + request.app.state.config.OLLAMA_API_CONFIGS.get( + url, {} + ), # Legacy support + ).get("key", None), + ) + for idx, url in enumerate(request.app.state.config.OLLAMA_BASE_URLS) + ] + responses = await asyncio.gather(*request_tasks) + responses = list(filter(lambda x: x is not None, responses)) + + if len(responses) > 0: + lowest_version = min( + responses, + key=lambda x: tuple( + map(int, re.sub(r"^v|-.*", "", x["version"]).split(".")) + ), + ) + + return {"version": lowest_version["version"]} + else: + raise HTTPException( + status_code=500, + detail=ERROR_MESSAGES.OLLAMA_NOT_FOUND, + ) + else: + url = request.app.state.config.OLLAMA_BASE_URLS[url_idx] + + r = None + try: + r = requests.request(method="GET", url=f"{url}/api/version") + r.raise_for_status() + + return r.json() + except Exception as e: + log.exception(e) + + detail = None + if r is not None: + try: + res = r.json() + if "error" in res: + detail = f"Ollama: {res['error']}" + except Exception: + detail = f"Ollama: {e}" + + raise HTTPException( + status_code=r.status_code if r else 500, + detail=detail if detail else "Open WebUI: Server Connection Error", + ) + else: + return {"version": False} + + +@router.get("/api/ps") +async def get_ollama_loaded_models(request: Request, user=Depends(get_verified_user)): + """ + List models that are currently loaded into Ollama memory, and which node they are loaded on. + """ + if request.app.state.config.ENABLE_OLLAMA_API: + request_tasks = [ + send_get_request( + f"{url}/api/ps", + request.app.state.config.OLLAMA_API_CONFIGS.get( + str(idx), + request.app.state.config.OLLAMA_API_CONFIGS.get( + url, {} + ), # Legacy support + ).get("key", None), + user=user, + ) + for idx, url in enumerate(request.app.state.config.OLLAMA_BASE_URLS) + ] + responses = await asyncio.gather(*request_tasks) + + return dict(zip(request.app.state.config.OLLAMA_BASE_URLS, responses)) + else: + return {} + + +class ModelNameForm(BaseModel): + name: str + + +@router.post("/api/pull") +@router.post("/api/pull/{url_idx}") +async def pull_model( + request: Request, + form_data: ModelNameForm, + url_idx: int = 0, + user=Depends(get_admin_user), +): + url = request.app.state.config.OLLAMA_BASE_URLS[url_idx] + log.info(f"url: {url}") + + # Admin should be able to pull models from any source + payload = {**form_data.model_dump(exclude_none=True), "insecure": True} + + return await send_post_request( + url=f"{url}/api/pull", + payload=json.dumps(payload), + key=get_api_key(url_idx, url, request.app.state.config.OLLAMA_API_CONFIGS), + user=user, + ) + + +class PushModelForm(BaseModel): + name: str + insecure: Optional[bool] = None + stream: Optional[bool] = None + + +@router.delete("/api/push") +@router.delete("/api/push/{url_idx}") +async def push_model( + request: Request, + form_data: PushModelForm, + url_idx: Optional[int] = None, + user=Depends(get_admin_user), +): + if url_idx is None: + await get_all_models(request, user=user) + models = request.app.state.OLLAMA_MODELS + + if form_data.name in models: + url_idx = models[form_data.name]["urls"][0] + else: + raise HTTPException( + status_code=400, + detail=ERROR_MESSAGES.MODEL_NOT_FOUND(form_data.name), + ) + + url = request.app.state.config.OLLAMA_BASE_URLS[url_idx] + log.debug(f"url: {url}") + + return await send_post_request( + url=f"{url}/api/push", + payload=form_data.model_dump_json(exclude_none=True).encode(), + key=get_api_key(url_idx, url, request.app.state.config.OLLAMA_API_CONFIGS), + user=user, + ) + + +class CreateModelForm(BaseModel): + model: Optional[str] = None + stream: Optional[bool] = None + path: Optional[str] = None + + model_config = ConfigDict(extra="allow") + + +@router.post("/api/create") +@router.post("/api/create/{url_idx}") +async def create_model( + request: Request, + form_data: CreateModelForm, + url_idx: int = 0, + user=Depends(get_admin_user), +): + log.debug(f"form_data: {form_data}") + url = request.app.state.config.OLLAMA_BASE_URLS[url_idx] + + return await send_post_request( + url=f"{url}/api/create", + payload=form_data.model_dump_json(exclude_none=True).encode(), + key=get_api_key(url_idx, url, request.app.state.config.OLLAMA_API_CONFIGS), + user=user, + ) + + +class CopyModelForm(BaseModel): + source: str + destination: str + + +@router.post("/api/copy") +@router.post("/api/copy/{url_idx}") +async def copy_model( + request: Request, + form_data: CopyModelForm, + url_idx: Optional[int] = None, + user=Depends(get_admin_user), +): + if url_idx is None: + await get_all_models(request, user=user) + models = request.app.state.OLLAMA_MODELS + + if form_data.source in models: + url_idx = models[form_data.source]["urls"][0] + else: + raise HTTPException( + status_code=400, + detail=ERROR_MESSAGES.MODEL_NOT_FOUND(form_data.source), + ) + + url = request.app.state.config.OLLAMA_BASE_URLS[url_idx] + key = get_api_key(url_idx, url, request.app.state.config.OLLAMA_API_CONFIGS) + + try: + r = requests.request( + method="POST", + url=f"{url}/api/copy", + headers={ + "Content-Type": "application/json", + **({"Authorization": f"Bearer {key}"} if key else {}), + **( + { + "X-OpenWebUI-User-Name": user.name, + "X-OpenWebUI-User-Id": user.id, + "X-OpenWebUI-User-Email": user.email, + "X-OpenWebUI-User-Role": user.role, + } + if ENABLE_FORWARD_USER_INFO_HEADERS and user + else {} + ), + }, + data=form_data.model_dump_json(exclude_none=True).encode(), + ) + r.raise_for_status() + + log.debug(f"r.text: {r.text}") + return True + except Exception as e: + log.exception(e) + + detail = None + if r is not None: + try: + res = r.json() + if "error" in res: + detail = f"Ollama: {res['error']}" + except Exception: + detail = f"Ollama: {e}" + + raise HTTPException( + status_code=r.status_code if r else 500, + detail=detail if detail else "Open WebUI: Server Connection Error", + ) + + +@router.delete("/api/delete") +@router.delete("/api/delete/{url_idx}") +async def delete_model( + request: Request, + form_data: ModelNameForm, + url_idx: Optional[int] = None, + user=Depends(get_admin_user), +): + if url_idx is None: + await get_all_models(request, user=user) + models = request.app.state.OLLAMA_MODELS + + if form_data.name in models: + url_idx = models[form_data.name]["urls"][0] + else: + raise HTTPException( + status_code=400, + detail=ERROR_MESSAGES.MODEL_NOT_FOUND(form_data.name), + ) + + url = request.app.state.config.OLLAMA_BASE_URLS[url_idx] + key = get_api_key(url_idx, url, request.app.state.config.OLLAMA_API_CONFIGS) + + try: + r = requests.request( + method="DELETE", + url=f"{url}/api/delete", + data=form_data.model_dump_json(exclude_none=True).encode(), + headers={ + "Content-Type": "application/json", + **({"Authorization": f"Bearer {key}"} if key else {}), + **( + { + "X-OpenWebUI-User-Name": user.name, + "X-OpenWebUI-User-Id": user.id, + "X-OpenWebUI-User-Email": user.email, + "X-OpenWebUI-User-Role": user.role, + } + if ENABLE_FORWARD_USER_INFO_HEADERS and user + else {} + ), + }, + ) + r.raise_for_status() + + log.debug(f"r.text: {r.text}") + return True + except Exception as e: + log.exception(e) + + detail = None + if r is not None: + try: + res = r.json() + if "error" in res: + detail = f"Ollama: {res['error']}" + except Exception: + detail = f"Ollama: {e}" + + raise HTTPException( + status_code=r.status_code if r else 500, + detail=detail if detail else "Open WebUI: Server Connection Error", + ) + + +@router.post("/api/show") +async def show_model_info( + request: Request, form_data: ModelNameForm, user=Depends(get_verified_user) +): + await get_all_models(request, user=user) + models = request.app.state.OLLAMA_MODELS + + if form_data.name not in models: + raise HTTPException( + status_code=400, + detail=ERROR_MESSAGES.MODEL_NOT_FOUND(form_data.name), + ) + + url_idx = random.choice(models[form_data.name]["urls"]) + + url = request.app.state.config.OLLAMA_BASE_URLS[url_idx] + key = get_api_key(url_idx, url, request.app.state.config.OLLAMA_API_CONFIGS) + + try: + r = requests.request( + method="POST", + url=f"{url}/api/show", + headers={ + "Content-Type": "application/json", + **({"Authorization": f"Bearer {key}"} if key else {}), + **( + { + "X-OpenWebUI-User-Name": user.name, + "X-OpenWebUI-User-Id": user.id, + "X-OpenWebUI-User-Email": user.email, + "X-OpenWebUI-User-Role": user.role, + } + if ENABLE_FORWARD_USER_INFO_HEADERS and user + else {} + ), + }, + data=form_data.model_dump_json(exclude_none=True).encode(), + ) + r.raise_for_status() + + return r.json() + except Exception as e: + log.exception(e) + + detail = None + if r is not None: + try: + res = r.json() + if "error" in res: + detail = f"Ollama: {res['error']}" + except Exception: + detail = f"Ollama: {e}" + + raise HTTPException( + status_code=r.status_code if r else 500, + detail=detail if detail else "Open WebUI: Server Connection Error", + ) + + +class GenerateEmbedForm(BaseModel): + model: str + input: list[str] | str + truncate: Optional[bool] = None + options: Optional[dict] = None + keep_alive: Optional[Union[int, str]] = None + + +@router.post("/api/embed") +@router.post("/api/embed/{url_idx}") +async def embed( + request: Request, + form_data: GenerateEmbedForm, + url_idx: Optional[int] = None, + user=Depends(get_verified_user), +): + log.info(f"generate_ollama_batch_embeddings {form_data}") + + if url_idx is None: + await get_all_models(request, user=user) + models = request.app.state.OLLAMA_MODELS + + model = form_data.model + + if ":" not in model: + model = f"{model}:latest" + + if model in models: + url_idx = random.choice(models[model]["urls"]) + else: + raise HTTPException( + status_code=400, + detail=ERROR_MESSAGES.MODEL_NOT_FOUND(form_data.model), + ) + + url = request.app.state.config.OLLAMA_BASE_URLS[url_idx] + key = get_api_key(url_idx, url, request.app.state.config.OLLAMA_API_CONFIGS) + + try: + r = requests.request( + method="POST", + url=f"{url}/api/embed", + headers={ + "Content-Type": "application/json", + **({"Authorization": f"Bearer {key}"} if key else {}), + **( + { + "X-OpenWebUI-User-Name": user.name, + "X-OpenWebUI-User-Id": user.id, + "X-OpenWebUI-User-Email": user.email, + "X-OpenWebUI-User-Role": user.role, + } + if ENABLE_FORWARD_USER_INFO_HEADERS and user + else {} + ), + }, + data=form_data.model_dump_json(exclude_none=True).encode(), + ) + r.raise_for_status() + + data = r.json() + return data + except Exception as e: + log.exception(e) + + detail = None + if r is not None: + try: + res = r.json() + if "error" in res: + detail = f"Ollama: {res['error']}" + except Exception: + detail = f"Ollama: {e}" + + raise HTTPException( + status_code=r.status_code if r else 500, + detail=detail if detail else "Open WebUI: Server Connection Error", + ) + + +class GenerateEmbeddingsForm(BaseModel): + model: str + prompt: str + options: Optional[dict] = None + keep_alive: Optional[Union[int, str]] = None + + +@router.post("/api/embeddings") +@router.post("/api/embeddings/{url_idx}") +async def embeddings( + request: Request, + form_data: GenerateEmbeddingsForm, + url_idx: Optional[int] = None, + user=Depends(get_verified_user), +): + log.info(f"generate_ollama_embeddings {form_data}") + + if url_idx is None: + await get_all_models(request, user=user) + models = request.app.state.OLLAMA_MODELS + + model = form_data.model + + if ":" not in model: + model = f"{model}:latest" + + if model in models: + url_idx = random.choice(models[model]["urls"]) + else: + raise HTTPException( + status_code=400, + detail=ERROR_MESSAGES.MODEL_NOT_FOUND(form_data.model), + ) + + url = request.app.state.config.OLLAMA_BASE_URLS[url_idx] + key = get_api_key(url_idx, url, request.app.state.config.OLLAMA_API_CONFIGS) + + try: + r = requests.request( + method="POST", + url=f"{url}/api/embeddings", + headers={ + "Content-Type": "application/json", + **({"Authorization": f"Bearer {key}"} if key else {}), + **( + { + "X-OpenWebUI-User-Name": user.name, + "X-OpenWebUI-User-Id": user.id, + "X-OpenWebUI-User-Email": user.email, + "X-OpenWebUI-User-Role": user.role, + } + if ENABLE_FORWARD_USER_INFO_HEADERS and user + else {} + ), + }, + data=form_data.model_dump_json(exclude_none=True).encode(), + ) + r.raise_for_status() + + data = r.json() + return data + except Exception as e: + log.exception(e) + + detail = None + if r is not None: + try: + res = r.json() + if "error" in res: + detail = f"Ollama: {res['error']}" + except Exception: + detail = f"Ollama: {e}" + + raise HTTPException( + status_code=r.status_code if r else 500, + detail=detail if detail else "Open WebUI: Server Connection Error", + ) + + +class GenerateCompletionForm(BaseModel): + model: str + prompt: str + suffix: Optional[str] = None + images: Optional[list[str]] = None + format: Optional[str] = None + options: Optional[dict] = None + system: Optional[str] = None + template: Optional[str] = None + context: Optional[list[int]] = None + stream: Optional[bool] = True + raw: Optional[bool] = None + keep_alive: Optional[Union[int, str]] = None + + +@router.post("/api/generate") +@router.post("/api/generate/{url_idx}") +async def generate_completion( + request: Request, + form_data: GenerateCompletionForm, + url_idx: Optional[int] = None, + user=Depends(get_verified_user), +): + if url_idx is None: + await get_all_models(request, user=user) + models = request.app.state.OLLAMA_MODELS + + model = form_data.model + + if ":" not in model: + model = f"{model}:latest" + + if model in models: + url_idx = random.choice(models[model]["urls"]) + else: + raise HTTPException( + status_code=400, + detail=ERROR_MESSAGES.MODEL_NOT_FOUND(form_data.model), + ) + + url = request.app.state.config.OLLAMA_BASE_URLS[url_idx] + api_config = request.app.state.config.OLLAMA_API_CONFIGS.get( + str(url_idx), + request.app.state.config.OLLAMA_API_CONFIGS.get(url, {}), # Legacy support + ) + + prefix_id = api_config.get("prefix_id", None) + if prefix_id: + form_data.model = form_data.model.replace(f"{prefix_id}.", "") + + return await send_post_request( + url=f"{url}/api/generate", + payload=form_data.model_dump_json(exclude_none=True).encode(), + key=get_api_key(url_idx, url, request.app.state.config.OLLAMA_API_CONFIGS), + user=user, + ) + + +class ChatMessage(BaseModel): + role: str + content: Optional[str] = None + tool_calls: Optional[list[dict]] = None + images: Optional[list[str]] = None + + @validator("content", pre=True) + @classmethod + def check_at_least_one_field(cls, field_value, values, **kwargs): + # Raise an error if both 'content' and 'tool_calls' are None + if field_value is None and ( + "tool_calls" not in values or values["tool_calls"] is None + ): + raise ValueError( + "At least one of 'content' or 'tool_calls' must be provided" + ) + + return field_value + + +class GenerateChatCompletionForm(BaseModel): + model: str + messages: list[ChatMessage] + format: Optional[Union[dict, str]] = None + options: Optional[dict] = None + template: Optional[str] = None + stream: Optional[bool] = True + keep_alive: Optional[Union[int, str]] = None + tools: Optional[list[dict]] = None + + +async def get_ollama_url(request: Request, model: str, url_idx: Optional[int] = None): + if url_idx is None: + models = request.app.state.OLLAMA_MODELS + if model not in models: + raise HTTPException( + status_code=400, + detail=ERROR_MESSAGES.MODEL_NOT_FOUND(model), + ) + url_idx = random.choice(models[model].get("urls", [])) + url = request.app.state.config.OLLAMA_BASE_URLS[url_idx] + return url, url_idx + + +@router.post("/api/chat") +@router.post("/api/chat/{url_idx}") +async def generate_chat_completion( + request: Request, + form_data: dict, + url_idx: Optional[int] = None, + user=Depends(get_verified_user), + bypass_filter: Optional[bool] = False, +): + if BYPASS_MODEL_ACCESS_CONTROL: + bypass_filter = True + + metadata = form_data.pop("metadata", None) + try: + form_data = GenerateChatCompletionForm(**form_data) + except Exception as e: + log.exception(e) + raise HTTPException( + status_code=400, + detail=str(e), + ) + + payload = {**form_data.model_dump(exclude_none=True)} + if "metadata" in payload: + del payload["metadata"] + + model_id = payload["model"] + model_info = Models.get_model_by_id(model_id) + + if model_info: + if model_info.base_model_id: + payload["model"] = model_info.base_model_id + + params = model_info.params.model_dump() + + if params: + if payload.get("options") is None: + payload["options"] = {} + + payload["options"] = apply_model_params_to_body_ollama( + params, payload["options"] + ) + payload = apply_model_system_prompt_to_body(params, payload, metadata, user) + + # Check if user has access to the model + if not bypass_filter and user.role == "user": + if not ( + user.id == model_info.user_id + or has_access( + user.id, type="read", access_control=model_info.access_control + ) + ): + raise HTTPException( + status_code=403, + detail="Model not found", + ) + elif not bypass_filter: + if user.role != "admin": + raise HTTPException( + status_code=403, + detail="Model not found", + ) + + if ":" not in payload["model"]: + payload["model"] = f"{payload['model']}:latest" + + url, url_idx = await get_ollama_url(request, payload["model"], url_idx) + api_config = request.app.state.config.OLLAMA_API_CONFIGS.get( + str(url_idx), + request.app.state.config.OLLAMA_API_CONFIGS.get(url, {}), # Legacy support + ) + + prefix_id = api_config.get("prefix_id", None) + if prefix_id: + payload["model"] = payload["model"].replace(f"{prefix_id}.", "") + + return await send_post_request( + url=f"{url}/api/chat", + payload=json.dumps(payload), + stream=form_data.stream, + key=get_api_key(url_idx, url, request.app.state.config.OLLAMA_API_CONFIGS), + content_type="application/x-ndjson", + user=user, + ) + + +# TODO: we should update this part once Ollama supports other types +class OpenAIChatMessageContent(BaseModel): + type: str + model_config = ConfigDict(extra="allow") + + +class OpenAIChatMessage(BaseModel): + role: str + content: Union[str, list[OpenAIChatMessageContent]] + + model_config = ConfigDict(extra="allow") + + +class OpenAIChatCompletionForm(BaseModel): + model: str + messages: list[OpenAIChatMessage] + + model_config = ConfigDict(extra="allow") + + +class OpenAICompletionForm(BaseModel): + model: str + prompt: str + + model_config = ConfigDict(extra="allow") + + +@router.post("/v1/completions") +@router.post("/v1/completions/{url_idx}") +async def generate_openai_completion( + request: Request, + form_data: dict, + url_idx: Optional[int] = None, + user=Depends(get_verified_user), +): + try: + form_data = OpenAICompletionForm(**form_data) + except Exception as e: + log.exception(e) + raise HTTPException( + status_code=400, + detail=str(e), + ) + + payload = {**form_data.model_dump(exclude_none=True, exclude=["metadata"])} + if "metadata" in payload: + del payload["metadata"] + + model_id = form_data.model + if ":" not in model_id: + model_id = f"{model_id}:latest" + + model_info = Models.get_model_by_id(model_id) + if model_info: + if model_info.base_model_id: + payload["model"] = model_info.base_model_id + params = model_info.params.model_dump() + + if params: + payload = apply_model_params_to_body_openai(params, payload) + + # Check if user has access to the model + if user.role == "user": + if not ( + user.id == model_info.user_id + or has_access( + user.id, type="read", access_control=model_info.access_control + ) + ): + raise HTTPException( + status_code=403, + detail="Model not found", + ) + else: + if user.role != "admin": + raise HTTPException( + status_code=403, + detail="Model not found", + ) + + if ":" not in payload["model"]: + payload["model"] = f"{payload['model']}:latest" + + url, url_idx = await get_ollama_url(request, payload["model"], url_idx) + api_config = request.app.state.config.OLLAMA_API_CONFIGS.get( + str(url_idx), + request.app.state.config.OLLAMA_API_CONFIGS.get(url, {}), # Legacy support + ) + + prefix_id = api_config.get("prefix_id", None) + + if prefix_id: + payload["model"] = payload["model"].replace(f"{prefix_id}.", "") + + return await send_post_request( + url=f"{url}/v1/completions", + payload=json.dumps(payload), + stream=payload.get("stream", False), + key=get_api_key(url_idx, url, request.app.state.config.OLLAMA_API_CONFIGS), + user=user, + ) + + +@router.post("/v1/chat/completions") +@router.post("/v1/chat/completions/{url_idx}") +async def generate_openai_chat_completion( + request: Request, + form_data: dict, + url_idx: Optional[int] = None, + user=Depends(get_verified_user), +): + metadata = form_data.pop("metadata", None) + + try: + completion_form = OpenAIChatCompletionForm(**form_data) + except Exception as e: + log.exception(e) + raise HTTPException( + status_code=400, + detail=str(e), + ) + + payload = {**completion_form.model_dump(exclude_none=True, exclude=["metadata"])} + if "metadata" in payload: + del payload["metadata"] + + model_id = completion_form.model + if ":" not in model_id: + model_id = f"{model_id}:latest" + + model_info = Models.get_model_by_id(model_id) + if model_info: + if model_info.base_model_id: + payload["model"] = model_info.base_model_id + + params = model_info.params.model_dump() + + if params: + payload = apply_model_params_to_body_openai(params, payload) + payload = apply_model_system_prompt_to_body(params, payload, metadata, user) + + # Check if user has access to the model + if user.role == "user": + if not ( + user.id == model_info.user_id + or has_access( + user.id, type="read", access_control=model_info.access_control + ) + ): + raise HTTPException( + status_code=403, + detail="Model not found", + ) + else: + if user.role != "admin": + raise HTTPException( + status_code=403, + detail="Model not found", + ) + + if ":" not in payload["model"]: + payload["model"] = f"{payload['model']}:latest" + + url, url_idx = await get_ollama_url(request, payload["model"], url_idx) + api_config = request.app.state.config.OLLAMA_API_CONFIGS.get( + str(url_idx), + request.app.state.config.OLLAMA_API_CONFIGS.get(url, {}), # Legacy support + ) + + prefix_id = api_config.get("prefix_id", None) + if prefix_id: + payload["model"] = payload["model"].replace(f"{prefix_id}.", "") + + return await send_post_request( + url=f"{url}/v1/chat/completions", + payload=json.dumps(payload), + stream=payload.get("stream", False), + key=get_api_key(url_idx, url, request.app.state.config.OLLAMA_API_CONFIGS), + user=user, + ) + + +@router.get("/v1/models") +@router.get("/v1/models/{url_idx}") +async def get_openai_models( + request: Request, + url_idx: Optional[int] = None, + user=Depends(get_verified_user), +): + + models = [] + if url_idx is None: + model_list = await get_all_models(request, user=user) + models = [ + { + "id": model["model"], + "object": "model", + "created": int(time.time()), + "owned_by": "openai", + } + for model in model_list["models"] + ] + + else: + url = request.app.state.config.OLLAMA_BASE_URLS[url_idx] + try: + r = requests.request(method="GET", url=f"{url}/api/tags") + r.raise_for_status() + + model_list = r.json() + + models = [ + { + "id": model["model"], + "object": "model", + "created": int(time.time()), + "owned_by": "openai", + } + for model in models["models"] + ] + except Exception as e: + log.exception(e) + error_detail = "Open WebUI: Server Connection Error" + if r is not None: + try: + res = r.json() + if "error" in res: + error_detail = f"Ollama: {res['error']}" + except Exception: + error_detail = f"Ollama: {e}" + + raise HTTPException( + status_code=r.status_code if r else 500, + detail=error_detail, + ) + + if user.role == "user" and not BYPASS_MODEL_ACCESS_CONTROL: + # Filter models based on user access control + filtered_models = [] + for model in models: + model_info = Models.get_model_by_id(model["id"]) + if model_info: + if user.id == model_info.user_id or has_access( + user.id, type="read", access_control=model_info.access_control + ): + filtered_models.append(model) + models = filtered_models + + return { + "data": models, + "object": "list", + } + + +class UrlForm(BaseModel): + url: str + + +class UploadBlobForm(BaseModel): + filename: str + + +def parse_huggingface_url(hf_url): + try: + # Parse the URL + parsed_url = urlparse(hf_url) + + # Get the path and split it into components + path_components = parsed_url.path.split("/") + + # Extract the desired output + model_file = path_components[-1] + + return model_file + except ValueError: + return None + + +async def download_file_stream( + ollama_url, file_url, file_path, file_name, chunk_size=1024 * 1024 +): + done = False + + if os.path.exists(file_path): + current_size = os.path.getsize(file_path) + else: + current_size = 0 + + headers = {"Range": f"bytes={current_size}-"} if current_size > 0 else {} + + timeout = aiohttp.ClientTimeout(total=600) # Set the timeout + + async with aiohttp.ClientSession(timeout=timeout, trust_env=True) as session: + async with session.get(file_url, headers=headers) as response: + total_size = int(response.headers.get("content-length", 0)) + current_size + + with open(file_path, "ab+") as file: + async for data in response.content.iter_chunked(chunk_size): + current_size += len(data) + file.write(data) + + done = current_size == total_size + progress = round((current_size / total_size) * 100, 2) + + yield f'data: {{"progress": {progress}, "completed": {current_size}, "total": {total_size}}}\n\n' + + if done: + file.seek(0) + hashed = calculate_sha256(file) + file.seek(0) + + url = f"{ollama_url}/api/blobs/sha256:{hashed}" + response = requests.post(url, data=file) + + if response.ok: + res = { + "done": done, + "blob": f"sha256:{hashed}", + "name": file_name, + } + os.remove(file_path) + + yield f"data: {json.dumps(res)}\n\n" + else: + raise "Ollama: Could not create blob, Please try again." + + +# url = "https://huggingface.co/TheBloke/stablelm-zephyr-3b-GGUF/resolve/main/stablelm-zephyr-3b.Q2_K.gguf" +@router.post("/models/download") +@router.post("/models/download/{url_idx}") +async def download_model( + request: Request, + form_data: UrlForm, + url_idx: Optional[int] = None, + user=Depends(get_admin_user), +): + allowed_hosts = ["https://huggingface.co/", "https://github.com/"] + + if not any(form_data.url.startswith(host) for host in allowed_hosts): + raise HTTPException( + status_code=400, + detail="Invalid file_url. Only URLs from allowed hosts are permitted.", + ) + + if url_idx is None: + url_idx = 0 + url = request.app.state.config.OLLAMA_BASE_URLS[url_idx] + + file_name = parse_huggingface_url(form_data.url) + + if file_name: + file_path = f"{UPLOAD_DIR}/{file_name}" + + return StreamingResponse( + download_file_stream(url, form_data.url, file_path, file_name), + ) + else: + return None + + +# TODO: Progress bar does not reflect size & duration of upload. +@router.post("/models/upload") +@router.post("/models/upload/{url_idx}") +async def upload_model( + request: Request, + file: UploadFile = File(...), + url_idx: Optional[int] = None, + user=Depends(get_admin_user), +): + if url_idx is None: + url_idx = 0 + ollama_url = request.app.state.config.OLLAMA_BASE_URLS[url_idx] + file_path = os.path.join(UPLOAD_DIR, file.filename) + os.makedirs(UPLOAD_DIR, exist_ok=True) + + # --- P1: save file locally --- + chunk_size = 1024 * 1024 * 2 # 2 MB chunks + with open(file_path, "wb") as out_f: + while True: + chunk = file.file.read(chunk_size) + # log.info(f"Chunk: {str(chunk)}") # DEBUG + if not chunk: + break + out_f.write(chunk) + + async def file_process_stream(): + nonlocal ollama_url + total_size = os.path.getsize(file_path) + log.info(f"Total Model Size: {str(total_size)}") # DEBUG + + # --- P2: SSE progress + calculate sha256 hash --- + file_hash = calculate_sha256(file_path, chunk_size) + log.info(f"Model Hash: {str(file_hash)}") # DEBUG + try: + with open(file_path, "rb") as f: + bytes_read = 0 + while chunk := f.read(chunk_size): + bytes_read += len(chunk) + progress = round(bytes_read / total_size * 100, 2) + data_msg = { + "progress": progress, + "total": total_size, + "completed": bytes_read, + } + yield f"data: {json.dumps(data_msg)}\n\n" + + # --- P3: Upload to ollama /api/blobs --- + with open(file_path, "rb") as f: + url = f"{ollama_url}/api/blobs/sha256:{file_hash}" + response = requests.post(url, data=f) + + if response.ok: + log.info(f"Uploaded to /api/blobs") # DEBUG + # Remove local file + os.remove(file_path) + + # Create model in ollama + model_name, ext = os.path.splitext(file.filename) + log.info(f"Created Model: {model_name}") # DEBUG + + create_payload = { + "model": model_name, + # Reference the file by its original name => the uploaded blob's digest + "files": {file.filename: f"sha256:{file_hash}"}, + } + log.info(f"Model Payload: {create_payload}") # DEBUG + + # Call ollama /api/create + # https://github.com/ollama/ollama/blob/main/docs/api.md#create-a-model + create_resp = requests.post( + url=f"{ollama_url}/api/create", + headers={"Content-Type": "application/json"}, + data=json.dumps(create_payload), + ) + + if create_resp.ok: + log.info(f"API SUCCESS!") # DEBUG + done_msg = { + "done": True, + "blob": f"sha256:{file_hash}", + "name": file.filename, + "model_created": model_name, + } + yield f"data: {json.dumps(done_msg)}\n\n" + else: + raise Exception( + f"Failed to create model in Ollama. {create_resp.text}" + ) + + else: + raise Exception("Ollama: Could not create blob, Please try again.") + + except Exception as e: + res = {"error": str(e)} + yield f"data: {json.dumps(res)}\n\n" + + return StreamingResponse(file_process_stream(), media_type="text/event-stream") diff --git a/backend/open_webui/routers/openai.py b/backend/open_webui/routers/openai.py new file mode 100644 index 0000000..990df83 --- /dev/null +++ b/backend/open_webui/routers/openai.py @@ -0,0 +1,826 @@ +import asyncio +import hashlib +import json +import logging +from pathlib import Path +from typing import Literal, Optional, overload + +import aiohttp +from aiocache import cached +import requests + + +from fastapi import Depends, FastAPI, HTTPException, Request, APIRouter +from fastapi.middleware.cors import CORSMiddleware +from fastapi.responses import FileResponse, StreamingResponse +from pydantic import BaseModel +from starlette.background import BackgroundTask + +from open_webui.models.models import Models +from open_webui.config import ( + CACHE_DIR, +) +from open_webui.env import ( + AIOHTTP_CLIENT_TIMEOUT, + AIOHTTP_CLIENT_TIMEOUT_OPENAI_MODEL_LIST, + ENABLE_FORWARD_USER_INFO_HEADERS, + BYPASS_MODEL_ACCESS_CONTROL, +) +from open_webui.models.users import UserModel + +from open_webui.constants import ERROR_MESSAGES +from open_webui.env import ENV, SRC_LOG_LEVELS + + +from open_webui.utils.payload import ( + apply_model_params_to_body_openai, + apply_model_system_prompt_to_body, +) + +from open_webui.utils.auth import get_admin_user, get_verified_user +from open_webui.utils.access_control import has_access + + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["OPENAI"]) + + +########################################## +# +# Utility functions +# +########################################## + + +async def send_get_request(url, key=None, user: UserModel = None): + timeout = aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT_OPENAI_MODEL_LIST) + try: + async with aiohttp.ClientSession(timeout=timeout, trust_env=True) as session: + async with session.get( + url, + headers={ + **({"Authorization": f"Bearer {key}"} if key else {}), + **( + { + "X-OpenWebUI-User-Name": user.name, + "X-OpenWebUI-User-Id": user.id, + "X-OpenWebUI-User-Email": user.email, + "X-OpenWebUI-User-Role": user.role, + } + if ENABLE_FORWARD_USER_INFO_HEADERS and user + else {} + ), + }, + ) as response: + return await response.json() + except Exception as e: + # Handle connection error here + log.error(f"Connection error: {e}") + return None + + +async def cleanup_response( + response: Optional[aiohttp.ClientResponse], + session: Optional[aiohttp.ClientSession], +): + if response: + response.close() + if session: + await session.close() + + +def openai_o1_o3_handler(payload): + """ + Handle o1, o3 specific parameters + """ + if "max_tokens" in payload: + # Remove "max_tokens" from the payload + payload["max_completion_tokens"] = payload["max_tokens"] + del payload["max_tokens"] + + # Fix: o1 and o3 do not support the "system" role directly. + # For older models like "o1-mini" or "o1-preview", use role "user". + # For newer o1/o3 models, replace "system" with "developer". + if payload["messages"][0]["role"] == "system": + model_lower = payload["model"].lower() + if model_lower.startswith("o1-mini") or model_lower.startswith("o1-preview"): + payload["messages"][0]["role"] = "user" + else: + payload["messages"][0]["role"] = "developer" + + return payload + + +########################################## +# +# API routes +# +########################################## + +router = APIRouter() + + +@router.get("/config") +async def get_config(request: Request, user=Depends(get_admin_user)): + return { + "ENABLE_OPENAI_API": request.app.state.config.ENABLE_OPENAI_API, + "OPENAI_API_BASE_URLS": request.app.state.config.OPENAI_API_BASE_URLS, + "OPENAI_API_KEYS": request.app.state.config.OPENAI_API_KEYS, + "OPENAI_API_CONFIGS": request.app.state.config.OPENAI_API_CONFIGS, + } + + +class OpenAIConfigForm(BaseModel): + ENABLE_OPENAI_API: Optional[bool] = None + OPENAI_API_BASE_URLS: list[str] + OPENAI_API_KEYS: list[str] + OPENAI_API_CONFIGS: dict + + +@router.post("/config/update") +async def update_config( + request: Request, form_data: OpenAIConfigForm, user=Depends(get_admin_user) +): + request.app.state.config.ENABLE_OPENAI_API = form_data.ENABLE_OPENAI_API + request.app.state.config.OPENAI_API_BASE_URLS = form_data.OPENAI_API_BASE_URLS + request.app.state.config.OPENAI_API_KEYS = form_data.OPENAI_API_KEYS + + # Check if API KEYS length is same than API URLS length + if len(request.app.state.config.OPENAI_API_KEYS) != len( + request.app.state.config.OPENAI_API_BASE_URLS + ): + if len(request.app.state.config.OPENAI_API_KEYS) > len( + request.app.state.config.OPENAI_API_BASE_URLS + ): + request.app.state.config.OPENAI_API_KEYS = ( + request.app.state.config.OPENAI_API_KEYS[ + : len(request.app.state.config.OPENAI_API_BASE_URLS) + ] + ) + else: + request.app.state.config.OPENAI_API_KEYS += [""] * ( + len(request.app.state.config.OPENAI_API_BASE_URLS) + - len(request.app.state.config.OPENAI_API_KEYS) + ) + + request.app.state.config.OPENAI_API_CONFIGS = form_data.OPENAI_API_CONFIGS + + # Remove the API configs that are not in the API URLS + keys = list(map(str, range(len(request.app.state.config.OPENAI_API_BASE_URLS)))) + request.app.state.config.OPENAI_API_CONFIGS = { + key: value + for key, value in request.app.state.config.OPENAI_API_CONFIGS.items() + if key in keys + } + + return { + "ENABLE_OPENAI_API": request.app.state.config.ENABLE_OPENAI_API, + "OPENAI_API_BASE_URLS": request.app.state.config.OPENAI_API_BASE_URLS, + "OPENAI_API_KEYS": request.app.state.config.OPENAI_API_KEYS, + "OPENAI_API_CONFIGS": request.app.state.config.OPENAI_API_CONFIGS, + } + + +@router.post("/audio/speech") +async def speech(request: Request, user=Depends(get_verified_user)): + idx = None + try: + idx = request.app.state.config.OPENAI_API_BASE_URLS.index( + "https://api.openai.com/v1" + ) + + body = await request.body() + name = hashlib.sha256(body).hexdigest() + + SPEECH_CACHE_DIR = Path(CACHE_DIR).joinpath("./audio/speech/") + SPEECH_CACHE_DIR.mkdir(parents=True, exist_ok=True) + file_path = SPEECH_CACHE_DIR.joinpath(f"{name}.mp3") + file_body_path = SPEECH_CACHE_DIR.joinpath(f"{name}.json") + + # Check if the file already exists in the cache + if file_path.is_file(): + return FileResponse(file_path) + + url = request.app.state.config.OPENAI_API_BASE_URLS[idx] + + r = None + try: + r = requests.post( + url=f"{url}/audio/speech", + data=body, + headers={ + "Content-Type": "application/json", + "Authorization": f"Bearer {request.app.state.config.OPENAI_API_KEYS[idx]}", + **( + { + "HTTP-Referer": "https://openwebui.com/", + "X-Title": "Open WebUI", + } + if "openrouter.ai" in url + else {} + ), + **( + { + "X-OpenWebUI-User-Name": user.name, + "X-OpenWebUI-User-Id": user.id, + "X-OpenWebUI-User-Email": user.email, + "X-OpenWebUI-User-Role": user.role, + } + if ENABLE_FORWARD_USER_INFO_HEADERS + else {} + ), + }, + stream=True, + ) + + r.raise_for_status() + + # Save the streaming content to a file + with open(file_path, "wb") as f: + for chunk in r.iter_content(chunk_size=8192): + f.write(chunk) + + with open(file_body_path, "w") as f: + json.dump(json.loads(body.decode("utf-8")), f) + + # Return the saved file + return FileResponse(file_path) + + except Exception as e: + log.exception(e) + + detail = None + if r is not None: + try: + res = r.json() + if "error" in res: + detail = f"External: {res['error']}" + except Exception: + detail = f"External: {e}" + + raise HTTPException( + status_code=r.status_code if r else 500, + detail=detail if detail else "Open WebUI: Server Connection Error", + ) + + except ValueError: + raise HTTPException(status_code=401, detail=ERROR_MESSAGES.OPENAI_NOT_FOUND) + + +async def get_all_models_responses(request: Request, user: UserModel) -> list: + if not request.app.state.config.ENABLE_OPENAI_API: + return [] + + # Check if API KEYS length is same than API URLS length + num_urls = len(request.app.state.config.OPENAI_API_BASE_URLS) + num_keys = len(request.app.state.config.OPENAI_API_KEYS) + + if num_keys != num_urls: + # if there are more keys than urls, remove the extra keys + if num_keys > num_urls: + new_keys = request.app.state.config.OPENAI_API_KEYS[:num_urls] + request.app.state.config.OPENAI_API_KEYS = new_keys + # if there are more urls than keys, add empty keys + else: + request.app.state.config.OPENAI_API_KEYS += [""] * (num_urls - num_keys) + + request_tasks = [] + for idx, url in enumerate(request.app.state.config.OPENAI_API_BASE_URLS): + if (str(idx) not in request.app.state.config.OPENAI_API_CONFIGS) and ( + url not in request.app.state.config.OPENAI_API_CONFIGS # Legacy support + ): + request_tasks.append( + send_get_request( + f"{url}/models", + request.app.state.config.OPENAI_API_KEYS[idx], + user=user, + ) + ) + else: + api_config = request.app.state.config.OPENAI_API_CONFIGS.get( + str(idx), + request.app.state.config.OPENAI_API_CONFIGS.get( + url, {} + ), # Legacy support + ) + + enable = api_config.get("enable", True) + model_ids = api_config.get("model_ids", []) + + if enable: + if len(model_ids) == 0: + request_tasks.append( + send_get_request( + f"{url}/models", + request.app.state.config.OPENAI_API_KEYS[idx], + user=user, + ) + ) + else: + model_list = { + "object": "list", + "data": [ + { + "id": model_id, + "name": model_id, + "owned_by": "openai", + "openai": {"id": model_id}, + "urlIdx": idx, + } + for model_id in model_ids + ], + } + + request_tasks.append( + asyncio.ensure_future(asyncio.sleep(0, model_list)) + ) + else: + request_tasks.append(asyncio.ensure_future(asyncio.sleep(0, None))) + + responses = await asyncio.gather(*request_tasks) + + for idx, response in enumerate(responses): + if response: + url = request.app.state.config.OPENAI_API_BASE_URLS[idx] + api_config = request.app.state.config.OPENAI_API_CONFIGS.get( + str(idx), + request.app.state.config.OPENAI_API_CONFIGS.get( + url, {} + ), # Legacy support + ) + + prefix_id = api_config.get("prefix_id", None) + + if prefix_id: + for model in ( + response if isinstance(response, list) else response.get("data", []) + ): + model["id"] = f"{prefix_id}.{model['id']}" + + log.debug(f"get_all_models:responses() {responses}") + return responses + + +async def get_filtered_models(models, user): + # Filter models based on user access control + filtered_models = [] + for model in models.get("data", []): + model_info = Models.get_model_by_id(model["id"]) + if model_info: + if user.id == model_info.user_id or has_access( + user.id, type="read", access_control=model_info.access_control + ): + filtered_models.append(model) + return filtered_models + + +@cached(ttl=3) +async def get_all_models(request: Request, user: UserModel) -> dict[str, list]: + log.info("get_all_models()") + + if not request.app.state.config.ENABLE_OPENAI_API: + return {"data": []} + + responses = await get_all_models_responses(request, user=user) + + def extract_data(response): + if response and "data" in response: + return response["data"] + if isinstance(response, list): + return response + return None + + def merge_models_lists(model_lists): + log.debug(f"merge_models_lists {model_lists}") + merged_list = [] + + for idx, models in enumerate(model_lists): + if models is not None and "error" not in models: + merged_list.extend( + [ + { + **model, + "name": model.get("name", model["id"]), + "owned_by": "openai", + "openai": model, + "urlIdx": idx, + } + for model in models + if "api.openai.com" + not in request.app.state.config.OPENAI_API_BASE_URLS[idx] + or not any( + name in model["id"] + for name in [ + "babbage", + "dall-e", + "davinci", + "embedding", + "tts", + "whisper", + ] + ) + ] + ) + + return merged_list + + models = {"data": merge_models_lists(map(extract_data, responses))} + log.debug(f"models: {models}") + + request.app.state.OPENAI_MODELS = {model["id"]: model for model in models["data"]} + return models + + +@router.get("/models") +@router.get("/models/{url_idx}") +async def get_models( + request: Request, url_idx: Optional[int] = None, user=Depends(get_verified_user) +): + models = { + "data": [], + } + + if url_idx is None: + models = await get_all_models(request, user=user) + else: + url = request.app.state.config.OPENAI_API_BASE_URLS[url_idx] + key = request.app.state.config.OPENAI_API_KEYS[url_idx] + + r = None + async with aiohttp.ClientSession( + timeout=aiohttp.ClientTimeout( + total=AIOHTTP_CLIENT_TIMEOUT_OPENAI_MODEL_LIST + ) + ) as session: + try: + async with session.get( + f"{url}/models", + headers={ + "Authorization": f"Bearer {key}", + "Content-Type": "application/json", + **( + { + "X-OpenWebUI-User-Name": user.name, + "X-OpenWebUI-User-Id": user.id, + "X-OpenWebUI-User-Email": user.email, + "X-OpenWebUI-User-Role": user.role, + } + if ENABLE_FORWARD_USER_INFO_HEADERS + else {} + ), + }, + ) as r: + if r.status != 200: + # Extract response error details if available + error_detail = f"HTTP Error: {r.status}" + res = await r.json() + if "error" in res: + error_detail = f"External Error: {res['error']}" + raise Exception(error_detail) + + response_data = await r.json() + + # Check if we're calling OpenAI API based on the URL + if "api.openai.com" in url: + # Filter models according to the specified conditions + response_data["data"] = [ + model + for model in response_data.get("data", []) + if not any( + name in model["id"] + for name in [ + "babbage", + "dall-e", + "davinci", + "embedding", + "tts", + "whisper", + ] + ) + ] + + models = response_data + except aiohttp.ClientError as e: + # ClientError covers all aiohttp requests issues + log.exception(f"Client error: {str(e)}") + raise HTTPException( + status_code=500, detail="Open WebUI: Server Connection Error" + ) + except Exception as e: + log.exception(f"Unexpected error: {e}") + error_detail = f"Unexpected error: {str(e)}" + raise HTTPException(status_code=500, detail=error_detail) + + if user.role == "user" and not BYPASS_MODEL_ACCESS_CONTROL: + models["data"] = await get_filtered_models(models, user) + + return models + + +class ConnectionVerificationForm(BaseModel): + url: str + key: str + + +@router.post("/verify") +async def verify_connection( + form_data: ConnectionVerificationForm, user=Depends(get_admin_user) +): + url = form_data.url + key = form_data.key + + async with aiohttp.ClientSession( + timeout=aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT_OPENAI_MODEL_LIST) + ) as session: + try: + async with session.get( + f"{url}/models", + headers={ + "Authorization": f"Bearer {key}", + "Content-Type": "application/json", + **( + { + "X-OpenWebUI-User-Name": user.name, + "X-OpenWebUI-User-Id": user.id, + "X-OpenWebUI-User-Email": user.email, + "X-OpenWebUI-User-Role": user.role, + } + if ENABLE_FORWARD_USER_INFO_HEADERS + else {} + ), + }, + ) as r: + if r.status != 200: + # Extract response error details if available + error_detail = f"HTTP Error: {r.status}" + res = await r.json() + if "error" in res: + error_detail = f"External Error: {res['error']}" + raise Exception(error_detail) + + response_data = await r.json() + return response_data + + except aiohttp.ClientError as e: + # ClientError covers all aiohttp requests issues + log.exception(f"Client error: {str(e)}") + raise HTTPException( + status_code=500, detail="Open WebUI: Server Connection Error" + ) + except Exception as e: + log.exception(f"Unexpected error: {e}") + error_detail = f"Unexpected error: {str(e)}" + raise HTTPException(status_code=500, detail=error_detail) + + +@router.post("/chat/completions") +async def generate_chat_completion( + request: Request, + form_data: dict, + user=Depends(get_verified_user), + bypass_filter: Optional[bool] = False, +): + if BYPASS_MODEL_ACCESS_CONTROL: + bypass_filter = True + + idx = 0 + + payload = {**form_data} + metadata = payload.pop("metadata", None) + + model_id = form_data.get("model") + model_info = Models.get_model_by_id(model_id) + + # Check model info and override the payload + if model_info: + if model_info.base_model_id: + payload["model"] = model_info.base_model_id + model_id = model_info.base_model_id + + params = model_info.params.model_dump() + payload = apply_model_params_to_body_openai(params, payload) + payload = apply_model_system_prompt_to_body(params, payload, metadata, user) + + # Check if user has access to the model + if not bypass_filter and user.role == "user": + if not ( + user.id == model_info.user_id + or has_access( + user.id, type="read", access_control=model_info.access_control + ) + ): + raise HTTPException( + status_code=403, + detail="Model not found", + ) + elif not bypass_filter: + if user.role != "admin": + raise HTTPException( + status_code=403, + detail="Model not found", + ) + + await get_all_models(request, user=user) + model = request.app.state.OPENAI_MODELS.get(model_id) + if model: + idx = model["urlIdx"] + else: + raise HTTPException( + status_code=404, + detail="Model not found", + ) + + # Get the API config for the model + api_config = request.app.state.config.OPENAI_API_CONFIGS.get( + str(idx), + request.app.state.config.OPENAI_API_CONFIGS.get( + request.app.state.config.OPENAI_API_BASE_URLS[idx], {} + ), # Legacy support + ) + + prefix_id = api_config.get("prefix_id", None) + if prefix_id: + payload["model"] = payload["model"].replace(f"{prefix_id}.", "") + + # Add user info to the payload if the model is a pipeline + if "pipeline" in model and model.get("pipeline"): + payload["user"] = { + "name": user.name, + "id": user.id, + "email": user.email, + "role": user.role, + } + + url = request.app.state.config.OPENAI_API_BASE_URLS[idx] + key = request.app.state.config.OPENAI_API_KEYS[idx] + + # Fix: o1,o3 does not support the "max_tokens" parameter, Modify "max_tokens" to "max_completion_tokens" + is_o1_o3 = payload["model"].lower().startswith(("o1", "o3-")) + if is_o1_o3: + payload = openai_o1_o3_handler(payload) + elif "api.openai.com" not in url: + # Remove "max_completion_tokens" from the payload for backward compatibility + if "max_completion_tokens" in payload: + payload["max_tokens"] = payload["max_completion_tokens"] + del payload["max_completion_tokens"] + + if "max_tokens" in payload and "max_completion_tokens" in payload: + del payload["max_tokens"] + + # Convert the modified body back to JSON + payload = json.dumps(payload) + + r = None + session = None + streaming = False + response = None + + try: + session = aiohttp.ClientSession( + trust_env=True, timeout=aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT) + ) + + r = await session.request( + method="POST", + url=f"{url}/chat/completions", + data=payload, + headers={ + "Authorization": f"Bearer {key}", + "Content-Type": "application/json", + **( + { + "HTTP-Referer": "https://openwebui.com/", + "X-Title": "Open WebUI", + } + if "openrouter.ai" in url + else {} + ), + **( + { + "X-OpenWebUI-User-Name": user.name, + "X-OpenWebUI-User-Id": user.id, + "X-OpenWebUI-User-Email": user.email, + "X-OpenWebUI-User-Role": user.role, + } + if ENABLE_FORWARD_USER_INFO_HEADERS + else {} + ), + }, + ) + + # Check if response is SSE + if "text/event-stream" in r.headers.get("Content-Type", ""): + streaming = True + return StreamingResponse( + r.content, + status_code=r.status, + headers=dict(r.headers), + background=BackgroundTask( + cleanup_response, response=r, session=session + ), + ) + else: + try: + response = await r.json() + except Exception as e: + log.error(e) + response = await r.text() + + r.raise_for_status() + return response + except Exception as e: + log.exception(e) + + detail = None + if isinstance(response, dict): + if "error" in response: + detail = f"{response['error']['message'] if 'message' in response['error'] else response['error']}" + elif isinstance(response, str): + detail = response + + raise HTTPException( + status_code=r.status if r else 500, + detail=detail if detail else "Open WebUI: Server Connection Error", + ) + finally: + if not streaming and session: + if r: + r.close() + await session.close() + + +@router.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE"]) +async def proxy(path: str, request: Request, user=Depends(get_verified_user)): + """ + Deprecated: proxy all requests to OpenAI API + """ + + body = await request.body() + + idx = 0 + url = request.app.state.config.OPENAI_API_BASE_URLS[idx] + key = request.app.state.config.OPENAI_API_KEYS[idx] + + r = None + session = None + streaming = False + + try: + session = aiohttp.ClientSession(trust_env=True) + r = await session.request( + method=request.method, + url=f"{url}/{path}", + data=body, + headers={ + "Authorization": f"Bearer {key}", + "Content-Type": "application/json", + **( + { + "X-OpenWebUI-User-Name": user.name, + "X-OpenWebUI-User-Id": user.id, + "X-OpenWebUI-User-Email": user.email, + "X-OpenWebUI-User-Role": user.role, + } + if ENABLE_FORWARD_USER_INFO_HEADERS + else {} + ), + }, + ) + r.raise_for_status() + + # Check if response is SSE + if "text/event-stream" in r.headers.get("Content-Type", ""): + streaming = True + return StreamingResponse( + r.content, + status_code=r.status, + headers=dict(r.headers), + background=BackgroundTask( + cleanup_response, response=r, session=session + ), + ) + else: + response_data = await r.json() + return response_data + + except Exception as e: + log.exception(e) + + detail = None + if r is not None: + try: + res = await r.json() + log.error(res) + if "error" in res: + detail = f"External: {res['error']['message'] if 'message' in res['error'] else res['error']}" + except Exception: + detail = f"External: {e}" + raise HTTPException( + status_code=r.status if r else 500, + detail=detail if detail else "Open WebUI: Server Connection Error", + ) + finally: + if not streaming and session: + if r: + r.close() + await session.close() diff --git a/backend/open_webui/routers/pipelines.py b/backend/open_webui/routers/pipelines.py new file mode 100644 index 0000000..599208e --- /dev/null +++ b/backend/open_webui/routers/pipelines.py @@ -0,0 +1,500 @@ +from fastapi import ( + Depends, + FastAPI, + File, + Form, + HTTPException, + Request, + UploadFile, + status, + APIRouter, +) +import aiohttp +import os +import logging +import shutil +import requests +from pydantic import BaseModel +from starlette.responses import FileResponse +from typing import Optional + +from open_webui.env import SRC_LOG_LEVELS +from open_webui.config import CACHE_DIR +from open_webui.constants import ERROR_MESSAGES + + +from open_webui.routers.openai import get_all_models_responses + +from open_webui.utils.auth import get_admin_user + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MAIN"]) + + +################################## +# +# Pipeline Middleware +# +################################## + + +def get_sorted_filters(model_id, models): + filters = [ + model + for model in models.values() + if "pipeline" in model + and "type" in model["pipeline"] + and model["pipeline"]["type"] == "filter" + and ( + model["pipeline"]["pipelines"] == ["*"] + or any( + model_id == target_model_id + for target_model_id in model["pipeline"]["pipelines"] + ) + ) + ] + sorted_filters = sorted(filters, key=lambda x: x["pipeline"]["priority"]) + return sorted_filters + + +async def process_pipeline_inlet_filter(request, payload, user, models): + user = {"id": user.id, "email": user.email, "name": user.name, "role": user.role} + model_id = payload["model"] + sorted_filters = get_sorted_filters(model_id, models) + model = models[model_id] + + if "pipeline" in model: + sorted_filters.append(model) + + async with aiohttp.ClientSession() as session: + for filter in sorted_filters: + urlIdx = filter.get("urlIdx") + if urlIdx is None: + continue + + url = request.app.state.config.OPENAI_API_BASE_URLS[urlIdx] + key = request.app.state.config.OPENAI_API_KEYS[urlIdx] + + if not key: + continue + + headers = {"Authorization": f"Bearer {key}"} + request_data = { + "user": user, + "body": payload, + } + + try: + async with session.post( + f"{url}/{filter['id']}/filter/inlet", + headers=headers, + json=request_data, + ) as response: + response.raise_for_status() + payload = await response.json() + except aiohttp.ClientResponseError as e: + res = ( + await response.json() + if response.content_type == "application/json" + else {} + ) + if "detail" in res: + raise Exception(response.status, res["detail"]) + except Exception as e: + log.exception(f"Connection error: {e}") + + return payload + + +async def process_pipeline_outlet_filter(request, payload, user, models): + user = {"id": user.id, "email": user.email, "name": user.name, "role": user.role} + model_id = payload["model"] + sorted_filters = get_sorted_filters(model_id, models) + model = models[model_id] + + if "pipeline" in model: + sorted_filters = [model] + sorted_filters + + async with aiohttp.ClientSession() as session: + for filter in sorted_filters: + urlIdx = filter.get("urlIdx") + if urlIdx is None: + continue + + url = request.app.state.config.OPENAI_API_BASE_URLS[urlIdx] + key = request.app.state.config.OPENAI_API_KEYS[urlIdx] + + if not key: + continue + + headers = {"Authorization": f"Bearer {key}"} + request_data = { + "user": user, + "body": payload, + } + + try: + async with session.post( + f"{url}/{filter['id']}/filter/outlet", + headers=headers, + json=request_data, + ) as response: + response.raise_for_status() + payload = await response.json() + except aiohttp.ClientResponseError as e: + try: + res = ( + await response.json() + if "application/json" in response.content_type + else {} + ) + if "detail" in res: + raise Exception(response.status, res) + except Exception: + pass + except Exception as e: + log.exception(f"Connection error: {e}") + + return payload + + +################################## +# +# Pipelines Endpoints +# +################################## + +router = APIRouter() + + +@router.get("/list") +async def get_pipelines_list(request: Request, user=Depends(get_admin_user)): + responses = await get_all_models_responses(request, user) + log.debug(f"get_pipelines_list: get_openai_models_responses returned {responses}") + + urlIdxs = [ + idx + for idx, response in enumerate(responses) + if response is not None and "pipelines" in response + ] + + return { + "data": [ + { + "url": request.app.state.config.OPENAI_API_BASE_URLS[urlIdx], + "idx": urlIdx, + } + for urlIdx in urlIdxs + ] + } + + +@router.post("/upload") +async def upload_pipeline( + request: Request, + urlIdx: int = Form(...), + file: UploadFile = File(...), + user=Depends(get_admin_user), +): + log.info(f"upload_pipeline: urlIdx={urlIdx}, filename={file.filename}") + # Check if the uploaded file is a python file + if not (file.filename and file.filename.endswith(".py")): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="Only Python (.py) files are allowed.", + ) + + upload_folder = f"{CACHE_DIR}/pipelines" + os.makedirs(upload_folder, exist_ok=True) + file_path = os.path.join(upload_folder, file.filename) + + r = None + try: + # Save the uploaded file + with open(file_path, "wb") as buffer: + shutil.copyfileobj(file.file, buffer) + + url = request.app.state.config.OPENAI_API_BASE_URLS[urlIdx] + key = request.app.state.config.OPENAI_API_KEYS[urlIdx] + + with open(file_path, "rb") as f: + files = {"file": f} + r = requests.post( + f"{url}/pipelines/upload", + headers={"Authorization": f"Bearer {key}"}, + files=files, + ) + + r.raise_for_status() + data = r.json() + + return {**data} + except Exception as e: + # Handle connection error here + log.exception(f"Connection error: {e}") + + detail = None + status_code = status.HTTP_404_NOT_FOUND + if r is not None: + status_code = r.status_code + try: + res = r.json() + if "detail" in res: + detail = res["detail"] + except Exception: + pass + + raise HTTPException( + status_code=status_code, + detail=detail if detail else "Pipeline not found", + ) + finally: + # Ensure the file is deleted after the upload is completed or on failure + if os.path.exists(file_path): + os.remove(file_path) + + +class AddPipelineForm(BaseModel): + url: str + urlIdx: int + + +@router.post("/add") +async def add_pipeline( + request: Request, form_data: AddPipelineForm, user=Depends(get_admin_user) +): + r = None + try: + urlIdx = form_data.urlIdx + + url = request.app.state.config.OPENAI_API_BASE_URLS[urlIdx] + key = request.app.state.config.OPENAI_API_KEYS[urlIdx] + + r = requests.post( + f"{url}/pipelines/add", + headers={"Authorization": f"Bearer {key}"}, + json={"url": form_data.url}, + ) + + r.raise_for_status() + data = r.json() + + return {**data} + except Exception as e: + # Handle connection error here + log.exception(f"Connection error: {e}") + + detail = None + if r is not None: + try: + res = r.json() + if "detail" in res: + detail = res["detail"] + except Exception: + pass + + raise HTTPException( + status_code=(r.status_code if r is not None else status.HTTP_404_NOT_FOUND), + detail=detail if detail else "Pipeline not found", + ) + + +class DeletePipelineForm(BaseModel): + id: str + urlIdx: int + + +@router.delete("/delete") +async def delete_pipeline( + request: Request, form_data: DeletePipelineForm, user=Depends(get_admin_user) +): + r = None + try: + urlIdx = form_data.urlIdx + + url = request.app.state.config.OPENAI_API_BASE_URLS[urlIdx] + key = request.app.state.config.OPENAI_API_KEYS[urlIdx] + + r = requests.delete( + f"{url}/pipelines/delete", + headers={"Authorization": f"Bearer {key}"}, + json={"id": form_data.id}, + ) + + r.raise_for_status() + data = r.json() + + return {**data} + except Exception as e: + # Handle connection error here + log.exception(f"Connection error: {e}") + + detail = None + if r is not None: + try: + res = r.json() + if "detail" in res: + detail = res["detail"] + except Exception: + pass + + raise HTTPException( + status_code=(r.status_code if r is not None else status.HTTP_404_NOT_FOUND), + detail=detail if detail else "Pipeline not found", + ) + + +@router.get("/") +async def get_pipelines( + request: Request, urlIdx: Optional[int] = None, user=Depends(get_admin_user) +): + r = None + try: + url = request.app.state.config.OPENAI_API_BASE_URLS[urlIdx] + key = request.app.state.config.OPENAI_API_KEYS[urlIdx] + + r = requests.get(f"{url}/pipelines", headers={"Authorization": f"Bearer {key}"}) + + r.raise_for_status() + data = r.json() + + return {**data} + except Exception as e: + # Handle connection error here + log.exception(f"Connection error: {e}") + + detail = None + if r is not None: + try: + res = r.json() + if "detail" in res: + detail = res["detail"] + except Exception: + pass + + raise HTTPException( + status_code=(r.status_code if r is not None else status.HTTP_404_NOT_FOUND), + detail=detail if detail else "Pipeline not found", + ) + + +@router.get("/{pipeline_id}/valves") +async def get_pipeline_valves( + request: Request, + urlIdx: Optional[int], + pipeline_id: str, + user=Depends(get_admin_user), +): + r = None + try: + url = request.app.state.config.OPENAI_API_BASE_URLS[urlIdx] + key = request.app.state.config.OPENAI_API_KEYS[urlIdx] + + r = requests.get( + f"{url}/{pipeline_id}/valves", headers={"Authorization": f"Bearer {key}"} + ) + + r.raise_for_status() + data = r.json() + + return {**data} + except Exception as e: + # Handle connection error here + log.exception(f"Connection error: {e}") + + detail = None + if r is not None: + try: + res = r.json() + if "detail" in res: + detail = res["detail"] + except Exception: + pass + + raise HTTPException( + status_code=(r.status_code if r is not None else status.HTTP_404_NOT_FOUND), + detail=detail if detail else "Pipeline not found", + ) + + +@router.get("/{pipeline_id}/valves/spec") +async def get_pipeline_valves_spec( + request: Request, + urlIdx: Optional[int], + pipeline_id: str, + user=Depends(get_admin_user), +): + r = None + try: + url = request.app.state.config.OPENAI_API_BASE_URLS[urlIdx] + key = request.app.state.config.OPENAI_API_KEYS[urlIdx] + + r = requests.get( + f"{url}/{pipeline_id}/valves/spec", + headers={"Authorization": f"Bearer {key}"}, + ) + + r.raise_for_status() + data = r.json() + + return {**data} + except Exception as e: + # Handle connection error here + log.exception(f"Connection error: {e}") + + detail = None + if r is not None: + try: + res = r.json() + if "detail" in res: + detail = res["detail"] + except Exception: + pass + + raise HTTPException( + status_code=(r.status_code if r is not None else status.HTTP_404_NOT_FOUND), + detail=detail if detail else "Pipeline not found", + ) + + +@router.post("/{pipeline_id}/valves/update") +async def update_pipeline_valves( + request: Request, + urlIdx: Optional[int], + pipeline_id: str, + form_data: dict, + user=Depends(get_admin_user), +): + r = None + try: + url = request.app.state.config.OPENAI_API_BASE_URLS[urlIdx] + key = request.app.state.config.OPENAI_API_KEYS[urlIdx] + + r = requests.post( + f"{url}/{pipeline_id}/valves/update", + headers={"Authorization": f"Bearer {key}"}, + json={**form_data}, + ) + + r.raise_for_status() + data = r.json() + + return {**data} + except Exception as e: + # Handle connection error here + log.exception(f"Connection error: {e}") + + detail = None + + if r is not None: + try: + res = r.json() + if "detail" in res: + detail = res["detail"] + except Exception: + pass + + raise HTTPException( + status_code=(r.status_code if r is not None else status.HTTP_404_NOT_FOUND), + detail=detail if detail else "Pipeline not found", + ) diff --git a/backend/open_webui/routers/prompts.py b/backend/open_webui/routers/prompts.py new file mode 100644 index 0000000..9fb946c --- /dev/null +++ b/backend/open_webui/routers/prompts.py @@ -0,0 +1,161 @@ +from typing import Optional + +from open_webui.models.prompts import ( + PromptForm, + PromptUserResponse, + PromptModel, + Prompts, +) +from open_webui.constants import ERROR_MESSAGES +from fastapi import APIRouter, Depends, HTTPException, status, Request +from open_webui.utils.auth import get_admin_user, get_verified_user +from open_webui.utils.access_control import has_access, has_permission + +router = APIRouter() + +############################ +# GetPrompts +############################ + + +@router.get("/", response_model=list[PromptModel]) +async def get_prompts(user=Depends(get_verified_user)): + if user.role == "admin": + prompts = Prompts.get_prompts() + else: + prompts = Prompts.get_prompts_by_user_id(user.id, "read") + + return prompts + + +@router.get("/list", response_model=list[PromptUserResponse]) +async def get_prompt_list(user=Depends(get_verified_user)): + if user.role == "admin": + prompts = Prompts.get_prompts() + else: + prompts = Prompts.get_prompts_by_user_id(user.id, "write") + + return prompts + + +############################ +# CreateNewPrompt +############################ + + +@router.post("/create", response_model=Optional[PromptModel]) +async def create_new_prompt( + request: Request, form_data: PromptForm, user=Depends(get_verified_user) +): + if user.role != "admin" and not has_permission( + user.id, "workspace.prompts", request.app.state.config.USER_PERMISSIONS + ): + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.UNAUTHORIZED, + ) + + prompt = Prompts.get_prompt_by_command(form_data.command) + if prompt is None: + prompt = Prompts.insert_new_prompt(user.id, form_data) + + if prompt: + return prompt + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT(), + ) + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.COMMAND_TAKEN, + ) + + +############################ +# GetPromptByCommand +############################ + + +@router.get("/command/{command}", response_model=Optional[PromptModel]) +async def get_prompt_by_command(command: str, user=Depends(get_verified_user)): + prompt = Prompts.get_prompt_by_command(f"/{command}") + + if prompt: + if ( + user.role == "admin" + or prompt.user_id == user.id + or has_access(user.id, "read", prompt.access_control) + ): + return prompt + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +############################ +# UpdatePromptByCommand +############################ + + +@router.post("/command/{command}/update", response_model=Optional[PromptModel]) +async def update_prompt_by_command( + command: str, + form_data: PromptForm, + user=Depends(get_verified_user), +): + prompt = Prompts.get_prompt_by_command(f"/{command}") + if not prompt: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + # Is the user the original creator, in a group with write access, or an admin + if ( + prompt.user_id != user.id + and not has_access(user.id, "write", prompt.access_control) + and user.role != "admin" + ): + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + ) + + prompt = Prompts.update_prompt_by_command(f"/{command}", form_data) + if prompt: + return prompt + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + ) + + +############################ +# DeletePromptByCommand +############################ + + +@router.delete("/command/{command}/delete", response_model=bool) +async def delete_prompt_by_command(command: str, user=Depends(get_verified_user)): + prompt = Prompts.get_prompt_by_command(f"/{command}") + if not prompt: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + if ( + prompt.user_id != user.id + and not has_access(user.id, "write", prompt.access_control) + and user.role != "admin" + ): + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + ) + + result = Prompts.delete_prompt_by_command(f"/{command}") + return result diff --git a/backend/open_webui/routers/retrieval.py b/backend/open_webui/routers/retrieval.py new file mode 100644 index 0000000..7dd324b --- /dev/null +++ b/backend/open_webui/routers/retrieval.py @@ -0,0 +1,1719 @@ +import json +import logging +import mimetypes +import os +import shutil + +import uuid +from datetime import datetime +from pathlib import Path +from typing import Iterator, List, Optional, Sequence, Union + +from fastapi import ( + Depends, + FastAPI, + File, + Form, + HTTPException, + UploadFile, + Request, + status, + APIRouter, +) +from fastapi.middleware.cors import CORSMiddleware +from fastapi.concurrency import run_in_threadpool +from pydantic import BaseModel +import tiktoken + + +from langchain.text_splitter import RecursiveCharacterTextSplitter, TokenTextSplitter +from langchain_core.documents import Document + +from open_webui.models.files import FileModel, Files +from open_webui.models.knowledge import Knowledges +from open_webui.storage.provider import Storage + + +from open_webui.retrieval.vector.connector import VECTOR_DB_CLIENT + +# Document loaders +from open_webui.retrieval.loaders.main import Loader +from open_webui.retrieval.loaders.youtube import YoutubeLoader + +# Web search engines +from open_webui.retrieval.web.main import SearchResult +from open_webui.retrieval.web.utils import get_web_loader +from open_webui.retrieval.web.brave import search_brave +from open_webui.retrieval.web.kagi import search_kagi +from open_webui.retrieval.web.mojeek import search_mojeek +from open_webui.retrieval.web.bocha import search_bocha +from open_webui.retrieval.web.duckduckgo import search_duckduckgo +from open_webui.retrieval.web.google_pse import search_google_pse +from open_webui.retrieval.web.jina_search import search_jina +from open_webui.retrieval.web.searchapi import search_searchapi +from open_webui.retrieval.web.serpapi import search_serpapi +from open_webui.retrieval.web.searxng import search_searxng +from open_webui.retrieval.web.serper import search_serper +from open_webui.retrieval.web.serply import search_serply +from open_webui.retrieval.web.serpstack import search_serpstack +from open_webui.retrieval.web.tavily import search_tavily +from open_webui.retrieval.web.bing import search_bing +from open_webui.retrieval.web.exa import search_exa + + +from open_webui.retrieval.utils import ( + get_embedding_function, + get_model_path, + query_collection, + query_collection_with_hybrid_search, + query_doc, + query_doc_with_hybrid_search, +) +from open_webui.utils.misc import ( + calculate_sha256_string, +) +from open_webui.utils.auth import get_admin_user, get_verified_user + + +from open_webui.config import ( + ENV, + RAG_EMBEDDING_MODEL_AUTO_UPDATE, + RAG_EMBEDDING_MODEL_TRUST_REMOTE_CODE, + RAG_RERANKING_MODEL_AUTO_UPDATE, + RAG_RERANKING_MODEL_TRUST_REMOTE_CODE, + UPLOAD_DIR, + DEFAULT_LOCALE, +) +from open_webui.env import ( + SRC_LOG_LEVELS, + DEVICE_TYPE, + DOCKER, +) +from open_webui.constants import ERROR_MESSAGES + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["RAG"]) + +########################################## +# +# Utility functions +# +########################################## + + +def get_ef( + engine: str, + embedding_model: str, + auto_update: bool = False, +): + ef = None + if embedding_model and engine == "": + from sentence_transformers import SentenceTransformer + + try: + ef = SentenceTransformer( + get_model_path(embedding_model, auto_update), + device=DEVICE_TYPE, + trust_remote_code=RAG_EMBEDDING_MODEL_TRUST_REMOTE_CODE, + ) + except Exception as e: + log.debug(f"Error loading SentenceTransformer: {e}") + + return ef + + +def get_rf( + reranking_model: str, + auto_update: bool = False, +): + rf = None + if reranking_model: + if any(model in reranking_model for model in ["jinaai/jina-colbert-v2"]): + try: + from open_webui.retrieval.models.colbert import ColBERT + + rf = ColBERT( + get_model_path(reranking_model, auto_update), + env="docker" if DOCKER else None, + ) + + except Exception as e: + log.error(f"ColBERT: {e}") + raise Exception(ERROR_MESSAGES.DEFAULT(e)) + else: + import sentence_transformers + + try: + rf = sentence_transformers.CrossEncoder( + get_model_path(reranking_model, auto_update), + device=DEVICE_TYPE, + trust_remote_code=RAG_RERANKING_MODEL_TRUST_REMOTE_CODE, + ) + except: + log.error("CrossEncoder error") + raise Exception(ERROR_MESSAGES.DEFAULT("CrossEncoder error")) + return rf + + +########################################## +# +# API routes +# +########################################## + + +router = APIRouter() + + +class CollectionNameForm(BaseModel): + collection_name: Optional[str] = None + + +class ProcessUrlForm(CollectionNameForm): + url: str + + +class SearchForm(CollectionNameForm): + query: str + + +@router.get("/") +async def get_status(request: Request): + return { + "status": True, + "chunk_size": request.app.state.config.CHUNK_SIZE, + "chunk_overlap": request.app.state.config.CHUNK_OVERLAP, + "template": request.app.state.config.RAG_TEMPLATE, + "embedding_engine": request.app.state.config.RAG_EMBEDDING_ENGINE, + "embedding_model": request.app.state.config.RAG_EMBEDDING_MODEL, + "reranking_model": request.app.state.config.RAG_RERANKING_MODEL, + "embedding_batch_size": request.app.state.config.RAG_EMBEDDING_BATCH_SIZE, + } + + +@router.get("/embedding") +async def get_embedding_config(request: Request, user=Depends(get_admin_user)): + return { + "status": True, + "embedding_engine": request.app.state.config.RAG_EMBEDDING_ENGINE, + "embedding_model": request.app.state.config.RAG_EMBEDDING_MODEL, + "embedding_batch_size": request.app.state.config.RAG_EMBEDDING_BATCH_SIZE, + "openai_config": { + "url": request.app.state.config.RAG_OPENAI_API_BASE_URL, + "key": request.app.state.config.RAG_OPENAI_API_KEY, + }, + "ollama_config": { + "url": request.app.state.config.RAG_OLLAMA_BASE_URL, + "key": request.app.state.config.RAG_OLLAMA_API_KEY, + }, + } + + +@router.get("/reranking") +async def get_reraanking_config(request: Request, user=Depends(get_admin_user)): + return { + "status": True, + "reranking_model": request.app.state.config.RAG_RERANKING_MODEL, + } + + +class OpenAIConfigForm(BaseModel): + url: str + key: str + + +class OllamaConfigForm(BaseModel): + url: str + key: str + + +class EmbeddingModelUpdateForm(BaseModel): + openai_config: Optional[OpenAIConfigForm] = None + ollama_config: Optional[OllamaConfigForm] = None + embedding_engine: str + embedding_model: str + embedding_batch_size: Optional[int] = 1 + + +@router.post("/embedding/update") +async def update_embedding_config( + request: Request, form_data: EmbeddingModelUpdateForm, user=Depends(get_admin_user) +): + log.info( + f"Updating embedding model: {request.app.state.config.RAG_EMBEDDING_MODEL} to {form_data.embedding_model}" + ) + try: + request.app.state.config.RAG_EMBEDDING_ENGINE = form_data.embedding_engine + request.app.state.config.RAG_EMBEDDING_MODEL = form_data.embedding_model + + if request.app.state.config.RAG_EMBEDDING_ENGINE in ["ollama", "openai"]: + if form_data.openai_config is not None: + request.app.state.config.RAG_OPENAI_API_BASE_URL = ( + form_data.openai_config.url + ) + request.app.state.config.RAG_OPENAI_API_KEY = ( + form_data.openai_config.key + ) + + if form_data.ollama_config is not None: + request.app.state.config.RAG_OLLAMA_BASE_URL = ( + form_data.ollama_config.url + ) + request.app.state.config.RAG_OLLAMA_API_KEY = ( + form_data.ollama_config.key + ) + + request.app.state.config.RAG_EMBEDDING_BATCH_SIZE = ( + form_data.embedding_batch_size + ) + + request.app.state.ef = get_ef( + request.app.state.config.RAG_EMBEDDING_ENGINE, + request.app.state.config.RAG_EMBEDDING_MODEL, + ) + + request.app.state.EMBEDDING_FUNCTION = get_embedding_function( + request.app.state.config.RAG_EMBEDDING_ENGINE, + request.app.state.config.RAG_EMBEDDING_MODEL, + request.app.state.ef, + ( + request.app.state.config.RAG_OPENAI_API_BASE_URL + if request.app.state.config.RAG_EMBEDDING_ENGINE == "openai" + else request.app.state.config.RAG_OLLAMA_BASE_URL + ), + ( + request.app.state.config.RAG_OPENAI_API_KEY + if request.app.state.config.RAG_EMBEDDING_ENGINE == "openai" + else request.app.state.config.RAG_OLLAMA_API_KEY + ), + request.app.state.config.RAG_EMBEDDING_BATCH_SIZE, + ) + + return { + "status": True, + "embedding_engine": request.app.state.config.RAG_EMBEDDING_ENGINE, + "embedding_model": request.app.state.config.RAG_EMBEDDING_MODEL, + "embedding_batch_size": request.app.state.config.RAG_EMBEDDING_BATCH_SIZE, + "openai_config": { + "url": request.app.state.config.RAG_OPENAI_API_BASE_URL, + "key": request.app.state.config.RAG_OPENAI_API_KEY, + }, + "ollama_config": { + "url": request.app.state.config.RAG_OLLAMA_BASE_URL, + "key": request.app.state.config.RAG_OLLAMA_API_KEY, + }, + } + except Exception as e: + log.exception(f"Problem updating embedding model: {e}") + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=ERROR_MESSAGES.DEFAULT(e), + ) + + +class RerankingModelUpdateForm(BaseModel): + reranking_model: str + + +@router.post("/reranking/update") +async def update_reranking_config( + request: Request, form_data: RerankingModelUpdateForm, user=Depends(get_admin_user) +): + log.info( + f"Updating reranking model: {request.app.state.config.RAG_RERANKING_MODEL} to {form_data.reranking_model}" + ) + try: + request.app.state.config.RAG_RERANKING_MODEL = form_data.reranking_model + + try: + request.app.state.rf = get_rf( + request.app.state.config.RAG_RERANKING_MODEL, + True, + ) + except Exception as e: + log.error(f"Error loading reranking model: {e}") + request.app.state.config.ENABLE_RAG_HYBRID_SEARCH = False + + return { + "status": True, + "reranking_model": request.app.state.config.RAG_RERANKING_MODEL, + } + except Exception as e: + log.exception(f"Problem updating reranking model: {e}") + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=ERROR_MESSAGES.DEFAULT(e), + ) + + +@router.get("/config") +async def get_rag_config(request: Request, user=Depends(get_admin_user)): + return { + "status": True, + "pdf_extract_images": request.app.state.config.PDF_EXTRACT_IMAGES, + "RAG_FULL_CONTEXT": request.app.state.config.RAG_FULL_CONTEXT, + "BYPASS_EMBEDDING_AND_RETRIEVAL": request.app.state.config.BYPASS_EMBEDDING_AND_RETRIEVAL, + "enable_google_drive_integration": request.app.state.config.ENABLE_GOOGLE_DRIVE_INTEGRATION, + "enable_onedrive_integration": request.app.state.config.ENABLE_ONEDRIVE_INTEGRATION, + "content_extraction": { + "engine": request.app.state.config.CONTENT_EXTRACTION_ENGINE, + "tika_server_url": request.app.state.config.TIKA_SERVER_URL, + "document_intelligence_config": { + "endpoint": request.app.state.config.DOCUMENT_INTELLIGENCE_ENDPOINT, + "key": request.app.state.config.DOCUMENT_INTELLIGENCE_KEY, + }, + }, + "chunk": { + "text_splitter": request.app.state.config.TEXT_SPLITTER, + "chunk_size": request.app.state.config.CHUNK_SIZE, + "chunk_overlap": request.app.state.config.CHUNK_OVERLAP, + }, + "file": { + "max_size": request.app.state.config.FILE_MAX_SIZE, + "max_count": request.app.state.config.FILE_MAX_COUNT, + }, + "youtube": { + "language": request.app.state.config.YOUTUBE_LOADER_LANGUAGE, + "translation": request.app.state.YOUTUBE_LOADER_TRANSLATION, + "proxy_url": request.app.state.config.YOUTUBE_LOADER_PROXY_URL, + }, + "web": { + "ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION": request.app.state.config.ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION, + "BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL": request.app.state.config.BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL, + "search": { + "enabled": request.app.state.config.ENABLE_RAG_WEB_SEARCH, + "drive": request.app.state.config.ENABLE_GOOGLE_DRIVE_INTEGRATION, + "onedrive": request.app.state.config.ENABLE_ONEDRIVE_INTEGRATION, + "engine": request.app.state.config.RAG_WEB_SEARCH_ENGINE, + "searxng_query_url": request.app.state.config.SEARXNG_QUERY_URL, + "google_pse_api_key": request.app.state.config.GOOGLE_PSE_API_KEY, + "google_pse_engine_id": request.app.state.config.GOOGLE_PSE_ENGINE_ID, + "brave_search_api_key": request.app.state.config.BRAVE_SEARCH_API_KEY, + "kagi_search_api_key": request.app.state.config.KAGI_SEARCH_API_KEY, + "mojeek_search_api_key": request.app.state.config.MOJEEK_SEARCH_API_KEY, + "bocha_search_api_key": request.app.state.config.BOCHA_SEARCH_API_KEY, + "serpstack_api_key": request.app.state.config.SERPSTACK_API_KEY, + "serpstack_https": request.app.state.config.SERPSTACK_HTTPS, + "serper_api_key": request.app.state.config.SERPER_API_KEY, + "serply_api_key": request.app.state.config.SERPLY_API_KEY, + "tavily_api_key": request.app.state.config.TAVILY_API_KEY, + "searchapi_api_key": request.app.state.config.SEARCHAPI_API_KEY, + "searchapi_engine": request.app.state.config.SEARCHAPI_ENGINE, + "serpapi_api_key": request.app.state.config.SERPAPI_API_KEY, + "serpapi_engine": request.app.state.config.SERPAPI_ENGINE, + "jina_api_key": request.app.state.config.JINA_API_KEY, + "bing_search_v7_endpoint": request.app.state.config.BING_SEARCH_V7_ENDPOINT, + "bing_search_v7_subscription_key": request.app.state.config.BING_SEARCH_V7_SUBSCRIPTION_KEY, + "exa_api_key": request.app.state.config.EXA_API_KEY, + "result_count": request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT, + "trust_env": request.app.state.config.RAG_WEB_SEARCH_TRUST_ENV, + "concurrent_requests": request.app.state.config.RAG_WEB_SEARCH_CONCURRENT_REQUESTS, + "domain_filter_list": request.app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST, + }, + }, + } + + +class FileConfig(BaseModel): + max_size: Optional[int] = None + max_count: Optional[int] = None + + +class DocumentIntelligenceConfigForm(BaseModel): + endpoint: str + key: str + + +class ContentExtractionConfig(BaseModel): + engine: str = "" + tika_server_url: Optional[str] = None + document_intelligence_config: Optional[DocumentIntelligenceConfigForm] = None + + +class ChunkParamUpdateForm(BaseModel): + text_splitter: Optional[str] = None + chunk_size: int + chunk_overlap: int + + +class YoutubeLoaderConfig(BaseModel): + language: list[str] + translation: Optional[str] = None + proxy_url: str = "" + + +class WebSearchConfig(BaseModel): + enabled: bool + engine: Optional[str] = None + searxng_query_url: Optional[str] = None + google_pse_api_key: Optional[str] = None + google_pse_engine_id: Optional[str] = None + brave_search_api_key: Optional[str] = None + kagi_search_api_key: Optional[str] = None + mojeek_search_api_key: Optional[str] = None + bocha_search_api_key: Optional[str] = None + serpstack_api_key: Optional[str] = None + serpstack_https: Optional[bool] = None + serper_api_key: Optional[str] = None + serply_api_key: Optional[str] = None + tavily_api_key: Optional[str] = None + searchapi_api_key: Optional[str] = None + searchapi_engine: Optional[str] = None + serpapi_api_key: Optional[str] = None + serpapi_engine: Optional[str] = None + jina_api_key: Optional[str] = None + bing_search_v7_endpoint: Optional[str] = None + bing_search_v7_subscription_key: Optional[str] = None + exa_api_key: Optional[str] = None + result_count: Optional[int] = None + concurrent_requests: Optional[int] = None + trust_env: Optional[bool] = None + domain_filter_list: Optional[List[str]] = [] + + +class WebConfig(BaseModel): + search: WebSearchConfig + ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION: Optional[bool] = None + BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL: Optional[bool] = None + + +class ConfigUpdateForm(BaseModel): + RAG_FULL_CONTEXT: Optional[bool] = None + BYPASS_EMBEDDING_AND_RETRIEVAL: Optional[bool] = None + pdf_extract_images: Optional[bool] = None + enable_google_drive_integration: Optional[bool] = None + enable_onedrive_integration: Optional[bool] = None + file: Optional[FileConfig] = None + content_extraction: Optional[ContentExtractionConfig] = None + chunk: Optional[ChunkParamUpdateForm] = None + youtube: Optional[YoutubeLoaderConfig] = None + web: Optional[WebConfig] = None + + +@router.post("/config/update") +async def update_rag_config( + request: Request, form_data: ConfigUpdateForm, user=Depends(get_admin_user) +): + request.app.state.config.PDF_EXTRACT_IMAGES = ( + form_data.pdf_extract_images + if form_data.pdf_extract_images is not None + else request.app.state.config.PDF_EXTRACT_IMAGES + ) + + request.app.state.config.RAG_FULL_CONTEXT = ( + form_data.RAG_FULL_CONTEXT + if form_data.RAG_FULL_CONTEXT is not None + else request.app.state.config.RAG_FULL_CONTEXT + ) + + request.app.state.config.BYPASS_EMBEDDING_AND_RETRIEVAL = ( + form_data.BYPASS_EMBEDDING_AND_RETRIEVAL + if form_data.BYPASS_EMBEDDING_AND_RETRIEVAL is not None + else request.app.state.config.BYPASS_EMBEDDING_AND_RETRIEVAL + ) + + request.app.state.config.ENABLE_GOOGLE_DRIVE_INTEGRATION = ( + form_data.enable_google_drive_integration + if form_data.enable_google_drive_integration is not None + else request.app.state.config.ENABLE_GOOGLE_DRIVE_INTEGRATION + ) + + request.app.state.config.ENABLE_ONEDRIVE_INTEGRATION = ( + form_data.enable_onedrive_integration + if form_data.enable_onedrive_integration is not None + else request.app.state.config.ENABLE_ONEDRIVE_INTEGRATION + ) + + if form_data.file is not None: + request.app.state.config.FILE_MAX_SIZE = form_data.file.max_size + request.app.state.config.FILE_MAX_COUNT = form_data.file.max_count + + if form_data.content_extraction is not None: + log.info( + f"Updating content extraction: {request.app.state.config.CONTENT_EXTRACTION_ENGINE} to {form_data.content_extraction.engine}" + ) + request.app.state.config.CONTENT_EXTRACTION_ENGINE = ( + form_data.content_extraction.engine + ) + request.app.state.config.TIKA_SERVER_URL = ( + form_data.content_extraction.tika_server_url + ) + if form_data.content_extraction.document_intelligence_config is not None: + request.app.state.config.DOCUMENT_INTELLIGENCE_ENDPOINT = ( + form_data.content_extraction.document_intelligence_config.endpoint + ) + request.app.state.config.DOCUMENT_INTELLIGENCE_KEY = ( + form_data.content_extraction.document_intelligence_config.key + ) + + if form_data.chunk is not None: + request.app.state.config.TEXT_SPLITTER = form_data.chunk.text_splitter + request.app.state.config.CHUNK_SIZE = form_data.chunk.chunk_size + request.app.state.config.CHUNK_OVERLAP = form_data.chunk.chunk_overlap + + if form_data.youtube is not None: + request.app.state.config.YOUTUBE_LOADER_LANGUAGE = form_data.youtube.language + request.app.state.config.YOUTUBE_LOADER_PROXY_URL = form_data.youtube.proxy_url + request.app.state.YOUTUBE_LOADER_TRANSLATION = form_data.youtube.translation + + if form_data.web is not None: + request.app.state.config.ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION = ( + # Note: When UI "Bypass SSL verification for Websites"=True then ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION=False + form_data.web.ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION + ) + + request.app.state.config.ENABLE_RAG_WEB_SEARCH = form_data.web.search.enabled + request.app.state.config.RAG_WEB_SEARCH_ENGINE = form_data.web.search.engine + + request.app.state.config.BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL = ( + form_data.web.BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL + ) + + request.app.state.config.SEARXNG_QUERY_URL = ( + form_data.web.search.searxng_query_url + ) + request.app.state.config.GOOGLE_PSE_API_KEY = ( + form_data.web.search.google_pse_api_key + ) + request.app.state.config.GOOGLE_PSE_ENGINE_ID = ( + form_data.web.search.google_pse_engine_id + ) + request.app.state.config.BRAVE_SEARCH_API_KEY = ( + form_data.web.search.brave_search_api_key + ) + request.app.state.config.KAGI_SEARCH_API_KEY = ( + form_data.web.search.kagi_search_api_key + ) + request.app.state.config.MOJEEK_SEARCH_API_KEY = ( + form_data.web.search.mojeek_search_api_key + ) + request.app.state.config.BOCHA_SEARCH_API_KEY = ( + form_data.web.search.bocha_search_api_key + ) + request.app.state.config.SERPSTACK_API_KEY = ( + form_data.web.search.serpstack_api_key + ) + request.app.state.config.SERPSTACK_HTTPS = form_data.web.search.serpstack_https + request.app.state.config.SERPER_API_KEY = form_data.web.search.serper_api_key + request.app.state.config.SERPLY_API_KEY = form_data.web.search.serply_api_key + request.app.state.config.TAVILY_API_KEY = form_data.web.search.tavily_api_key + request.app.state.config.SEARCHAPI_API_KEY = ( + form_data.web.search.searchapi_api_key + ) + request.app.state.config.SEARCHAPI_ENGINE = ( + form_data.web.search.searchapi_engine + ) + + request.app.state.config.SERPAPI_API_KEY = form_data.web.search.serpapi_api_key + request.app.state.config.SERPAPI_ENGINE = form_data.web.search.serpapi_engine + + request.app.state.config.JINA_API_KEY = form_data.web.search.jina_api_key + request.app.state.config.BING_SEARCH_V7_ENDPOINT = ( + form_data.web.search.bing_search_v7_endpoint + ) + request.app.state.config.BING_SEARCH_V7_SUBSCRIPTION_KEY = ( + form_data.web.search.bing_search_v7_subscription_key + ) + + request.app.state.config.EXA_API_KEY = form_data.web.search.exa_api_key + + request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT = ( + form_data.web.search.result_count + ) + request.app.state.config.RAG_WEB_SEARCH_CONCURRENT_REQUESTS = ( + form_data.web.search.concurrent_requests + ) + request.app.state.config.RAG_WEB_SEARCH_TRUST_ENV = ( + form_data.web.search.trust_env + ) + request.app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST = ( + form_data.web.search.domain_filter_list + ) + + return { + "status": True, + "pdf_extract_images": request.app.state.config.PDF_EXTRACT_IMAGES, + "RAG_FULL_CONTEXT": request.app.state.config.RAG_FULL_CONTEXT, + "BYPASS_EMBEDDING_AND_RETRIEVAL": request.app.state.config.BYPASS_EMBEDDING_AND_RETRIEVAL, + "file": { + "max_size": request.app.state.config.FILE_MAX_SIZE, + "max_count": request.app.state.config.FILE_MAX_COUNT, + }, + "content_extraction": { + "engine": request.app.state.config.CONTENT_EXTRACTION_ENGINE, + "tika_server_url": request.app.state.config.TIKA_SERVER_URL, + "document_intelligence_config": { + "endpoint": request.app.state.config.DOCUMENT_INTELLIGENCE_ENDPOINT, + "key": request.app.state.config.DOCUMENT_INTELLIGENCE_KEY, + }, + }, + "chunk": { + "text_splitter": request.app.state.config.TEXT_SPLITTER, + "chunk_size": request.app.state.config.CHUNK_SIZE, + "chunk_overlap": request.app.state.config.CHUNK_OVERLAP, + }, + "youtube": { + "language": request.app.state.config.YOUTUBE_LOADER_LANGUAGE, + "proxy_url": request.app.state.config.YOUTUBE_LOADER_PROXY_URL, + "translation": request.app.state.YOUTUBE_LOADER_TRANSLATION, + }, + "web": { + "ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION": request.app.state.config.ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION, + "BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL": request.app.state.config.BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL, + "search": { + "enabled": request.app.state.config.ENABLE_RAG_WEB_SEARCH, + "engine": request.app.state.config.RAG_WEB_SEARCH_ENGINE, + "searxng_query_url": request.app.state.config.SEARXNG_QUERY_URL, + "google_pse_api_key": request.app.state.config.GOOGLE_PSE_API_KEY, + "google_pse_engine_id": request.app.state.config.GOOGLE_PSE_ENGINE_ID, + "brave_search_api_key": request.app.state.config.BRAVE_SEARCH_API_KEY, + "kagi_search_api_key": request.app.state.config.KAGI_SEARCH_API_KEY, + "mojeek_search_api_key": request.app.state.config.MOJEEK_SEARCH_API_KEY, + "bocha_search_api_key": request.app.state.config.BOCHA_SEARCH_API_KEY, + "serpstack_api_key": request.app.state.config.SERPSTACK_API_KEY, + "serpstack_https": request.app.state.config.SERPSTACK_HTTPS, + "serper_api_key": request.app.state.config.SERPER_API_KEY, + "serply_api_key": request.app.state.config.SERPLY_API_KEY, + "serachapi_api_key": request.app.state.config.SEARCHAPI_API_KEY, + "searchapi_engine": request.app.state.config.SEARCHAPI_ENGINE, + "serpapi_api_key": request.app.state.config.SERPAPI_API_KEY, + "serpapi_engine": request.app.state.config.SERPAPI_ENGINE, + "tavily_api_key": request.app.state.config.TAVILY_API_KEY, + "jina_api_key": request.app.state.config.JINA_API_KEY, + "bing_search_v7_endpoint": request.app.state.config.BING_SEARCH_V7_ENDPOINT, + "bing_search_v7_subscription_key": request.app.state.config.BING_SEARCH_V7_SUBSCRIPTION_KEY, + "exa_api_key": request.app.state.config.EXA_API_KEY, + "result_count": request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT, + "concurrent_requests": request.app.state.config.RAG_WEB_SEARCH_CONCURRENT_REQUESTS, + "trust_env": request.app.state.config.RAG_WEB_SEARCH_TRUST_ENV, + "domain_filter_list": request.app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST, + }, + }, + } + + +@router.get("/template") +async def get_rag_template(request: Request, user=Depends(get_verified_user)): + return { + "status": True, + "template": request.app.state.config.RAG_TEMPLATE, + } + + +@router.get("/query/settings") +async def get_query_settings(request: Request, user=Depends(get_admin_user)): + return { + "status": True, + "template": request.app.state.config.RAG_TEMPLATE, + "k": request.app.state.config.TOP_K, + "r": request.app.state.config.RELEVANCE_THRESHOLD, + "hybrid": request.app.state.config.ENABLE_RAG_HYBRID_SEARCH, + } + + +class QuerySettingsForm(BaseModel): + k: Optional[int] = None + r: Optional[float] = None + template: Optional[str] = None + hybrid: Optional[bool] = None + + +@router.post("/query/settings/update") +async def update_query_settings( + request: Request, form_data: QuerySettingsForm, user=Depends(get_admin_user) +): + request.app.state.config.RAG_TEMPLATE = form_data.template + request.app.state.config.TOP_K = form_data.k if form_data.k else 4 + request.app.state.config.RELEVANCE_THRESHOLD = form_data.r if form_data.r else 0.0 + + request.app.state.config.ENABLE_RAG_HYBRID_SEARCH = ( + form_data.hybrid if form_data.hybrid else False + ) + + return { + "status": True, + "template": request.app.state.config.RAG_TEMPLATE, + "k": request.app.state.config.TOP_K, + "r": request.app.state.config.RELEVANCE_THRESHOLD, + "hybrid": request.app.state.config.ENABLE_RAG_HYBRID_SEARCH, + } + + +#################################### +# +# Document process and retrieval +# +#################################### + + +def save_docs_to_vector_db( + request: Request, + docs, + collection_name, + metadata: Optional[dict] = None, + overwrite: bool = False, + split: bool = True, + add: bool = False, + user=None, +) -> bool: + def _get_docs_info(docs: list[Document]) -> str: + docs_info = set() + + # Trying to select relevant metadata identifying the document. + for doc in docs: + metadata = getattr(doc, "metadata", {}) + doc_name = metadata.get("name", "") + if not doc_name: + doc_name = metadata.get("title", "") + if not doc_name: + doc_name = metadata.get("source", "") + if doc_name: + docs_info.add(doc_name) + + return ", ".join(docs_info) + + log.info( + f"save_docs_to_vector_db: document {_get_docs_info(docs)} {collection_name}" + ) + + # Check if entries with the same hash (metadata.hash) already exist + if metadata and "hash" in metadata: + result = VECTOR_DB_CLIENT.query( + collection_name=collection_name, + filter={"hash": metadata["hash"]}, + ) + + if result is not None: + existing_doc_ids = result.ids[0] + if existing_doc_ids: + log.info(f"Document with hash {metadata['hash']} already exists") + raise ValueError(ERROR_MESSAGES.DUPLICATE_CONTENT) + + if split: + if request.app.state.config.TEXT_SPLITTER in ["", "character"]: + text_splitter = RecursiveCharacterTextSplitter( + chunk_size=request.app.state.config.CHUNK_SIZE, + chunk_overlap=request.app.state.config.CHUNK_OVERLAP, + add_start_index=True, + ) + elif request.app.state.config.TEXT_SPLITTER == "token": + log.info( + f"Using token text splitter: {request.app.state.config.TIKTOKEN_ENCODING_NAME}" + ) + + tiktoken.get_encoding(str(request.app.state.config.TIKTOKEN_ENCODING_NAME)) + text_splitter = TokenTextSplitter( + encoding_name=str(request.app.state.config.TIKTOKEN_ENCODING_NAME), + chunk_size=request.app.state.config.CHUNK_SIZE, + chunk_overlap=request.app.state.config.CHUNK_OVERLAP, + add_start_index=True, + ) + else: + raise ValueError(ERROR_MESSAGES.DEFAULT("Invalid text splitter")) + + docs = text_splitter.split_documents(docs) + + if len(docs) == 0: + raise ValueError(ERROR_MESSAGES.EMPTY_CONTENT) + + texts = [doc.page_content for doc in docs] + metadatas = [ + { + **doc.metadata, + **(metadata if metadata else {}), + "embedding_config": json.dumps( + { + "engine": request.app.state.config.RAG_EMBEDDING_ENGINE, + "model": request.app.state.config.RAG_EMBEDDING_MODEL, + } + ), + } + for doc in docs + ] + + # ChromaDB does not like datetime formats + # for meta-data so convert them to string. + for metadata in metadatas: + for key, value in metadata.items(): + if ( + isinstance(value, datetime) + or isinstance(value, list) + or isinstance(value, dict) + ): + metadata[key] = str(value) + + try: + if VECTOR_DB_CLIENT.has_collection(collection_name=collection_name): + log.info(f"collection {collection_name} already exists") + + if overwrite: + VECTOR_DB_CLIENT.delete_collection(collection_name=collection_name) + log.info(f"deleting existing collection {collection_name}") + elif add is False: + log.info( + f"collection {collection_name} already exists, overwrite is False and add is False" + ) + return True + + log.info(f"adding to collection {collection_name}") + embedding_function = get_embedding_function( + request.app.state.config.RAG_EMBEDDING_ENGINE, + request.app.state.config.RAG_EMBEDDING_MODEL, + request.app.state.ef, + ( + request.app.state.config.RAG_OPENAI_API_BASE_URL + if request.app.state.config.RAG_EMBEDDING_ENGINE == "openai" + else request.app.state.config.RAG_OLLAMA_BASE_URL + ), + ( + request.app.state.config.RAG_OPENAI_API_KEY + if request.app.state.config.RAG_EMBEDDING_ENGINE == "openai" + else request.app.state.config.RAG_OLLAMA_API_KEY + ), + request.app.state.config.RAG_EMBEDDING_BATCH_SIZE, + ) + + embeddings = embedding_function( + list(map(lambda x: x.replace("\n", " "), texts)), user=user + ) + + items = [ + { + "id": str(uuid.uuid4()), + "text": text, + "vector": embeddings[idx], + "metadata": metadatas[idx], + } + for idx, text in enumerate(texts) + ] + + VECTOR_DB_CLIENT.insert( + collection_name=collection_name, + items=items, + ) + + return True + except Exception as e: + log.exception(e) + raise e + + +class ProcessFileForm(BaseModel): + file_id: str + content: Optional[str] = None + collection_name: Optional[str] = None + + +@router.post("/process/file") +def process_file( + request: Request, + form_data: ProcessFileForm, + user=Depends(get_verified_user), +): + try: + file = Files.get_file_by_id(form_data.file_id) + + collection_name = form_data.collection_name + + if collection_name is None: + collection_name = f"file-{file.id}" + + if form_data.content: + # Update the content in the file + # Usage: /files/{file_id}/data/content/update + + try: + # /files/{file_id}/data/content/update + VECTOR_DB_CLIENT.delete_collection(collection_name=f"file-{file.id}") + except: + # Audio file upload pipeline + pass + + docs = [ + Document( + page_content=form_data.content.replace("
", "\n"), + metadata={ + **file.meta, + "name": file.filename, + "created_by": file.user_id, + "file_id": file.id, + "source": file.filename, + }, + ) + ] + + text_content = form_data.content + elif form_data.collection_name: + # Check if the file has already been processed and save the content + # Usage: /knowledge/{id}/file/add, /knowledge/{id}/file/update + + result = VECTOR_DB_CLIENT.query( + collection_name=f"file-{file.id}", filter={"file_id": file.id} + ) + + if result is not None and len(result.ids[0]) > 0: + docs = [ + Document( + page_content=result.documents[0][idx], + metadata=result.metadatas[0][idx], + ) + for idx, id in enumerate(result.ids[0]) + ] + else: + docs = [ + Document( + page_content=file.data.get("content", ""), + metadata={ + **file.meta, + "name": file.filename, + "created_by": file.user_id, + "file_id": file.id, + "source": file.filename, + }, + ) + ] + + text_content = file.data.get("content", "") + else: + # Process the file and save the content + # Usage: /files/ + file_path = file.path + if file_path: + file_path = Storage.get_file(file_path) + loader = Loader( + engine=request.app.state.config.CONTENT_EXTRACTION_ENGINE, + TIKA_SERVER_URL=request.app.state.config.TIKA_SERVER_URL, + PDF_EXTRACT_IMAGES=request.app.state.config.PDF_EXTRACT_IMAGES, + DOCUMENT_INTELLIGENCE_ENDPOINT=request.app.state.config.DOCUMENT_INTELLIGENCE_ENDPOINT, + DOCUMENT_INTELLIGENCE_KEY=request.app.state.config.DOCUMENT_INTELLIGENCE_KEY, + ) + docs = loader.load( + file.filename, file.meta.get("content_type"), file_path + ) + + docs = [ + Document( + page_content=doc.page_content, + metadata={ + **doc.metadata, + "name": file.filename, + "created_by": file.user_id, + "file_id": file.id, + "source": file.filename, + }, + ) + for doc in docs + ] + else: + docs = [ + Document( + page_content=file.data.get("content", ""), + metadata={ + **file.meta, + "name": file.filename, + "created_by": file.user_id, + "file_id": file.id, + "source": file.filename, + }, + ) + ] + text_content = " ".join([doc.page_content for doc in docs]) + + log.debug(f"text_content: {text_content}") + Files.update_file_data_by_id( + file.id, + {"content": text_content}, + ) + + hash = calculate_sha256_string(text_content) + Files.update_file_hash_by_id(file.id, hash) + + if not request.app.state.config.BYPASS_EMBEDDING_AND_RETRIEVAL: + try: + result = save_docs_to_vector_db( + request, + docs=docs, + collection_name=collection_name, + metadata={ + "file_id": file.id, + "name": file.filename, + "hash": hash, + }, + add=(True if form_data.collection_name else False), + user=user, + ) + + if result: + Files.update_file_metadata_by_id( + file.id, + { + "collection_name": collection_name, + }, + ) + + return { + "status": True, + "collection_name": collection_name, + "filename": file.filename, + "content": text_content, + } + except Exception as e: + raise e + else: + return { + "status": True, + "collection_name": None, + "filename": file.filename, + "content": text_content, + } + + except Exception as e: + log.exception(e) + if "No pandoc was found" in str(e): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.PANDOC_NOT_INSTALLED, + ) + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=str(e), + ) + + +class ProcessTextForm(BaseModel): + name: str + content: str + collection_name: Optional[str] = None + + +@router.post("/process/text") +def process_text( + request: Request, + form_data: ProcessTextForm, + user=Depends(get_verified_user), +): + collection_name = form_data.collection_name + if collection_name is None: + collection_name = calculate_sha256_string(form_data.content) + + docs = [ + Document( + page_content=form_data.content, + metadata={"name": form_data.name, "created_by": user.id}, + ) + ] + text_content = form_data.content + log.debug(f"text_content: {text_content}") + + result = save_docs_to_vector_db(request, docs, collection_name, user=user) + if result: + return { + "status": True, + "collection_name": collection_name, + "content": text_content, + } + else: + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=ERROR_MESSAGES.DEFAULT(), + ) + + +@router.post("/process/youtube") +def process_youtube_video( + request: Request, form_data: ProcessUrlForm, user=Depends(get_verified_user) +): + try: + collection_name = form_data.collection_name + if not collection_name: + collection_name = calculate_sha256_string(form_data.url)[:63] + + loader = YoutubeLoader( + form_data.url, + language=request.app.state.config.YOUTUBE_LOADER_LANGUAGE, + proxy_url=request.app.state.config.YOUTUBE_LOADER_PROXY_URL, + ) + + docs = loader.load() + content = " ".join([doc.page_content for doc in docs]) + log.debug(f"text_content: {content}") + + save_docs_to_vector_db( + request, docs, collection_name, overwrite=True, user=user + ) + + return { + "status": True, + "collection_name": collection_name, + "filename": form_data.url, + "file": { + "data": { + "content": content, + }, + "meta": { + "name": form_data.url, + }, + }, + } + except Exception as e: + log.exception(e) + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT(e), + ) + + +@router.post("/process/web") +def process_web( + request: Request, form_data: ProcessUrlForm, user=Depends(get_verified_user) +): + try: + collection_name = form_data.collection_name + if not collection_name: + collection_name = calculate_sha256_string(form_data.url)[:63] + + loader = get_web_loader( + form_data.url, + verify_ssl=request.app.state.config.ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION, + requests_per_second=request.app.state.config.RAG_WEB_SEARCH_CONCURRENT_REQUESTS, + ) + docs = loader.load() + content = " ".join([doc.page_content for doc in docs]) + + log.debug(f"text_content: {content}") + save_docs_to_vector_db( + request, docs, collection_name, overwrite=True, user=user + ) + + return { + "status": True, + "collection_name": collection_name, + "filename": form_data.url, + "file": { + "data": { + "content": content, + }, + "meta": { + "name": form_data.url, + }, + }, + } + except Exception as e: + log.exception(e) + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT(e), + ) + + +def search_web(request: Request, engine: str, query: str) -> list[SearchResult]: + """Search the web using a search engine and return the results as a list of SearchResult objects. + Will look for a search engine API key in environment variables in the following order: + - SEARXNG_QUERY_URL + - GOOGLE_PSE_API_KEY + GOOGLE_PSE_ENGINE_ID + - BRAVE_SEARCH_API_KEY + - KAGI_SEARCH_API_KEY + - MOJEEK_SEARCH_API_KEY + - BOCHA_SEARCH_API_KEY + - SERPSTACK_API_KEY + - SERPER_API_KEY + - SERPLY_API_KEY + - TAVILY_API_KEY + - EXA_API_KEY + - SEARCHAPI_API_KEY + SEARCHAPI_ENGINE (by default `google`) + - SERPAPI_API_KEY + SERPAPI_ENGINE (by default `google`) + Args: + query (str): The query to search for + """ + + # TODO: add playwright to search the web + if engine == "searxng": + if request.app.state.config.SEARXNG_QUERY_URL: + return search_searxng( + request.app.state.config.SEARXNG_QUERY_URL, + query, + request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT, + request.app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST, + ) + else: + raise Exception("No SEARXNG_QUERY_URL found in environment variables") + elif engine == "google_pse": + if ( + request.app.state.config.GOOGLE_PSE_API_KEY + and request.app.state.config.GOOGLE_PSE_ENGINE_ID + ): + return search_google_pse( + request.app.state.config.GOOGLE_PSE_API_KEY, + request.app.state.config.GOOGLE_PSE_ENGINE_ID, + query, + request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT, + request.app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST, + ) + else: + raise Exception( + "No GOOGLE_PSE_API_KEY or GOOGLE_PSE_ENGINE_ID found in environment variables" + ) + elif engine == "brave": + if request.app.state.config.BRAVE_SEARCH_API_KEY: + return search_brave( + request.app.state.config.BRAVE_SEARCH_API_KEY, + query, + request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT, + request.app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST, + ) + else: + raise Exception("No BRAVE_SEARCH_API_KEY found in environment variables") + elif engine == "kagi": + if request.app.state.config.KAGI_SEARCH_API_KEY: + return search_kagi( + request.app.state.config.KAGI_SEARCH_API_KEY, + query, + request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT, + request.app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST, + ) + else: + raise Exception("No KAGI_SEARCH_API_KEY found in environment variables") + elif engine == "mojeek": + if request.app.state.config.MOJEEK_SEARCH_API_KEY: + return search_mojeek( + request.app.state.config.MOJEEK_SEARCH_API_KEY, + query, + request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT, + request.app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST, + ) + else: + raise Exception("No MOJEEK_SEARCH_API_KEY found in environment variables") + elif engine == "bocha": + if request.app.state.config.BOCHA_SEARCH_API_KEY: + return search_bocha( + request.app.state.config.BOCHA_SEARCH_API_KEY, + query, + request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT, + request.app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST, + ) + else: + raise Exception("No BOCHA_SEARCH_API_KEY found in environment variables") + elif engine == "serpstack": + if request.app.state.config.SERPSTACK_API_KEY: + return search_serpstack( + request.app.state.config.SERPSTACK_API_KEY, + query, + request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT, + request.app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST, + https_enabled=request.app.state.config.SERPSTACK_HTTPS, + ) + else: + raise Exception("No SERPSTACK_API_KEY found in environment variables") + elif engine == "serper": + if request.app.state.config.SERPER_API_KEY: + return search_serper( + request.app.state.config.SERPER_API_KEY, + query, + request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT, + request.app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST, + ) + else: + raise Exception("No SERPER_API_KEY found in environment variables") + elif engine == "serply": + if request.app.state.config.SERPLY_API_KEY: + return search_serply( + request.app.state.config.SERPLY_API_KEY, + query, + request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT, + request.app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST, + ) + else: + raise Exception("No SERPLY_API_KEY found in environment variables") + elif engine == "duckduckgo": + return search_duckduckgo( + query, + request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT, + request.app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST, + ) + elif engine == "tavily": + if request.app.state.config.TAVILY_API_KEY: + return search_tavily( + request.app.state.config.TAVILY_API_KEY, + query, + request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT, + request.app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST, + ) + else: + raise Exception("No TAVILY_API_KEY found in environment variables") + elif engine == "searchapi": + if request.app.state.config.SEARCHAPI_API_KEY: + return search_searchapi( + request.app.state.config.SEARCHAPI_API_KEY, + request.app.state.config.SEARCHAPI_ENGINE, + query, + request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT, + request.app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST, + ) + else: + raise Exception("No SEARCHAPI_API_KEY found in environment variables") + elif engine == "serpapi": + if request.app.state.config.SERPAPI_API_KEY: + return search_serpapi( + request.app.state.config.SERPAPI_API_KEY, + request.app.state.config.SERPAPI_ENGINE, + query, + request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT, + request.app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST, + ) + else: + raise Exception("No SERPAPI_API_KEY found in environment variables") + elif engine == "jina": + return search_jina( + request.app.state.config.JINA_API_KEY, + query, + request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT, + ) + elif engine == "bing": + return search_bing( + request.app.state.config.BING_SEARCH_V7_SUBSCRIPTION_KEY, + request.app.state.config.BING_SEARCH_V7_ENDPOINT, + str(DEFAULT_LOCALE), + query, + request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT, + request.app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST, + ) + elif engine == "exa": + return search_exa( + request.app.state.config.EXA_API_KEY, + query, + request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT, + request.app.state.config.RAG_WEB_SEARCH_DOMAIN_FILTER_LIST, + ) + else: + raise Exception("No search engine API key found in environment variables") + + +@router.post("/process/web/search") +async def process_web_search( + request: Request, form_data: SearchForm, user=Depends(get_verified_user) +): + try: + logging.info( + f"trying to web search with {request.app.state.config.RAG_WEB_SEARCH_ENGINE, form_data.query}" + ) + web_results = search_web( + request, request.app.state.config.RAG_WEB_SEARCH_ENGINE, form_data.query + ) + except Exception as e: + log.exception(e) + + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.WEB_SEARCH_ERROR(e), + ) + + log.debug(f"web_results: {web_results}") + + try: + collection_name = form_data.collection_name + if collection_name == "" or collection_name is None: + collection_name = f"web-search-{calculate_sha256_string(form_data.query)}"[ + :63 + ] + + urls = [result.link for result in web_results] + loader = get_web_loader( + urls, + verify_ssl=request.app.state.config.ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION, + requests_per_second=request.app.state.config.RAG_WEB_SEARCH_CONCURRENT_REQUESTS, + trust_env=request.app.state.config.RAG_WEB_SEARCH_TRUST_ENV, + ) + docs = await loader.aload() + + if request.app.state.config.BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL: + return { + "status": True, + "collection_name": None, + "filenames": urls, + "docs": [ + { + "content": doc.page_content, + "metadata": doc.metadata, + } + for doc in docs + ], + "loaded_count": len(docs), + } + else: + await run_in_threadpool( + save_docs_to_vector_db, + request, + docs, + collection_name, + overwrite=True, + user=user, + ) + + return { + "status": True, + "collection_name": collection_name, + "filenames": urls, + "loaded_count": len(docs), + } + except Exception as e: + log.exception(e) + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT(e), + ) + + +class QueryDocForm(BaseModel): + collection_name: str + query: str + k: Optional[int] = None + r: Optional[float] = None + hybrid: Optional[bool] = None + + +@router.post("/query/doc") +def query_doc_handler( + request: Request, + form_data: QueryDocForm, + user=Depends(get_verified_user), +): + try: + if request.app.state.config.ENABLE_RAG_HYBRID_SEARCH: + return query_doc_with_hybrid_search( + collection_name=form_data.collection_name, + query=form_data.query, + embedding_function=lambda query: request.app.state.EMBEDDING_FUNCTION( + query, user=user + ), + k=form_data.k if form_data.k else request.app.state.config.TOP_K, + reranking_function=request.app.state.rf, + r=( + form_data.r + if form_data.r + else request.app.state.config.RELEVANCE_THRESHOLD + ), + user=user, + ) + else: + return query_doc( + collection_name=form_data.collection_name, + query_embedding=request.app.state.EMBEDDING_FUNCTION( + form_data.query, user=user + ), + k=form_data.k if form_data.k else request.app.state.config.TOP_K, + user=user, + ) + except Exception as e: + log.exception(e) + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT(e), + ) + + +class QueryCollectionsForm(BaseModel): + collection_names: list[str] + query: str + k: Optional[int] = None + r: Optional[float] = None + hybrid: Optional[bool] = None + + +@router.post("/query/collection") +def query_collection_handler( + request: Request, + form_data: QueryCollectionsForm, + user=Depends(get_verified_user), +): + try: + if request.app.state.config.ENABLE_RAG_HYBRID_SEARCH: + return query_collection_with_hybrid_search( + collection_names=form_data.collection_names, + queries=[form_data.query], + embedding_function=lambda query: request.app.state.EMBEDDING_FUNCTION( + query, user=user + ), + k=form_data.k if form_data.k else request.app.state.config.TOP_K, + reranking_function=request.app.state.rf, + r=( + form_data.r + if form_data.r + else request.app.state.config.RELEVANCE_THRESHOLD + ), + ) + else: + return query_collection( + collection_names=form_data.collection_names, + queries=[form_data.query], + embedding_function=lambda query: request.app.state.EMBEDDING_FUNCTION( + query, user=user + ), + k=form_data.k if form_data.k else request.app.state.config.TOP_K, + ) + + except Exception as e: + log.exception(e) + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT(e), + ) + + +#################################### +# +# Vector DB operations +# +#################################### + + +class DeleteForm(BaseModel): + collection_name: str + file_id: str + + +@router.post("/delete") +def delete_entries_from_collection(form_data: DeleteForm, user=Depends(get_admin_user)): + try: + if VECTOR_DB_CLIENT.has_collection(collection_name=form_data.collection_name): + file = Files.get_file_by_id(form_data.file_id) + hash = file.hash + + VECTOR_DB_CLIENT.delete( + collection_name=form_data.collection_name, + metadata={"hash": hash}, + ) + return {"status": True} + else: + return {"status": False} + except Exception as e: + log.exception(e) + return {"status": False} + + +@router.post("/reset/db") +def reset_vector_db(user=Depends(get_admin_user)): + VECTOR_DB_CLIENT.reset() + Knowledges.delete_all_knowledge() + + +@router.post("/reset/uploads") +def reset_upload_dir(user=Depends(get_admin_user)) -> bool: + folder = f"{UPLOAD_DIR}" + try: + # Check if the directory exists + if os.path.exists(folder): + # Iterate over all the files and directories in the specified directory + for filename in os.listdir(folder): + file_path = os.path.join(folder, filename) + try: + if os.path.isfile(file_path) or os.path.islink(file_path): + os.unlink(file_path) # Remove the file or link + elif os.path.isdir(file_path): + shutil.rmtree(file_path) # Remove the directory + except Exception as e: + log.exception(f"Failed to delete {file_path}. Reason: {e}") + else: + log.warning(f"The directory {folder} does not exist") + except Exception as e: + log.exception(f"Failed to process the directory {folder}. Reason: {e}") + return True + + +if ENV == "dev": + + @router.get("/ef/{text}") + async def get_embeddings(request: Request, text: Optional[str] = "Hello World!"): + return {"result": request.app.state.EMBEDDING_FUNCTION(text)} + + +class BatchProcessFilesForm(BaseModel): + files: List[FileModel] + collection_name: str + + +class BatchProcessFilesResult(BaseModel): + file_id: str + status: str + error: Optional[str] = None + + +class BatchProcessFilesResponse(BaseModel): + results: List[BatchProcessFilesResult] + errors: List[BatchProcessFilesResult] + + +@router.post("/process/files/batch") +def process_files_batch( + request: Request, + form_data: BatchProcessFilesForm, + user=Depends(get_verified_user), +) -> BatchProcessFilesResponse: + """ + Process a batch of files and save them to the vector database. + """ + results: List[BatchProcessFilesResult] = [] + errors: List[BatchProcessFilesResult] = [] + collection_name = form_data.collection_name + + # Prepare all documents first + all_docs: List[Document] = [] + for file in form_data.files: + try: + text_content = file.data.get("content", "") + + docs: List[Document] = [ + Document( + page_content=text_content.replace("
", "\n"), + metadata={ + **file.meta, + "name": file.filename, + "created_by": file.user_id, + "file_id": file.id, + "source": file.filename, + }, + ) + ] + + hash = calculate_sha256_string(text_content) + Files.update_file_hash_by_id(file.id, hash) + Files.update_file_data_by_id(file.id, {"content": text_content}) + + all_docs.extend(docs) + results.append(BatchProcessFilesResult(file_id=file.id, status="prepared")) + + except Exception as e: + log.error(f"process_files_batch: Error processing file {file.id}: {str(e)}") + errors.append( + BatchProcessFilesResult(file_id=file.id, status="failed", error=str(e)) + ) + + # Save all documents in one batch + if all_docs: + try: + save_docs_to_vector_db( + request=request, + docs=all_docs, + collection_name=collection_name, + add=True, + user=user, + ) + + # Update all files with collection name + for result in results: + Files.update_file_metadata_by_id( + result.file_id, {"collection_name": collection_name} + ) + result.status = "completed" + + except Exception as e: + log.error( + f"process_files_batch: Error saving documents to vector DB: {str(e)}" + ) + for result in results: + result.status = "failed" + errors.append( + BatchProcessFilesResult(file_id=result.file_id, error=str(e)) + ) + + return BatchProcessFilesResponse(results=results, errors=errors) diff --git a/backend/open_webui/routers/tasks.py b/backend/open_webui/routers/tasks.py new file mode 100644 index 0000000..b63c973 --- /dev/null +++ b/backend/open_webui/routers/tasks.py @@ -0,0 +1,699 @@ +from fastapi import APIRouter, Depends, HTTPException, Response, status, Request +from fastapi.responses import JSONResponse, RedirectResponse + +from pydantic import BaseModel +from typing import Optional +import logging +import re + +from open_webui.utils.chat import generate_chat_completion +from open_webui.utils.task import ( + title_generation_template, + query_generation_template, + image_prompt_generation_template, + autocomplete_generation_template, + tags_generation_template, + emoji_generation_template, + moa_response_generation_template, +) +from open_webui.utils.auth import get_admin_user, get_verified_user +from open_webui.constants import TASKS + +from open_webui.routers.pipelines import process_pipeline_inlet_filter +from open_webui.utils.filter import ( + get_sorted_filter_ids, + process_filter_functions, +) +from open_webui.utils.task import get_task_model_id + +from open_webui.config import ( + DEFAULT_TITLE_GENERATION_PROMPT_TEMPLATE, + DEFAULT_TAGS_GENERATION_PROMPT_TEMPLATE, + DEFAULT_IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE, + DEFAULT_QUERY_GENERATION_PROMPT_TEMPLATE, + DEFAULT_AUTOCOMPLETE_GENERATION_PROMPT_TEMPLATE, + DEFAULT_EMOJI_GENERATION_PROMPT_TEMPLATE, + DEFAULT_MOA_GENERATION_PROMPT_TEMPLATE, +) +from open_webui.env import SRC_LOG_LEVELS + + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MODELS"]) + +router = APIRouter() + + +################################## +# +# Task Endpoints +# +################################## + + +@router.get("/config") +async def get_task_config(request: Request, user=Depends(get_verified_user)): + return { + "TASK_MODEL": request.app.state.config.TASK_MODEL, + "TASK_MODEL_EXTERNAL": request.app.state.config.TASK_MODEL_EXTERNAL, + "TITLE_GENERATION_PROMPT_TEMPLATE": request.app.state.config.TITLE_GENERATION_PROMPT_TEMPLATE, + "IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE": request.app.state.config.IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE, + "ENABLE_AUTOCOMPLETE_GENERATION": request.app.state.config.ENABLE_AUTOCOMPLETE_GENERATION, + "AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH": request.app.state.config.AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH, + "TAGS_GENERATION_PROMPT_TEMPLATE": request.app.state.config.TAGS_GENERATION_PROMPT_TEMPLATE, + "ENABLE_TAGS_GENERATION": request.app.state.config.ENABLE_TAGS_GENERATION, + "ENABLE_TITLE_GENERATION": request.app.state.config.ENABLE_TITLE_GENERATION, + "ENABLE_SEARCH_QUERY_GENERATION": request.app.state.config.ENABLE_SEARCH_QUERY_GENERATION, + "ENABLE_RETRIEVAL_QUERY_GENERATION": request.app.state.config.ENABLE_RETRIEVAL_QUERY_GENERATION, + "QUERY_GENERATION_PROMPT_TEMPLATE": request.app.state.config.QUERY_GENERATION_PROMPT_TEMPLATE, + "TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE": request.app.state.config.TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE, + } + + +class TaskConfigForm(BaseModel): + TASK_MODEL: Optional[str] + TASK_MODEL_EXTERNAL: Optional[str] + ENABLE_TITLE_GENERATION: bool + TITLE_GENERATION_PROMPT_TEMPLATE: str + IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE: str + ENABLE_AUTOCOMPLETE_GENERATION: bool + AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH: int + TAGS_GENERATION_PROMPT_TEMPLATE: str + ENABLE_TAGS_GENERATION: bool + ENABLE_SEARCH_QUERY_GENERATION: bool + ENABLE_RETRIEVAL_QUERY_GENERATION: bool + QUERY_GENERATION_PROMPT_TEMPLATE: str + TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE: str + + +@router.post("/config/update") +async def update_task_config( + request: Request, form_data: TaskConfigForm, user=Depends(get_admin_user) +): + request.app.state.config.TASK_MODEL = form_data.TASK_MODEL + request.app.state.config.TASK_MODEL_EXTERNAL = form_data.TASK_MODEL_EXTERNAL + request.app.state.config.ENABLE_TITLE_GENERATION = form_data.ENABLE_TITLE_GENERATION + request.app.state.config.TITLE_GENERATION_PROMPT_TEMPLATE = ( + form_data.TITLE_GENERATION_PROMPT_TEMPLATE + ) + + request.app.state.config.IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE = ( + form_data.IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE + ) + + request.app.state.config.ENABLE_AUTOCOMPLETE_GENERATION = ( + form_data.ENABLE_AUTOCOMPLETE_GENERATION + ) + request.app.state.config.AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH = ( + form_data.AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH + ) + + request.app.state.config.TAGS_GENERATION_PROMPT_TEMPLATE = ( + form_data.TAGS_GENERATION_PROMPT_TEMPLATE + ) + request.app.state.config.ENABLE_TAGS_GENERATION = form_data.ENABLE_TAGS_GENERATION + request.app.state.config.ENABLE_SEARCH_QUERY_GENERATION = ( + form_data.ENABLE_SEARCH_QUERY_GENERATION + ) + request.app.state.config.ENABLE_RETRIEVAL_QUERY_GENERATION = ( + form_data.ENABLE_RETRIEVAL_QUERY_GENERATION + ) + + request.app.state.config.QUERY_GENERATION_PROMPT_TEMPLATE = ( + form_data.QUERY_GENERATION_PROMPT_TEMPLATE + ) + request.app.state.config.TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE = ( + form_data.TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE + ) + + return { + "TASK_MODEL": request.app.state.config.TASK_MODEL, + "TASK_MODEL_EXTERNAL": request.app.state.config.TASK_MODEL_EXTERNAL, + "ENABLE_TITLE_GENERATION": request.app.state.config.ENABLE_TITLE_GENERATION, + "TITLE_GENERATION_PROMPT_TEMPLATE": request.app.state.config.TITLE_GENERATION_PROMPT_TEMPLATE, + "IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE": request.app.state.config.IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE, + "ENABLE_AUTOCOMPLETE_GENERATION": request.app.state.config.ENABLE_AUTOCOMPLETE_GENERATION, + "AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH": request.app.state.config.AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH, + "TAGS_GENERATION_PROMPT_TEMPLATE": request.app.state.config.TAGS_GENERATION_PROMPT_TEMPLATE, + "ENABLE_TAGS_GENERATION": request.app.state.config.ENABLE_TAGS_GENERATION, + "ENABLE_SEARCH_QUERY_GENERATION": request.app.state.config.ENABLE_SEARCH_QUERY_GENERATION, + "ENABLE_RETRIEVAL_QUERY_GENERATION": request.app.state.config.ENABLE_RETRIEVAL_QUERY_GENERATION, + "QUERY_GENERATION_PROMPT_TEMPLATE": request.app.state.config.QUERY_GENERATION_PROMPT_TEMPLATE, + "TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE": request.app.state.config.TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE, + } + + +@router.post("/title/completions") +async def generate_title( + request: Request, form_data: dict, user=Depends(get_verified_user) +): + + if not request.app.state.config.ENABLE_TITLE_GENERATION: + return JSONResponse( + status_code=status.HTTP_200_OK, + content={"detail": "Title generation is disabled"}, + ) + + if getattr(request.state, "direct", False) and hasattr(request.state, "model"): + models = { + request.state.model["id"]: request.state.model, + } + else: + models = request.app.state.MODELS + + model_id = form_data["model"] + if model_id not in models: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="Model not found", + ) + + # Check if the user has a custom task model + # If the user has a custom task model, use that model + task_model_id = get_task_model_id( + model_id, + request.app.state.config.TASK_MODEL, + request.app.state.config.TASK_MODEL_EXTERNAL, + models, + ) + + log.debug( + f"generating chat title using model {task_model_id} for user {user.email} " + ) + + if request.app.state.config.TITLE_GENERATION_PROMPT_TEMPLATE != "": + template = request.app.state.config.TITLE_GENERATION_PROMPT_TEMPLATE + else: + template = DEFAULT_TITLE_GENERATION_PROMPT_TEMPLATE + + messages = form_data["messages"] + + # Remove reasoning details from the messages + for message in messages: + message["content"] = re.sub( + r"]*>.*?<\/details>", + "", + message["content"], + flags=re.S, + ).strip() + + content = title_generation_template( + template, + messages, + { + "name": user.name, + "location": user.info.get("location") if user.info else None, + }, + ) + + payload = { + "model": task_model_id, + "messages": [{"role": "user", "content": content}], + "stream": False, + **( + {"max_tokens": 1000} + if models[task_model_id].get("owned_by") == "ollama" + else { + "max_completion_tokens": 1000, + } + ), + "metadata": { + **(request.state.metadata if hasattr(request.state, "metadata") else {}), + "task": str(TASKS.TITLE_GENERATION), + "task_body": form_data, + "chat_id": form_data.get("chat_id", None), + }, + } + + # Process the payload through the pipeline + try: + payload = await process_pipeline_inlet_filter(request, payload, user, models) + except Exception as e: + raise e + + try: + return await generate_chat_completion(request, form_data=payload, user=user) + except Exception as e: + log.error("Exception occurred", exc_info=True) + return JSONResponse( + status_code=status.HTTP_400_BAD_REQUEST, + content={"detail": "An internal error has occurred."}, + ) + + +@router.post("/tags/completions") +async def generate_chat_tags( + request: Request, form_data: dict, user=Depends(get_verified_user) +): + + if not request.app.state.config.ENABLE_TAGS_GENERATION: + return JSONResponse( + status_code=status.HTTP_200_OK, + content={"detail": "Tags generation is disabled"}, + ) + + if getattr(request.state, "direct", False) and hasattr(request.state, "model"): + models = { + request.state.model["id"]: request.state.model, + } + else: + models = request.app.state.MODELS + + model_id = form_data["model"] + if model_id not in models: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="Model not found", + ) + + # Check if the user has a custom task model + # If the user has a custom task model, use that model + task_model_id = get_task_model_id( + model_id, + request.app.state.config.TASK_MODEL, + request.app.state.config.TASK_MODEL_EXTERNAL, + models, + ) + + log.debug( + f"generating chat tags using model {task_model_id} for user {user.email} " + ) + + if request.app.state.config.TAGS_GENERATION_PROMPT_TEMPLATE != "": + template = request.app.state.config.TAGS_GENERATION_PROMPT_TEMPLATE + else: + template = DEFAULT_TAGS_GENERATION_PROMPT_TEMPLATE + + content = tags_generation_template( + template, form_data["messages"], {"name": user.name} + ) + + payload = { + "model": task_model_id, + "messages": [{"role": "user", "content": content}], + "stream": False, + "metadata": { + **(request.state.metadata if hasattr(request.state, "metadata") else {}), + "task": str(TASKS.TAGS_GENERATION), + "task_body": form_data, + "chat_id": form_data.get("chat_id", None), + }, + } + + # Process the payload through the pipeline + try: + payload = await process_pipeline_inlet_filter(request, payload, user, models) + except Exception as e: + raise e + + try: + return await generate_chat_completion(request, form_data=payload, user=user) + except Exception as e: + log.error(f"Error generating chat completion: {e}") + return JSONResponse( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + content={"detail": "An internal error has occurred."}, + ) + + +@router.post("/image_prompt/completions") +async def generate_image_prompt( + request: Request, form_data: dict, user=Depends(get_verified_user) +): + if getattr(request.state, "direct", False) and hasattr(request.state, "model"): + models = { + request.state.model["id"]: request.state.model, + } + else: + models = request.app.state.MODELS + + model_id = form_data["model"] + if model_id not in models: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="Model not found", + ) + + # Check if the user has a custom task model + # If the user has a custom task model, use that model + task_model_id = get_task_model_id( + model_id, + request.app.state.config.TASK_MODEL, + request.app.state.config.TASK_MODEL_EXTERNAL, + models, + ) + + log.debug( + f"generating image prompt using model {task_model_id} for user {user.email} " + ) + + if request.app.state.config.IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE != "": + template = request.app.state.config.IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE + else: + template = DEFAULT_IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE + + content = image_prompt_generation_template( + template, + form_data["messages"], + user={ + "name": user.name, + }, + ) + + payload = { + "model": task_model_id, + "messages": [{"role": "user", "content": content}], + "stream": False, + "metadata": { + **(request.state.metadata if hasattr(request.state, "metadata") else {}), + "task": str(TASKS.IMAGE_PROMPT_GENERATION), + "task_body": form_data, + "chat_id": form_data.get("chat_id", None), + }, + } + + # Process the payload through the pipeline + try: + payload = await process_pipeline_inlet_filter(request, payload, user, models) + except Exception as e: + raise e + + try: + return await generate_chat_completion(request, form_data=payload, user=user) + except Exception as e: + log.error("Exception occurred", exc_info=True) + return JSONResponse( + status_code=status.HTTP_400_BAD_REQUEST, + content={"detail": "An internal error has occurred."}, + ) + + +@router.post("/queries/completions") +async def generate_queries( + request: Request, form_data: dict, user=Depends(get_verified_user) +): + + type = form_data.get("type") + if type == "web_search": + if not request.app.state.config.ENABLE_SEARCH_QUERY_GENERATION: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=f"Search query generation is disabled", + ) + elif type == "retrieval": + if not request.app.state.config.ENABLE_RETRIEVAL_QUERY_GENERATION: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=f"Query generation is disabled", + ) + + if getattr(request.state, "direct", False) and hasattr(request.state, "model"): + models = { + request.state.model["id"]: request.state.model, + } + else: + models = request.app.state.MODELS + + model_id = form_data["model"] + if model_id not in models: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="Model not found", + ) + + # Check if the user has a custom task model + # If the user has a custom task model, use that model + task_model_id = get_task_model_id( + model_id, + request.app.state.config.TASK_MODEL, + request.app.state.config.TASK_MODEL_EXTERNAL, + models, + ) + + log.debug( + f"generating {type} queries using model {task_model_id} for user {user.email}" + ) + + if (request.app.state.config.QUERY_GENERATION_PROMPT_TEMPLATE).strip() != "": + template = request.app.state.config.QUERY_GENERATION_PROMPT_TEMPLATE + else: + template = DEFAULT_QUERY_GENERATION_PROMPT_TEMPLATE + + content = query_generation_template( + template, form_data["messages"], {"name": user.name} + ) + + payload = { + "model": task_model_id, + "messages": [{"role": "user", "content": content}], + "stream": False, + "metadata": { + **(request.state.metadata if hasattr(request.state, "metadata") else {}), + "task": str(TASKS.QUERY_GENERATION), + "task_body": form_data, + "chat_id": form_data.get("chat_id", None), + }, + } + + # Process the payload through the pipeline + try: + payload = await process_pipeline_inlet_filter(request, payload, user, models) + except Exception as e: + raise e + + try: + return await generate_chat_completion(request, form_data=payload, user=user) + except Exception as e: + return JSONResponse( + status_code=status.HTTP_400_BAD_REQUEST, + content={"detail": str(e)}, + ) + + +@router.post("/auto/completions") +async def generate_autocompletion( + request: Request, form_data: dict, user=Depends(get_verified_user) +): + if not request.app.state.config.ENABLE_AUTOCOMPLETE_GENERATION: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=f"Autocompletion generation is disabled", + ) + + type = form_data.get("type") + prompt = form_data.get("prompt") + messages = form_data.get("messages") + + if request.app.state.config.AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH > 0: + if ( + len(prompt) + > request.app.state.config.AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH + ): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=f"Input prompt exceeds maximum length of {request.app.state.config.AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH}", + ) + + if getattr(request.state, "direct", False) and hasattr(request.state, "model"): + models = { + request.state.model["id"]: request.state.model, + } + else: + models = request.app.state.MODELS + + model_id = form_data["model"] + if model_id not in models: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="Model not found", + ) + + # Check if the user has a custom task model + # If the user has a custom task model, use that model + task_model_id = get_task_model_id( + model_id, + request.app.state.config.TASK_MODEL, + request.app.state.config.TASK_MODEL_EXTERNAL, + models, + ) + + log.debug( + f"generating autocompletion using model {task_model_id} for user {user.email}" + ) + + if (request.app.state.config.AUTOCOMPLETE_GENERATION_PROMPT_TEMPLATE).strip() != "": + template = request.app.state.config.AUTOCOMPLETE_GENERATION_PROMPT_TEMPLATE + else: + template = DEFAULT_AUTOCOMPLETE_GENERATION_PROMPT_TEMPLATE + + content = autocomplete_generation_template( + template, prompt, messages, type, {"name": user.name} + ) + + payload = { + "model": task_model_id, + "messages": [{"role": "user", "content": content}], + "stream": False, + "metadata": { + **(request.state.metadata if hasattr(request.state, "metadata") else {}), + "task": str(TASKS.AUTOCOMPLETE_GENERATION), + "task_body": form_data, + "chat_id": form_data.get("chat_id", None), + }, + } + + # Process the payload through the pipeline + try: + payload = await process_pipeline_inlet_filter(request, payload, user, models) + except Exception as e: + raise e + + try: + return await generate_chat_completion(request, form_data=payload, user=user) + except Exception as e: + log.error(f"Error generating chat completion: {e}") + return JSONResponse( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + content={"detail": "An internal error has occurred."}, + ) + + +@router.post("/emoji/completions") +async def generate_emoji( + request: Request, form_data: dict, user=Depends(get_verified_user) +): + + if getattr(request.state, "direct", False) and hasattr(request.state, "model"): + models = { + request.state.model["id"]: request.state.model, + } + else: + models = request.app.state.MODELS + + model_id = form_data["model"] + if model_id not in models: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="Model not found", + ) + + # Check if the user has a custom task model + # If the user has a custom task model, use that model + task_model_id = get_task_model_id( + model_id, + request.app.state.config.TASK_MODEL, + request.app.state.config.TASK_MODEL_EXTERNAL, + models, + ) + + log.debug(f"generating emoji using model {task_model_id} for user {user.email} ") + + template = DEFAULT_EMOJI_GENERATION_PROMPT_TEMPLATE + + content = emoji_generation_template( + template, + form_data["prompt"], + { + "name": user.name, + "location": user.info.get("location") if user.info else None, + }, + ) + + payload = { + "model": task_model_id, + "messages": [{"role": "user", "content": content}], + "stream": False, + **( + {"max_tokens": 4} + if models[task_model_id].get("owned_by") == "ollama" + else { + "max_completion_tokens": 4, + } + ), + "chat_id": form_data.get("chat_id", None), + "metadata": { + **(request.state.metadata if hasattr(request.state, "metadata") else {}), + "task": str(TASKS.EMOJI_GENERATION), + "task_body": form_data, + }, + } + + # Process the payload through the pipeline + try: + payload = await process_pipeline_inlet_filter(request, payload, user, models) + except Exception as e: + raise e + + try: + return await generate_chat_completion(request, form_data=payload, user=user) + except Exception as e: + return JSONResponse( + status_code=status.HTTP_400_BAD_REQUEST, + content={"detail": str(e)}, + ) + + +@router.post("/moa/completions") +async def generate_moa_response( + request: Request, form_data: dict, user=Depends(get_verified_user) +): + + if getattr(request.state, "direct", False) and hasattr(request.state, "model"): + models = { + request.state.model["id"]: request.state.model, + } + else: + models = request.app.state.MODELS + + model_id = form_data["model"] + + if model_id not in models: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="Model not found", + ) + + # Check if the user has a custom task model + # If the user has a custom task model, use that model + task_model_id = get_task_model_id( + model_id, + request.app.state.config.TASK_MODEL, + request.app.state.config.TASK_MODEL_EXTERNAL, + models, + ) + + log.debug(f"generating MOA model {task_model_id} for user {user.email} ") + + template = DEFAULT_MOA_GENERATION_PROMPT_TEMPLATE + + content = moa_response_generation_template( + template, + form_data["prompt"], + form_data["responses"], + ) + + payload = { + "model": task_model_id, + "messages": [{"role": "user", "content": content}], + "stream": form_data.get("stream", False), + "metadata": { + **(request.state.metadata if hasattr(request.state, "metadata") else {}), + "chat_id": form_data.get("chat_id", None), + "task": str(TASKS.MOA_RESPONSE_GENERATION), + "task_body": form_data, + }, + } + + # Process the payload through the pipeline + try: + payload = await process_pipeline_inlet_filter(request, payload, user, models) + except Exception as e: + raise e + + try: + return await generate_chat_completion(request, form_data=payload, user=user) + except Exception as e: + return JSONResponse( + status_code=status.HTTP_400_BAD_REQUEST, + content={"detail": str(e)}, + ) diff --git a/backend/open_webui/routers/tools.py b/backend/open_webui/routers/tools.py new file mode 100644 index 0000000..5e41090 --- /dev/null +++ b/backend/open_webui/routers/tools.py @@ -0,0 +1,443 @@ +import logging +from pathlib import Path +from typing import Optional + +from open_webui.models.tools import ( + ToolForm, + ToolModel, + ToolResponse, + ToolUserResponse, + Tools, +) +from open_webui.utils.plugin import load_tools_module_by_id, replace_imports +from open_webui.config import CACHE_DIR +from open_webui.constants import ERROR_MESSAGES +from fastapi import APIRouter, Depends, HTTPException, Request, status +from open_webui.utils.tools import get_tools_specs +from open_webui.utils.auth import get_admin_user, get_verified_user +from open_webui.utils.access_control import has_access, has_permission +from open_webui.env import SRC_LOG_LEVELS + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MAIN"]) + + +router = APIRouter() + +############################ +# GetTools +############################ + + +@router.get("/", response_model=list[ToolUserResponse]) +async def get_tools(user=Depends(get_verified_user)): + if user.role == "admin": + tools = Tools.get_tools() + else: + tools = Tools.get_tools_by_user_id(user.id, "read") + return tools + + +############################ +# GetToolList +############################ + + +@router.get("/list", response_model=list[ToolUserResponse]) +async def get_tool_list(user=Depends(get_verified_user)): + if user.role == "admin": + tools = Tools.get_tools() + else: + tools = Tools.get_tools_by_user_id(user.id, "write") + return tools + + +############################ +# ExportTools +############################ + + +@router.get("/export", response_model=list[ToolModel]) +async def export_tools(user=Depends(get_admin_user)): + tools = Tools.get_tools() + return tools + + +############################ +# CreateNewTools +############################ + + +@router.post("/create", response_model=Optional[ToolResponse]) +async def create_new_tools( + request: Request, + form_data: ToolForm, + user=Depends(get_verified_user), +): + if user.role != "admin" and not has_permission( + user.id, "workspace.tools", request.app.state.config.USER_PERMISSIONS + ): + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.UNAUTHORIZED, + ) + + if not form_data.id.isidentifier(): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="Only alphanumeric characters and underscores are allowed in the id", + ) + + form_data.id = form_data.id.lower() + + tools = Tools.get_tool_by_id(form_data.id) + if tools is None: + try: + form_data.content = replace_imports(form_data.content) + tools_module, frontmatter = load_tools_module_by_id( + form_data.id, content=form_data.content + ) + form_data.meta.manifest = frontmatter + + TOOLS = request.app.state.TOOLS + TOOLS[form_data.id] = tools_module + + specs = get_tools_specs(TOOLS[form_data.id]) + tools = Tools.insert_new_tool(user.id, form_data, specs) + + tool_cache_dir = Path(CACHE_DIR) / "tools" / form_data.id + tool_cache_dir.mkdir(parents=True, exist_ok=True) + + if tools: + return tools + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("Error creating tools"), + ) + except Exception as e: + log.exception(f"Failed to load the tool by id {form_data.id}: {e}") + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT(str(e)), + ) + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.ID_TAKEN, + ) + + +############################ +# GetToolsById +############################ + + +@router.get("/id/{id}", response_model=Optional[ToolModel]) +async def get_tools_by_id(id: str, user=Depends(get_verified_user)): + tools = Tools.get_tool_by_id(id) + + if tools: + if ( + user.role == "admin" + or tools.user_id == user.id + or has_access(user.id, "read", tools.access_control) + ): + return tools + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +############################ +# UpdateToolsById +############################ + + +@router.post("/id/{id}/update", response_model=Optional[ToolModel]) +async def update_tools_by_id( + request: Request, + id: str, + form_data: ToolForm, + user=Depends(get_verified_user), +): + tools = Tools.get_tool_by_id(id) + if not tools: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + # Is the user the original creator, in a group with write access, or an admin + if ( + tools.user_id != user.id + and not has_access(user.id, "write", tools.access_control) + and user.role != "admin" + ): + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.UNAUTHORIZED, + ) + + try: + form_data.content = replace_imports(form_data.content) + tools_module, frontmatter = load_tools_module_by_id( + id, content=form_data.content + ) + form_data.meta.manifest = frontmatter + + TOOLS = request.app.state.TOOLS + TOOLS[id] = tools_module + + specs = get_tools_specs(TOOLS[id]) + + updated = { + **form_data.model_dump(exclude={"id"}), + "specs": specs, + } + + log.debug(updated) + tools = Tools.update_tool_by_id(id, updated) + + if tools: + return tools + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT("Error updating tools"), + ) + + except Exception as e: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT(str(e)), + ) + + +############################ +# DeleteToolsById +############################ + + +@router.delete("/id/{id}/delete", response_model=bool) +async def delete_tools_by_id( + request: Request, id: str, user=Depends(get_verified_user) +): + tools = Tools.get_tool_by_id(id) + if not tools: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + if ( + tools.user_id != user.id + and not has_access(user.id, "write", tools.access_control) + and user.role != "admin" + ): + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.UNAUTHORIZED, + ) + + result = Tools.delete_tool_by_id(id) + if result: + TOOLS = request.app.state.TOOLS + if id in TOOLS: + del TOOLS[id] + + return result + + +############################ +# GetToolValves +############################ + + +@router.get("/id/{id}/valves", response_model=Optional[dict]) +async def get_tools_valves_by_id(id: str, user=Depends(get_verified_user)): + tools = Tools.get_tool_by_id(id) + if tools: + try: + valves = Tools.get_tool_valves_by_id(id) + return valves + except Exception as e: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT(str(e)), + ) + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +############################ +# GetToolValvesSpec +############################ + + +@router.get("/id/{id}/valves/spec", response_model=Optional[dict]) +async def get_tools_valves_spec_by_id( + request: Request, id: str, user=Depends(get_verified_user) +): + tools = Tools.get_tool_by_id(id) + if tools: + if id in request.app.state.TOOLS: + tools_module = request.app.state.TOOLS[id] + else: + tools_module, _ = load_tools_module_by_id(id) + request.app.state.TOOLS[id] = tools_module + + if hasattr(tools_module, "Valves"): + Valves = tools_module.Valves + return Valves.schema() + return None + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +############################ +# UpdateToolValves +############################ + + +@router.post("/id/{id}/valves/update", response_model=Optional[dict]) +async def update_tools_valves_by_id( + request: Request, id: str, form_data: dict, user=Depends(get_verified_user) +): + tools = Tools.get_tool_by_id(id) + if not tools: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + if ( + tools.user_id != user.id + and not has_access(user.id, "write", tools.access_control) + and user.role != "admin" + ): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + ) + + if id in request.app.state.TOOLS: + tools_module = request.app.state.TOOLS[id] + else: + tools_module, _ = load_tools_module_by_id(id) + request.app.state.TOOLS[id] = tools_module + + if not hasattr(tools_module, "Valves"): + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + Valves = tools_module.Valves + + try: + form_data = {k: v for k, v in form_data.items() if v is not None} + valves = Valves(**form_data) + Tools.update_tool_valves_by_id(id, valves.model_dump()) + return valves.model_dump() + except Exception as e: + log.exception(f"Failed to update tool valves by id {id}: {e}") + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT(str(e)), + ) + + +############################ +# ToolUserValves +############################ + + +@router.get("/id/{id}/valves/user", response_model=Optional[dict]) +async def get_tools_user_valves_by_id(id: str, user=Depends(get_verified_user)): + tools = Tools.get_tool_by_id(id) + if tools: + try: + user_valves = Tools.get_user_valves_by_id_and_user_id(id, user.id) + return user_valves + except Exception as e: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT(str(e)), + ) + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +@router.get("/id/{id}/valves/user/spec", response_model=Optional[dict]) +async def get_tools_user_valves_spec_by_id( + request: Request, id: str, user=Depends(get_verified_user) +): + tools = Tools.get_tool_by_id(id) + if tools: + if id in request.app.state.TOOLS: + tools_module = request.app.state.TOOLS[id] + else: + tools_module, _ = load_tools_module_by_id(id) + request.app.state.TOOLS[id] = tools_module + + if hasattr(tools_module, "UserValves"): + UserValves = tools_module.UserValves + return UserValves.schema() + return None + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + + +@router.post("/id/{id}/valves/user/update", response_model=Optional[dict]) +async def update_tools_user_valves_by_id( + request: Request, id: str, form_data: dict, user=Depends(get_verified_user) +): + tools = Tools.get_tool_by_id(id) + + if tools: + if id in request.app.state.TOOLS: + tools_module = request.app.state.TOOLS[id] + else: + tools_module, _ = load_tools_module_by_id(id) + request.app.state.TOOLS[id] = tools_module + + if hasattr(tools_module, "UserValves"): + UserValves = tools_module.UserValves + + try: + form_data = {k: v for k, v in form_data.items() if v is not None} + user_valves = UserValves(**form_data) + Tools.update_user_valves_by_id_and_user_id( + id, user.id, user_valves.model_dump() + ) + return user_valves.model_dump() + except Exception as e: + log.exception(f"Failed to update user valves by id {id}: {e}") + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT(str(e)), + ) + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.NOT_FOUND, + ) diff --git a/backend/open_webui/routers/users.py b/backend/open_webui/routers/users.py new file mode 100644 index 0000000..872212d --- /dev/null +++ b/backend/open_webui/routers/users.py @@ -0,0 +1,327 @@ +import logging +from typing import Optional + +from open_webui.models.auths import Auths +from open_webui.models.chats import Chats +from open_webui.models.users import ( + UserModel, + UserRoleUpdateForm, + Users, + UserSettings, + UserUpdateForm, +) + + +from open_webui.socket.main import get_active_status_by_user_id +from open_webui.constants import ERROR_MESSAGES +from open_webui.env import SRC_LOG_LEVELS +from fastapi import APIRouter, Depends, HTTPException, Request, status +from pydantic import BaseModel +from open_webui.utils.auth import get_admin_user, get_password_hash, get_verified_user + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MODELS"]) + +router = APIRouter() + +############################ +# GetUsers +############################ + + +@router.get("/", response_model=list[UserModel]) +async def get_users( + skip: Optional[int] = None, + limit: Optional[int] = None, + user=Depends(get_admin_user), +): + return Users.get_users(skip, limit) + + +############################ +# User Groups +############################ + + +@router.get("/groups") +async def get_user_groups(user=Depends(get_verified_user)): + return Users.get_user_groups(user.id) + + +############################ +# User Permissions +############################ + + +@router.get("/permissions") +async def get_user_permissisions(user=Depends(get_verified_user)): + return Users.get_user_groups(user.id) + + +############################ +# User Default Permissions +############################ +class WorkspacePermissions(BaseModel): + models: bool = False + knowledge: bool = False + prompts: bool = False + tools: bool = False + + +class ChatPermissions(BaseModel): + controls: bool = True + file_upload: bool = True + delete: bool = True + edit: bool = True + temporary: bool = True + + +class FeaturesPermissions(BaseModel): + web_search: bool = True + image_generation: bool = True + code_interpreter: bool = True + + +class UserPermissions(BaseModel): + workspace: WorkspacePermissions + chat: ChatPermissions + features: FeaturesPermissions + + +@router.get("/default/permissions", response_model=UserPermissions) +async def get_user_permissions(request: Request, user=Depends(get_admin_user)): + return { + "workspace": WorkspacePermissions( + **request.app.state.config.USER_PERMISSIONS.get("workspace", {}) + ), + "chat": ChatPermissions( + **request.app.state.config.USER_PERMISSIONS.get("chat", {}) + ), + "features": FeaturesPermissions( + **request.app.state.config.USER_PERMISSIONS.get("features", {}) + ), + } + + +@router.post("/default/permissions") +async def update_user_permissions( + request: Request, form_data: UserPermissions, user=Depends(get_admin_user) +): + request.app.state.config.USER_PERMISSIONS = form_data.model_dump() + return request.app.state.config.USER_PERMISSIONS + + +############################ +# UpdateUserRole +############################ + + +@router.post("/update/role", response_model=Optional[UserModel]) +async def update_user_role(form_data: UserRoleUpdateForm, user=Depends(get_admin_user)): + if user.id != form_data.id and form_data.id != Users.get_first_user().id: + return Users.update_user_role_by_id(form_data.id, form_data.role) + + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail=ERROR_MESSAGES.ACTION_PROHIBITED, + ) + + +############################ +# GetUserSettingsBySessionUser +############################ + + +@router.get("/user/settings", response_model=Optional[UserSettings]) +async def get_user_settings_by_session_user(user=Depends(get_verified_user)): + user = Users.get_user_by_id(user.id) + if user: + return user.settings + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.USER_NOT_FOUND, + ) + + +############################ +# UpdateUserSettingsBySessionUser +############################ + + +@router.post("/user/settings/update", response_model=UserSettings) +async def update_user_settings_by_session_user( + form_data: UserSettings, user=Depends(get_verified_user) +): + user = Users.update_user_settings_by_id(user.id, form_data.model_dump()) + if user: + return user.settings + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.USER_NOT_FOUND, + ) + + +############################ +# GetUserInfoBySessionUser +############################ + + +@router.get("/user/info", response_model=Optional[dict]) +async def get_user_info_by_session_user(user=Depends(get_verified_user)): + user = Users.get_user_by_id(user.id) + if user: + return user.info + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.USER_NOT_FOUND, + ) + + +############################ +# UpdateUserInfoBySessionUser +############################ + + +@router.post("/user/info/update", response_model=Optional[dict]) +async def update_user_info_by_session_user( + form_data: dict, user=Depends(get_verified_user) +): + user = Users.get_user_by_id(user.id) + if user: + if user.info is None: + user.info = {} + + user = Users.update_user_by_id(user.id, {"info": {**user.info, **form_data}}) + if user: + return user.info + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.USER_NOT_FOUND, + ) + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.USER_NOT_FOUND, + ) + + +############################ +# GetUserById +############################ + + +class UserResponse(BaseModel): + name: str + profile_image_url: str + active: Optional[bool] = None + + +@router.get("/{user_id}", response_model=UserResponse) +async def get_user_by_id(user_id: str, user=Depends(get_verified_user)): + # Check if user_id is a shared chat + # If it is, get the user_id from the chat + if user_id.startswith("shared-"): + chat_id = user_id.replace("shared-", "") + chat = Chats.get_chat_by_id(chat_id) + if chat: + user_id = chat.user_id + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.USER_NOT_FOUND, + ) + + user = Users.get_user_by_id(user_id) + + if user: + return UserResponse( + **{ + "name": user.name, + "profile_image_url": user.profile_image_url, + "active": get_active_status_by_user_id(user_id), + } + ) + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.USER_NOT_FOUND, + ) + + +############################ +# UpdateUserById +############################ + + +@router.post("/{user_id}/update", response_model=Optional[UserModel]) +async def update_user_by_id( + user_id: str, + form_data: UserUpdateForm, + session_user=Depends(get_admin_user), +): + user = Users.get_user_by_id(user_id) + + if user: + if form_data.email.lower() != user.email: + email_user = Users.get_user_by_email(form_data.email.lower()) + if email_user: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.EMAIL_TAKEN, + ) + + if form_data.password: + hashed = get_password_hash(form_data.password) + log.debug(f"hashed: {hashed}") + Auths.update_user_password_by_id(user_id, hashed) + + Auths.update_email_by_id(user_id, form_data.email.lower()) + updated_user = Users.update_user_by_id( + user_id, + { + "name": form_data.name, + "email": form_data.email.lower(), + "profile_image_url": form_data.profile_image_url, + }, + ) + + if updated_user: + return updated_user + + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DEFAULT(), + ) + + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.USER_NOT_FOUND, + ) + + +############################ +# DeleteUserById +############################ + + +@router.delete("/{user_id}", response_model=bool) +async def delete_user_by_id(user_id: str, user=Depends(get_admin_user)): + if user.id != user_id: + result = Auths.delete_auth_by_id(user_id) + + if result: + return True + + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=ERROR_MESSAGES.DELETE_USER_ERROR, + ) + + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail=ERROR_MESSAGES.ACTION_PROHIBITED, + ) diff --git a/backend/open_webui/routers/utils.py b/backend/open_webui/routers/utils.py new file mode 100644 index 0000000..b64adaf --- /dev/null +++ b/backend/open_webui/routers/utils.py @@ -0,0 +1,135 @@ +import black +import logging +import markdown + +from open_webui.models.chats import ChatTitleMessagesForm +from open_webui.config import DATA_DIR, ENABLE_ADMIN_EXPORT +from open_webui.constants import ERROR_MESSAGES +from fastapi import APIRouter, Depends, HTTPException, Request, Response, status +from pydantic import BaseModel +from starlette.responses import FileResponse + + +from open_webui.utils.misc import get_gravatar_url +from open_webui.utils.pdf_generator import PDFGenerator +from open_webui.utils.auth import get_admin_user, get_verified_user +from open_webui.utils.code_interpreter import execute_code_jupyter +from open_webui.env import SRC_LOG_LEVELS + + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MAIN"]) + +router = APIRouter() + + +@router.get("/gravatar") +async def get_gravatar(email: str, user=Depends(get_verified_user)): + return get_gravatar_url(email) + + +class CodeForm(BaseModel): + code: str + + +@router.post("/code/format") +async def format_code(form_data: CodeForm, user=Depends(get_verified_user)): + try: + formatted_code = black.format_str(form_data.code, mode=black.Mode()) + return {"code": formatted_code} + except black.NothingChanged: + return {"code": form_data.code} + except Exception as e: + raise HTTPException(status_code=400, detail=str(e)) + + +@router.post("/code/execute") +async def execute_code( + request: Request, form_data: CodeForm, user=Depends(get_verified_user) +): + if request.app.state.config.CODE_EXECUTION_ENGINE == "jupyter": + output = await execute_code_jupyter( + request.app.state.config.CODE_EXECUTION_JUPYTER_URL, + form_data.code, + ( + request.app.state.config.CODE_EXECUTION_JUPYTER_AUTH_TOKEN + if request.app.state.config.CODE_EXECUTION_JUPYTER_AUTH == "token" + else None + ), + ( + request.app.state.config.CODE_EXECUTION_JUPYTER_AUTH_PASSWORD + if request.app.state.config.CODE_EXECUTION_JUPYTER_AUTH == "password" + else None + ), + request.app.state.config.CODE_EXECUTION_JUPYTER_TIMEOUT, + ) + + return output + else: + raise HTTPException( + status_code=400, + detail="Code execution engine not supported", + ) + + +class MarkdownForm(BaseModel): + md: str + + +@router.post("/markdown") +async def get_html_from_markdown( + form_data: MarkdownForm, user=Depends(get_verified_user) +): + return {"html": markdown.markdown(form_data.md)} + + +class ChatForm(BaseModel): + title: str + messages: list[dict] + + +@router.post("/pdf") +async def download_chat_as_pdf( + form_data: ChatTitleMessagesForm, user=Depends(get_verified_user) +): + try: + pdf_bytes = PDFGenerator(form_data).generate_chat_pdf() + + return Response( + content=pdf_bytes, + media_type="application/pdf", + headers={"Content-Disposition": "attachment;filename=chat.pdf"}, + ) + except Exception as e: + log.exception(f"Error generating PDF: {e}") + raise HTTPException(status_code=400, detail=str(e)) + + +@router.get("/db/download") +async def download_db(user=Depends(get_admin_user)): + if not ENABLE_ADMIN_EXPORT: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + ) + from open_webui.internal.db import engine + + if engine.name != "sqlite": + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=ERROR_MESSAGES.DB_NOT_SQLITE, + ) + return FileResponse( + engine.url.database, + media_type="application/octet-stream", + filename="webui.db", + ) + + +@router.get("/litellm/config") +async def download_litellm_config_yaml(user=Depends(get_admin_user)): + return FileResponse( + f"{DATA_DIR}/litellm/config.yaml", + media_type="application/octet-stream", + filename="config.yaml", + ) diff --git a/backend/open_webui/socket/main.py b/backend/open_webui/socket/main.py new file mode 100644 index 0000000..6f59151 --- /dev/null +++ b/backend/open_webui/socket/main.py @@ -0,0 +1,370 @@ +import asyncio +import socketio +import logging +import sys +import time + +from open_webui.models.users import Users, UserNameResponse +from open_webui.models.channels import Channels +from open_webui.models.chats import Chats + +from open_webui.env import ( + ENABLE_WEBSOCKET_SUPPORT, + WEBSOCKET_MANAGER, + WEBSOCKET_REDIS_URL, +) +from open_webui.utils.auth import decode_token +from open_webui.socket.utils import RedisDict, RedisLock + +from open_webui.env import ( + GLOBAL_LOG_LEVEL, + SRC_LOG_LEVELS, +) + + +logging.basicConfig(stream=sys.stdout, level=GLOBAL_LOG_LEVEL) +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["SOCKET"]) + + +if WEBSOCKET_MANAGER == "redis": + mgr = socketio.AsyncRedisManager(WEBSOCKET_REDIS_URL) + sio = socketio.AsyncServer( + cors_allowed_origins=[], + async_mode="asgi", + transports=(["websocket"] if ENABLE_WEBSOCKET_SUPPORT else ["polling"]), + allow_upgrades=ENABLE_WEBSOCKET_SUPPORT, + always_connect=True, + client_manager=mgr, + ) +else: + sio = socketio.AsyncServer( + cors_allowed_origins=[], + async_mode="asgi", + transports=(["websocket"] if ENABLE_WEBSOCKET_SUPPORT else ["polling"]), + allow_upgrades=ENABLE_WEBSOCKET_SUPPORT, + always_connect=True, + ) + + +# Timeout duration in seconds +TIMEOUT_DURATION = 3 + +# Dictionary to maintain the user pool + +if WEBSOCKET_MANAGER == "redis": + log.debug("Using Redis to manage websockets.") + SESSION_POOL = RedisDict("open-webui:session_pool", redis_url=WEBSOCKET_REDIS_URL) + USER_POOL = RedisDict("open-webui:user_pool", redis_url=WEBSOCKET_REDIS_URL) + USAGE_POOL = RedisDict("open-webui:usage_pool", redis_url=WEBSOCKET_REDIS_URL) + + clean_up_lock = RedisLock( + redis_url=WEBSOCKET_REDIS_URL, + lock_name="usage_cleanup_lock", + timeout_secs=TIMEOUT_DURATION * 2, + ) + aquire_func = clean_up_lock.aquire_lock + renew_func = clean_up_lock.renew_lock + release_func = clean_up_lock.release_lock +else: + SESSION_POOL = {} + USER_POOL = {} + USAGE_POOL = {} + aquire_func = release_func = renew_func = lambda: True + + +async def periodic_usage_pool_cleanup(): + if not aquire_func(): + log.debug("Usage pool cleanup lock already exists. Not running it.") + return + log.debug("Running periodic_usage_pool_cleanup") + try: + while True: + if not renew_func(): + log.error(f"Unable to renew cleanup lock. Exiting usage pool cleanup.") + raise Exception("Unable to renew usage pool cleanup lock.") + + now = int(time.time()) + send_usage = False + for model_id, connections in list(USAGE_POOL.items()): + # Creating a list of sids to remove if they have timed out + expired_sids = [ + sid + for sid, details in connections.items() + if now - details["updated_at"] > TIMEOUT_DURATION + ] + + for sid in expired_sids: + del connections[sid] + + if not connections: + log.debug(f"Cleaning up model {model_id} from usage pool") + del USAGE_POOL[model_id] + else: + USAGE_POOL[model_id] = connections + + send_usage = True + + if send_usage: + # Emit updated usage information after cleaning + await sio.emit("usage", {"models": get_models_in_use()}) + + await asyncio.sleep(TIMEOUT_DURATION) + finally: + release_func() + + +app = socketio.ASGIApp( + sio, + socketio_path="/ws/socket.io", +) + + +def get_models_in_use(): + # List models that are currently in use + models_in_use = list(USAGE_POOL.keys()) + return models_in_use + + +@sio.on("usage") +async def usage(sid, data): + model_id = data["model"] + # Record the timestamp for the last update + current_time = int(time.time()) + + # Store the new usage data and task + USAGE_POOL[model_id] = { + **(USAGE_POOL[model_id] if model_id in USAGE_POOL else {}), + sid: {"updated_at": current_time}, + } + + # Broadcast the usage data to all clients + await sio.emit("usage", {"models": get_models_in_use()}) + + +@sio.event +async def connect(sid, environ, auth): + user = None + if auth and "token" in auth: + data = decode_token(auth["token"]) + + if data is not None and "id" in data: + user = Users.get_user_by_id(data["id"]) + + if user: + SESSION_POOL[sid] = user.model_dump() + if user.id in USER_POOL: + USER_POOL[user.id] = USER_POOL[user.id] + [sid] + else: + USER_POOL[user.id] = [sid] + + # print(f"user {user.name}({user.id}) connected with session ID {sid}") + await sio.emit("user-list", {"user_ids": list(USER_POOL.keys())}) + await sio.emit("usage", {"models": get_models_in_use()}) + + +@sio.on("user-join") +async def user_join(sid, data): + + auth = data["auth"] if "auth" in data else None + if not auth or "token" not in auth: + return + + data = decode_token(auth["token"]) + if data is None or "id" not in data: + return + + user = Users.get_user_by_id(data["id"]) + if not user: + return + + SESSION_POOL[sid] = user.model_dump() + if user.id in USER_POOL: + USER_POOL[user.id] = USER_POOL[user.id] + [sid] + else: + USER_POOL[user.id] = [sid] + + # Join all the channels + channels = Channels.get_channels_by_user_id(user.id) + log.debug(f"{channels=}") + for channel in channels: + await sio.enter_room(sid, f"channel:{channel.id}") + + # print(f"user {user.name}({user.id}) connected with session ID {sid}") + + await sio.emit("user-list", {"user_ids": list(USER_POOL.keys())}) + return {"id": user.id, "name": user.name} + + +@sio.on("join-channels") +async def join_channel(sid, data): + auth = data["auth"] if "auth" in data else None + if not auth or "token" not in auth: + return + + data = decode_token(auth["token"]) + if data is None or "id" not in data: + return + + user = Users.get_user_by_id(data["id"]) + if not user: + return + + # Join all the channels + channels = Channels.get_channels_by_user_id(user.id) + log.debug(f"{channels=}") + for channel in channels: + await sio.enter_room(sid, f"channel:{channel.id}") + + +@sio.on("channel-events") +async def channel_events(sid, data): + room = f"channel:{data['channel_id']}" + participants = sio.manager.get_participants( + namespace="/", + room=room, + ) + + sids = [sid for sid, _ in participants] + if sid not in sids: + return + + event_data = data["data"] + event_type = event_data["type"] + + if event_type == "typing": + await sio.emit( + "channel-events", + { + "channel_id": data["channel_id"], + "message_id": data.get("message_id", None), + "data": event_data, + "user": UserNameResponse(**SESSION_POOL[sid]).model_dump(), + }, + room=room, + ) + + +@sio.on("user-list") +async def user_list(sid): + await sio.emit("user-list", {"user_ids": list(USER_POOL.keys())}) + + +@sio.event +async def disconnect(sid): + if sid in SESSION_POOL: + user = SESSION_POOL[sid] + del SESSION_POOL[sid] + + user_id = user["id"] + USER_POOL[user_id] = [_sid for _sid in USER_POOL[user_id] if _sid != sid] + + if len(USER_POOL[user_id]) == 0: + del USER_POOL[user_id] + + await sio.emit("user-list", {"user_ids": list(USER_POOL.keys())}) + else: + pass + # print(f"Unknown session ID {sid} disconnected") + + +def get_event_emitter(request_info): + async def __event_emitter__(event_data): + user_id = request_info["user_id"] + session_ids = list( + set(USER_POOL.get(user_id, []) + [request_info["session_id"]]) + ) + + for session_id in session_ids: + await sio.emit( + "chat-events", + { + "chat_id": request_info.get("chat_id", None), + "message_id": request_info.get("message_id", None), + "data": event_data, + }, + to=session_id, + ) + + if "type" in event_data and event_data["type"] == "status": + Chats.add_message_status_to_chat_by_id_and_message_id( + request_info["chat_id"], + request_info["message_id"], + event_data.get("data", {}), + ) + + if "type" in event_data and event_data["type"] == "message": + message = Chats.get_message_by_id_and_message_id( + request_info["chat_id"], + request_info["message_id"], + ) + + content = message.get("content", "") + content += event_data.get("data", {}).get("content", "") + + Chats.upsert_message_to_chat_by_id_and_message_id( + request_info["chat_id"], + request_info["message_id"], + { + "content": content, + }, + ) + + if "type" in event_data and event_data["type"] == "replace": + content = event_data.get("data", {}).get("content", "") + + Chats.upsert_message_to_chat_by_id_and_message_id( + request_info["chat_id"], + request_info["message_id"], + { + "content": content, + }, + ) + + return __event_emitter__ + + +def get_event_call(request_info): + async def __event_caller__(event_data): + response = await sio.call( + "chat-events", + { + "chat_id": request_info.get("chat_id", None), + "message_id": request_info.get("message_id", None), + "data": event_data, + }, + to=request_info["session_id"], + ) + return response + + return __event_caller__ + + +get_event_caller = get_event_call + + +def get_user_id_from_session_pool(sid): + user = SESSION_POOL.get(sid) + if user: + return user["id"] + return None + + +def get_user_ids_from_room(room): + active_session_ids = sio.manager.get_participants( + namespace="/", + room=room, + ) + + active_user_ids = list( + set( + [SESSION_POOL.get(session_id[0])["id"] for session_id in active_session_ids] + ) + ) + return active_user_ids + + +def get_active_status_by_user_id(user_id): + if user_id in USER_POOL: + return True + return False diff --git a/backend/open_webui/socket/utils.py b/backend/open_webui/socket/utils.py new file mode 100644 index 0000000..46fafbb --- /dev/null +++ b/backend/open_webui/socket/utils.py @@ -0,0 +1,87 @@ +import json +import redis +import uuid + + +class RedisLock: + def __init__(self, redis_url, lock_name, timeout_secs): + self.lock_name = lock_name + self.lock_id = str(uuid.uuid4()) + self.timeout_secs = timeout_secs + self.lock_obtained = False + self.redis = redis.Redis.from_url(redis_url, decode_responses=True) + + def aquire_lock(self): + # nx=True will only set this key if it _hasn't_ already been set + self.lock_obtained = self.redis.set( + self.lock_name, self.lock_id, nx=True, ex=self.timeout_secs + ) + return self.lock_obtained + + def renew_lock(self): + # xx=True will only set this key if it _has_ already been set + return self.redis.set( + self.lock_name, self.lock_id, xx=True, ex=self.timeout_secs + ) + + def release_lock(self): + lock_value = self.redis.get(self.lock_name) + if lock_value and lock_value == self.lock_id: + self.redis.delete(self.lock_name) + + +class RedisDict: + def __init__(self, name, redis_url): + self.name = name + self.redis = redis.Redis.from_url(redis_url, decode_responses=True) + + def __setitem__(self, key, value): + serialized_value = json.dumps(value) + self.redis.hset(self.name, key, serialized_value) + + def __getitem__(self, key): + value = self.redis.hget(self.name, key) + if value is None: + raise KeyError(key) + return json.loads(value) + + def __delitem__(self, key): + result = self.redis.hdel(self.name, key) + if result == 0: + raise KeyError(key) + + def __contains__(self, key): + return self.redis.hexists(self.name, key) + + def __len__(self): + return self.redis.hlen(self.name) + + def keys(self): + return self.redis.hkeys(self.name) + + def values(self): + return [json.loads(v) for v in self.redis.hvals(self.name)] + + def items(self): + return [(k, json.loads(v)) for k, v in self.redis.hgetall(self.name).items()] + + def get(self, key, default=None): + try: + return self[key] + except KeyError: + return default + + def clear(self): + self.redis.delete(self.name) + + def update(self, other=None, **kwargs): + if other is not None: + for k, v in other.items() if hasattr(other, "items") else other: + self[k] = v + for k, v in kwargs.items(): + self[k] = v + + def setdefault(self, key, default=None): + if key not in self: + self[key] = default + return self[key] diff --git a/backend/open_webui/static/assets/pdf-style.css b/backend/open_webui/static/assets/pdf-style.css new file mode 100644 index 0000000..7cb5b0c --- /dev/null +++ b/backend/open_webui/static/assets/pdf-style.css @@ -0,0 +1,319 @@ +/* HTML and Body */ +@font-face { + font-family: 'NotoSans'; + src: url('fonts/NotoSans-Variable.ttf'); +} + +@font-face { + font-family: 'NotoSansJP'; + src: url('fonts/NotoSansJP-Variable.ttf'); +} + +@font-face { + font-family: 'NotoSansKR'; + src: url('fonts/NotoSansKR-Variable.ttf'); +} + +@font-face { + font-family: 'NotoSansSC'; + src: url('fonts/NotoSansSC-Variable.ttf'); +} + +@font-face { + font-family: 'NotoSansSC-Regular'; + src: url('fonts/NotoSansSC-Regular.ttf'); +} + +html { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'NotoSans', 'NotoSansJP', 'NotoSansKR', + 'NotoSansSC', 'Twemoji', 'STSong-Light', 'MSung-Light', 'HeiseiMin-W3', 'HYSMyeongJo-Medium', + Roboto, 'Helvetica Neue', Arial, sans-serif; + font-size: 14px; /* Default font size */ + line-height: 1.5; +} + +*, +*::before, +*::after { + box-sizing: inherit; +} + +body { + margin: 0; + padding: 0; + background-color: #fff; + width: auto; +} + +/* Typography */ +h1, +h2, +h3, +h4, +h5, +h6 { + font-weight: 500; + margin: 0; +} + +h1 { + font-size: 2.5rem; +} + +h2 { + font-size: 2rem; +} + +h3 { + font-size: 1.75rem; +} + +h4 { + font-size: 1.5rem; +} + +h5 { + font-size: 1.25rem; +} + +h6 { + font-size: 1rem; +} + +p { + margin-top: 0; + margin-bottom: 1rem; +} + +/* Grid System */ +.container { + width: 100%; + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} + +/* Utilities */ +.text-center { + text-align: center; +} + +/* Additional Text Utilities */ +.text-muted { + color: #6c757d; /* Muted text color */ +} + +/* Small Text */ +small { + font-size: 80%; /* Smaller font size relative to the base */ + color: #6c757d; /* Lighter text color for secondary information */ + margin-bottom: 0; + margin-top: 0; +} + +/* Strong Element Styles */ +strong { + font-weight: bolder; /* Ensures the text is bold */ + color: inherit; /* Inherits the color from its parent element */ +} + +/* link */ +a { + color: #007bff; + text-decoration: none; + background-color: transparent; +} + +a:hover { + color: #0056b3; + text-decoration: underline; +} + +/* General styles for lists */ +ol, +ul, +li { + padding-left: 40px; /* Increase padding to move bullet points to the right */ + margin-left: 20px; /* Indent lists from the left */ +} + +/* Ordered list styles */ +ol { + list-style-type: decimal; /* Use numbers for ordered lists */ + margin-bottom: 10px; /* Space after each list */ +} + +ol li { + margin-bottom: 0.5rem; /* Space between ordered list items */ +} + +/* Unordered list styles */ +ul { + list-style-type: disc; /* Use bullets for unordered lists */ + margin-bottom: 10px; /* Space after each list */ +} + +ul li { + margin-bottom: 0.5rem; /* Space between unordered list items */ +} + +/* List item styles */ +li { + margin-bottom: 5px; /* Space between list items */ + line-height: 1.5; /* Line height for better readability */ +} + +/* Nested lists */ +ol ol, +ol ul, +ul ol, +ul ul { + padding-left: 20px; + margin-left: 30px; /* Further indent nested lists */ + margin-bottom: 0; /* Remove extra margin at the bottom of nested lists */ +} + +/* Code blocks */ +pre { + background-color: #f4f4f4; + padding: 10px; + overflow-x: auto; + max-width: 100%; /* Ensure it doesn't overflow the page */ + width: 80%; /* Set a specific width for a container-like appearance */ + margin: 0 1em; /* Center the pre block */ + box-sizing: border-box; /* Include padding in the width */ + border: 1px solid #ccc; /* Optional: Add a border for better definition */ + border-radius: 4px; /* Optional: Add rounded corners */ +} + +code { + font-family: 'Courier New', Courier, monospace; + background-color: #f4f4f4; + padding: 2px 4px; + border-radius: 4px; + box-sizing: border-box; /* Include padding in the width */ +} + +.message { + margin-top: 8px; + margin-bottom: 8px; + max-width: 100%; + overflow-wrap: break-word; +} + +/* Table Styles */ +table { + width: 100%; + margin-bottom: 1rem; + color: #212529; + border-collapse: collapse; /* Removes the space between borders */ +} + +th, +td { + margin: 0; + padding: 0.75rem; + vertical-align: top; + border-top: 1px solid #dee2e6; +} + +thead th { + vertical-align: bottom; + border-bottom: 2px solid #dee2e6; +} + +tbody + tbody { + border-top: 2px solid #dee2e6; +} + +/* markdown-section styles */ +.markdown-section blockquote, +.markdown-section h1, +.markdown-section h2, +.markdown-section h3, +.markdown-section h4, +.markdown-section h5, +.markdown-section h6, +.markdown-section p, +.markdown-section pre, +.markdown-section table, +.markdown-section ul { + /* Give most block elements margin top and bottom */ + margin-top: 1rem; +} + +/* Remove top margin if it's the first child */ +.markdown-section blockquote:first-child, +.markdown-section h1:first-child, +.markdown-section h2:first-child, +.markdown-section h3:first-child, +.markdown-section h4:first-child, +.markdown-section h5:first-child, +.markdown-section h6:first-child, +.markdown-section p:first-child, +.markdown-section pre:first-child, +.markdown-section table:first-child, +.markdown-section ul:first-child { + margin-top: 0; +} + +/* Remove top margin of
    following a

    */ +.markdown-section p + ul { + margin-top: 0; +} + +/* Remove bottom margin of

    if it is followed by a

      */ +/* Note: :has is not supported in CSS, so you would need JavaScript for this behavior */ +.markdown-section p { + margin-bottom: 0; +} + +/* Add a rule to reset margin-bottom for

      not followed by

        */ +.markdown-section p + ul { + margin-top: 0; +} + +/* List item styles */ +.markdown-section li { + padding: 2px; +} + +.markdown-section li p { + margin-bottom: 0; + padding: 0; +} + +/* Avoid margins for nested lists */ +.markdown-section li > ul { + margin-top: 0; + margin-bottom: 0; +} + +/* Table styles */ +.markdown-section table { + width: 100%; + border-collapse: collapse; + margin: 1rem 0; +} + +.markdown-section th, +.markdown-section td { + border: 1px solid #ddd; + padding: 0.5rem; + text-align: left; +} + +.markdown-section th { + background-color: #f2f2f2; +} + +.markdown-section pre { + padding: 10px; + margin: 10px; +} + +.markdown-section pre code { + position: relative; + color: rgb(172, 0, 95); +} diff --git a/backend/open_webui/static/favicon.png b/backend/open_webui/static/favicon.png new file mode 100644 index 0000000..63735ad Binary files /dev/null and b/backend/open_webui/static/favicon.png differ diff --git a/backend/open_webui/static/fonts/NotoSans-Bold.ttf b/backend/open_webui/static/fonts/NotoSans-Bold.ttf new file mode 100644 index 0000000..d84248e Binary files /dev/null and b/backend/open_webui/static/fonts/NotoSans-Bold.ttf differ diff --git a/backend/open_webui/static/fonts/NotoSans-Italic.ttf b/backend/open_webui/static/fonts/NotoSans-Italic.ttf new file mode 100644 index 0000000..c40c356 Binary files /dev/null and b/backend/open_webui/static/fonts/NotoSans-Italic.ttf differ diff --git a/backend/open_webui/static/fonts/NotoSans-Regular.ttf b/backend/open_webui/static/fonts/NotoSans-Regular.ttf new file mode 100644 index 0000000..fa4cff5 Binary files /dev/null and b/backend/open_webui/static/fonts/NotoSans-Regular.ttf differ diff --git a/backend/open_webui/static/fonts/NotoSans-Variable.ttf b/backend/open_webui/static/fonts/NotoSans-Variable.ttf new file mode 100644 index 0000000..f7d0d78 Binary files /dev/null and b/backend/open_webui/static/fonts/NotoSans-Variable.ttf differ diff --git a/backend/open_webui/static/fonts/NotoSansJP-Regular.ttf b/backend/open_webui/static/fonts/NotoSansJP-Regular.ttf new file mode 100644 index 0000000..1583096 Binary files /dev/null and b/backend/open_webui/static/fonts/NotoSansJP-Regular.ttf differ diff --git a/backend/open_webui/static/fonts/NotoSansJP-Variable.ttf b/backend/open_webui/static/fonts/NotoSansJP-Variable.ttf new file mode 100644 index 0000000..53b5ec5 Binary files /dev/null and b/backend/open_webui/static/fonts/NotoSansJP-Variable.ttf differ diff --git a/backend/open_webui/static/fonts/NotoSansKR-Regular.ttf b/backend/open_webui/static/fonts/NotoSansKR-Regular.ttf new file mode 100644 index 0000000..1b14d32 Binary files /dev/null and b/backend/open_webui/static/fonts/NotoSansKR-Regular.ttf differ diff --git a/backend/open_webui/static/fonts/NotoSansKR-Variable.ttf b/backend/open_webui/static/fonts/NotoSansKR-Variable.ttf new file mode 100644 index 0000000..57016c2 Binary files /dev/null and b/backend/open_webui/static/fonts/NotoSansKR-Variable.ttf differ diff --git a/backend/open_webui/static/fonts/NotoSansSC-Regular.ttf b/backend/open_webui/static/fonts/NotoSansSC-Regular.ttf new file mode 100644 index 0000000..7056f5e Binary files /dev/null and b/backend/open_webui/static/fonts/NotoSansSC-Regular.ttf differ diff --git a/backend/open_webui/static/fonts/NotoSansSC-Variable.ttf b/backend/open_webui/static/fonts/NotoSansSC-Variable.ttf new file mode 100644 index 0000000..4e0c62e Binary files /dev/null and b/backend/open_webui/static/fonts/NotoSansSC-Variable.ttf differ diff --git a/backend/open_webui/static/fonts/Twemoji.ttf b/backend/open_webui/static/fonts/Twemoji.ttf new file mode 100644 index 0000000..281d356 Binary files /dev/null and b/backend/open_webui/static/fonts/Twemoji.ttf differ diff --git a/backend/open_webui/static/loader.js b/backend/open_webui/static/loader.js new file mode 100644 index 0000000..e69de29 diff --git a/backend/open_webui/static/logo.png b/backend/open_webui/static/logo.png new file mode 100644 index 0000000..a652a5f Binary files /dev/null and b/backend/open_webui/static/logo.png differ diff --git a/backend/open_webui/static/splash.png b/backend/open_webui/static/splash.png new file mode 100644 index 0000000..389196c Binary files /dev/null and b/backend/open_webui/static/splash.png differ diff --git a/backend/open_webui/static/swagger-ui/favicon.png b/backend/open_webui/static/swagger-ui/favicon.png new file mode 100644 index 0000000..e5b7c3a Binary files /dev/null and b/backend/open_webui/static/swagger-ui/favicon.png differ diff --git a/backend/open_webui/static/swagger-ui/swagger-ui-bundle.js b/backend/open_webui/static/swagger-ui/swagger-ui-bundle.js new file mode 100644 index 0000000..dcd1c53 --- /dev/null +++ b/backend/open_webui/static/swagger-ui/swagger-ui-bundle.js @@ -0,0 +1,72298 @@ +/*! For license information please see swagger-ui-bundle.js.LICENSE.txt */ +!(function webpackUniversalModuleDefinition(s, o) { + 'object' == typeof exports && 'object' == typeof module + ? (module.exports = o()) + : 'function' == typeof define && define.amd + ? define([], o) + : 'object' == typeof exports + ? (exports.SwaggerUIBundle = o()) + : (s.SwaggerUIBundle = o()); +})(this, () => + (() => { + var s, + o, + i = { + 69119: (s, o) => { + 'use strict'; + Object.defineProperty(o, '__esModule', { value: !0 }), + (o.BLANK_URL = + o.relativeFirstCharacters = + o.whitespaceEscapeCharsRegex = + o.urlSchemeRegex = + o.ctrlCharactersRegex = + o.htmlCtrlEntityRegex = + o.htmlEntitiesRegex = + o.invalidProtocolRegex = + void 0), + (o.invalidProtocolRegex = /^([^\w]*)(javascript|data|vbscript)/im), + (o.htmlEntitiesRegex = /&#(\w+)(^\w|;)?/g), + (o.htmlCtrlEntityRegex = /&(newline|tab);/gi), + (o.ctrlCharactersRegex = /[\u0000-\u001F\u007F-\u009F\u2000-\u200D\uFEFF]/gim), + (o.urlSchemeRegex = /^.+(:|:)/gim), + (o.whitespaceEscapeCharsRegex = /(\\|%5[cC])((%(6[eE]|72|74))|[nrt])/g), + (o.relativeFirstCharacters = ['.', '/']), + (o.BLANK_URL = 'about:blank'); + }, + 16750: (s, o, i) => { + 'use strict'; + o.J = void 0; + var u = i(69119); + function decodeURI(s) { + try { + return decodeURIComponent(s); + } catch (o) { + return s; + } + } + o.J = function sanitizeUrl(s) { + if (!s) return u.BLANK_URL; + var o, + i, + _ = decodeURI(s); + do { + o = + (_ = decodeURI( + (_ = ((i = _), + i + .replace(u.ctrlCharactersRegex, '') + .replace(u.htmlEntitiesRegex, function (s, o) { + return String.fromCharCode(o); + })) + .replace(u.htmlCtrlEntityRegex, '') + .replace(u.ctrlCharactersRegex, '') + .replace(u.whitespaceEscapeCharsRegex, '') + .trim()) + )).match(u.ctrlCharactersRegex) || + _.match(u.htmlEntitiesRegex) || + _.match(u.htmlCtrlEntityRegex) || + _.match(u.whitespaceEscapeCharsRegex); + } while (o && o.length > 0); + var w = _; + if (!w) return u.BLANK_URL; + if ( + (function isRelativeUrlWithoutProtocol(s) { + return u.relativeFirstCharacters.indexOf(s[0]) > -1; + })(w) + ) + return w; + var x = w.match(u.urlSchemeRegex); + if (!x) return w; + var C = x[0]; + return u.invalidProtocolRegex.test(C) ? u.BLANK_URL : w; + }; + }, + 67526: (s, o) => { + 'use strict'; + (o.byteLength = function byteLength(s) { + var o = getLens(s), + i = o[0], + u = o[1]; + return (3 * (i + u)) / 4 - u; + }), + (o.toByteArray = function toByteArray(s) { + var o, + i, + w = getLens(s), + x = w[0], + C = w[1], + j = new _( + (function _byteLength(s, o, i) { + return (3 * (o + i)) / 4 - i; + })(0, x, C) + ), + L = 0, + B = C > 0 ? x - 4 : x; + for (i = 0; i < B; i += 4) + (o = + (u[s.charCodeAt(i)] << 18) | + (u[s.charCodeAt(i + 1)] << 12) | + (u[s.charCodeAt(i + 2)] << 6) | + u[s.charCodeAt(i + 3)]), + (j[L++] = (o >> 16) & 255), + (j[L++] = (o >> 8) & 255), + (j[L++] = 255 & o); + 2 === C && + ((o = (u[s.charCodeAt(i)] << 2) | (u[s.charCodeAt(i + 1)] >> 4)), + (j[L++] = 255 & o)); + 1 === C && + ((o = + (u[s.charCodeAt(i)] << 10) | + (u[s.charCodeAt(i + 1)] << 4) | + (u[s.charCodeAt(i + 2)] >> 2)), + (j[L++] = (o >> 8) & 255), + (j[L++] = 255 & o)); + return j; + }), + (o.fromByteArray = function fromByteArray(s) { + for ( + var o, u = s.length, _ = u % 3, w = [], x = 16383, C = 0, j = u - _; + C < j; + C += x + ) + w.push(encodeChunk(s, C, C + x > j ? j : C + x)); + 1 === _ + ? ((o = s[u - 1]), w.push(i[o >> 2] + i[(o << 4) & 63] + '==')) + : 2 === _ && + ((o = (s[u - 2] << 8) + s[u - 1]), + w.push(i[o >> 10] + i[(o >> 4) & 63] + i[(o << 2) & 63] + '=')); + return w.join(''); + }); + for ( + var i = [], + u = [], + _ = 'undefined' != typeof Uint8Array ? Uint8Array : Array, + w = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', + x = 0; + x < 64; + ++x + ) + (i[x] = w[x]), (u[w.charCodeAt(x)] = x); + function getLens(s) { + var o = s.length; + if (o % 4 > 0) throw new Error('Invalid string. Length must be a multiple of 4'); + var i = s.indexOf('='); + return -1 === i && (i = o), [i, i === o ? 0 : 4 - (i % 4)]; + } + function encodeChunk(s, o, u) { + for (var _, w, x = [], C = o; C < u; C += 3) + (_ = ((s[C] << 16) & 16711680) + ((s[C + 1] << 8) & 65280) + (255 & s[C + 2])), + x.push(i[((w = _) >> 18) & 63] + i[(w >> 12) & 63] + i[(w >> 6) & 63] + i[63 & w]); + return x.join(''); + } + (u['-'.charCodeAt(0)] = 62), (u['_'.charCodeAt(0)] = 63); + }, + 48287: (s, o, i) => { + 'use strict'; + const u = i(67526), + _ = i(251), + w = + 'function' == typeof Symbol && 'function' == typeof Symbol.for + ? Symbol.for('nodejs.util.inspect.custom') + : null; + (o.Buffer = Buffer), + (o.SlowBuffer = function SlowBuffer(s) { + +s != s && (s = 0); + return Buffer.alloc(+s); + }), + (o.INSPECT_MAX_BYTES = 50); + const x = 2147483647; + function createBuffer(s) { + if (s > x) throw new RangeError('The value "' + s + '" is invalid for option "size"'); + const o = new Uint8Array(s); + return Object.setPrototypeOf(o, Buffer.prototype), o; + } + function Buffer(s, o, i) { + if ('number' == typeof s) { + if ('string' == typeof o) + throw new TypeError( + 'The "string" argument must be of type string. Received type number' + ); + return allocUnsafe(s); + } + return from(s, o, i); + } + function from(s, o, i) { + if ('string' == typeof s) + return (function fromString(s, o) { + ('string' == typeof o && '' !== o) || (o = 'utf8'); + if (!Buffer.isEncoding(o)) throw new TypeError('Unknown encoding: ' + o); + const i = 0 | byteLength(s, o); + let u = createBuffer(i); + const _ = u.write(s, o); + _ !== i && (u = u.slice(0, _)); + return u; + })(s, o); + if (ArrayBuffer.isView(s)) + return (function fromArrayView(s) { + if (isInstance(s, Uint8Array)) { + const o = new Uint8Array(s); + return fromArrayBuffer(o.buffer, o.byteOffset, o.byteLength); + } + return fromArrayLike(s); + })(s); + if (null == s) + throw new TypeError( + 'The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type ' + + typeof s + ); + if (isInstance(s, ArrayBuffer) || (s && isInstance(s.buffer, ArrayBuffer))) + return fromArrayBuffer(s, o, i); + if ( + 'undefined' != typeof SharedArrayBuffer && + (isInstance(s, SharedArrayBuffer) || (s && isInstance(s.buffer, SharedArrayBuffer))) + ) + return fromArrayBuffer(s, o, i); + if ('number' == typeof s) + throw new TypeError( + 'The "value" argument must not be of type number. Received type number' + ); + const u = s.valueOf && s.valueOf(); + if (null != u && u !== s) return Buffer.from(u, o, i); + const _ = (function fromObject(s) { + if (Buffer.isBuffer(s)) { + const o = 0 | checked(s.length), + i = createBuffer(o); + return 0 === i.length || s.copy(i, 0, 0, o), i; + } + if (void 0 !== s.length) + return 'number' != typeof s.length || numberIsNaN(s.length) + ? createBuffer(0) + : fromArrayLike(s); + if ('Buffer' === s.type && Array.isArray(s.data)) return fromArrayLike(s.data); + })(s); + if (_) return _; + if ( + 'undefined' != typeof Symbol && + null != Symbol.toPrimitive && + 'function' == typeof s[Symbol.toPrimitive] + ) + return Buffer.from(s[Symbol.toPrimitive]('string'), o, i); + throw new TypeError( + 'The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type ' + + typeof s + ); + } + function assertSize(s) { + if ('number' != typeof s) throw new TypeError('"size" argument must be of type number'); + if (s < 0) throw new RangeError('The value "' + s + '" is invalid for option "size"'); + } + function allocUnsafe(s) { + return assertSize(s), createBuffer(s < 0 ? 0 : 0 | checked(s)); + } + function fromArrayLike(s) { + const o = s.length < 0 ? 0 : 0 | checked(s.length), + i = createBuffer(o); + for (let u = 0; u < o; u += 1) i[u] = 255 & s[u]; + return i; + } + function fromArrayBuffer(s, o, i) { + if (o < 0 || s.byteLength < o) + throw new RangeError('"offset" is outside of buffer bounds'); + if (s.byteLength < o + (i || 0)) + throw new RangeError('"length" is outside of buffer bounds'); + let u; + return ( + (u = + void 0 === o && void 0 === i + ? new Uint8Array(s) + : void 0 === i + ? new Uint8Array(s, o) + : new Uint8Array(s, o, i)), + Object.setPrototypeOf(u, Buffer.prototype), + u + ); + } + function checked(s) { + if (s >= x) + throw new RangeError( + 'Attempt to allocate Buffer larger than maximum size: 0x' + + x.toString(16) + + ' bytes' + ); + return 0 | s; + } + function byteLength(s, o) { + if (Buffer.isBuffer(s)) return s.length; + if (ArrayBuffer.isView(s) || isInstance(s, ArrayBuffer)) return s.byteLength; + if ('string' != typeof s) + throw new TypeError( + 'The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type ' + + typeof s + ); + const i = s.length, + u = arguments.length > 2 && !0 === arguments[2]; + if (!u && 0 === i) return 0; + let _ = !1; + for (;;) + switch (o) { + case 'ascii': + case 'latin1': + case 'binary': + return i; + case 'utf8': + case 'utf-8': + return utf8ToBytes(s).length; + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return 2 * i; + case 'hex': + return i >>> 1; + case 'base64': + return base64ToBytes(s).length; + default: + if (_) return u ? -1 : utf8ToBytes(s).length; + (o = ('' + o).toLowerCase()), (_ = !0); + } + } + function slowToString(s, o, i) { + let u = !1; + if (((void 0 === o || o < 0) && (o = 0), o > this.length)) return ''; + if (((void 0 === i || i > this.length) && (i = this.length), i <= 0)) return ''; + if ((i >>>= 0) <= (o >>>= 0)) return ''; + for (s || (s = 'utf8'); ; ) + switch (s) { + case 'hex': + return hexSlice(this, o, i); + case 'utf8': + case 'utf-8': + return utf8Slice(this, o, i); + case 'ascii': + return asciiSlice(this, o, i); + case 'latin1': + case 'binary': + return latin1Slice(this, o, i); + case 'base64': + return base64Slice(this, o, i); + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return utf16leSlice(this, o, i); + default: + if (u) throw new TypeError('Unknown encoding: ' + s); + (s = (s + '').toLowerCase()), (u = !0); + } + } + function swap(s, o, i) { + const u = s[o]; + (s[o] = s[i]), (s[i] = u); + } + function bidirectionalIndexOf(s, o, i, u, _) { + if (0 === s.length) return -1; + if ( + ('string' == typeof i + ? ((u = i), (i = 0)) + : i > 2147483647 + ? (i = 2147483647) + : i < -2147483648 && (i = -2147483648), + numberIsNaN((i = +i)) && (i = _ ? 0 : s.length - 1), + i < 0 && (i = s.length + i), + i >= s.length) + ) { + if (_) return -1; + i = s.length - 1; + } else if (i < 0) { + if (!_) return -1; + i = 0; + } + if (('string' == typeof o && (o = Buffer.from(o, u)), Buffer.isBuffer(o))) + return 0 === o.length ? -1 : arrayIndexOf(s, o, i, u, _); + if ('number' == typeof o) + return ( + (o &= 255), + 'function' == typeof Uint8Array.prototype.indexOf + ? _ + ? Uint8Array.prototype.indexOf.call(s, o, i) + : Uint8Array.prototype.lastIndexOf.call(s, o, i) + : arrayIndexOf(s, [o], i, u, _) + ); + throw new TypeError('val must be string, number or Buffer'); + } + function arrayIndexOf(s, o, i, u, _) { + let w, + x = 1, + C = s.length, + j = o.length; + if ( + void 0 !== u && + ('ucs2' === (u = String(u).toLowerCase()) || + 'ucs-2' === u || + 'utf16le' === u || + 'utf-16le' === u) + ) { + if (s.length < 2 || o.length < 2) return -1; + (x = 2), (C /= 2), (j /= 2), (i /= 2); + } + function read(s, o) { + return 1 === x ? s[o] : s.readUInt16BE(o * x); + } + if (_) { + let u = -1; + for (w = i; w < C; w++) + if (read(s, w) === read(o, -1 === u ? 0 : w - u)) { + if ((-1 === u && (u = w), w - u + 1 === j)) return u * x; + } else -1 !== u && (w -= w - u), (u = -1); + } else + for (i + j > C && (i = C - j), w = i; w >= 0; w--) { + let i = !0; + for (let u = 0; u < j; u++) + if (read(s, w + u) !== read(o, u)) { + i = !1; + break; + } + if (i) return w; + } + return -1; + } + function hexWrite(s, o, i, u) { + i = Number(i) || 0; + const _ = s.length - i; + u ? (u = Number(u)) > _ && (u = _) : (u = _); + const w = o.length; + let x; + for (u > w / 2 && (u = w / 2), x = 0; x < u; ++x) { + const u = parseInt(o.substr(2 * x, 2), 16); + if (numberIsNaN(u)) return x; + s[i + x] = u; + } + return x; + } + function utf8Write(s, o, i, u) { + return blitBuffer(utf8ToBytes(o, s.length - i), s, i, u); + } + function asciiWrite(s, o, i, u) { + return blitBuffer( + (function asciiToBytes(s) { + const o = []; + for (let i = 0; i < s.length; ++i) o.push(255 & s.charCodeAt(i)); + return o; + })(o), + s, + i, + u + ); + } + function base64Write(s, o, i, u) { + return blitBuffer(base64ToBytes(o), s, i, u); + } + function ucs2Write(s, o, i, u) { + return blitBuffer( + (function utf16leToBytes(s, o) { + let i, u, _; + const w = []; + for (let x = 0; x < s.length && !((o -= 2) < 0); ++x) + (i = s.charCodeAt(x)), (u = i >> 8), (_ = i % 256), w.push(_), w.push(u); + return w; + })(o, s.length - i), + s, + i, + u + ); + } + function base64Slice(s, o, i) { + return 0 === o && i === s.length ? u.fromByteArray(s) : u.fromByteArray(s.slice(o, i)); + } + function utf8Slice(s, o, i) { + i = Math.min(s.length, i); + const u = []; + let _ = o; + for (; _ < i; ) { + const o = s[_]; + let w = null, + x = o > 239 ? 4 : o > 223 ? 3 : o > 191 ? 2 : 1; + if (_ + x <= i) { + let i, u, C, j; + switch (x) { + case 1: + o < 128 && (w = o); + break; + case 2: + (i = s[_ + 1]), + 128 == (192 & i) && ((j = ((31 & o) << 6) | (63 & i)), j > 127 && (w = j)); + break; + case 3: + (i = s[_ + 1]), + (u = s[_ + 2]), + 128 == (192 & i) && + 128 == (192 & u) && + ((j = ((15 & o) << 12) | ((63 & i) << 6) | (63 & u)), + j > 2047 && (j < 55296 || j > 57343) && (w = j)); + break; + case 4: + (i = s[_ + 1]), + (u = s[_ + 2]), + (C = s[_ + 3]), + 128 == (192 & i) && + 128 == (192 & u) && + 128 == (192 & C) && + ((j = ((15 & o) << 18) | ((63 & i) << 12) | ((63 & u) << 6) | (63 & C)), + j > 65535 && j < 1114112 && (w = j)); + } + } + null === w + ? ((w = 65533), (x = 1)) + : w > 65535 && + ((w -= 65536), u.push(((w >>> 10) & 1023) | 55296), (w = 56320 | (1023 & w))), + u.push(w), + (_ += x); + } + return (function decodeCodePointsArray(s) { + const o = s.length; + if (o <= C) return String.fromCharCode.apply(String, s); + let i = '', + u = 0; + for (; u < o; ) i += String.fromCharCode.apply(String, s.slice(u, (u += C))); + return i; + })(u); + } + (o.kMaxLength = x), + (Buffer.TYPED_ARRAY_SUPPORT = (function typedArraySupport() { + try { + const s = new Uint8Array(1), + o = { + foo: function () { + return 42; + } + }; + return ( + Object.setPrototypeOf(o, Uint8Array.prototype), + Object.setPrototypeOf(s, o), + 42 === s.foo() + ); + } catch (s) { + return !1; + } + })()), + Buffer.TYPED_ARRAY_SUPPORT || + 'undefined' == typeof console || + 'function' != typeof console.error || + console.error( + 'This browser lacks typed array (Uint8Array) support which is required by `buffer` v5.x. Use `buffer` v4.x if you require old browser support.' + ), + Object.defineProperty(Buffer.prototype, 'parent', { + enumerable: !0, + get: function () { + if (Buffer.isBuffer(this)) return this.buffer; + } + }), + Object.defineProperty(Buffer.prototype, 'offset', { + enumerable: !0, + get: function () { + if (Buffer.isBuffer(this)) return this.byteOffset; + } + }), + (Buffer.poolSize = 8192), + (Buffer.from = function (s, o, i) { + return from(s, o, i); + }), + Object.setPrototypeOf(Buffer.prototype, Uint8Array.prototype), + Object.setPrototypeOf(Buffer, Uint8Array), + (Buffer.alloc = function (s, o, i) { + return (function alloc(s, o, i) { + return ( + assertSize(s), + s <= 0 + ? createBuffer(s) + : void 0 !== o + ? 'string' == typeof i + ? createBuffer(s).fill(o, i) + : createBuffer(s).fill(o) + : createBuffer(s) + ); + })(s, o, i); + }), + (Buffer.allocUnsafe = function (s) { + return allocUnsafe(s); + }), + (Buffer.allocUnsafeSlow = function (s) { + return allocUnsafe(s); + }), + (Buffer.isBuffer = function isBuffer(s) { + return null != s && !0 === s._isBuffer && s !== Buffer.prototype; + }), + (Buffer.compare = function compare(s, o) { + if ( + (isInstance(s, Uint8Array) && (s = Buffer.from(s, s.offset, s.byteLength)), + isInstance(o, Uint8Array) && (o = Buffer.from(o, o.offset, o.byteLength)), + !Buffer.isBuffer(s) || !Buffer.isBuffer(o)) + ) + throw new TypeError( + 'The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array' + ); + if (s === o) return 0; + let i = s.length, + u = o.length; + for (let _ = 0, w = Math.min(i, u); _ < w; ++_) + if (s[_] !== o[_]) { + (i = s[_]), (u = o[_]); + break; + } + return i < u ? -1 : u < i ? 1 : 0; + }), + (Buffer.isEncoding = function isEncoding(s) { + switch (String(s).toLowerCase()) { + case 'hex': + case 'utf8': + case 'utf-8': + case 'ascii': + case 'latin1': + case 'binary': + case 'base64': + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return !0; + default: + return !1; + } + }), + (Buffer.concat = function concat(s, o) { + if (!Array.isArray(s)) + throw new TypeError('"list" argument must be an Array of Buffers'); + if (0 === s.length) return Buffer.alloc(0); + let i; + if (void 0 === o) for (o = 0, i = 0; i < s.length; ++i) o += s[i].length; + const u = Buffer.allocUnsafe(o); + let _ = 0; + for (i = 0; i < s.length; ++i) { + let o = s[i]; + if (isInstance(o, Uint8Array)) + _ + o.length > u.length + ? (Buffer.isBuffer(o) || (o = Buffer.from(o)), o.copy(u, _)) + : Uint8Array.prototype.set.call(u, o, _); + else { + if (!Buffer.isBuffer(o)) + throw new TypeError('"list" argument must be an Array of Buffers'); + o.copy(u, _); + } + _ += o.length; + } + return u; + }), + (Buffer.byteLength = byteLength), + (Buffer.prototype._isBuffer = !0), + (Buffer.prototype.swap16 = function swap16() { + const s = this.length; + if (s % 2 != 0) throw new RangeError('Buffer size must be a multiple of 16-bits'); + for (let o = 0; o < s; o += 2) swap(this, o, o + 1); + return this; + }), + (Buffer.prototype.swap32 = function swap32() { + const s = this.length; + if (s % 4 != 0) throw new RangeError('Buffer size must be a multiple of 32-bits'); + for (let o = 0; o < s; o += 4) swap(this, o, o + 3), swap(this, o + 1, o + 2); + return this; + }), + (Buffer.prototype.swap64 = function swap64() { + const s = this.length; + if (s % 8 != 0) throw new RangeError('Buffer size must be a multiple of 64-bits'); + for (let o = 0; o < s; o += 8) + swap(this, o, o + 7), + swap(this, o + 1, o + 6), + swap(this, o + 2, o + 5), + swap(this, o + 3, o + 4); + return this; + }), + (Buffer.prototype.toString = function toString() { + const s = this.length; + return 0 === s + ? '' + : 0 === arguments.length + ? utf8Slice(this, 0, s) + : slowToString.apply(this, arguments); + }), + (Buffer.prototype.toLocaleString = Buffer.prototype.toString), + (Buffer.prototype.equals = function equals(s) { + if (!Buffer.isBuffer(s)) throw new TypeError('Argument must be a Buffer'); + return this === s || 0 === Buffer.compare(this, s); + }), + (Buffer.prototype.inspect = function inspect() { + let s = ''; + const i = o.INSPECT_MAX_BYTES; + return ( + (s = this.toString('hex', 0, i) + .replace(/(.{2})/g, '$1 ') + .trim()), + this.length > i && (s += ' ... '), + '' + ); + }), + w && (Buffer.prototype[w] = Buffer.prototype.inspect), + (Buffer.prototype.compare = function compare(s, o, i, u, _) { + if ( + (isInstance(s, Uint8Array) && (s = Buffer.from(s, s.offset, s.byteLength)), + !Buffer.isBuffer(s)) + ) + throw new TypeError( + 'The "target" argument must be one of type Buffer or Uint8Array. Received type ' + + typeof s + ); + if ( + (void 0 === o && (o = 0), + void 0 === i && (i = s ? s.length : 0), + void 0 === u && (u = 0), + void 0 === _ && (_ = this.length), + o < 0 || i > s.length || u < 0 || _ > this.length) + ) + throw new RangeError('out of range index'); + if (u >= _ && o >= i) return 0; + if (u >= _) return -1; + if (o >= i) return 1; + if (this === s) return 0; + let w = (_ >>>= 0) - (u >>>= 0), + x = (i >>>= 0) - (o >>>= 0); + const C = Math.min(w, x), + j = this.slice(u, _), + L = s.slice(o, i); + for (let s = 0; s < C; ++s) + if (j[s] !== L[s]) { + (w = j[s]), (x = L[s]); + break; + } + return w < x ? -1 : x < w ? 1 : 0; + }), + (Buffer.prototype.includes = function includes(s, o, i) { + return -1 !== this.indexOf(s, o, i); + }), + (Buffer.prototype.indexOf = function indexOf(s, o, i) { + return bidirectionalIndexOf(this, s, o, i, !0); + }), + (Buffer.prototype.lastIndexOf = function lastIndexOf(s, o, i) { + return bidirectionalIndexOf(this, s, o, i, !1); + }), + (Buffer.prototype.write = function write(s, o, i, u) { + if (void 0 === o) (u = 'utf8'), (i = this.length), (o = 0); + else if (void 0 === i && 'string' == typeof o) (u = o), (i = this.length), (o = 0); + else { + if (!isFinite(o)) + throw new Error( + 'Buffer.write(string, encoding, offset[, length]) is no longer supported' + ); + (o >>>= 0), + isFinite(i) + ? ((i >>>= 0), void 0 === u && (u = 'utf8')) + : ((u = i), (i = void 0)); + } + const _ = this.length - o; + if ( + ((void 0 === i || i > _) && (i = _), + (s.length > 0 && (i < 0 || o < 0)) || o > this.length) + ) + throw new RangeError('Attempt to write outside buffer bounds'); + u || (u = 'utf8'); + let w = !1; + for (;;) + switch (u) { + case 'hex': + return hexWrite(this, s, o, i); + case 'utf8': + case 'utf-8': + return utf8Write(this, s, o, i); + case 'ascii': + case 'latin1': + case 'binary': + return asciiWrite(this, s, o, i); + case 'base64': + return base64Write(this, s, o, i); + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return ucs2Write(this, s, o, i); + default: + if (w) throw new TypeError('Unknown encoding: ' + u); + (u = ('' + u).toLowerCase()), (w = !0); + } + }), + (Buffer.prototype.toJSON = function toJSON() { + return { type: 'Buffer', data: Array.prototype.slice.call(this._arr || this, 0) }; + }); + const C = 4096; + function asciiSlice(s, o, i) { + let u = ''; + i = Math.min(s.length, i); + for (let _ = o; _ < i; ++_) u += String.fromCharCode(127 & s[_]); + return u; + } + function latin1Slice(s, o, i) { + let u = ''; + i = Math.min(s.length, i); + for (let _ = o; _ < i; ++_) u += String.fromCharCode(s[_]); + return u; + } + function hexSlice(s, o, i) { + const u = s.length; + (!o || o < 0) && (o = 0), (!i || i < 0 || i > u) && (i = u); + let _ = ''; + for (let u = o; u < i; ++u) _ += B[s[u]]; + return _; + } + function utf16leSlice(s, o, i) { + const u = s.slice(o, i); + let _ = ''; + for (let s = 0; s < u.length - 1; s += 2) + _ += String.fromCharCode(u[s] + 256 * u[s + 1]); + return _; + } + function checkOffset(s, o, i) { + if (s % 1 != 0 || s < 0) throw new RangeError('offset is not uint'); + if (s + o > i) throw new RangeError('Trying to access beyond buffer length'); + } + function checkInt(s, o, i, u, _, w) { + if (!Buffer.isBuffer(s)) + throw new TypeError('"buffer" argument must be a Buffer instance'); + if (o > _ || o < w) throw new RangeError('"value" argument is out of bounds'); + if (i + u > s.length) throw new RangeError('Index out of range'); + } + function wrtBigUInt64LE(s, o, i, u, _) { + checkIntBI(o, u, _, s, i, 7); + let w = Number(o & BigInt(4294967295)); + (s[i++] = w), (w >>= 8), (s[i++] = w), (w >>= 8), (s[i++] = w), (w >>= 8), (s[i++] = w); + let x = Number((o >> BigInt(32)) & BigInt(4294967295)); + return ( + (s[i++] = x), + (x >>= 8), + (s[i++] = x), + (x >>= 8), + (s[i++] = x), + (x >>= 8), + (s[i++] = x), + i + ); + } + function wrtBigUInt64BE(s, o, i, u, _) { + checkIntBI(o, u, _, s, i, 7); + let w = Number(o & BigInt(4294967295)); + (s[i + 7] = w), + (w >>= 8), + (s[i + 6] = w), + (w >>= 8), + (s[i + 5] = w), + (w >>= 8), + (s[i + 4] = w); + let x = Number((o >> BigInt(32)) & BigInt(4294967295)); + return ( + (s[i + 3] = x), + (x >>= 8), + (s[i + 2] = x), + (x >>= 8), + (s[i + 1] = x), + (x >>= 8), + (s[i] = x), + i + 8 + ); + } + function checkIEEE754(s, o, i, u, _, w) { + if (i + u > s.length) throw new RangeError('Index out of range'); + if (i < 0) throw new RangeError('Index out of range'); + } + function writeFloat(s, o, i, u, w) { + return ( + (o = +o), (i >>>= 0), w || checkIEEE754(s, 0, i, 4), _.write(s, o, i, u, 23, 4), i + 4 + ); + } + function writeDouble(s, o, i, u, w) { + return ( + (o = +o), (i >>>= 0), w || checkIEEE754(s, 0, i, 8), _.write(s, o, i, u, 52, 8), i + 8 + ); + } + (Buffer.prototype.slice = function slice(s, o) { + const i = this.length; + (s = ~~s) < 0 ? (s += i) < 0 && (s = 0) : s > i && (s = i), + (o = void 0 === o ? i : ~~o) < 0 ? (o += i) < 0 && (o = 0) : o > i && (o = i), + o < s && (o = s); + const u = this.subarray(s, o); + return Object.setPrototypeOf(u, Buffer.prototype), u; + }), + (Buffer.prototype.readUintLE = Buffer.prototype.readUIntLE = + function readUIntLE(s, o, i) { + (s >>>= 0), (o >>>= 0), i || checkOffset(s, o, this.length); + let u = this[s], + _ = 1, + w = 0; + for (; ++w < o && (_ *= 256); ) u += this[s + w] * _; + return u; + }), + (Buffer.prototype.readUintBE = Buffer.prototype.readUIntBE = + function readUIntBE(s, o, i) { + (s >>>= 0), (o >>>= 0), i || checkOffset(s, o, this.length); + let u = this[s + --o], + _ = 1; + for (; o > 0 && (_ *= 256); ) u += this[s + --o] * _; + return u; + }), + (Buffer.prototype.readUint8 = Buffer.prototype.readUInt8 = + function readUInt8(s, o) { + return (s >>>= 0), o || checkOffset(s, 1, this.length), this[s]; + }), + (Buffer.prototype.readUint16LE = Buffer.prototype.readUInt16LE = + function readUInt16LE(s, o) { + return ( + (s >>>= 0), o || checkOffset(s, 2, this.length), this[s] | (this[s + 1] << 8) + ); + }), + (Buffer.prototype.readUint16BE = Buffer.prototype.readUInt16BE = + function readUInt16BE(s, o) { + return ( + (s >>>= 0), o || checkOffset(s, 2, this.length), (this[s] << 8) | this[s + 1] + ); + }), + (Buffer.prototype.readUint32LE = Buffer.prototype.readUInt32LE = + function readUInt32LE(s, o) { + return ( + (s >>>= 0), + o || checkOffset(s, 4, this.length), + (this[s] | (this[s + 1] << 8) | (this[s + 2] << 16)) + 16777216 * this[s + 3] + ); + }), + (Buffer.prototype.readUint32BE = Buffer.prototype.readUInt32BE = + function readUInt32BE(s, o) { + return ( + (s >>>= 0), + o || checkOffset(s, 4, this.length), + 16777216 * this[s] + ((this[s + 1] << 16) | (this[s + 2] << 8) | this[s + 3]) + ); + }), + (Buffer.prototype.readBigUInt64LE = defineBigIntMethod(function readBigUInt64LE(s) { + validateNumber((s >>>= 0), 'offset'); + const o = this[s], + i = this[s + 7]; + (void 0 !== o && void 0 !== i) || boundsError(s, this.length - 8); + const u = o + 256 * this[++s] + 65536 * this[++s] + this[++s] * 2 ** 24, + _ = this[++s] + 256 * this[++s] + 65536 * this[++s] + i * 2 ** 24; + return BigInt(u) + (BigInt(_) << BigInt(32)); + })), + (Buffer.prototype.readBigUInt64BE = defineBigIntMethod(function readBigUInt64BE(s) { + validateNumber((s >>>= 0), 'offset'); + const o = this[s], + i = this[s + 7]; + (void 0 !== o && void 0 !== i) || boundsError(s, this.length - 8); + const u = o * 2 ** 24 + 65536 * this[++s] + 256 * this[++s] + this[++s], + _ = this[++s] * 2 ** 24 + 65536 * this[++s] + 256 * this[++s] + i; + return (BigInt(u) << BigInt(32)) + BigInt(_); + })), + (Buffer.prototype.readIntLE = function readIntLE(s, o, i) { + (s >>>= 0), (o >>>= 0), i || checkOffset(s, o, this.length); + let u = this[s], + _ = 1, + w = 0; + for (; ++w < o && (_ *= 256); ) u += this[s + w] * _; + return (_ *= 128), u >= _ && (u -= Math.pow(2, 8 * o)), u; + }), + (Buffer.prototype.readIntBE = function readIntBE(s, o, i) { + (s >>>= 0), (o >>>= 0), i || checkOffset(s, o, this.length); + let u = o, + _ = 1, + w = this[s + --u]; + for (; u > 0 && (_ *= 256); ) w += this[s + --u] * _; + return (_ *= 128), w >= _ && (w -= Math.pow(2, 8 * o)), w; + }), + (Buffer.prototype.readInt8 = function readInt8(s, o) { + return ( + (s >>>= 0), + o || checkOffset(s, 1, this.length), + 128 & this[s] ? -1 * (255 - this[s] + 1) : this[s] + ); + }), + (Buffer.prototype.readInt16LE = function readInt16LE(s, o) { + (s >>>= 0), o || checkOffset(s, 2, this.length); + const i = this[s] | (this[s + 1] << 8); + return 32768 & i ? 4294901760 | i : i; + }), + (Buffer.prototype.readInt16BE = function readInt16BE(s, o) { + (s >>>= 0), o || checkOffset(s, 2, this.length); + const i = this[s + 1] | (this[s] << 8); + return 32768 & i ? 4294901760 | i : i; + }), + (Buffer.prototype.readInt32LE = function readInt32LE(s, o) { + return ( + (s >>>= 0), + o || checkOffset(s, 4, this.length), + this[s] | (this[s + 1] << 8) | (this[s + 2] << 16) | (this[s + 3] << 24) + ); + }), + (Buffer.prototype.readInt32BE = function readInt32BE(s, o) { + return ( + (s >>>= 0), + o || checkOffset(s, 4, this.length), + (this[s] << 24) | (this[s + 1] << 16) | (this[s + 2] << 8) | this[s + 3] + ); + }), + (Buffer.prototype.readBigInt64LE = defineBigIntMethod(function readBigInt64LE(s) { + validateNumber((s >>>= 0), 'offset'); + const o = this[s], + i = this[s + 7]; + (void 0 !== o && void 0 !== i) || boundsError(s, this.length - 8); + const u = this[s + 4] + 256 * this[s + 5] + 65536 * this[s + 6] + (i << 24); + return ( + (BigInt(u) << BigInt(32)) + + BigInt(o + 256 * this[++s] + 65536 * this[++s] + this[++s] * 2 ** 24) + ); + })), + (Buffer.prototype.readBigInt64BE = defineBigIntMethod(function readBigInt64BE(s) { + validateNumber((s >>>= 0), 'offset'); + const o = this[s], + i = this[s + 7]; + (void 0 !== o && void 0 !== i) || boundsError(s, this.length - 8); + const u = (o << 24) + 65536 * this[++s] + 256 * this[++s] + this[++s]; + return ( + (BigInt(u) << BigInt(32)) + + BigInt(this[++s] * 2 ** 24 + 65536 * this[++s] + 256 * this[++s] + i) + ); + })), + (Buffer.prototype.readFloatLE = function readFloatLE(s, o) { + return (s >>>= 0), o || checkOffset(s, 4, this.length), _.read(this, s, !0, 23, 4); + }), + (Buffer.prototype.readFloatBE = function readFloatBE(s, o) { + return (s >>>= 0), o || checkOffset(s, 4, this.length), _.read(this, s, !1, 23, 4); + }), + (Buffer.prototype.readDoubleLE = function readDoubleLE(s, o) { + return (s >>>= 0), o || checkOffset(s, 8, this.length), _.read(this, s, !0, 52, 8); + }), + (Buffer.prototype.readDoubleBE = function readDoubleBE(s, o) { + return (s >>>= 0), o || checkOffset(s, 8, this.length), _.read(this, s, !1, 52, 8); + }), + (Buffer.prototype.writeUintLE = Buffer.prototype.writeUIntLE = + function writeUIntLE(s, o, i, u) { + if (((s = +s), (o >>>= 0), (i >>>= 0), !u)) { + checkInt(this, s, o, i, Math.pow(2, 8 * i) - 1, 0); + } + let _ = 1, + w = 0; + for (this[o] = 255 & s; ++w < i && (_ *= 256); ) this[o + w] = (s / _) & 255; + return o + i; + }), + (Buffer.prototype.writeUintBE = Buffer.prototype.writeUIntBE = + function writeUIntBE(s, o, i, u) { + if (((s = +s), (o >>>= 0), (i >>>= 0), !u)) { + checkInt(this, s, o, i, Math.pow(2, 8 * i) - 1, 0); + } + let _ = i - 1, + w = 1; + for (this[o + _] = 255 & s; --_ >= 0 && (w *= 256); ) this[o + _] = (s / w) & 255; + return o + i; + }), + (Buffer.prototype.writeUint8 = Buffer.prototype.writeUInt8 = + function writeUInt8(s, o, i) { + return ( + (s = +s), + (o >>>= 0), + i || checkInt(this, s, o, 1, 255, 0), + (this[o] = 255 & s), + o + 1 + ); + }), + (Buffer.prototype.writeUint16LE = Buffer.prototype.writeUInt16LE = + function writeUInt16LE(s, o, i) { + return ( + (s = +s), + (o >>>= 0), + i || checkInt(this, s, o, 2, 65535, 0), + (this[o] = 255 & s), + (this[o + 1] = s >>> 8), + o + 2 + ); + }), + (Buffer.prototype.writeUint16BE = Buffer.prototype.writeUInt16BE = + function writeUInt16BE(s, o, i) { + return ( + (s = +s), + (o >>>= 0), + i || checkInt(this, s, o, 2, 65535, 0), + (this[o] = s >>> 8), + (this[o + 1] = 255 & s), + o + 2 + ); + }), + (Buffer.prototype.writeUint32LE = Buffer.prototype.writeUInt32LE = + function writeUInt32LE(s, o, i) { + return ( + (s = +s), + (o >>>= 0), + i || checkInt(this, s, o, 4, 4294967295, 0), + (this[o + 3] = s >>> 24), + (this[o + 2] = s >>> 16), + (this[o + 1] = s >>> 8), + (this[o] = 255 & s), + o + 4 + ); + }), + (Buffer.prototype.writeUint32BE = Buffer.prototype.writeUInt32BE = + function writeUInt32BE(s, o, i) { + return ( + (s = +s), + (o >>>= 0), + i || checkInt(this, s, o, 4, 4294967295, 0), + (this[o] = s >>> 24), + (this[o + 1] = s >>> 16), + (this[o + 2] = s >>> 8), + (this[o + 3] = 255 & s), + o + 4 + ); + }), + (Buffer.prototype.writeBigUInt64LE = defineBigIntMethod(function writeBigUInt64LE( + s, + o = 0 + ) { + return wrtBigUInt64LE(this, s, o, BigInt(0), BigInt('0xffffffffffffffff')); + })), + (Buffer.prototype.writeBigUInt64BE = defineBigIntMethod(function writeBigUInt64BE( + s, + o = 0 + ) { + return wrtBigUInt64BE(this, s, o, BigInt(0), BigInt('0xffffffffffffffff')); + })), + (Buffer.prototype.writeIntLE = function writeIntLE(s, o, i, u) { + if (((s = +s), (o >>>= 0), !u)) { + const u = Math.pow(2, 8 * i - 1); + checkInt(this, s, o, i, u - 1, -u); + } + let _ = 0, + w = 1, + x = 0; + for (this[o] = 255 & s; ++_ < i && (w *= 256); ) + s < 0 && 0 === x && 0 !== this[o + _ - 1] && (x = 1), + (this[o + _] = (((s / w) | 0) - x) & 255); + return o + i; + }), + (Buffer.prototype.writeIntBE = function writeIntBE(s, o, i, u) { + if (((s = +s), (o >>>= 0), !u)) { + const u = Math.pow(2, 8 * i - 1); + checkInt(this, s, o, i, u - 1, -u); + } + let _ = i - 1, + w = 1, + x = 0; + for (this[o + _] = 255 & s; --_ >= 0 && (w *= 256); ) + s < 0 && 0 === x && 0 !== this[o + _ + 1] && (x = 1), + (this[o + _] = (((s / w) | 0) - x) & 255); + return o + i; + }), + (Buffer.prototype.writeInt8 = function writeInt8(s, o, i) { + return ( + (s = +s), + (o >>>= 0), + i || checkInt(this, s, o, 1, 127, -128), + s < 0 && (s = 255 + s + 1), + (this[o] = 255 & s), + o + 1 + ); + }), + (Buffer.prototype.writeInt16LE = function writeInt16LE(s, o, i) { + return ( + (s = +s), + (o >>>= 0), + i || checkInt(this, s, o, 2, 32767, -32768), + (this[o] = 255 & s), + (this[o + 1] = s >>> 8), + o + 2 + ); + }), + (Buffer.prototype.writeInt16BE = function writeInt16BE(s, o, i) { + return ( + (s = +s), + (o >>>= 0), + i || checkInt(this, s, o, 2, 32767, -32768), + (this[o] = s >>> 8), + (this[o + 1] = 255 & s), + o + 2 + ); + }), + (Buffer.prototype.writeInt32LE = function writeInt32LE(s, o, i) { + return ( + (s = +s), + (o >>>= 0), + i || checkInt(this, s, o, 4, 2147483647, -2147483648), + (this[o] = 255 & s), + (this[o + 1] = s >>> 8), + (this[o + 2] = s >>> 16), + (this[o + 3] = s >>> 24), + o + 4 + ); + }), + (Buffer.prototype.writeInt32BE = function writeInt32BE(s, o, i) { + return ( + (s = +s), + (o >>>= 0), + i || checkInt(this, s, o, 4, 2147483647, -2147483648), + s < 0 && (s = 4294967295 + s + 1), + (this[o] = s >>> 24), + (this[o + 1] = s >>> 16), + (this[o + 2] = s >>> 8), + (this[o + 3] = 255 & s), + o + 4 + ); + }), + (Buffer.prototype.writeBigInt64LE = defineBigIntMethod(function writeBigInt64LE( + s, + o = 0 + ) { + return wrtBigUInt64LE( + this, + s, + o, + -BigInt('0x8000000000000000'), + BigInt('0x7fffffffffffffff') + ); + })), + (Buffer.prototype.writeBigInt64BE = defineBigIntMethod(function writeBigInt64BE( + s, + o = 0 + ) { + return wrtBigUInt64BE( + this, + s, + o, + -BigInt('0x8000000000000000'), + BigInt('0x7fffffffffffffff') + ); + })), + (Buffer.prototype.writeFloatLE = function writeFloatLE(s, o, i) { + return writeFloat(this, s, o, !0, i); + }), + (Buffer.prototype.writeFloatBE = function writeFloatBE(s, o, i) { + return writeFloat(this, s, o, !1, i); + }), + (Buffer.prototype.writeDoubleLE = function writeDoubleLE(s, o, i) { + return writeDouble(this, s, o, !0, i); + }), + (Buffer.prototype.writeDoubleBE = function writeDoubleBE(s, o, i) { + return writeDouble(this, s, o, !1, i); + }), + (Buffer.prototype.copy = function copy(s, o, i, u) { + if (!Buffer.isBuffer(s)) throw new TypeError('argument should be a Buffer'); + if ( + (i || (i = 0), + u || 0 === u || (u = this.length), + o >= s.length && (o = s.length), + o || (o = 0), + u > 0 && u < i && (u = i), + u === i) + ) + return 0; + if (0 === s.length || 0 === this.length) return 0; + if (o < 0) throw new RangeError('targetStart out of bounds'); + if (i < 0 || i >= this.length) throw new RangeError('Index out of range'); + if (u < 0) throw new RangeError('sourceEnd out of bounds'); + u > this.length && (u = this.length), s.length - o < u - i && (u = s.length - o + i); + const _ = u - i; + return ( + this === s && 'function' == typeof Uint8Array.prototype.copyWithin + ? this.copyWithin(o, i, u) + : Uint8Array.prototype.set.call(s, this.subarray(i, u), o), + _ + ); + }), + (Buffer.prototype.fill = function fill(s, o, i, u) { + if ('string' == typeof s) { + if ( + ('string' == typeof o + ? ((u = o), (o = 0), (i = this.length)) + : 'string' == typeof i && ((u = i), (i = this.length)), + void 0 !== u && 'string' != typeof u) + ) + throw new TypeError('encoding must be a string'); + if ('string' == typeof u && !Buffer.isEncoding(u)) + throw new TypeError('Unknown encoding: ' + u); + if (1 === s.length) { + const o = s.charCodeAt(0); + (('utf8' === u && o < 128) || 'latin1' === u) && (s = o); + } + } else 'number' == typeof s ? (s &= 255) : 'boolean' == typeof s && (s = Number(s)); + if (o < 0 || this.length < o || this.length < i) + throw new RangeError('Out of range index'); + if (i <= o) return this; + let _; + if ( + ((o >>>= 0), + (i = void 0 === i ? this.length : i >>> 0), + s || (s = 0), + 'number' == typeof s) + ) + for (_ = o; _ < i; ++_) this[_] = s; + else { + const w = Buffer.isBuffer(s) ? s : Buffer.from(s, u), + x = w.length; + if (0 === x) + throw new TypeError('The value "' + s + '" is invalid for argument "value"'); + for (_ = 0; _ < i - o; ++_) this[_ + o] = w[_ % x]; + } + return this; + }); + const j = {}; + function E(s, o, i) { + j[s] = class NodeError extends i { + constructor() { + super(), + Object.defineProperty(this, 'message', { + value: o.apply(this, arguments), + writable: !0, + configurable: !0 + }), + (this.name = `${this.name} [${s}]`), + this.stack, + delete this.name; + } + get code() { + return s; + } + set code(s) { + Object.defineProperty(this, 'code', { + configurable: !0, + enumerable: !0, + value: s, + writable: !0 + }); + } + toString() { + return `${this.name} [${s}]: ${this.message}`; + } + }; + } + function addNumericalSeparator(s) { + let o = '', + i = s.length; + const u = '-' === s[0] ? 1 : 0; + for (; i >= u + 4; i -= 3) o = `_${s.slice(i - 3, i)}${o}`; + return `${s.slice(0, i)}${o}`; + } + function checkIntBI(s, o, i, u, _, w) { + if (s > i || s < o) { + const u = 'bigint' == typeof o ? 'n' : ''; + let _; + throw ( + ((_ = + w > 3 + ? 0 === o || o === BigInt(0) + ? `>= 0${u} and < 2${u} ** ${8 * (w + 1)}${u}` + : `>= -(2${u} ** ${8 * (w + 1) - 1}${u}) and < 2 ** ${8 * (w + 1) - 1}${u}` + : `>= ${o}${u} and <= ${i}${u}`), + new j.ERR_OUT_OF_RANGE('value', _, s)) + ); + } + !(function checkBounds(s, o, i) { + validateNumber(o, 'offset'), + (void 0 !== s[o] && void 0 !== s[o + i]) || boundsError(o, s.length - (i + 1)); + })(u, _, w); + } + function validateNumber(s, o) { + if ('number' != typeof s) throw new j.ERR_INVALID_ARG_TYPE(o, 'number', s); + } + function boundsError(s, o, i) { + if (Math.floor(s) !== s) + throw (validateNumber(s, i), new j.ERR_OUT_OF_RANGE(i || 'offset', 'an integer', s)); + if (o < 0) throw new j.ERR_BUFFER_OUT_OF_BOUNDS(); + throw new j.ERR_OUT_OF_RANGE(i || 'offset', `>= ${i ? 1 : 0} and <= ${o}`, s); + } + E( + 'ERR_BUFFER_OUT_OF_BOUNDS', + function (s) { + return s + ? `${s} is outside of buffer bounds` + : 'Attempt to access memory outside buffer bounds'; + }, + RangeError + ), + E( + 'ERR_INVALID_ARG_TYPE', + function (s, o) { + return `The "${s}" argument must be of type number. Received type ${typeof o}`; + }, + TypeError + ), + E( + 'ERR_OUT_OF_RANGE', + function (s, o, i) { + let u = `The value of "${s}" is out of range.`, + _ = i; + return ( + Number.isInteger(i) && Math.abs(i) > 2 ** 32 + ? (_ = addNumericalSeparator(String(i))) + : 'bigint' == typeof i && + ((_ = String(i)), + (i > BigInt(2) ** BigInt(32) || i < -(BigInt(2) ** BigInt(32))) && + (_ = addNumericalSeparator(_)), + (_ += 'n')), + (u += ` It must be ${o}. Received ${_}`), + u + ); + }, + RangeError + ); + const L = /[^+/0-9A-Za-z-_]/g; + function utf8ToBytes(s, o) { + let i; + o = o || 1 / 0; + const u = s.length; + let _ = null; + const w = []; + for (let x = 0; x < u; ++x) { + if (((i = s.charCodeAt(x)), i > 55295 && i < 57344)) { + if (!_) { + if (i > 56319) { + (o -= 3) > -1 && w.push(239, 191, 189); + continue; + } + if (x + 1 === u) { + (o -= 3) > -1 && w.push(239, 191, 189); + continue; + } + _ = i; + continue; + } + if (i < 56320) { + (o -= 3) > -1 && w.push(239, 191, 189), (_ = i); + continue; + } + i = 65536 + (((_ - 55296) << 10) | (i - 56320)); + } else _ && (o -= 3) > -1 && w.push(239, 191, 189); + if (((_ = null), i < 128)) { + if ((o -= 1) < 0) break; + w.push(i); + } else if (i < 2048) { + if ((o -= 2) < 0) break; + w.push((i >> 6) | 192, (63 & i) | 128); + } else if (i < 65536) { + if ((o -= 3) < 0) break; + w.push((i >> 12) | 224, ((i >> 6) & 63) | 128, (63 & i) | 128); + } else { + if (!(i < 1114112)) throw new Error('Invalid code point'); + if ((o -= 4) < 0) break; + w.push( + (i >> 18) | 240, + ((i >> 12) & 63) | 128, + ((i >> 6) & 63) | 128, + (63 & i) | 128 + ); + } + } + return w; + } + function base64ToBytes(s) { + return u.toByteArray( + (function base64clean(s) { + if ((s = (s = s.split('=')[0]).trim().replace(L, '')).length < 2) return ''; + for (; s.length % 4 != 0; ) s += '='; + return s; + })(s) + ); + } + function blitBuffer(s, o, i, u) { + let _; + for (_ = 0; _ < u && !(_ + i >= o.length || _ >= s.length); ++_) o[_ + i] = s[_]; + return _; + } + function isInstance(s, o) { + return ( + s instanceof o || + (null != s && + null != s.constructor && + null != s.constructor.name && + s.constructor.name === o.name) + ); + } + function numberIsNaN(s) { + return s != s; + } + const B = (function () { + const s = '0123456789abcdef', + o = new Array(256); + for (let i = 0; i < 16; ++i) { + const u = 16 * i; + for (let _ = 0; _ < 16; ++_) o[u + _] = s[i] + s[_]; + } + return o; + })(); + function defineBigIntMethod(s) { + return 'undefined' == typeof BigInt ? BufferBigIntNotDefined : s; + } + function BufferBigIntNotDefined() { + throw new Error('BigInt not supported'); + } + }, + 17965: (s, o, i) => { + 'use strict'; + var u = i(16426), + _ = { 'text/plain': 'Text', 'text/html': 'Url', default: 'Text' }; + s.exports = function copy(s, o) { + var i, + w, + x, + C, + j, + L, + B = !1; + o || (o = {}), (i = o.debug || !1); + try { + if ( + ((x = u()), + (C = document.createRange()), + (j = document.getSelection()), + ((L = document.createElement('span')).textContent = s), + (L.ariaHidden = 'true'), + (L.style.all = 'unset'), + (L.style.position = 'fixed'), + (L.style.top = 0), + (L.style.clip = 'rect(0, 0, 0, 0)'), + (L.style.whiteSpace = 'pre'), + (L.style.webkitUserSelect = 'text'), + (L.style.MozUserSelect = 'text'), + (L.style.msUserSelect = 'text'), + (L.style.userSelect = 'text'), + L.addEventListener('copy', function (u) { + if ((u.stopPropagation(), o.format)) + if ((u.preventDefault(), void 0 === u.clipboardData)) { + i && console.warn('unable to use e.clipboardData'), + i && console.warn('trying IE specific stuff'), + window.clipboardData.clearData(); + var w = _[o.format] || _.default; + window.clipboardData.setData(w, s); + } else u.clipboardData.clearData(), u.clipboardData.setData(o.format, s); + o.onCopy && (u.preventDefault(), o.onCopy(u.clipboardData)); + }), + document.body.appendChild(L), + C.selectNodeContents(L), + j.addRange(C), + !document.execCommand('copy')) + ) + throw new Error('copy command was unsuccessful'); + B = !0; + } catch (u) { + i && console.error('unable to copy using execCommand: ', u), + i && console.warn('trying IE specific stuff'); + try { + window.clipboardData.setData(o.format || 'text', s), + o.onCopy && o.onCopy(window.clipboardData), + (B = !0); + } catch (u) { + i && console.error('unable to copy using clipboardData: ', u), + i && console.error('falling back to prompt'), + (w = (function format(s) { + var o = (/mac os x/i.test(navigator.userAgent) ? '⌘' : 'Ctrl') + '+C'; + return s.replace(/#{\s*key\s*}/g, o); + })('message' in o ? o.message : 'Copy to clipboard: #{key}, Enter')), + window.prompt(w, s); + } + } finally { + j && ('function' == typeof j.removeRange ? j.removeRange(C) : j.removeAllRanges()), + L && document.body.removeChild(L), + x(); + } + return B; + }; + }, + 2205: function (s, o, i) { + var u; + (u = void 0 !== i.g ? i.g : this), + (s.exports = (function (s) { + if (s.CSS && s.CSS.escape) return s.CSS.escape; + var cssEscape = function (s) { + if (0 == arguments.length) + throw new TypeError('`CSS.escape` requires an argument.'); + for ( + var o, i = String(s), u = i.length, _ = -1, w = '', x = i.charCodeAt(0); + ++_ < u; + + ) + 0 != (o = i.charCodeAt(_)) + ? (w += + (o >= 1 && o <= 31) || + 127 == o || + (0 == _ && o >= 48 && o <= 57) || + (1 == _ && o >= 48 && o <= 57 && 45 == x) + ? '\\' + o.toString(16) + ' ' + : (0 == _ && 1 == u && 45 == o) || + !( + o >= 128 || + 45 == o || + 95 == o || + (o >= 48 && o <= 57) || + (o >= 65 && o <= 90) || + (o >= 97 && o <= 122) + ) + ? '\\' + i.charAt(_) + : i.charAt(_)) + : (w += '�'); + return w; + }; + return s.CSS || (s.CSS = {}), (s.CSS.escape = cssEscape), cssEscape; + })(u)); + }, + 81919: (s, o, i) => { + 'use strict'; + var u = i(48287).Buffer; + function isSpecificValue(s) { + return s instanceof u || s instanceof Date || s instanceof RegExp; + } + function cloneSpecificValue(s) { + if (s instanceof u) { + var o = u.alloc ? u.alloc(s.length) : new u(s.length); + return s.copy(o), o; + } + if (s instanceof Date) return new Date(s.getTime()); + if (s instanceof RegExp) return new RegExp(s); + throw new Error('Unexpected situation'); + } + function deepCloneArray(s) { + var o = []; + return ( + s.forEach(function (s, i) { + 'object' == typeof s && null !== s + ? Array.isArray(s) + ? (o[i] = deepCloneArray(s)) + : isSpecificValue(s) + ? (o[i] = cloneSpecificValue(s)) + : (o[i] = _({}, s)) + : (o[i] = s); + }), + o + ); + } + function safeGetProperty(s, o) { + return '__proto__' === o ? void 0 : s[o]; + } + var _ = (s.exports = function () { + if (arguments.length < 1 || 'object' != typeof arguments[0]) return !1; + if (arguments.length < 2) return arguments[0]; + var s, + o, + i = arguments[0]; + return ( + Array.prototype.slice.call(arguments, 1).forEach(function (u) { + 'object' != typeof u || + null === u || + Array.isArray(u) || + Object.keys(u).forEach(function (w) { + return ( + (o = safeGetProperty(i, w)), + (s = safeGetProperty(u, w)) === i + ? void 0 + : 'object' != typeof s || null === s + ? void (i[w] = s) + : Array.isArray(s) + ? void (i[w] = deepCloneArray(s)) + : isSpecificValue(s) + ? void (i[w] = cloneSpecificValue(s)) + : 'object' != typeof o || null === o || Array.isArray(o) + ? void (i[w] = _({}, s)) + : void (i[w] = _(o, s)) + ); + }); + }), + i + ); + }); + }, + 14744: (s) => { + 'use strict'; + var o = function isMergeableObject(s) { + return ( + (function isNonNullObject(s) { + return !!s && 'object' == typeof s; + })(s) && + !(function isSpecial(s) { + var o = Object.prototype.toString.call(s); + return ( + '[object RegExp]' === o || + '[object Date]' === o || + (function isReactElement(s) { + return s.$$typeof === i; + })(s) + ); + })(s) + ); + }; + var i = 'function' == typeof Symbol && Symbol.for ? Symbol.for('react.element') : 60103; + function cloneUnlessOtherwiseSpecified(s, o) { + return !1 !== o.clone && o.isMergeableObject(s) + ? deepmerge( + (function emptyTarget(s) { + return Array.isArray(s) ? [] : {}; + })(s), + s, + o + ) + : s; + } + function defaultArrayMerge(s, o, i) { + return s.concat(o).map(function (s) { + return cloneUnlessOtherwiseSpecified(s, i); + }); + } + function getKeys(s) { + return Object.keys(s).concat( + (function getEnumerableOwnPropertySymbols(s) { + return Object.getOwnPropertySymbols + ? Object.getOwnPropertySymbols(s).filter(function (o) { + return Object.propertyIsEnumerable.call(s, o); + }) + : []; + })(s) + ); + } + function propertyIsOnObject(s, o) { + try { + return o in s; + } catch (s) { + return !1; + } + } + function mergeObject(s, o, i) { + var u = {}; + return ( + i.isMergeableObject(s) && + getKeys(s).forEach(function (o) { + u[o] = cloneUnlessOtherwiseSpecified(s[o], i); + }), + getKeys(o).forEach(function (_) { + (function propertyIsUnsafe(s, o) { + return ( + propertyIsOnObject(s, o) && + !(Object.hasOwnProperty.call(s, o) && Object.propertyIsEnumerable.call(s, o)) + ); + })(s, _) || + (propertyIsOnObject(s, _) && i.isMergeableObject(o[_]) + ? (u[_] = (function getMergeFunction(s, o) { + if (!o.customMerge) return deepmerge; + var i = o.customMerge(s); + return 'function' == typeof i ? i : deepmerge; + })(_, i)(s[_], o[_], i)) + : (u[_] = cloneUnlessOtherwiseSpecified(o[_], i))); + }), + u + ); + } + function deepmerge(s, i, u) { + ((u = u || {}).arrayMerge = u.arrayMerge || defaultArrayMerge), + (u.isMergeableObject = u.isMergeableObject || o), + (u.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified); + var _ = Array.isArray(i); + return _ === Array.isArray(s) + ? _ + ? u.arrayMerge(s, i, u) + : mergeObject(s, i, u) + : cloneUnlessOtherwiseSpecified(i, u); + } + deepmerge.all = function deepmergeAll(s, o) { + if (!Array.isArray(s)) throw new Error('first argument should be an array'); + return s.reduce(function (s, i) { + return deepmerge(s, i, o); + }, {}); + }; + var u = deepmerge; + s.exports = u; + }, + 42838: function (s) { + s.exports = (function () { + 'use strict'; + const { + entries: s, + setPrototypeOf: o, + isFrozen: i, + getPrototypeOf: u, + getOwnPropertyDescriptor: _ + } = Object; + let { freeze: w, seal: x, create: C } = Object, + { apply: j, construct: L } = 'undefined' != typeof Reflect && Reflect; + w || + (w = function freeze(s) { + return s; + }), + x || + (x = function seal(s) { + return s; + }), + j || + (j = function apply(s, o, i) { + return s.apply(o, i); + }), + L || + (L = function construct(s, o) { + return new s(...o); + }); + const B = unapply(Array.prototype.forEach), + $ = unapply(Array.prototype.pop), + V = unapply(Array.prototype.push), + U = unapply(String.prototype.toLowerCase), + z = unapply(String.prototype.toString), + Y = unapply(String.prototype.match), + Z = unapply(String.prototype.replace), + ee = unapply(String.prototype.indexOf), + ie = unapply(String.prototype.trim), + ae = unapply(Object.prototype.hasOwnProperty), + le = unapply(RegExp.prototype.test), + ce = unconstruct(TypeError); + function unapply(s) { + return function (o) { + for (var i = arguments.length, u = new Array(i > 1 ? i - 1 : 0), _ = 1; _ < i; _++) + u[_ - 1] = arguments[_]; + return j(s, o, u); + }; + } + function unconstruct(s) { + return function () { + for (var o = arguments.length, i = new Array(o), u = 0; u < o; u++) + i[u] = arguments[u]; + return L(s, i); + }; + } + function addToSet(s, u) { + let _ = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : U; + o && o(s, null); + let w = u.length; + for (; w--; ) { + let o = u[w]; + if ('string' == typeof o) { + const s = _(o); + s !== o && (i(u) || (u[w] = s), (o = s)); + } + s[o] = !0; + } + return s; + } + function cleanArray(s) { + for (let o = 0; o < s.length; o++) ae(s, o) || (s[o] = null); + return s; + } + function clone(o) { + const i = C(null); + for (const [u, _] of s(o)) + ae(o, u) && + (Array.isArray(_) + ? (i[u] = cleanArray(_)) + : _ && 'object' == typeof _ && _.constructor === Object + ? (i[u] = clone(_)) + : (i[u] = _)); + return i; + } + function lookupGetter(s, o) { + for (; null !== s; ) { + const i = _(s, o); + if (i) { + if (i.get) return unapply(i.get); + if ('function' == typeof i.value) return unapply(i.value); + } + s = u(s); + } + function fallbackValue() { + return null; + } + return fallbackValue; + } + const pe = w([ + 'a', + 'abbr', + 'acronym', + 'address', + 'area', + 'article', + 'aside', + 'audio', + 'b', + 'bdi', + 'bdo', + 'big', + 'blink', + 'blockquote', + 'body', + 'br', + 'button', + 'canvas', + 'caption', + 'center', + 'cite', + 'code', + 'col', + 'colgroup', + 'content', + 'data', + 'datalist', + 'dd', + 'decorator', + 'del', + 'details', + 'dfn', + 'dialog', + 'dir', + 'div', + 'dl', + 'dt', + 'element', + 'em', + 'fieldset', + 'figcaption', + 'figure', + 'font', + 'footer', + 'form', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'head', + 'header', + 'hgroup', + 'hr', + 'html', + 'i', + 'img', + 'input', + 'ins', + 'kbd', + 'label', + 'legend', + 'li', + 'main', + 'map', + 'mark', + 'marquee', + 'menu', + 'menuitem', + 'meter', + 'nav', + 'nobr', + 'ol', + 'optgroup', + 'option', + 'output', + 'p', + 'picture', + 'pre', + 'progress', + 'q', + 'rp', + 'rt', + 'ruby', + 's', + 'samp', + 'section', + 'select', + 'shadow', + 'small', + 'source', + 'spacer', + 'span', + 'strike', + 'strong', + 'style', + 'sub', + 'summary', + 'sup', + 'table', + 'tbody', + 'td', + 'template', + 'textarea', + 'tfoot', + 'th', + 'thead', + 'time', + 'tr', + 'track', + 'tt', + 'u', + 'ul', + 'var', + 'video', + 'wbr' + ]), + de = w([ + 'svg', + 'a', + 'altglyph', + 'altglyphdef', + 'altglyphitem', + 'animatecolor', + 'animatemotion', + 'animatetransform', + 'circle', + 'clippath', + 'defs', + 'desc', + 'ellipse', + 'filter', + 'font', + 'g', + 'glyph', + 'glyphref', + 'hkern', + 'image', + 'line', + 'lineargradient', + 'marker', + 'mask', + 'metadata', + 'mpath', + 'path', + 'pattern', + 'polygon', + 'polyline', + 'radialgradient', + 'rect', + 'stop', + 'style', + 'switch', + 'symbol', + 'text', + 'textpath', + 'title', + 'tref', + 'tspan', + 'view', + 'vkern' + ]), + fe = w([ + 'feBlend', + 'feColorMatrix', + 'feComponentTransfer', + 'feComposite', + 'feConvolveMatrix', + 'feDiffuseLighting', + 'feDisplacementMap', + 'feDistantLight', + 'feDropShadow', + 'feFlood', + 'feFuncA', + 'feFuncB', + 'feFuncG', + 'feFuncR', + 'feGaussianBlur', + 'feImage', + 'feMerge', + 'feMergeNode', + 'feMorphology', + 'feOffset', + 'fePointLight', + 'feSpecularLighting', + 'feSpotLight', + 'feTile', + 'feTurbulence' + ]), + ye = w([ + 'animate', + 'color-profile', + 'cursor', + 'discard', + 'font-face', + 'font-face-format', + 'font-face-name', + 'font-face-src', + 'font-face-uri', + 'foreignobject', + 'hatch', + 'hatchpath', + 'mesh', + 'meshgradient', + 'meshpatch', + 'meshrow', + 'missing-glyph', + 'script', + 'set', + 'solidcolor', + 'unknown', + 'use' + ]), + be = w([ + 'math', + 'menclose', + 'merror', + 'mfenced', + 'mfrac', + 'mglyph', + 'mi', + 'mlabeledtr', + 'mmultiscripts', + 'mn', + 'mo', + 'mover', + 'mpadded', + 'mphantom', + 'mroot', + 'mrow', + 'ms', + 'mspace', + 'msqrt', + 'mstyle', + 'msub', + 'msup', + 'msubsup', + 'mtable', + 'mtd', + 'mtext', + 'mtr', + 'munder', + 'munderover', + 'mprescripts' + ]), + _e = w([ + 'maction', + 'maligngroup', + 'malignmark', + 'mlongdiv', + 'mscarries', + 'mscarry', + 'msgroup', + 'mstack', + 'msline', + 'msrow', + 'semantics', + 'annotation', + 'annotation-xml', + 'mprescripts', + 'none' + ]), + we = w(['#text']), + Se = w([ + 'accept', + 'action', + 'align', + 'alt', + 'autocapitalize', + 'autocomplete', + 'autopictureinpicture', + 'autoplay', + 'background', + 'bgcolor', + 'border', + 'capture', + 'cellpadding', + 'cellspacing', + 'checked', + 'cite', + 'class', + 'clear', + 'color', + 'cols', + 'colspan', + 'controls', + 'controlslist', + 'coords', + 'crossorigin', + 'datetime', + 'decoding', + 'default', + 'dir', + 'disabled', + 'disablepictureinpicture', + 'disableremoteplayback', + 'download', + 'draggable', + 'enctype', + 'enterkeyhint', + 'face', + 'for', + 'headers', + 'height', + 'hidden', + 'high', + 'href', + 'hreflang', + 'id', + 'inputmode', + 'integrity', + 'ismap', + 'kind', + 'label', + 'lang', + 'list', + 'loading', + 'loop', + 'low', + 'max', + 'maxlength', + 'media', + 'method', + 'min', + 'minlength', + 'multiple', + 'muted', + 'name', + 'nonce', + 'noshade', + 'novalidate', + 'nowrap', + 'open', + 'optimum', + 'pattern', + 'placeholder', + 'playsinline', + 'popover', + 'popovertarget', + 'popovertargetaction', + 'poster', + 'preload', + 'pubdate', + 'radiogroup', + 'readonly', + 'rel', + 'required', + 'rev', + 'reversed', + 'role', + 'rows', + 'rowspan', + 'spellcheck', + 'scope', + 'selected', + 'shape', + 'size', + 'sizes', + 'span', + 'srclang', + 'start', + 'src', + 'srcset', + 'step', + 'style', + 'summary', + 'tabindex', + 'title', + 'translate', + 'type', + 'usemap', + 'valign', + 'value', + 'width', + 'wrap', + 'xmlns', + 'slot' + ]), + xe = w([ + 'accent-height', + 'accumulate', + 'additive', + 'alignment-baseline', + 'ascent', + 'attributename', + 'attributetype', + 'azimuth', + 'basefrequency', + 'baseline-shift', + 'begin', + 'bias', + 'by', + 'class', + 'clip', + 'clippathunits', + 'clip-path', + 'clip-rule', + 'color', + 'color-interpolation', + 'color-interpolation-filters', + 'color-profile', + 'color-rendering', + 'cx', + 'cy', + 'd', + 'dx', + 'dy', + 'diffuseconstant', + 'direction', + 'display', + 'divisor', + 'dur', + 'edgemode', + 'elevation', + 'end', + 'fill', + 'fill-opacity', + 'fill-rule', + 'filter', + 'filterunits', + 'flood-color', + 'flood-opacity', + 'font-family', + 'font-size', + 'font-size-adjust', + 'font-stretch', + 'font-style', + 'font-variant', + 'font-weight', + 'fx', + 'fy', + 'g1', + 'g2', + 'glyph-name', + 'glyphref', + 'gradientunits', + 'gradienttransform', + 'height', + 'href', + 'id', + 'image-rendering', + 'in', + 'in2', + 'k', + 'k1', + 'k2', + 'k3', + 'k4', + 'kerning', + 'keypoints', + 'keysplines', + 'keytimes', + 'lang', + 'lengthadjust', + 'letter-spacing', + 'kernelmatrix', + 'kernelunitlength', + 'lighting-color', + 'local', + 'marker-end', + 'marker-mid', + 'marker-start', + 'markerheight', + 'markerunits', + 'markerwidth', + 'maskcontentunits', + 'maskunits', + 'max', + 'mask', + 'media', + 'method', + 'mode', + 'min', + 'name', + 'numoctaves', + 'offset', + 'operator', + 'opacity', + 'order', + 'orient', + 'orientation', + 'origin', + 'overflow', + 'paint-order', + 'path', + 'pathlength', + 'patterncontentunits', + 'patterntransform', + 'patternunits', + 'points', + 'preservealpha', + 'preserveaspectratio', + 'primitiveunits', + 'r', + 'rx', + 'ry', + 'radius', + 'refx', + 'refy', + 'repeatcount', + 'repeatdur', + 'restart', + 'result', + 'rotate', + 'scale', + 'seed', + 'shape-rendering', + 'specularconstant', + 'specularexponent', + 'spreadmethod', + 'startoffset', + 'stddeviation', + 'stitchtiles', + 'stop-color', + 'stop-opacity', + 'stroke-dasharray', + 'stroke-dashoffset', + 'stroke-linecap', + 'stroke-linejoin', + 'stroke-miterlimit', + 'stroke-opacity', + 'stroke', + 'stroke-width', + 'style', + 'surfacescale', + 'systemlanguage', + 'tabindex', + 'targetx', + 'targety', + 'transform', + 'transform-origin', + 'text-anchor', + 'text-decoration', + 'text-rendering', + 'textlength', + 'type', + 'u1', + 'u2', + 'unicode', + 'values', + 'viewbox', + 'visibility', + 'version', + 'vert-adv-y', + 'vert-origin-x', + 'vert-origin-y', + 'width', + 'word-spacing', + 'wrap', + 'writing-mode', + 'xchannelselector', + 'ychannelselector', + 'x', + 'x1', + 'x2', + 'xmlns', + 'y', + 'y1', + 'y2', + 'z', + 'zoomandpan' + ]), + Pe = w([ + 'accent', + 'accentunder', + 'align', + 'bevelled', + 'close', + 'columnsalign', + 'columnlines', + 'columnspan', + 'denomalign', + 'depth', + 'dir', + 'display', + 'displaystyle', + 'encoding', + 'fence', + 'frame', + 'height', + 'href', + 'id', + 'largeop', + 'length', + 'linethickness', + 'lspace', + 'lquote', + 'mathbackground', + 'mathcolor', + 'mathsize', + 'mathvariant', + 'maxsize', + 'minsize', + 'movablelimits', + 'notation', + 'numalign', + 'open', + 'rowalign', + 'rowlines', + 'rowspacing', + 'rowspan', + 'rspace', + 'rquote', + 'scriptlevel', + 'scriptminsize', + 'scriptsizemultiplier', + 'selection', + 'separator', + 'separators', + 'stretchy', + 'subscriptshift', + 'supscriptshift', + 'symmetric', + 'voffset', + 'width', + 'xmlns' + ]), + Te = w(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']), + Re = x(/\{\{[\w\W]*|[\w\W]*\}\}/gm), + qe = x(/<%[\w\W]*|[\w\W]*%>/gm), + $e = x(/\${[\w\W]*}/gm), + ze = x(/^data-[\-\w.\u00B7-\uFFFF]/), + We = x(/^aria-[\-\w]+$/), + He = x( + /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i + ), + Ye = x(/^(?:\w+script|data):/i), + Xe = x(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g), + Qe = x(/^html$/i), + et = x(/^[a-z][.\w]*(-[.\w]+)+$/i); + var tt = Object.freeze({ + __proto__: null, + MUSTACHE_EXPR: Re, + ERB_EXPR: qe, + TMPLIT_EXPR: $e, + DATA_ATTR: ze, + ARIA_ATTR: We, + IS_ALLOWED_URI: He, + IS_SCRIPT_OR_DATA: Ye, + ATTR_WHITESPACE: Xe, + DOCTYPE_NAME: Qe, + CUSTOM_ELEMENT: et + }); + const rt = { + element: 1, + attribute: 2, + text: 3, + cdataSection: 4, + entityReference: 5, + entityNode: 6, + progressingInstruction: 7, + comment: 8, + document: 9, + documentType: 10, + documentFragment: 11, + notation: 12 + }, + nt = function getGlobal() { + return 'undefined' == typeof window ? null : window; + }, + st = function _createTrustedTypesPolicy(s, o) { + if ('object' != typeof s || 'function' != typeof s.createPolicy) return null; + let i = null; + const u = 'data-tt-policy-suffix'; + o && o.hasAttribute(u) && (i = o.getAttribute(u)); + const _ = 'dompurify' + (i ? '#' + i : ''); + try { + return s.createPolicy(_, { createHTML: (s) => s, createScriptURL: (s) => s }); + } catch (s) { + return console.warn('TrustedTypes policy ' + _ + ' could not be created.'), null; + } + }; + function createDOMPurify() { + let o = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : nt(); + const DOMPurify = (s) => createDOMPurify(s); + if ( + ((DOMPurify.version = '3.1.6'), + (DOMPurify.removed = []), + !o || !o.document || o.document.nodeType !== rt.document) + ) + return (DOMPurify.isSupported = !1), DOMPurify; + let { document: i } = o; + const u = i, + _ = u.currentScript, + { + DocumentFragment: x, + HTMLTemplateElement: j, + Node: L, + Element: Re, + NodeFilter: qe, + NamedNodeMap: $e = o.NamedNodeMap || o.MozNamedAttrMap, + HTMLFormElement: ze, + DOMParser: We, + trustedTypes: Ye + } = o, + Xe = Re.prototype, + et = lookupGetter(Xe, 'cloneNode'), + ot = lookupGetter(Xe, 'remove'), + it = lookupGetter(Xe, 'nextSibling'), + at = lookupGetter(Xe, 'childNodes'), + lt = lookupGetter(Xe, 'parentNode'); + if ('function' == typeof j) { + const s = i.createElement('template'); + s.content && s.content.ownerDocument && (i = s.content.ownerDocument); + } + let ct, + ut = ''; + const { + implementation: pt, + createNodeIterator: ht, + createDocumentFragment: dt, + getElementsByTagName: mt + } = i, + { importNode: gt } = u; + let yt = {}; + DOMPurify.isSupported = + 'function' == typeof s && + 'function' == typeof lt && + pt && + void 0 !== pt.createHTMLDocument; + const { + MUSTACHE_EXPR: vt, + ERB_EXPR: bt, + TMPLIT_EXPR: _t, + DATA_ATTR: Et, + ARIA_ATTR: wt, + IS_SCRIPT_OR_DATA: St, + ATTR_WHITESPACE: xt, + CUSTOM_ELEMENT: kt + } = tt; + let { IS_ALLOWED_URI: Ct } = tt, + Ot = null; + const At = addToSet({}, [...pe, ...de, ...fe, ...be, ...we]); + let jt = null; + const It = addToSet({}, [...Se, ...xe, ...Pe, ...Te]); + let Pt = Object.seal( + C(null, { + tagNameCheck: { writable: !0, configurable: !1, enumerable: !0, value: null }, + attributeNameCheck: { + writable: !0, + configurable: !1, + enumerable: !0, + value: null + }, + allowCustomizedBuiltInElements: { + writable: !0, + configurable: !1, + enumerable: !0, + value: !1 + } + }) + ), + Mt = null, + Tt = null, + Nt = !0, + Rt = !0, + Dt = !1, + Lt = !0, + Bt = !1, + Ft = !0, + qt = !1, + $t = !1, + Vt = !1, + Ut = !1, + zt = !1, + Wt = !1, + Kt = !0, + Ht = !1; + const Jt = 'user-content-'; + let Gt = !0, + Yt = !1, + Xt = {}, + Zt = null; + const Qt = addToSet({}, [ + 'annotation-xml', + 'audio', + 'colgroup', + 'desc', + 'foreignobject', + 'head', + 'iframe', + 'math', + 'mi', + 'mn', + 'mo', + 'ms', + 'mtext', + 'noembed', + 'noframes', + 'noscript', + 'plaintext', + 'script', + 'style', + 'svg', + 'template', + 'thead', + 'title', + 'video', + 'xmp' + ]); + let er = null; + const tr = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']); + let rr = null; + const nr = addToSet({}, [ + 'alt', + 'class', + 'for', + 'id', + 'label', + 'name', + 'pattern', + 'placeholder', + 'role', + 'summary', + 'title', + 'value', + 'style', + 'xmlns' + ]), + sr = 'http://www.w3.org/1998/Math/MathML', + ir = 'http://www.w3.org/2000/svg', + ar = 'http://www.w3.org/1999/xhtml'; + let lr = ar, + cr = !1, + ur = null; + const pr = addToSet({}, [sr, ir, ar], z); + let dr = null; + const fr = ['application/xhtml+xml', 'text/html'], + mr = 'text/html'; + let gr = null, + yr = null; + const vr = i.createElement('form'), + br = function isRegexOrFunction(s) { + return s instanceof RegExp || s instanceof Function; + }, + _r = function _parseConfig() { + let s = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}; + if (!yr || yr !== s) { + if ( + ((s && 'object' == typeof s) || (s = {}), + (s = clone(s)), + (dr = -1 === fr.indexOf(s.PARSER_MEDIA_TYPE) ? mr : s.PARSER_MEDIA_TYPE), + (gr = 'application/xhtml+xml' === dr ? z : U), + (Ot = ae(s, 'ALLOWED_TAGS') ? addToSet({}, s.ALLOWED_TAGS, gr) : At), + (jt = ae(s, 'ALLOWED_ATTR') ? addToSet({}, s.ALLOWED_ATTR, gr) : It), + (ur = ae(s, 'ALLOWED_NAMESPACES') + ? addToSet({}, s.ALLOWED_NAMESPACES, z) + : pr), + (rr = ae(s, 'ADD_URI_SAFE_ATTR') + ? addToSet(clone(nr), s.ADD_URI_SAFE_ATTR, gr) + : nr), + (er = ae(s, 'ADD_DATA_URI_TAGS') + ? addToSet(clone(tr), s.ADD_DATA_URI_TAGS, gr) + : tr), + (Zt = ae(s, 'FORBID_CONTENTS') ? addToSet({}, s.FORBID_CONTENTS, gr) : Qt), + (Mt = ae(s, 'FORBID_TAGS') ? addToSet({}, s.FORBID_TAGS, gr) : {}), + (Tt = ae(s, 'FORBID_ATTR') ? addToSet({}, s.FORBID_ATTR, gr) : {}), + (Xt = !!ae(s, 'USE_PROFILES') && s.USE_PROFILES), + (Nt = !1 !== s.ALLOW_ARIA_ATTR), + (Rt = !1 !== s.ALLOW_DATA_ATTR), + (Dt = s.ALLOW_UNKNOWN_PROTOCOLS || !1), + (Lt = !1 !== s.ALLOW_SELF_CLOSE_IN_ATTR), + (Bt = s.SAFE_FOR_TEMPLATES || !1), + (Ft = !1 !== s.SAFE_FOR_XML), + (qt = s.WHOLE_DOCUMENT || !1), + (Ut = s.RETURN_DOM || !1), + (zt = s.RETURN_DOM_FRAGMENT || !1), + (Wt = s.RETURN_TRUSTED_TYPE || !1), + (Vt = s.FORCE_BODY || !1), + (Kt = !1 !== s.SANITIZE_DOM), + (Ht = s.SANITIZE_NAMED_PROPS || !1), + (Gt = !1 !== s.KEEP_CONTENT), + (Yt = s.IN_PLACE || !1), + (Ct = s.ALLOWED_URI_REGEXP || He), + (lr = s.NAMESPACE || ar), + (Pt = s.CUSTOM_ELEMENT_HANDLING || {}), + s.CUSTOM_ELEMENT_HANDLING && + br(s.CUSTOM_ELEMENT_HANDLING.tagNameCheck) && + (Pt.tagNameCheck = s.CUSTOM_ELEMENT_HANDLING.tagNameCheck), + s.CUSTOM_ELEMENT_HANDLING && + br(s.CUSTOM_ELEMENT_HANDLING.attributeNameCheck) && + (Pt.attributeNameCheck = s.CUSTOM_ELEMENT_HANDLING.attributeNameCheck), + s.CUSTOM_ELEMENT_HANDLING && + 'boolean' == + typeof s.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && + (Pt.allowCustomizedBuiltInElements = + s.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements), + Bt && (Rt = !1), + zt && (Ut = !0), + Xt && + ((Ot = addToSet({}, we)), + (jt = []), + !0 === Xt.html && (addToSet(Ot, pe), addToSet(jt, Se)), + !0 === Xt.svg && (addToSet(Ot, de), addToSet(jt, xe), addToSet(jt, Te)), + !0 === Xt.svgFilters && + (addToSet(Ot, fe), addToSet(jt, xe), addToSet(jt, Te)), + !0 === Xt.mathMl && (addToSet(Ot, be), addToSet(jt, Pe), addToSet(jt, Te))), + s.ADD_TAGS && (Ot === At && (Ot = clone(Ot)), addToSet(Ot, s.ADD_TAGS, gr)), + s.ADD_ATTR && (jt === It && (jt = clone(jt)), addToSet(jt, s.ADD_ATTR, gr)), + s.ADD_URI_SAFE_ATTR && addToSet(rr, s.ADD_URI_SAFE_ATTR, gr), + s.FORBID_CONTENTS && + (Zt === Qt && (Zt = clone(Zt)), addToSet(Zt, s.FORBID_CONTENTS, gr)), + Gt && (Ot['#text'] = !0), + qt && addToSet(Ot, ['html', 'head', 'body']), + Ot.table && (addToSet(Ot, ['tbody']), delete Mt.tbody), + s.TRUSTED_TYPES_POLICY) + ) { + if ('function' != typeof s.TRUSTED_TYPES_POLICY.createHTML) + throw ce( + 'TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.' + ); + if ('function' != typeof s.TRUSTED_TYPES_POLICY.createScriptURL) + throw ce( + 'TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.' + ); + (ct = s.TRUSTED_TYPES_POLICY), (ut = ct.createHTML('')); + } else + void 0 === ct && (ct = st(Ye, _)), + null !== ct && 'string' == typeof ut && (ut = ct.createHTML('')); + w && w(s), (yr = s); + } + }, + Er = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']), + wr = addToSet({}, ['foreignobject', 'annotation-xml']), + Sr = addToSet({}, ['title', 'style', 'font', 'a', 'script']), + xr = addToSet({}, [...de, ...fe, ...ye]), + kr = addToSet({}, [...be, ..._e]), + Cr = function _checkValidNamespace(s) { + let o = lt(s); + (o && o.tagName) || (o = { namespaceURI: lr, tagName: 'template' }); + const i = U(s.tagName), + u = U(o.tagName); + return ( + !!ur[s.namespaceURI] && + (s.namespaceURI === ir + ? o.namespaceURI === ar + ? 'svg' === i + : o.namespaceURI === sr + ? 'svg' === i && ('annotation-xml' === u || Er[u]) + : Boolean(xr[i]) + : s.namespaceURI === sr + ? o.namespaceURI === ar + ? 'math' === i + : o.namespaceURI === ir + ? 'math' === i && wr[u] + : Boolean(kr[i]) + : s.namespaceURI === ar + ? !(o.namespaceURI === ir && !wr[u]) && + !(o.namespaceURI === sr && !Er[u]) && + !kr[i] && + (Sr[i] || !xr[i]) + : !('application/xhtml+xml' !== dr || !ur[s.namespaceURI])) + ); + }, + Or = function _forceRemove(s) { + V(DOMPurify.removed, { element: s }); + try { + lt(s).removeChild(s); + } catch (o) { + ot(s); + } + }, + Ar = function _removeAttribute(s, o) { + try { + V(DOMPurify.removed, { attribute: o.getAttributeNode(s), from: o }); + } catch (s) { + V(DOMPurify.removed, { attribute: null, from: o }); + } + if ((o.removeAttribute(s), 'is' === s && !jt[s])) + if (Ut || zt) + try { + Or(o); + } catch (s) {} + else + try { + o.setAttribute(s, ''); + } catch (s) {} + }, + jr = function _initDocument(s) { + let o = null, + u = null; + if (Vt) s = '' + s; + else { + const o = Y(s, /^[\r\n\t ]+/); + u = o && o[0]; + } + 'application/xhtml+xml' === dr && + lr === ar && + (s = + '' + + s + + ''); + const _ = ct ? ct.createHTML(s) : s; + if (lr === ar) + try { + o = new We().parseFromString(_, dr); + } catch (s) {} + if (!o || !o.documentElement) { + o = pt.createDocument(lr, 'template', null); + try { + o.documentElement.innerHTML = cr ? ut : _; + } catch (s) {} + } + const w = o.body || o.documentElement; + return ( + s && u && w.insertBefore(i.createTextNode(u), w.childNodes[0] || null), + lr === ar ? mt.call(o, qt ? 'html' : 'body')[0] : qt ? o.documentElement : w + ); + }, + Ir = function _createNodeIterator(s) { + return ht.call( + s.ownerDocument || s, + s, + qe.SHOW_ELEMENT | + qe.SHOW_COMMENT | + qe.SHOW_TEXT | + qe.SHOW_PROCESSING_INSTRUCTION | + qe.SHOW_CDATA_SECTION, + null + ); + }, + Pr = function _isClobbered(s) { + return ( + s instanceof ze && + ('string' != typeof s.nodeName || + 'string' != typeof s.textContent || + 'function' != typeof s.removeChild || + !(s.attributes instanceof $e) || + 'function' != typeof s.removeAttribute || + 'function' != typeof s.setAttribute || + 'string' != typeof s.namespaceURI || + 'function' != typeof s.insertBefore || + 'function' != typeof s.hasChildNodes) + ); + }, + Mr = function _isNode(s) { + return 'function' == typeof L && s instanceof L; + }, + Tr = function _executeHook(s, o, i) { + yt[s] && + B(yt[s], (s) => { + s.call(DOMPurify, o, i, yr); + }); + }, + Nr = function _sanitizeElements(s) { + let o = null; + if ((Tr('beforeSanitizeElements', s, null), Pr(s))) return Or(s), !0; + const i = gr(s.nodeName); + if ( + (Tr('uponSanitizeElement', s, { tagName: i, allowedTags: Ot }), + s.hasChildNodes() && + !Mr(s.firstElementChild) && + le(/<[/\w]/g, s.innerHTML) && + le(/<[/\w]/g, s.textContent)) + ) + return Or(s), !0; + if (s.nodeType === rt.progressingInstruction) return Or(s), !0; + if (Ft && s.nodeType === rt.comment && le(/<[/\w]/g, s.data)) return Or(s), !0; + if (!Ot[i] || Mt[i]) { + if (!Mt[i] && Dr(i)) { + if (Pt.tagNameCheck instanceof RegExp && le(Pt.tagNameCheck, i)) return !1; + if (Pt.tagNameCheck instanceof Function && Pt.tagNameCheck(i)) return !1; + } + if (Gt && !Zt[i]) { + const o = lt(s) || s.parentNode, + i = at(s) || s.childNodes; + if (i && o) + for (let u = i.length - 1; u >= 0; --u) { + const _ = et(i[u], !0); + (_.__removalCount = (s.__removalCount || 0) + 1), + o.insertBefore(_, it(s)); + } + } + return Or(s), !0; + } + return s instanceof Re && !Cr(s) + ? (Or(s), !0) + : ('noscript' !== i && 'noembed' !== i && 'noframes' !== i) || + !le(/<\/no(script|embed|frames)/i, s.innerHTML) + ? (Bt && + s.nodeType === rt.text && + ((o = s.textContent), + B([vt, bt, _t], (s) => { + o = Z(o, s, ' '); + }), + s.textContent !== o && + (V(DOMPurify.removed, { element: s.cloneNode() }), + (s.textContent = o))), + Tr('afterSanitizeElements', s, null), + !1) + : (Or(s), !0); + }, + Rr = function _isValidAttribute(s, o, u) { + if (Kt && ('id' === o || 'name' === o) && (u in i || u in vr)) return !1; + if (Rt && !Tt[o] && le(Et, o)); + else if (Nt && le(wt, o)); + else if (!jt[o] || Tt[o]) { + if ( + !( + (Dr(s) && + ((Pt.tagNameCheck instanceof RegExp && le(Pt.tagNameCheck, s)) || + (Pt.tagNameCheck instanceof Function && Pt.tagNameCheck(s))) && + ((Pt.attributeNameCheck instanceof RegExp && + le(Pt.attributeNameCheck, o)) || + (Pt.attributeNameCheck instanceof Function && + Pt.attributeNameCheck(o)))) || + ('is' === o && + Pt.allowCustomizedBuiltInElements && + ((Pt.tagNameCheck instanceof RegExp && le(Pt.tagNameCheck, u)) || + (Pt.tagNameCheck instanceof Function && Pt.tagNameCheck(u)))) + ) + ) + return !1; + } else if (rr[o]); + else if (le(Ct, Z(u, xt, ''))); + else if ( + ('src' !== o && 'xlink:href' !== o && 'href' !== o) || + 'script' === s || + 0 !== ee(u, 'data:') || + !er[s] + ) + if (Dt && !le(St, Z(u, xt, ''))); + else if (u) return !1; + return !0; + }, + Dr = function _isBasicCustomElement(s) { + return 'annotation-xml' !== s && Y(s, kt); + }, + Lr = function _sanitizeAttributes(s) { + Tr('beforeSanitizeAttributes', s, null); + const { attributes: o } = s; + if (!o) return; + const i = { attrName: '', attrValue: '', keepAttr: !0, allowedAttributes: jt }; + let u = o.length; + for (; u--; ) { + const _ = o[u], + { name: w, namespaceURI: x, value: C } = _, + j = gr(w); + let L = 'value' === w ? C : ie(C); + if ( + ((i.attrName = j), + (i.attrValue = L), + (i.keepAttr = !0), + (i.forceKeepAttr = void 0), + Tr('uponSanitizeAttribute', s, i), + (L = i.attrValue), + Ft && le(/((--!?|])>)|<\/(style|title)/i, L)) + ) { + Ar(w, s); + continue; + } + if (i.forceKeepAttr) continue; + if ((Ar(w, s), !i.keepAttr)) continue; + if (!Lt && le(/\/>/i, L)) { + Ar(w, s); + continue; + } + Bt && + B([vt, bt, _t], (s) => { + L = Z(L, s, ' '); + }); + const V = gr(s.nodeName); + if (Rr(V, j, L)) { + if ( + (!Ht || ('id' !== j && 'name' !== j) || (Ar(w, s), (L = Jt + L)), + ct && 'object' == typeof Ye && 'function' == typeof Ye.getAttributeType) + ) + if (x); + else + switch (Ye.getAttributeType(V, j)) { + case 'TrustedHTML': + L = ct.createHTML(L); + break; + case 'TrustedScriptURL': + L = ct.createScriptURL(L); + } + try { + x ? s.setAttributeNS(x, w, L) : s.setAttribute(w, L), + Pr(s) ? Or(s) : $(DOMPurify.removed); + } catch (s) {} + } + } + Tr('afterSanitizeAttributes', s, null); + }, + Br = function _sanitizeShadowDOM(s) { + let o = null; + const i = Ir(s); + for (Tr('beforeSanitizeShadowDOM', s, null); (o = i.nextNode()); ) + Tr('uponSanitizeShadowNode', o, null), + Nr(o) || (o.content instanceof x && _sanitizeShadowDOM(o.content), Lr(o)); + Tr('afterSanitizeShadowDOM', s, null); + }; + return ( + (DOMPurify.sanitize = function (s) { + let o = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, + i = null, + _ = null, + w = null, + C = null; + if (((cr = !s), cr && (s = '\x3c!--\x3e'), 'string' != typeof s && !Mr(s))) { + if ('function' != typeof s.toString) throw ce('toString is not a function'); + if ('string' != typeof (s = s.toString())) + throw ce('dirty is not a string, aborting'); + } + if (!DOMPurify.isSupported) return s; + if ( + ($t || _r(o), (DOMPurify.removed = []), 'string' == typeof s && (Yt = !1), Yt) + ) { + if (s.nodeName) { + const o = gr(s.nodeName); + if (!Ot[o] || Mt[o]) + throw ce('root node is forbidden and cannot be sanitized in-place'); + } + } else if (s instanceof L) + (i = jr('\x3c!----\x3e')), + (_ = i.ownerDocument.importNode(s, !0)), + (_.nodeType === rt.element && 'BODY' === _.nodeName) || 'HTML' === _.nodeName + ? (i = _) + : i.appendChild(_); + else { + if (!Ut && !Bt && !qt && -1 === s.indexOf('<')) + return ct && Wt ? ct.createHTML(s) : s; + if (((i = jr(s)), !i)) return Ut ? null : Wt ? ut : ''; + } + i && Vt && Or(i.firstChild); + const j = Ir(Yt ? s : i); + for (; (w = j.nextNode()); ) + Nr(w) || (w.content instanceof x && Br(w.content), Lr(w)); + if (Yt) return s; + if (Ut) { + if (zt) + for (C = dt.call(i.ownerDocument); i.firstChild; ) + C.appendChild(i.firstChild); + else C = i; + return (jt.shadowroot || jt.shadowrootmode) && (C = gt.call(u, C, !0)), C; + } + let $ = qt ? i.outerHTML : i.innerHTML; + return ( + qt && + Ot['!doctype'] && + i.ownerDocument && + i.ownerDocument.doctype && + i.ownerDocument.doctype.name && + le(Qe, i.ownerDocument.doctype.name) && + ($ = '\n' + $), + Bt && + B([vt, bt, _t], (s) => { + $ = Z($, s, ' '); + }), + ct && Wt ? ct.createHTML($) : $ + ); + }), + (DOMPurify.setConfig = function () { + _r(arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}), + ($t = !0); + }), + (DOMPurify.clearConfig = function () { + (yr = null), ($t = !1); + }), + (DOMPurify.isValidAttribute = function (s, o, i) { + yr || _r({}); + const u = gr(s), + _ = gr(o); + return Rr(u, _, i); + }), + (DOMPurify.addHook = function (s, o) { + 'function' == typeof o && ((yt[s] = yt[s] || []), V(yt[s], o)); + }), + (DOMPurify.removeHook = function (s) { + if (yt[s]) return $(yt[s]); + }), + (DOMPurify.removeHooks = function (s) { + yt[s] && (yt[s] = []); + }), + (DOMPurify.removeAllHooks = function () { + yt = {}; + }), + DOMPurify + ); + } + return createDOMPurify(); + })(); + }, + 78004: (s) => { + 'use strict'; + class SubRange { + constructor(s, o) { + (this.low = s), (this.high = o), (this.length = 1 + o - s); + } + overlaps(s) { + return !(this.high < s.low || this.low > s.high); + } + touches(s) { + return !(this.high + 1 < s.low || this.low - 1 > s.high); + } + add(s) { + return new SubRange(Math.min(this.low, s.low), Math.max(this.high, s.high)); + } + subtract(s) { + return s.low <= this.low && s.high >= this.high + ? [] + : s.low > this.low && s.high < this.high + ? [new SubRange(this.low, s.low - 1), new SubRange(s.high + 1, this.high)] + : s.low <= this.low + ? [new SubRange(s.high + 1, this.high)] + : [new SubRange(this.low, s.low - 1)]; + } + toString() { + return this.low == this.high ? this.low.toString() : this.low + '-' + this.high; + } + } + class DRange { + constructor(s, o) { + (this.ranges = []), (this.length = 0), null != s && this.add(s, o); + } + _update_length() { + this.length = this.ranges.reduce((s, o) => s + o.length, 0); + } + add(s, o) { + var _add = (s) => { + for (var o = 0; o < this.ranges.length && !s.touches(this.ranges[o]); ) o++; + for ( + var i = this.ranges.slice(0, o); + o < this.ranges.length && s.touches(this.ranges[o]); + + ) + (s = s.add(this.ranges[o])), o++; + i.push(s), (this.ranges = i.concat(this.ranges.slice(o))), this._update_length(); + }; + return ( + s instanceof DRange + ? s.ranges.forEach(_add) + : (null == o && (o = s), _add(new SubRange(s, o))), + this + ); + } + subtract(s, o) { + var _subtract = (s) => { + for (var o = 0; o < this.ranges.length && !s.overlaps(this.ranges[o]); ) o++; + for ( + var i = this.ranges.slice(0, o); + o < this.ranges.length && s.overlaps(this.ranges[o]); + + ) + (i = i.concat(this.ranges[o].subtract(s))), o++; + (this.ranges = i.concat(this.ranges.slice(o))), this._update_length(); + }; + return ( + s instanceof DRange + ? s.ranges.forEach(_subtract) + : (null == o && (o = s), _subtract(new SubRange(s, o))), + this + ); + } + intersect(s, o) { + var i = [], + _intersect = (s) => { + for (var o = 0; o < this.ranges.length && !s.overlaps(this.ranges[o]); ) o++; + for (; o < this.ranges.length && s.overlaps(this.ranges[o]); ) { + var u = Math.max(this.ranges[o].low, s.low), + _ = Math.min(this.ranges[o].high, s.high); + i.push(new SubRange(u, _)), o++; + } + }; + return ( + s instanceof DRange + ? s.ranges.forEach(_intersect) + : (null == o && (o = s), _intersect(new SubRange(s, o))), + (this.ranges = i), + this._update_length(), + this + ); + } + index(s) { + for (var o = 0; o < this.ranges.length && this.ranges[o].length <= s; ) + (s -= this.ranges[o].length), o++; + return this.ranges[o].low + s; + } + toString() { + return '[ ' + this.ranges.join(', ') + ' ]'; + } + clone() { + return new DRange(this); + } + numbers() { + return this.ranges.reduce((s, o) => { + for (var i = o.low; i <= o.high; ) s.push(i), i++; + return s; + }, []); + } + subranges() { + return this.ranges.map((s) => ({ + low: s.low, + high: s.high, + length: 1 + s.high - s.low + })); + } + } + s.exports = DRange; + }, + 37007: (s) => { + 'use strict'; + var o, + i = 'object' == typeof Reflect ? Reflect : null, + u = + i && 'function' == typeof i.apply + ? i.apply + : function ReflectApply(s, o, i) { + return Function.prototype.apply.call(s, o, i); + }; + o = + i && 'function' == typeof i.ownKeys + ? i.ownKeys + : Object.getOwnPropertySymbols + ? function ReflectOwnKeys(s) { + return Object.getOwnPropertyNames(s).concat(Object.getOwnPropertySymbols(s)); + } + : function ReflectOwnKeys(s) { + return Object.getOwnPropertyNames(s); + }; + var _ = + Number.isNaN || + function NumberIsNaN(s) { + return s != s; + }; + function EventEmitter() { + EventEmitter.init.call(this); + } + (s.exports = EventEmitter), + (s.exports.once = function once(s, o) { + return new Promise(function (i, u) { + function errorListener(i) { + s.removeListener(o, resolver), u(i); + } + function resolver() { + 'function' == typeof s.removeListener && s.removeListener('error', errorListener), + i([].slice.call(arguments)); + } + eventTargetAgnosticAddListener(s, o, resolver, { once: !0 }), + 'error' !== o && + (function addErrorHandlerIfEventEmitter(s, o, i) { + 'function' == typeof s.on && eventTargetAgnosticAddListener(s, 'error', o, i); + })(s, errorListener, { once: !0 }); + }); + }), + (EventEmitter.EventEmitter = EventEmitter), + (EventEmitter.prototype._events = void 0), + (EventEmitter.prototype._eventsCount = 0), + (EventEmitter.prototype._maxListeners = void 0); + var w = 10; + function checkListener(s) { + if ('function' != typeof s) + throw new TypeError( + 'The "listener" argument must be of type Function. Received type ' + typeof s + ); + } + function _getMaxListeners(s) { + return void 0 === s._maxListeners ? EventEmitter.defaultMaxListeners : s._maxListeners; + } + function _addListener(s, o, i, u) { + var _, w, x; + if ( + (checkListener(i), + void 0 === (w = s._events) + ? ((w = s._events = Object.create(null)), (s._eventsCount = 0)) + : (void 0 !== w.newListener && + (s.emit('newListener', o, i.listener ? i.listener : i), (w = s._events)), + (x = w[o])), + void 0 === x) + ) + (x = w[o] = i), ++s._eventsCount; + else if ( + ('function' == typeof x + ? (x = w[o] = u ? [i, x] : [x, i]) + : u + ? x.unshift(i) + : x.push(i), + (_ = _getMaxListeners(s)) > 0 && x.length > _ && !x.warned) + ) { + x.warned = !0; + var C = new Error( + 'Possible EventEmitter memory leak detected. ' + + x.length + + ' ' + + String(o) + + ' listeners added. Use emitter.setMaxListeners() to increase limit' + ); + (C.name = 'MaxListenersExceededWarning'), + (C.emitter = s), + (C.type = o), + (C.count = x.length), + (function ProcessEmitWarning(s) { + console && console.warn && console.warn(s); + })(C); + } + return s; + } + function onceWrapper() { + if (!this.fired) + return ( + this.target.removeListener(this.type, this.wrapFn), + (this.fired = !0), + 0 === arguments.length + ? this.listener.call(this.target) + : this.listener.apply(this.target, arguments) + ); + } + function _onceWrap(s, o, i) { + var u = { fired: !1, wrapFn: void 0, target: s, type: o, listener: i }, + _ = onceWrapper.bind(u); + return (_.listener = i), (u.wrapFn = _), _; + } + function _listeners(s, o, i) { + var u = s._events; + if (void 0 === u) return []; + var _ = u[o]; + return void 0 === _ + ? [] + : 'function' == typeof _ + ? i + ? [_.listener || _] + : [_] + : i + ? (function unwrapListeners(s) { + for (var o = new Array(s.length), i = 0; i < o.length; ++i) + o[i] = s[i].listener || s[i]; + return o; + })(_) + : arrayClone(_, _.length); + } + function listenerCount(s) { + var o = this._events; + if (void 0 !== o) { + var i = o[s]; + if ('function' == typeof i) return 1; + if (void 0 !== i) return i.length; + } + return 0; + } + function arrayClone(s, o) { + for (var i = new Array(o), u = 0; u < o; ++u) i[u] = s[u]; + return i; + } + function eventTargetAgnosticAddListener(s, o, i, u) { + if ('function' == typeof s.on) u.once ? s.once(o, i) : s.on(o, i); + else { + if ('function' != typeof s.addEventListener) + throw new TypeError( + 'The "emitter" argument must be of type EventEmitter. Received type ' + typeof s + ); + s.addEventListener(o, function wrapListener(_) { + u.once && s.removeEventListener(o, wrapListener), i(_); + }); + } + } + Object.defineProperty(EventEmitter, 'defaultMaxListeners', { + enumerable: !0, + get: function () { + return w; + }, + set: function (s) { + if ('number' != typeof s || s < 0 || _(s)) + throw new RangeError( + 'The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + + s + + '.' + ); + w = s; + } + }), + (EventEmitter.init = function () { + (void 0 !== this._events && this._events !== Object.getPrototypeOf(this)._events) || + ((this._events = Object.create(null)), (this._eventsCount = 0)), + (this._maxListeners = this._maxListeners || void 0); + }), + (EventEmitter.prototype.setMaxListeners = function setMaxListeners(s) { + if ('number' != typeof s || s < 0 || _(s)) + throw new RangeError( + 'The value of "n" is out of range. It must be a non-negative number. Received ' + + s + + '.' + ); + return (this._maxListeners = s), this; + }), + (EventEmitter.prototype.getMaxListeners = function getMaxListeners() { + return _getMaxListeners(this); + }), + (EventEmitter.prototype.emit = function emit(s) { + for (var o = [], i = 1; i < arguments.length; i++) o.push(arguments[i]); + var _ = 'error' === s, + w = this._events; + if (void 0 !== w) _ = _ && void 0 === w.error; + else if (!_) return !1; + if (_) { + var x; + if ((o.length > 0 && (x = o[0]), x instanceof Error)) throw x; + var C = new Error('Unhandled error.' + (x ? ' (' + x.message + ')' : '')); + throw ((C.context = x), C); + } + var j = w[s]; + if (void 0 === j) return !1; + if ('function' == typeof j) u(j, this, o); + else { + var L = j.length, + B = arrayClone(j, L); + for (i = 0; i < L; ++i) u(B[i], this, o); + } + return !0; + }), + (EventEmitter.prototype.addListener = function addListener(s, o) { + return _addListener(this, s, o, !1); + }), + (EventEmitter.prototype.on = EventEmitter.prototype.addListener), + (EventEmitter.prototype.prependListener = function prependListener(s, o) { + return _addListener(this, s, o, !0); + }), + (EventEmitter.prototype.once = function once(s, o) { + return checkListener(o), this.on(s, _onceWrap(this, s, o)), this; + }), + (EventEmitter.prototype.prependOnceListener = function prependOnceListener(s, o) { + return checkListener(o), this.prependListener(s, _onceWrap(this, s, o)), this; + }), + (EventEmitter.prototype.removeListener = function removeListener(s, o) { + var i, u, _, w, x; + if ((checkListener(o), void 0 === (u = this._events))) return this; + if (void 0 === (i = u[s])) return this; + if (i === o || i.listener === o) + 0 == --this._eventsCount + ? (this._events = Object.create(null)) + : (delete u[s], + u.removeListener && this.emit('removeListener', s, i.listener || o)); + else if ('function' != typeof i) { + for (_ = -1, w = i.length - 1; w >= 0; w--) + if (i[w] === o || i[w].listener === o) { + (x = i[w].listener), (_ = w); + break; + } + if (_ < 0) return this; + 0 === _ + ? i.shift() + : (function spliceOne(s, o) { + for (; o + 1 < s.length; o++) s[o] = s[o + 1]; + s.pop(); + })(i, _), + 1 === i.length && (u[s] = i[0]), + void 0 !== u.removeListener && this.emit('removeListener', s, x || o); + } + return this; + }), + (EventEmitter.prototype.off = EventEmitter.prototype.removeListener), + (EventEmitter.prototype.removeAllListeners = function removeAllListeners(s) { + var o, i, u; + if (void 0 === (i = this._events)) return this; + if (void 0 === i.removeListener) + return ( + 0 === arguments.length + ? ((this._events = Object.create(null)), (this._eventsCount = 0)) + : void 0 !== i[s] && + (0 == --this._eventsCount + ? (this._events = Object.create(null)) + : delete i[s]), + this + ); + if (0 === arguments.length) { + var _, + w = Object.keys(i); + for (u = 0; u < w.length; ++u) + 'removeListener' !== (_ = w[u]) && this.removeAllListeners(_); + return ( + this.removeAllListeners('removeListener'), + (this._events = Object.create(null)), + (this._eventsCount = 0), + this + ); + } + if ('function' == typeof (o = i[s])) this.removeListener(s, o); + else if (void 0 !== o) + for (u = o.length - 1; u >= 0; u--) this.removeListener(s, o[u]); + return this; + }), + (EventEmitter.prototype.listeners = function listeners(s) { + return _listeners(this, s, !0); + }), + (EventEmitter.prototype.rawListeners = function rawListeners(s) { + return _listeners(this, s, !1); + }), + (EventEmitter.listenerCount = function (s, o) { + return 'function' == typeof s.listenerCount + ? s.listenerCount(o) + : listenerCount.call(s, o); + }), + (EventEmitter.prototype.listenerCount = listenerCount), + (EventEmitter.prototype.eventNames = function eventNames() { + return this._eventsCount > 0 ? o(this._events) : []; + }); + }, + 85587: (s, o, i) => { + 'use strict'; + var u = i(26311), + _ = create(Error); + function create(s) { + return (FormattedError.displayName = s.displayName || s.name), FormattedError; + function FormattedError(o) { + return o && (o = u.apply(null, arguments)), new s(o); + } + } + (s.exports = _), + (_.eval = create(EvalError)), + (_.range = create(RangeError)), + (_.reference = create(ReferenceError)), + (_.syntax = create(SyntaxError)), + (_.type = create(TypeError)), + (_.uri = create(URIError)), + (_.create = create); + }, + 26311: (s) => { + !(function () { + var o; + function format(s) { + for ( + var o, + i, + u, + _, + w = 1, + x = [].slice.call(arguments), + C = 0, + j = s.length, + L = '', + B = !1, + $ = !1, + nextArg = function () { + return x[w++]; + }, + slurpNumber = function () { + for (var i = ''; /\d/.test(s[C]); ) (i += s[C++]), (o = s[C]); + return i.length > 0 ? parseInt(i) : null; + }; + C < j; + ++C + ) + if (((o = s[C]), B)) + switch ( + ((B = !1), + '.' == o + ? (($ = !1), (o = s[++C])) + : '0' == o && '.' == s[C + 1] + ? (($ = !0), (o = s[(C += 2)])) + : ($ = !0), + (_ = slurpNumber()), + o) + ) { + case 'b': + L += parseInt(nextArg(), 10).toString(2); + break; + case 'c': + L += + 'string' == typeof (i = nextArg()) || i instanceof String + ? i + : String.fromCharCode(parseInt(i, 10)); + break; + case 'd': + L += parseInt(nextArg(), 10); + break; + case 'f': + (u = String(parseFloat(nextArg()).toFixed(_ || 6))), + (L += $ ? u : u.replace(/^0/, '')); + break; + case 'j': + L += JSON.stringify(nextArg()); + break; + case 'o': + L += '0' + parseInt(nextArg(), 10).toString(8); + break; + case 's': + L += nextArg(); + break; + case 'x': + L += '0x' + parseInt(nextArg(), 10).toString(16); + break; + case 'X': + L += '0x' + parseInt(nextArg(), 10).toString(16).toUpperCase(); + break; + default: + L += o; + } + else '%' === o ? (B = !0) : (L += o); + return L; + } + ((o = s.exports = format).format = format), + (o.vsprintf = function vsprintf(s, o) { + return format.apply(null, [s].concat(o)); + }), + 'undefined' != typeof console && + 'function' == typeof console.log && + (o.printf = function printf() { + console.log(format.apply(null, arguments)); + }); + })(); + }, + 45981: (s) => { + function deepFreeze(s) { + return ( + s instanceof Map + ? (s.clear = + s.delete = + s.set = + function () { + throw new Error('map is read-only'); + }) + : s instanceof Set && + (s.add = + s.clear = + s.delete = + function () { + throw new Error('set is read-only'); + }), + Object.freeze(s), + Object.getOwnPropertyNames(s).forEach(function (o) { + var i = s[o]; + 'object' != typeof i || Object.isFrozen(i) || deepFreeze(i); + }), + s + ); + } + var o = deepFreeze, + i = deepFreeze; + o.default = i; + class Response { + constructor(s) { + void 0 === s.data && (s.data = {}), (this.data = s.data), (this.isMatchIgnored = !1); + } + ignoreMatch() { + this.isMatchIgnored = !0; + } + } + function escapeHTML(s) { + return s + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); + } + function inherit(s, ...o) { + const i = Object.create(null); + for (const o in s) i[o] = s[o]; + return ( + o.forEach(function (s) { + for (const o in s) i[o] = s[o]; + }), + i + ); + } + const emitsWrappingTags = (s) => !!s.kind; + class HTMLRenderer { + constructor(s, o) { + (this.buffer = ''), (this.classPrefix = o.classPrefix), s.walk(this); + } + addText(s) { + this.buffer += escapeHTML(s); + } + openNode(s) { + if (!emitsWrappingTags(s)) return; + let o = s.kind; + s.sublanguage || (o = `${this.classPrefix}${o}`), this.span(o); + } + closeNode(s) { + emitsWrappingTags(s) && (this.buffer += ''); + } + value() { + return this.buffer; + } + span(s) { + this.buffer += ``; + } + } + class TokenTree { + constructor() { + (this.rootNode = { children: [] }), (this.stack = [this.rootNode]); + } + get top() { + return this.stack[this.stack.length - 1]; + } + get root() { + return this.rootNode; + } + add(s) { + this.top.children.push(s); + } + openNode(s) { + const o = { kind: s, children: [] }; + this.add(o), this.stack.push(o); + } + closeNode() { + if (this.stack.length > 1) return this.stack.pop(); + } + closeAllNodes() { + for (; this.closeNode(); ); + } + toJSON() { + return JSON.stringify(this.rootNode, null, 4); + } + walk(s) { + return this.constructor._walk(s, this.rootNode); + } + static _walk(s, o) { + return ( + 'string' == typeof o + ? s.addText(o) + : o.children && + (s.openNode(o), o.children.forEach((o) => this._walk(s, o)), s.closeNode(o)), + s + ); + } + static _collapse(s) { + 'string' != typeof s && + s.children && + (s.children.every((s) => 'string' == typeof s) + ? (s.children = [s.children.join('')]) + : s.children.forEach((s) => { + TokenTree._collapse(s); + })); + } + } + class TokenTreeEmitter extends TokenTree { + constructor(s) { + super(), (this.options = s); + } + addKeyword(s, o) { + '' !== s && (this.openNode(o), this.addText(s), this.closeNode()); + } + addText(s) { + '' !== s && this.add(s); + } + addSublanguage(s, o) { + const i = s.root; + (i.kind = o), (i.sublanguage = !0), this.add(i); + } + toHTML() { + return new HTMLRenderer(this, this.options).value(); + } + finalize() { + return !0; + } + } + function source(s) { + return s ? ('string' == typeof s ? s : s.source) : null; + } + const u = /\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./; + const _ = '[a-zA-Z]\\w*', + w = '[a-zA-Z_]\\w*', + x = '\\b\\d+(\\.\\d+)?', + C = '(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)', + j = '\\b(0b[01]+)', + L = { begin: '\\\\[\\s\\S]', relevance: 0 }, + B = { className: 'string', begin: "'", end: "'", illegal: '\\n', contains: [L] }, + $ = { className: 'string', begin: '"', end: '"', illegal: '\\n', contains: [L] }, + V = { + begin: + /\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/ + }, + COMMENT = function (s, o, i = {}) { + const u = inherit({ className: 'comment', begin: s, end: o, contains: [] }, i); + return ( + u.contains.push(V), + u.contains.push({ + className: 'doctag', + begin: '(?:TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):', + relevance: 0 + }), + u + ); + }, + U = COMMENT('//', '$'), + z = COMMENT('/\\*', '\\*/'), + Y = COMMENT('#', '$'), + Z = { className: 'number', begin: x, relevance: 0 }, + ee = { className: 'number', begin: C, relevance: 0 }, + ie = { className: 'number', begin: j, relevance: 0 }, + ae = { + className: 'number', + begin: + x + + '(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?', + relevance: 0 + }, + le = { + begin: /(?=\/[^/\n]*\/)/, + contains: [ + { + className: 'regexp', + begin: /\//, + end: /\/[gimuy]*/, + illegal: /\n/, + contains: [L, { begin: /\[/, end: /\]/, relevance: 0, contains: [L] }] + } + ] + }, + ce = { className: 'title', begin: _, relevance: 0 }, + pe = { className: 'title', begin: w, relevance: 0 }, + de = { begin: '\\.\\s*' + w, relevance: 0 }; + var fe = Object.freeze({ + __proto__: null, + MATCH_NOTHING_RE: /\b\B/, + IDENT_RE: _, + UNDERSCORE_IDENT_RE: w, + NUMBER_RE: x, + C_NUMBER_RE: C, + BINARY_NUMBER_RE: j, + RE_STARTERS_RE: + '!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~', + SHEBANG: (s = {}) => { + const o = /^#![ ]*\//; + return ( + s.binary && + (s.begin = (function concat(...s) { + return s.map((s) => source(s)).join(''); + })(o, /.*\b/, s.binary, /\b.*/)), + inherit( + { + className: 'meta', + begin: o, + end: /$/, + relevance: 0, + 'on:begin': (s, o) => { + 0 !== s.index && o.ignoreMatch(); + } + }, + s + ) + ); + }, + BACKSLASH_ESCAPE: L, + APOS_STRING_MODE: B, + QUOTE_STRING_MODE: $, + PHRASAL_WORDS_MODE: V, + COMMENT, + C_LINE_COMMENT_MODE: U, + C_BLOCK_COMMENT_MODE: z, + HASH_COMMENT_MODE: Y, + NUMBER_MODE: Z, + C_NUMBER_MODE: ee, + BINARY_NUMBER_MODE: ie, + CSS_NUMBER_MODE: ae, + REGEXP_MODE: le, + TITLE_MODE: ce, + UNDERSCORE_TITLE_MODE: pe, + METHOD_GUARD: de, + END_SAME_AS_BEGIN: function (s) { + return Object.assign(s, { + 'on:begin': (s, o) => { + o.data._beginMatch = s[1]; + }, + 'on:end': (s, o) => { + o.data._beginMatch !== s[1] && o.ignoreMatch(); + } + }); + } + }); + function skipIfhasPrecedingDot(s, o) { + '.' === s.input[s.index - 1] && o.ignoreMatch(); + } + function beginKeywords(s, o) { + o && + s.beginKeywords && + ((s.begin = '\\b(' + s.beginKeywords.split(' ').join('|') + ')(?!\\.)(?=\\b|\\s)'), + (s.__beforeBegin = skipIfhasPrecedingDot), + (s.keywords = s.keywords || s.beginKeywords), + delete s.beginKeywords, + void 0 === s.relevance && (s.relevance = 0)); + } + function compileIllegal(s, o) { + Array.isArray(s.illegal) && + (s.illegal = (function either(...s) { + return '(' + s.map((s) => source(s)).join('|') + ')'; + })(...s.illegal)); + } + function compileMatch(s, o) { + if (s.match) { + if (s.begin || s.end) throw new Error('begin & end are not supported with match'); + (s.begin = s.match), delete s.match; + } + } + function compileRelevance(s, o) { + void 0 === s.relevance && (s.relevance = 1); + } + const ye = [ + 'of', + 'and', + 'for', + 'in', + 'not', + 'or', + 'if', + 'then', + 'parent', + 'list', + 'value' + ]; + function compileKeywords(s, o, i = 'keyword') { + const u = {}; + return ( + 'string' == typeof s + ? compileList(i, s.split(' ')) + : Array.isArray(s) + ? compileList(i, s) + : Object.keys(s).forEach(function (i) { + Object.assign(u, compileKeywords(s[i], o, i)); + }), + u + ); + function compileList(s, i) { + o && (i = i.map((s) => s.toLowerCase())), + i.forEach(function (o) { + const i = o.split('|'); + u[i[0]] = [s, scoreForKeyword(i[0], i[1])]; + }); + } + } + function scoreForKeyword(s, o) { + return o + ? Number(o) + : (function commonKeyword(s) { + return ye.includes(s.toLowerCase()); + })(s) + ? 0 + : 1; + } + function compileLanguage(s, { plugins: o }) { + function langRe(o, i) { + return new RegExp(source(o), 'm' + (s.case_insensitive ? 'i' : '') + (i ? 'g' : '')); + } + class MultiRegex { + constructor() { + (this.matchIndexes = {}), + (this.regexes = []), + (this.matchAt = 1), + (this.position = 0); + } + addRule(s, o) { + (o.position = this.position++), + (this.matchIndexes[this.matchAt] = o), + this.regexes.push([o, s]), + (this.matchAt += + (function countMatchGroups(s) { + return new RegExp(s.toString() + '|').exec('').length - 1; + })(s) + 1); + } + compile() { + 0 === this.regexes.length && (this.exec = () => null); + const s = this.regexes.map((s) => s[1]); + (this.matcherRe = langRe( + (function join(s, o = '|') { + let i = 0; + return s + .map((s) => { + i += 1; + const o = i; + let _ = source(s), + w = ''; + for (; _.length > 0; ) { + const s = u.exec(_); + if (!s) { + w += _; + break; + } + (w += _.substring(0, s.index)), + (_ = _.substring(s.index + s[0].length)), + '\\' === s[0][0] && s[1] + ? (w += '\\' + String(Number(s[1]) + o)) + : ((w += s[0]), '(' === s[0] && i++); + } + return w; + }) + .map((s) => `(${s})`) + .join(o); + })(s), + !0 + )), + (this.lastIndex = 0); + } + exec(s) { + this.matcherRe.lastIndex = this.lastIndex; + const o = this.matcherRe.exec(s); + if (!o) return null; + const i = o.findIndex((s, o) => o > 0 && void 0 !== s), + u = this.matchIndexes[i]; + return o.splice(0, i), Object.assign(o, u); + } + } + class ResumableMultiRegex { + constructor() { + (this.rules = []), + (this.multiRegexes = []), + (this.count = 0), + (this.lastIndex = 0), + (this.regexIndex = 0); + } + getMatcher(s) { + if (this.multiRegexes[s]) return this.multiRegexes[s]; + const o = new MultiRegex(); + return ( + this.rules.slice(s).forEach(([s, i]) => o.addRule(s, i)), + o.compile(), + (this.multiRegexes[s] = o), + o + ); + } + resumingScanAtSamePosition() { + return 0 !== this.regexIndex; + } + considerAll() { + this.regexIndex = 0; + } + addRule(s, o) { + this.rules.push([s, o]), 'begin' === o.type && this.count++; + } + exec(s) { + const o = this.getMatcher(this.regexIndex); + o.lastIndex = this.lastIndex; + let i = o.exec(s); + if (this.resumingScanAtSamePosition()) + if (i && i.index === this.lastIndex); + else { + const o = this.getMatcher(0); + (o.lastIndex = this.lastIndex + 1), (i = o.exec(s)); + } + return ( + i && + ((this.regexIndex += i.position + 1), + this.regexIndex === this.count && this.considerAll()), + i + ); + } + } + if ( + (s.compilerExtensions || (s.compilerExtensions = []), + s.contains && s.contains.includes('self')) + ) + throw new Error( + 'ERR: contains `self` is not supported at the top-level of a language. See documentation.' + ); + return ( + (s.classNameAliases = inherit(s.classNameAliases || {})), + (function compileMode(o, i) { + const u = o; + if (o.isCompiled) return u; + [compileMatch].forEach((s) => s(o, i)), + s.compilerExtensions.forEach((s) => s(o, i)), + (o.__beforeBegin = null), + [beginKeywords, compileIllegal, compileRelevance].forEach((s) => s(o, i)), + (o.isCompiled = !0); + let _ = null; + if ( + ('object' == typeof o.keywords && + ((_ = o.keywords.$pattern), delete o.keywords.$pattern), + o.keywords && (o.keywords = compileKeywords(o.keywords, s.case_insensitive)), + o.lexemes && _) + ) + throw new Error( + 'ERR: Prefer `keywords.$pattern` to `mode.lexemes`, BOTH are not allowed. (see mode reference) ' + ); + return ( + (_ = _ || o.lexemes || /\w+/), + (u.keywordPatternRe = langRe(_, !0)), + i && + (o.begin || (o.begin = /\B|\b/), + (u.beginRe = langRe(o.begin)), + o.endSameAsBegin && (o.end = o.begin), + o.end || o.endsWithParent || (o.end = /\B|\b/), + o.end && (u.endRe = langRe(o.end)), + (u.terminatorEnd = source(o.end) || ''), + o.endsWithParent && + i.terminatorEnd && + (u.terminatorEnd += (o.end ? '|' : '') + i.terminatorEnd)), + o.illegal && (u.illegalRe = langRe(o.illegal)), + o.contains || (o.contains = []), + (o.contains = [].concat( + ...o.contains.map(function (s) { + return (function expandOrCloneMode(s) { + s.variants && + !s.cachedVariants && + (s.cachedVariants = s.variants.map(function (o) { + return inherit(s, { variants: null }, o); + })); + if (s.cachedVariants) return s.cachedVariants; + if (dependencyOnParent(s)) + return inherit(s, { starts: s.starts ? inherit(s.starts) : null }); + if (Object.isFrozen(s)) return inherit(s); + return s; + })('self' === s ? o : s); + }) + )), + o.contains.forEach(function (s) { + compileMode(s, u); + }), + o.starts && compileMode(o.starts, i), + (u.matcher = (function buildModeRegex(s) { + const o = new ResumableMultiRegex(); + return ( + s.contains.forEach((s) => o.addRule(s.begin, { rule: s, type: 'begin' })), + s.terminatorEnd && o.addRule(s.terminatorEnd, { type: 'end' }), + s.illegal && o.addRule(s.illegal, { type: 'illegal' }), + o + ); + })(u)), + u + ); + })(s) + ); + } + function dependencyOnParent(s) { + return !!s && (s.endsWithParent || dependencyOnParent(s.starts)); + } + function BuildVuePlugin(s) { + const o = { + props: ['language', 'code', 'autodetect'], + data: function () { + return { detectedLanguage: '', unknownLanguage: !1 }; + }, + computed: { + className() { + return this.unknownLanguage ? '' : 'hljs ' + this.detectedLanguage; + }, + highlighted() { + if (!this.autoDetect && !s.getLanguage(this.language)) + return ( + console.warn( + `The language "${this.language}" you specified could not be found.` + ), + (this.unknownLanguage = !0), + escapeHTML(this.code) + ); + let o = {}; + return ( + this.autoDetect + ? ((o = s.highlightAuto(this.code)), (this.detectedLanguage = o.language)) + : ((o = s.highlight(this.language, this.code, this.ignoreIllegals)), + (this.detectedLanguage = this.language)), + o.value + ); + }, + autoDetect() { + return ( + !this.language || + (function hasValueOrEmptyAttribute(s) { + return Boolean(s || '' === s); + })(this.autodetect) + ); + }, + ignoreIllegals: () => !0 + }, + render(s) { + return s('pre', {}, [ + s('code', { class: this.className, domProps: { innerHTML: this.highlighted } }) + ]); + } + }; + return { + Component: o, + VuePlugin: { + install(s) { + s.component('highlightjs', o); + } + } + }; + } + const be = { + 'after:highlightElement': ({ el: s, result: o, text: i }) => { + const u = nodeStream(s); + if (!u.length) return; + const _ = document.createElement('div'); + (_.innerHTML = o.value), + (o.value = (function mergeStreams(s, o, i) { + let u = 0, + _ = ''; + const w = []; + function selectStream() { + return s.length && o.length + ? s[0].offset !== o[0].offset + ? s[0].offset < o[0].offset + ? s + : o + : 'start' === o[0].event + ? s + : o + : s.length + ? s + : o; + } + function open(s) { + function attributeString(s) { + return ' ' + s.nodeName + '="' + escapeHTML(s.value) + '"'; + } + _ += '<' + tag(s) + [].map.call(s.attributes, attributeString).join('') + '>'; + } + function close(s) { + _ += ''; + } + function render(s) { + ('start' === s.event ? open : close)(s.node); + } + for (; s.length || o.length; ) { + let o = selectStream(); + if ( + ((_ += escapeHTML(i.substring(u, o[0].offset))), (u = o[0].offset), o === s) + ) { + w.reverse().forEach(close); + do { + render(o.splice(0, 1)[0]), (o = selectStream()); + } while (o === s && o.length && o[0].offset === u); + w.reverse().forEach(open); + } else + 'start' === o[0].event ? w.push(o[0].node) : w.pop(), + render(o.splice(0, 1)[0]); + } + return _ + escapeHTML(i.substr(u)); + })(u, nodeStream(_), i)); + } + }; + function tag(s) { + return s.nodeName.toLowerCase(); + } + function nodeStream(s) { + const o = []; + return ( + (function _nodeStream(s, i) { + for (let u = s.firstChild; u; u = u.nextSibling) + 3 === u.nodeType + ? (i += u.nodeValue.length) + : 1 === u.nodeType && + (o.push({ event: 'start', offset: i, node: u }), + (i = _nodeStream(u, i)), + tag(u).match(/br|hr|img|input/) || + o.push({ event: 'stop', offset: i, node: u })); + return i; + })(s, 0), + o + ); + } + const _e = {}, + error = (s) => { + console.error(s); + }, + warn = (s, ...o) => { + console.log(`WARN: ${s}`, ...o); + }, + deprecated = (s, o) => { + _e[`${s}/${o}`] || + (console.log(`Deprecated as of ${s}. ${o}`), (_e[`${s}/${o}`] = !0)); + }, + we = escapeHTML, + Se = inherit, + xe = Symbol('nomatch'); + var Pe = (function (s) { + const i = Object.create(null), + u = Object.create(null), + _ = []; + let w = !0; + const x = /(^(<[^>]+>|\t|)+|\n)/gm, + C = + "Could not find the language '{}', did you forget to load/include a language module?", + j = { disableAutodetect: !0, name: 'Plain text', contains: [] }; + let L = { + noHighlightRe: /^(no-?highlight)$/i, + languageDetectRe: /\blang(?:uage)?-([\w-]+)\b/i, + classPrefix: 'hljs-', + tabReplace: null, + useBR: !1, + languages: null, + __emitter: TokenTreeEmitter + }; + function shouldNotHighlight(s) { + return L.noHighlightRe.test(s); + } + function highlight(s, o, i, u) { + let _ = '', + w = ''; + 'object' == typeof o + ? ((_ = s), (i = o.ignoreIllegals), (w = o.language), (u = void 0)) + : (deprecated('10.7.0', 'highlight(lang, code, ...args) has been deprecated.'), + deprecated( + '10.7.0', + 'Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277' + ), + (w = s), + (_ = o)); + const x = { code: _, language: w }; + fire('before:highlight', x); + const C = x.result ? x.result : _highlight(x.language, x.code, i, u); + return (C.code = x.code), fire('after:highlight', C), C; + } + function _highlight(s, o, u, x) { + function keywordData(s, o) { + const i = B.case_insensitive ? o[0].toLowerCase() : o[0]; + return Object.prototype.hasOwnProperty.call(s.keywords, i) && s.keywords[i]; + } + function processBuffer() { + null != U.subLanguage + ? (function processSubLanguage() { + if ('' === Z) return; + let s = null; + if ('string' == typeof U.subLanguage) { + if (!i[U.subLanguage]) return void Y.addText(Z); + (s = _highlight(U.subLanguage, Z, !0, z[U.subLanguage])), + (z[U.subLanguage] = s.top); + } else s = highlightAuto(Z, U.subLanguage.length ? U.subLanguage : null); + U.relevance > 0 && (ee += s.relevance), + Y.addSublanguage(s.emitter, s.language); + })() + : (function processKeywords() { + if (!U.keywords) return void Y.addText(Z); + let s = 0; + U.keywordPatternRe.lastIndex = 0; + let o = U.keywordPatternRe.exec(Z), + i = ''; + for (; o; ) { + i += Z.substring(s, o.index); + const u = keywordData(U, o); + if (u) { + const [s, _] = u; + if ((Y.addText(i), (i = ''), (ee += _), s.startsWith('_'))) i += o[0]; + else { + const i = B.classNameAliases[s] || s; + Y.addKeyword(o[0], i); + } + } else i += o[0]; + (s = U.keywordPatternRe.lastIndex), (o = U.keywordPatternRe.exec(Z)); + } + (i += Z.substr(s)), Y.addText(i); + })(), + (Z = ''); + } + function startNewMode(s) { + return ( + s.className && Y.openNode(B.classNameAliases[s.className] || s.className), + (U = Object.create(s, { parent: { value: U } })), + U + ); + } + function endOfMode(s, o, i) { + let u = (function startsWith(s, o) { + const i = s && s.exec(o); + return i && 0 === i.index; + })(s.endRe, i); + if (u) { + if (s['on:end']) { + const i = new Response(s); + s['on:end'](o, i), i.isMatchIgnored && (u = !1); + } + if (u) { + for (; s.endsParent && s.parent; ) s = s.parent; + return s; + } + } + if (s.endsWithParent) return endOfMode(s.parent, o, i); + } + function doIgnore(s) { + return 0 === U.matcher.regexIndex ? ((Z += s[0]), 1) : ((le = !0), 0); + } + function doBeginMatch(s) { + const o = s[0], + i = s.rule, + u = new Response(i), + _ = [i.__beforeBegin, i['on:begin']]; + for (const i of _) if (i && (i(s, u), u.isMatchIgnored)) return doIgnore(o); + return ( + i && + i.endSameAsBegin && + (i.endRe = (function escape(s) { + return new RegExp(s.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&'), 'm'); + })(o)), + i.skip + ? (Z += o) + : (i.excludeBegin && (Z += o), + processBuffer(), + i.returnBegin || i.excludeBegin || (Z = o)), + startNewMode(i), + i.returnBegin ? 0 : o.length + ); + } + function doEndMatch(s) { + const i = s[0], + u = o.substr(s.index), + _ = endOfMode(U, s, u); + if (!_) return xe; + const w = U; + w.skip + ? (Z += i) + : (w.returnEnd || w.excludeEnd || (Z += i), + processBuffer(), + w.excludeEnd && (Z = i)); + do { + U.className && Y.closeNode(), + U.skip || U.subLanguage || (ee += U.relevance), + (U = U.parent); + } while (U !== _.parent); + return ( + _.starts && + (_.endSameAsBegin && (_.starts.endRe = _.endRe), startNewMode(_.starts)), + w.returnEnd ? 0 : i.length + ); + } + let j = {}; + function processLexeme(i, _) { + const x = _ && _[0]; + if (((Z += i), null == x)) return processBuffer(), 0; + if ('begin' === j.type && 'end' === _.type && j.index === _.index && '' === x) { + if (((Z += o.slice(_.index, _.index + 1)), !w)) { + const o = new Error('0 width match regex'); + throw ((o.languageName = s), (o.badRule = j.rule), o); + } + return 1; + } + if (((j = _), 'begin' === _.type)) return doBeginMatch(_); + if ('illegal' === _.type && !u) { + const s = new Error( + 'Illegal lexeme "' + x + '" for mode "' + (U.className || '') + '"' + ); + throw ((s.mode = U), s); + } + if ('end' === _.type) { + const s = doEndMatch(_); + if (s !== xe) return s; + } + if ('illegal' === _.type && '' === x) return 1; + if (ae > 1e5 && ae > 3 * _.index) { + throw new Error('potential infinite loop, way more iterations than matches'); + } + return (Z += x), x.length; + } + const B = getLanguage(s); + if (!B) throw (error(C.replace('{}', s)), new Error('Unknown language: "' + s + '"')); + const $ = compileLanguage(B, { plugins: _ }); + let V = '', + U = x || $; + const z = {}, + Y = new L.__emitter(L); + !(function processContinuations() { + const s = []; + for (let o = U; o !== B; o = o.parent) o.className && s.unshift(o.className); + s.forEach((s) => Y.openNode(s)); + })(); + let Z = '', + ee = 0, + ie = 0, + ae = 0, + le = !1; + try { + for (U.matcher.considerAll(); ; ) { + ae++, le ? (le = !1) : U.matcher.considerAll(), (U.matcher.lastIndex = ie); + const s = U.matcher.exec(o); + if (!s) break; + const i = processLexeme(o.substring(ie, s.index), s); + ie = s.index + i; + } + return ( + processLexeme(o.substr(ie)), + Y.closeAllNodes(), + Y.finalize(), + (V = Y.toHTML()), + { + relevance: Math.floor(ee), + value: V, + language: s, + illegal: !1, + emitter: Y, + top: U + } + ); + } catch (i) { + if (i.message && i.message.includes('Illegal')) + return { + illegal: !0, + illegalBy: { + msg: i.message, + context: o.slice(ie - 100, ie + 100), + mode: i.mode + }, + sofar: V, + relevance: 0, + value: we(o), + emitter: Y + }; + if (w) + return { + illegal: !1, + relevance: 0, + value: we(o), + emitter: Y, + language: s, + top: U, + errorRaised: i + }; + throw i; + } + } + function highlightAuto(s, o) { + o = o || L.languages || Object.keys(i); + const u = (function justTextHighlightResult(s) { + const o = { + relevance: 0, + emitter: new L.__emitter(L), + value: we(s), + illegal: !1, + top: j + }; + return o.emitter.addText(s), o; + })(s), + _ = o + .filter(getLanguage) + .filter(autoDetection) + .map((o) => _highlight(o, s, !1)); + _.unshift(u); + const w = _.sort((s, o) => { + if (s.relevance !== o.relevance) return o.relevance - s.relevance; + if (s.language && o.language) { + if (getLanguage(s.language).supersetOf === o.language) return 1; + if (getLanguage(o.language).supersetOf === s.language) return -1; + } + return 0; + }), + [x, C] = w, + B = x; + return (B.second_best = C), B; + } + const B = { + 'before:highlightElement': ({ el: s }) => { + L.useBR && + (s.innerHTML = s.innerHTML.replace(/\n/g, '').replace(//g, '\n')); + }, + 'after:highlightElement': ({ result: s }) => { + L.useBR && (s.value = s.value.replace(/\n/g, '
        ')); + } + }, + $ = /^(<[^>]+>|\t)+/gm, + V = { + 'after:highlightElement': ({ result: s }) => { + L.tabReplace && + (s.value = s.value.replace($, (s) => s.replace(/\t/g, L.tabReplace))); + } + }; + function highlightElement(s) { + let o = null; + const i = (function blockLanguage(s) { + let o = s.className + ' '; + o += s.parentNode ? s.parentNode.className : ''; + const i = L.languageDetectRe.exec(o); + if (i) { + const o = getLanguage(i[1]); + return ( + o || + (warn(C.replace('{}', i[1])), + warn('Falling back to no-highlight mode for this block.', s)), + o ? i[1] : 'no-highlight' + ); + } + return o.split(/\s+/).find((s) => shouldNotHighlight(s) || getLanguage(s)); + })(s); + if (shouldNotHighlight(i)) return; + fire('before:highlightElement', { el: s, language: i }), (o = s); + const _ = o.textContent, + w = i ? highlight(_, { language: i, ignoreIllegals: !0 }) : highlightAuto(_); + fire('after:highlightElement', { el: s, result: w, text: _ }), + (s.innerHTML = w.value), + (function updateClassName(s, o, i) { + const _ = o ? u[o] : i; + s.classList.add('hljs'), _ && s.classList.add(_); + })(s, i, w.language), + (s.result = { language: w.language, re: w.relevance, relavance: w.relevance }), + w.second_best && + (s.second_best = { + language: w.second_best.language, + re: w.second_best.relevance, + relavance: w.second_best.relevance + }); + } + const initHighlighting = () => { + if (initHighlighting.called) return; + (initHighlighting.called = !0), + deprecated( + '10.6.0', + 'initHighlighting() is deprecated. Use highlightAll() instead.' + ); + document.querySelectorAll('pre code').forEach(highlightElement); + }; + let U = !1; + function highlightAll() { + if ('loading' === document.readyState) return void (U = !0); + document.querySelectorAll('pre code').forEach(highlightElement); + } + function getLanguage(s) { + return (s = (s || '').toLowerCase()), i[s] || i[u[s]]; + } + function registerAliases(s, { languageName: o }) { + 'string' == typeof s && (s = [s]), + s.forEach((s) => { + u[s.toLowerCase()] = o; + }); + } + function autoDetection(s) { + const o = getLanguage(s); + return o && !o.disableAutodetect; + } + function fire(s, o) { + const i = s; + _.forEach(function (s) { + s[i] && s[i](o); + }); + } + 'undefined' != typeof window && + window.addEventListener && + window.addEventListener( + 'DOMContentLoaded', + function boot() { + U && highlightAll(); + }, + !1 + ), + Object.assign(s, { + highlight, + highlightAuto, + highlightAll, + fixMarkup: function deprecateFixMarkup(s) { + return ( + deprecated('10.2.0', 'fixMarkup will be removed entirely in v11.0'), + deprecated( + '10.2.0', + 'Please see https://github.com/highlightjs/highlight.js/issues/2534' + ), + (function fixMarkup(s) { + return L.tabReplace || L.useBR + ? s.replace(x, (s) => + '\n' === s + ? L.useBR + ? '
        ' + : s + : L.tabReplace + ? s.replace(/\t/g, L.tabReplace) + : s + ) + : s; + })(s) + ); + }, + highlightElement, + highlightBlock: function deprecateHighlightBlock(s) { + return ( + deprecated('10.7.0', 'highlightBlock will be removed entirely in v12.0'), + deprecated('10.7.0', 'Please use highlightElement now.'), + highlightElement(s) + ); + }, + configure: function configure(s) { + s.useBR && + (deprecated('10.3.0', "'useBR' will be removed entirely in v11.0"), + deprecated( + '10.3.0', + 'Please see https://github.com/highlightjs/highlight.js/issues/2559' + )), + (L = Se(L, s)); + }, + initHighlighting, + initHighlightingOnLoad: function initHighlightingOnLoad() { + deprecated( + '10.6.0', + 'initHighlightingOnLoad() is deprecated. Use highlightAll() instead.' + ), + (U = !0); + }, + registerLanguage: function registerLanguage(o, u) { + let _ = null; + try { + _ = u(s); + } catch (s) { + if ( + (error( + "Language definition for '{}' could not be registered.".replace('{}', o) + ), + !w) + ) + throw s; + error(s), (_ = j); + } + _.name || (_.name = o), + (i[o] = _), + (_.rawDefinition = u.bind(null, s)), + _.aliases && registerAliases(_.aliases, { languageName: o }); + }, + unregisterLanguage: function unregisterLanguage(s) { + delete i[s]; + for (const o of Object.keys(u)) u[o] === s && delete u[o]; + }, + listLanguages: function listLanguages() { + return Object.keys(i); + }, + getLanguage, + registerAliases, + requireLanguage: function requireLanguage(s) { + deprecated('10.4.0', 'requireLanguage will be removed entirely in v11.'), + deprecated( + '10.4.0', + 'Please see https://github.com/highlightjs/highlight.js/pull/2844' + ); + const o = getLanguage(s); + if (o) return o; + throw new Error( + "The '{}' language is required, but not loaded.".replace('{}', s) + ); + }, + autoDetection, + inherit: Se, + addPlugin: function addPlugin(s) { + !(function upgradePluginAPI(s) { + s['before:highlightBlock'] && + !s['before:highlightElement'] && + (s['before:highlightElement'] = (o) => { + s['before:highlightBlock'](Object.assign({ block: o.el }, o)); + }), + s['after:highlightBlock'] && + !s['after:highlightElement'] && + (s['after:highlightElement'] = (o) => { + s['after:highlightBlock'](Object.assign({ block: o.el }, o)); + }); + })(s), + _.push(s); + }, + vuePlugin: BuildVuePlugin(s).VuePlugin + }), + (s.debugMode = function () { + w = !1; + }), + (s.safeMode = function () { + w = !0; + }), + (s.versionString = '10.7.3'); + for (const s in fe) 'object' == typeof fe[s] && o(fe[s]); + return Object.assign(s, fe), s.addPlugin(B), s.addPlugin(be), s.addPlugin(V), s; + })({}); + s.exports = Pe; + }, + 35344: (s) => { + function concat(...s) { + return s + .map((s) => + (function source(s) { + return s ? ('string' == typeof s ? s : s.source) : null; + })(s) + ) + .join(''); + } + s.exports = function bash(s) { + const o = {}, + i = { begin: /\$\{/, end: /\}/, contains: ['self', { begin: /:-/, contains: [o] }] }; + Object.assign(o, { + className: 'variable', + variants: [{ begin: concat(/\$[\w\d#@][\w\d_]*/, '(?![\\w\\d])(?![$])') }, i] + }); + const u = { + className: 'subst', + begin: /\$\(/, + end: /\)/, + contains: [s.BACKSLASH_ESCAPE] + }, + _ = { + begin: /<<-?\s*(?=\w+)/, + starts: { + contains: [ + s.END_SAME_AS_BEGIN({ begin: /(\w+)/, end: /(\w+)/, className: 'string' }) + ] + } + }, + w = { + className: 'string', + begin: /"/, + end: /"/, + contains: [s.BACKSLASH_ESCAPE, o, u] + }; + u.contains.push(w); + const x = { + begin: /\$\(\(/, + end: /\)\)/, + contains: [{ begin: /\d+#[0-9a-f]+/, className: 'number' }, s.NUMBER_MODE, o] + }, + C = s.SHEBANG({ + binary: `(${['fish', 'bash', 'zsh', 'sh', 'csh', 'ksh', 'tcsh', 'dash', 'scsh'].join('|')})`, + relevance: 10 + }), + j = { + className: 'function', + begin: /\w[\w\d_]*\s*\(\s*\)\s*\{/, + returnBegin: !0, + contains: [s.inherit(s.TITLE_MODE, { begin: /\w[\w\d_]*/ })], + relevance: 0 + }; + return { + name: 'Bash', + aliases: ['sh', 'zsh'], + keywords: { + $pattern: /\b[a-z._-]+\b/, + keyword: 'if then else elif fi for while in do done case esac function', + literal: 'true false', + built_in: + 'break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp' + }, + contains: [ + C, + s.SHEBANG(), + j, + x, + s.HASH_COMMENT_MODE, + _, + w, + { className: '', begin: /\\"/ }, + { className: 'string', begin: /'/, end: /'/ }, + o + ] + }; + }; + }, + 73402: (s) => { + function concat(...s) { + return s + .map((s) => + (function source(s) { + return s ? ('string' == typeof s ? s : s.source) : null; + })(s) + ) + .join(''); + } + s.exports = function http(s) { + const o = 'HTTP/(2|1\\.[01])', + i = { + className: 'attribute', + begin: concat('^', /[A-Za-z][A-Za-z0-9-]*/, '(?=\\:\\s)'), + starts: { + contains: [ + { + className: 'punctuation', + begin: /: /, + relevance: 0, + starts: { end: '$', relevance: 0 } + } + ] + } + }, + u = [i, { begin: '\\n\\n', starts: { subLanguage: [], endsWithParent: !0 } }]; + return { + name: 'HTTP', + aliases: ['https'], + illegal: /\S/, + contains: [ + { + begin: '^(?=' + o + ' \\d{3})', + end: /$/, + contains: [ + { className: 'meta', begin: o }, + { className: 'number', begin: '\\b\\d{3}\\b' } + ], + starts: { end: /\b\B/, illegal: /\S/, contains: u } + }, + { + begin: '(?=^[A-Z]+ (.*?) ' + o + '$)', + end: /$/, + contains: [ + { className: 'string', begin: ' ', end: ' ', excludeBegin: !0, excludeEnd: !0 }, + { className: 'meta', begin: o }, + { className: 'keyword', begin: '[A-Z]+' } + ], + starts: { end: /\b\B/, illegal: /\S/, contains: u } + }, + s.inherit(i, { relevance: 0 }) + ] + }; + }; + }, + 95089: (s) => { + const o = '[A-Za-z$_][0-9A-Za-z$_]*', + i = [ + 'as', + 'in', + 'of', + 'if', + 'for', + 'while', + 'finally', + 'var', + 'new', + 'function', + 'do', + 'return', + 'void', + 'else', + 'break', + 'catch', + 'instanceof', + 'with', + 'throw', + 'case', + 'default', + 'try', + 'switch', + 'continue', + 'typeof', + 'delete', + 'let', + 'yield', + 'const', + 'class', + 'debugger', + 'async', + 'await', + 'static', + 'import', + 'from', + 'export', + 'extends' + ], + u = ['true', 'false', 'null', 'undefined', 'NaN', 'Infinity'], + _ = [].concat( + [ + 'setInterval', + 'setTimeout', + 'clearInterval', + 'clearTimeout', + 'require', + 'exports', + 'eval', + 'isFinite', + 'isNaN', + 'parseFloat', + 'parseInt', + 'decodeURI', + 'decodeURIComponent', + 'encodeURI', + 'encodeURIComponent', + 'escape', + 'unescape' + ], + [ + 'arguments', + 'this', + 'super', + 'console', + 'window', + 'document', + 'localStorage', + 'module', + 'global' + ], + [ + 'Intl', + 'DataView', + 'Number', + 'Math', + 'Date', + 'String', + 'RegExp', + 'Object', + 'Function', + 'Boolean', + 'Error', + 'Symbol', + 'Set', + 'Map', + 'WeakSet', + 'WeakMap', + 'Proxy', + 'Reflect', + 'JSON', + 'Promise', + 'Float64Array', + 'Int16Array', + 'Int32Array', + 'Int8Array', + 'Uint16Array', + 'Uint32Array', + 'Float32Array', + 'Array', + 'Uint8Array', + 'Uint8ClampedArray', + 'ArrayBuffer', + 'BigInt64Array', + 'BigUint64Array', + 'BigInt' + ], + [ + 'EvalError', + 'InternalError', + 'RangeError', + 'ReferenceError', + 'SyntaxError', + 'TypeError', + 'URIError' + ] + ); + function lookahead(s) { + return concat('(?=', s, ')'); + } + function concat(...s) { + return s + .map((s) => + (function source(s) { + return s ? ('string' == typeof s ? s : s.source) : null; + })(s) + ) + .join(''); + } + s.exports = function javascript(s) { + const w = o, + x = '<>', + C = '', + j = { + begin: /<[A-Za-z0-9\\._:-]+/, + end: /\/[A-Za-z0-9\\._:-]+>|\/>/, + isTrulyOpeningTag: (s, o) => { + const i = s[0].length + s.index, + u = s.input[i]; + '<' !== u + ? '>' === u && + (((s, { after: o }) => { + const i = '', + returnBegin: !0, + end: '\\s*=>', + contains: [ + { + className: 'params', + variants: [ + { begin: s.UNDERSCORE_IDENT_RE, relevance: 0 }, + { className: null, begin: /\(\s*\)/, skip: !0 }, + { + begin: /\(/, + end: /\)/, + excludeBegin: !0, + excludeEnd: !0, + keywords: L, + contains: ce + } + ] + } + ] + }, + { begin: /,/, relevance: 0 }, + { className: '', begin: /\s/, end: /\s*/, skip: !0 }, + { + variants: [ + { begin: x, end: C }, + { begin: j.begin, 'on:begin': j.isTrulyOpeningTag, end: j.end } + ], + subLanguage: 'xml', + contains: [{ begin: j.begin, end: j.end, skip: !0, contains: ['self'] }] + } + ], + relevance: 0 + }, + { + className: 'function', + beginKeywords: 'function', + end: /[{;]/, + excludeEnd: !0, + keywords: L, + contains: ['self', s.inherit(s.TITLE_MODE, { begin: w }), pe], + illegal: /%/ + }, + { beginKeywords: 'while if switch catch for' }, + { + className: 'function', + begin: + s.UNDERSCORE_IDENT_RE + + '\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{', + returnBegin: !0, + contains: [pe, s.inherit(s.TITLE_MODE, { begin: w })] + }, + { variants: [{ begin: '\\.' + w }, { begin: '\\$' + w }], relevance: 0 }, + { + className: 'class', + beginKeywords: 'class', + end: /[{;=]/, + excludeEnd: !0, + illegal: /[:"[\]]/, + contains: [{ beginKeywords: 'extends' }, s.UNDERSCORE_TITLE_MODE] + }, + { + begin: /\b(?=constructor)/, + end: /[{;]/, + excludeEnd: !0, + contains: [s.inherit(s.TITLE_MODE, { begin: w }), 'self', pe] + }, + { + begin: '(get|set)\\s+(?=' + w + '\\()', + end: /\{/, + keywords: 'get set', + contains: [s.inherit(s.TITLE_MODE, { begin: w }), { begin: /\(\)/ }, pe] + }, + { begin: /\$[(.]/ } + ] + }; + }; + }, + 65772: (s) => { + s.exports = function json(s) { + const o = { literal: 'true false null' }, + i = [s.C_LINE_COMMENT_MODE, s.C_BLOCK_COMMENT_MODE], + u = [s.QUOTE_STRING_MODE, s.C_NUMBER_MODE], + _ = { end: ',', endsWithParent: !0, excludeEnd: !0, contains: u, keywords: o }, + w = { + begin: /\{/, + end: /\}/, + contains: [ + { + className: 'attr', + begin: /"/, + end: /"/, + contains: [s.BACKSLASH_ESCAPE], + illegal: '\\n' + }, + s.inherit(_, { begin: /:/ }) + ].concat(i), + illegal: '\\S' + }, + x = { begin: '\\[', end: '\\]', contains: [s.inherit(_)], illegal: '\\S' }; + return ( + u.push(w, x), + i.forEach(function (s) { + u.push(s); + }), + { name: 'JSON', contains: u, keywords: o, illegal: '\\S' } + ); + }; + }, + 26571: (s) => { + s.exports = function powershell(s) { + const o = { + $pattern: /-?[A-z\.\-]+\b/, + keyword: + 'if else foreach return do while until elseif begin for trap data dynamicparam end break throw param continue finally in switch exit filter try process catch hidden static parameter', + built_in: + 'ac asnp cat cd CFS chdir clc clear clhy cli clp cls clv cnsn compare copy cp cpi cpp curl cvpa dbp del diff dir dnsn ebp echo|0 epal epcsv epsn erase etsn exsn fc fhx fl ft fw gal gbp gc gcb gci gcm gcs gdr gerr ghy gi gin gjb gl gm gmo gp gps gpv group gsn gsnp gsv gtz gu gv gwmi h history icm iex ihy ii ipal ipcsv ipmo ipsn irm ise iwmi iwr kill lp ls man md measure mi mount move mp mv nal ndr ni nmo npssc nsn nv ogv oh popd ps pushd pwd r rbp rcjb rcsn rd rdr ren ri rjb rm rmdir rmo rni rnp rp rsn rsnp rujb rv rvpa rwmi sajb sal saps sasv sbp sc scb select set shcm si sl sleep sls sort sp spjb spps spsv start stz sujb sv swmi tee trcm type wget where wjb write' + }, + i = { begin: '`[\\s\\S]', relevance: 0 }, + u = { + className: 'variable', + variants: [ + { begin: /\$\B/ }, + { className: 'keyword', begin: /\$this/ }, + { begin: /\$[\w\d][\w\d_:]*/ } + ] + }, + _ = { + className: 'string', + variants: [ + { begin: /"/, end: /"/ }, + { begin: /@"/, end: /^"@/ } + ], + contains: [i, u, { className: 'variable', begin: /\$[A-z]/, end: /[^A-z]/ }] + }, + w = { + className: 'string', + variants: [ + { begin: /'/, end: /'/ }, + { begin: /@'/, end: /^'@/ } + ] + }, + x = s.inherit(s.COMMENT(null, null), { + variants: [ + { begin: /#/, end: /$/ }, + { begin: /<#/, end: /#>/ } + ], + contains: [ + { + className: 'doctag', + variants: [ + { + begin: + /\.(synopsis|description|example|inputs|outputs|notes|link|component|role|functionality)/ + }, + { + begin: + /\.(parameter|forwardhelptargetname|forwardhelpcategory|remotehelprunspace|externalhelp)\s+\S+/ + } + ] + } + ] + }), + C = { + className: 'built_in', + variants: [ + { + begin: '('.concat( + 'Add|Clear|Close|Copy|Enter|Exit|Find|Format|Get|Hide|Join|Lock|Move|New|Open|Optimize|Pop|Push|Redo|Remove|Rename|Reset|Resize|Search|Select|Set|Show|Skip|Split|Step|Switch|Undo|Unlock|Watch|Backup|Checkpoint|Compare|Compress|Convert|ConvertFrom|ConvertTo|Dismount|Edit|Expand|Export|Group|Import|Initialize|Limit|Merge|Mount|Out|Publish|Restore|Save|Sync|Unpublish|Update|Approve|Assert|Build|Complete|Confirm|Deny|Deploy|Disable|Enable|Install|Invoke|Register|Request|Restart|Resume|Start|Stop|Submit|Suspend|Uninstall|Unregister|Wait|Debug|Measure|Ping|Repair|Resolve|Test|Trace|Connect|Disconnect|Read|Receive|Send|Write|Block|Grant|Protect|Revoke|Unblock|Unprotect|Use|ForEach|Sort|Tee|Where', + ')+(-)[\\w\\d]+' + ) + } + ] + }, + j = { + className: 'class', + beginKeywords: 'class enum', + end: /\s*[{]/, + excludeEnd: !0, + relevance: 0, + contains: [s.TITLE_MODE] + }, + L = { + className: 'function', + begin: /function\s+/, + end: /\s*\{|$/, + excludeEnd: !0, + returnBegin: !0, + relevance: 0, + contains: [ + { begin: 'function', relevance: 0, className: 'keyword' }, + { className: 'title', begin: /\w[\w\d]*((-)[\w\d]+)*/, relevance: 0 }, + { begin: /\(/, end: /\)/, className: 'params', relevance: 0, contains: [u] } + ] + }, + B = { + begin: /using\s/, + end: /$/, + returnBegin: !0, + contains: [ + _, + w, + { className: 'keyword', begin: /(using|assembly|command|module|namespace|type)/ } + ] + }, + $ = { + variants: [ + { + className: 'operator', + begin: '('.concat( + '-and|-as|-band|-bnot|-bor|-bxor|-casesensitive|-ccontains|-ceq|-cge|-cgt|-cle|-clike|-clt|-cmatch|-cne|-cnotcontains|-cnotlike|-cnotmatch|-contains|-creplace|-csplit|-eq|-exact|-f|-file|-ge|-gt|-icontains|-ieq|-ige|-igt|-ile|-ilike|-ilt|-imatch|-in|-ine|-inotcontains|-inotlike|-inotmatch|-ireplace|-is|-isnot|-isplit|-join|-le|-like|-lt|-match|-ne|-not|-notcontains|-notin|-notlike|-notmatch|-or|-regex|-replace|-shl|-shr|-split|-wildcard|-xor', + ')\\b' + ) + }, + { className: 'literal', begin: /(-)[\w\d]+/, relevance: 0 } + ] + }, + V = { + className: 'function', + begin: /\[.*\]\s*[\w]+[ ]??\(/, + end: /$/, + returnBegin: !0, + relevance: 0, + contains: [ + { + className: 'keyword', + begin: '('.concat(o.keyword.toString().replace(/\s/g, '|'), ')\\b'), + endsParent: !0, + relevance: 0 + }, + s.inherit(s.TITLE_MODE, { endsParent: !0 }) + ] + }, + U = [ + V, + x, + i, + s.NUMBER_MODE, + _, + w, + C, + u, + { className: 'literal', begin: /\$(null|true|false)\b/ }, + { className: 'selector-tag', begin: /@\B/, relevance: 0 } + ], + z = { + begin: /\[/, + end: /\]/, + excludeBegin: !0, + excludeEnd: !0, + relevance: 0, + contains: [].concat( + 'self', + U, + { + begin: + '(' + + [ + 'string', + 'char', + 'byte', + 'int', + 'long', + 'bool', + 'decimal', + 'single', + 'double', + 'DateTime', + 'xml', + 'array', + 'hashtable', + 'void' + ].join('|') + + ')', + className: 'built_in', + relevance: 0 + }, + { className: 'type', begin: /[\.\w\d]+/, relevance: 0 } + ) + }; + return ( + V.contains.unshift(z), + { + name: 'PowerShell', + aliases: ['ps', 'ps1'], + case_insensitive: !0, + keywords: o, + contains: U.concat(j, L, B, $, z) + } + ); + }; + }, + 17285: (s) => { + function source(s) { + return s ? ('string' == typeof s ? s : s.source) : null; + } + function lookahead(s) { + return concat('(?=', s, ')'); + } + function concat(...s) { + return s.map((s) => source(s)).join(''); + } + function either(...s) { + return '(' + s.map((s) => source(s)).join('|') + ')'; + } + s.exports = function xml(s) { + const o = concat( + /[A-Z_]/, + (function optional(s) { + return concat('(', s, ')?'); + })(/[A-Z0-9_.-]*:/), + /[A-Z0-9_.-]*/ + ), + i = { className: 'symbol', begin: /&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/ }, + u = { + begin: /\s/, + contains: [ + { className: 'meta-keyword', begin: /#?[a-z_][a-z1-9_-]+/, illegal: /\n/ } + ] + }, + _ = s.inherit(u, { begin: /\(/, end: /\)/ }), + w = s.inherit(s.APOS_STRING_MODE, { className: 'meta-string' }), + x = s.inherit(s.QUOTE_STRING_MODE, { className: 'meta-string' }), + C = { + endsWithParent: !0, + illegal: /`]+/ } + ] + } + ] + } + ] + }; + return { + name: 'HTML, XML', + aliases: ['html', 'xhtml', 'rss', 'atom', 'xjb', 'xsd', 'xsl', 'plist', 'wsf', 'svg'], + case_insensitive: !0, + contains: [ + { + className: 'meta', + begin: //, + relevance: 10, + contains: [ + u, + x, + w, + _, + { + begin: /\[/, + end: /\]/, + contains: [ + { className: 'meta', begin: //, contains: [u, _, x, w] } + ] + } + ] + }, + s.COMMENT(//, { relevance: 10 }), + { begin: //, relevance: 10 }, + i, + { className: 'meta', begin: /<\?xml/, end: /\?>/, relevance: 10 }, + { + className: 'tag', + begin: /)/, + end: />/, + keywords: { name: 'style' }, + contains: [C], + starts: { end: /<\/style>/, returnEnd: !0, subLanguage: ['css', 'xml'] } + }, + { + className: 'tag', + begin: /)/, + end: />/, + keywords: { name: 'script' }, + contains: [C], + starts: { + end: /<\/script>/, + returnEnd: !0, + subLanguage: ['javascript', 'handlebars', 'xml'] + } + }, + { className: 'tag', begin: /<>|<\/>/ }, + { + className: 'tag', + begin: concat(//, />/, /\s/)))), + end: /\/?>/, + contains: [{ className: 'name', begin: o, relevance: 0, starts: C }] + }, + { + className: 'tag', + begin: concat(/<\//, lookahead(concat(o, />/))), + contains: [ + { className: 'name', begin: o, relevance: 0 }, + { begin: />/, relevance: 0, endsParent: !0 } + ] + } + ] + }; + }; + }, + 17533: (s) => { + s.exports = function yaml(s) { + var o = 'true false yes no null', + i = "[\\w#;/?:@&=+$,.~*'()[\\]]+", + u = { + className: 'string', + relevance: 0, + variants: [{ begin: /'/, end: /'/ }, { begin: /"/, end: /"/ }, { begin: /\S+/ }], + contains: [ + s.BACKSLASH_ESCAPE, + { + className: 'template-variable', + variants: [ + { begin: /\{\{/, end: /\}\}/ }, + { begin: /%\{/, end: /\}/ } + ] + } + ] + }, + _ = s.inherit(u, { + variants: [ + { begin: /'/, end: /'/ }, + { begin: /"/, end: /"/ }, + { begin: /[^\s,{}[\]]+/ } + ] + }), + w = { + className: 'number', + begin: + '\\b[0-9]{4}(-[0-9][0-9]){0,2}([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?(\\.[0-9]*)?([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?\\b' + }, + x = { end: ',', endsWithParent: !0, excludeEnd: !0, keywords: o, relevance: 0 }, + C = { begin: /\{/, end: /\}/, contains: [x], illegal: '\\n', relevance: 0 }, + j = { begin: '\\[', end: '\\]', contains: [x], illegal: '\\n', relevance: 0 }, + L = [ + { + className: 'attr', + variants: [ + { begin: '\\w[\\w :\\/.-]*:(?=[ \t]|$)' }, + { begin: '"\\w[\\w :\\/.-]*":(?=[ \t]|$)' }, + { begin: "'\\w[\\w :\\/.-]*':(?=[ \t]|$)" } + ] + }, + { className: 'meta', begin: '^---\\s*$', relevance: 10 }, + { + className: 'string', + begin: '[\\|>]([1-9]?[+-])?[ ]*\\n( +)[^ ][^\\n]*\\n(\\2[^\\n]+\\n?)*' + }, + { + begin: '<%[%=-]?', + end: '[%-]?%>', + subLanguage: 'ruby', + excludeBegin: !0, + excludeEnd: !0, + relevance: 0 + }, + { className: 'type', begin: '!\\w+!' + i }, + { className: 'type', begin: '!<' + i + '>' }, + { className: 'type', begin: '!' + i }, + { className: 'type', begin: '!!' + i }, + { className: 'meta', begin: '&' + s.UNDERSCORE_IDENT_RE + '$' }, + { className: 'meta', begin: '\\*' + s.UNDERSCORE_IDENT_RE + '$' }, + { className: 'bullet', begin: '-(?=[ ]|$)', relevance: 0 }, + s.HASH_COMMENT_MODE, + { beginKeywords: o, keywords: { literal: o } }, + w, + { className: 'number', begin: s.C_NUMBER_RE + '\\b', relevance: 0 }, + C, + j, + u + ], + B = [...L]; + return ( + B.pop(), + B.push(_), + (x.contains = B), + { name: 'YAML', case_insensitive: !0, aliases: ['yml'], contains: L } + ); + }; + }, + 251: (s, o) => { + (o.read = function (s, o, i, u, _) { + var w, + x, + C = 8 * _ - u - 1, + j = (1 << C) - 1, + L = j >> 1, + B = -7, + $ = i ? _ - 1 : 0, + V = i ? -1 : 1, + U = s[o + $]; + for ( + $ += V, w = U & ((1 << -B) - 1), U >>= -B, B += C; + B > 0; + w = 256 * w + s[o + $], $ += V, B -= 8 + ); + for ( + x = w & ((1 << -B) - 1), w >>= -B, B += u; + B > 0; + x = 256 * x + s[o + $], $ += V, B -= 8 + ); + if (0 === w) w = 1 - L; + else { + if (w === j) return x ? NaN : (1 / 0) * (U ? -1 : 1); + (x += Math.pow(2, u)), (w -= L); + } + return (U ? -1 : 1) * x * Math.pow(2, w - u); + }), + (o.write = function (s, o, i, u, _, w) { + var x, + C, + j, + L = 8 * w - _ - 1, + B = (1 << L) - 1, + $ = B >> 1, + V = 23 === _ ? Math.pow(2, -24) - Math.pow(2, -77) : 0, + U = u ? 0 : w - 1, + z = u ? 1 : -1, + Y = o < 0 || (0 === o && 1 / o < 0) ? 1 : 0; + for ( + o = Math.abs(o), + isNaN(o) || o === 1 / 0 + ? ((C = isNaN(o) ? 1 : 0), (x = B)) + : ((x = Math.floor(Math.log(o) / Math.LN2)), + o * (j = Math.pow(2, -x)) < 1 && (x--, (j *= 2)), + (o += x + $ >= 1 ? V / j : V * Math.pow(2, 1 - $)) * j >= 2 && + (x++, (j /= 2)), + x + $ >= B + ? ((C = 0), (x = B)) + : x + $ >= 1 + ? ((C = (o * j - 1) * Math.pow(2, _)), (x += $)) + : ((C = o * Math.pow(2, $ - 1) * Math.pow(2, _)), (x = 0))); + _ >= 8; + s[i + U] = 255 & C, U += z, C /= 256, _ -= 8 + ); + for (x = (x << _) | C, L += _; L > 0; s[i + U] = 255 & x, U += z, x /= 256, L -= 8); + s[i + U - z] |= 128 * Y; + }); + }, + 9404: function (s) { + s.exports = (function () { + 'use strict'; + var s = Array.prototype.slice; + function createClass(s, o) { + o && (s.prototype = Object.create(o.prototype)), (s.prototype.constructor = s); + } + function Iterable(s) { + return isIterable(s) ? s : Seq(s); + } + function KeyedIterable(s) { + return isKeyed(s) ? s : KeyedSeq(s); + } + function IndexedIterable(s) { + return isIndexed(s) ? s : IndexedSeq(s); + } + function SetIterable(s) { + return isIterable(s) && !isAssociative(s) ? s : SetSeq(s); + } + function isIterable(s) { + return !(!s || !s[o]); + } + function isKeyed(s) { + return !(!s || !s[i]); + } + function isIndexed(s) { + return !(!s || !s[u]); + } + function isAssociative(s) { + return isKeyed(s) || isIndexed(s); + } + function isOrdered(s) { + return !(!s || !s[_]); + } + createClass(KeyedIterable, Iterable), + createClass(IndexedIterable, Iterable), + createClass(SetIterable, Iterable), + (Iterable.isIterable = isIterable), + (Iterable.isKeyed = isKeyed), + (Iterable.isIndexed = isIndexed), + (Iterable.isAssociative = isAssociative), + (Iterable.isOrdered = isOrdered), + (Iterable.Keyed = KeyedIterable), + (Iterable.Indexed = IndexedIterable), + (Iterable.Set = SetIterable); + var o = '@@__IMMUTABLE_ITERABLE__@@', + i = '@@__IMMUTABLE_KEYED__@@', + u = '@@__IMMUTABLE_INDEXED__@@', + _ = '@@__IMMUTABLE_ORDERED__@@', + w = 'delete', + x = 5, + C = 1 << x, + j = C - 1, + L = {}, + B = { value: !1 }, + $ = { value: !1 }; + function MakeRef(s) { + return (s.value = !1), s; + } + function SetRef(s) { + s && (s.value = !0); + } + function OwnerID() {} + function arrCopy(s, o) { + o = o || 0; + for (var i = Math.max(0, s.length - o), u = new Array(i), _ = 0; _ < i; _++) + u[_] = s[_ + o]; + return u; + } + function ensureSize(s) { + return void 0 === s.size && (s.size = s.__iterate(returnTrue)), s.size; + } + function wrapIndex(s, o) { + if ('number' != typeof o) { + var i = o >>> 0; + if ('' + i !== o || 4294967295 === i) return NaN; + o = i; + } + return o < 0 ? ensureSize(s) + o : o; + } + function returnTrue() { + return !0; + } + function wholeSlice(s, o, i) { + return ( + (0 === s || (void 0 !== i && s <= -i)) && (void 0 === o || (void 0 !== i && o >= i)) + ); + } + function resolveBegin(s, o) { + return resolveIndex(s, o, 0); + } + function resolveEnd(s, o) { + return resolveIndex(s, o, o); + } + function resolveIndex(s, o, i) { + return void 0 === s + ? i + : s < 0 + ? Math.max(0, o + s) + : void 0 === o + ? s + : Math.min(o, s); + } + var V = 0, + U = 1, + z = 2, + Y = 'function' == typeof Symbol && Symbol.iterator, + Z = '@@iterator', + ee = Y || Z; + function Iterator(s) { + this.next = s; + } + function iteratorValue(s, o, i, u) { + var _ = 0 === s ? o : 1 === s ? i : [o, i]; + return u ? (u.value = _) : (u = { value: _, done: !1 }), u; + } + function iteratorDone() { + return { value: void 0, done: !0 }; + } + function hasIterator(s) { + return !!getIteratorFn(s); + } + function isIterator(s) { + return s && 'function' == typeof s.next; + } + function getIterator(s) { + var o = getIteratorFn(s); + return o && o.call(s); + } + function getIteratorFn(s) { + var o = s && ((Y && s[Y]) || s[Z]); + if ('function' == typeof o) return o; + } + function isArrayLike(s) { + return s && 'number' == typeof s.length; + } + function Seq(s) { + return null == s ? emptySequence() : isIterable(s) ? s.toSeq() : seqFromValue(s); + } + function KeyedSeq(s) { + return null == s + ? emptySequence().toKeyedSeq() + : isIterable(s) + ? isKeyed(s) + ? s.toSeq() + : s.fromEntrySeq() + : keyedSeqFromValue(s); + } + function IndexedSeq(s) { + return null == s + ? emptySequence() + : isIterable(s) + ? isKeyed(s) + ? s.entrySeq() + : s.toIndexedSeq() + : indexedSeqFromValue(s); + } + function SetSeq(s) { + return ( + null == s + ? emptySequence() + : isIterable(s) + ? isKeyed(s) + ? s.entrySeq() + : s + : indexedSeqFromValue(s) + ).toSetSeq(); + } + (Iterator.prototype.toString = function () { + return '[Iterator]'; + }), + (Iterator.KEYS = V), + (Iterator.VALUES = U), + (Iterator.ENTRIES = z), + (Iterator.prototype.inspect = Iterator.prototype.toSource = + function () { + return this.toString(); + }), + (Iterator.prototype[ee] = function () { + return this; + }), + createClass(Seq, Iterable), + (Seq.of = function () { + return Seq(arguments); + }), + (Seq.prototype.toSeq = function () { + return this; + }), + (Seq.prototype.toString = function () { + return this.__toString('Seq {', '}'); + }), + (Seq.prototype.cacheResult = function () { + return ( + !this._cache && + this.__iterateUncached && + ((this._cache = this.entrySeq().toArray()), (this.size = this._cache.length)), + this + ); + }), + (Seq.prototype.__iterate = function (s, o) { + return seqIterate(this, s, o, !0); + }), + (Seq.prototype.__iterator = function (s, o) { + return seqIterator(this, s, o, !0); + }), + createClass(KeyedSeq, Seq), + (KeyedSeq.prototype.toKeyedSeq = function () { + return this; + }), + createClass(IndexedSeq, Seq), + (IndexedSeq.of = function () { + return IndexedSeq(arguments); + }), + (IndexedSeq.prototype.toIndexedSeq = function () { + return this; + }), + (IndexedSeq.prototype.toString = function () { + return this.__toString('Seq [', ']'); + }), + (IndexedSeq.prototype.__iterate = function (s, o) { + return seqIterate(this, s, o, !1); + }), + (IndexedSeq.prototype.__iterator = function (s, o) { + return seqIterator(this, s, o, !1); + }), + createClass(SetSeq, Seq), + (SetSeq.of = function () { + return SetSeq(arguments); + }), + (SetSeq.prototype.toSetSeq = function () { + return this; + }), + (Seq.isSeq = isSeq), + (Seq.Keyed = KeyedSeq), + (Seq.Set = SetSeq), + (Seq.Indexed = IndexedSeq); + var ie, + ae, + le, + ce = '@@__IMMUTABLE_SEQ__@@'; + function ArraySeq(s) { + (this._array = s), (this.size = s.length); + } + function ObjectSeq(s) { + var o = Object.keys(s); + (this._object = s), (this._keys = o), (this.size = o.length); + } + function IterableSeq(s) { + (this._iterable = s), (this.size = s.length || s.size); + } + function IteratorSeq(s) { + (this._iterator = s), (this._iteratorCache = []); + } + function isSeq(s) { + return !(!s || !s[ce]); + } + function emptySequence() { + return ie || (ie = new ArraySeq([])); + } + function keyedSeqFromValue(s) { + var o = Array.isArray(s) + ? new ArraySeq(s).fromEntrySeq() + : isIterator(s) + ? new IteratorSeq(s).fromEntrySeq() + : hasIterator(s) + ? new IterableSeq(s).fromEntrySeq() + : 'object' == typeof s + ? new ObjectSeq(s) + : void 0; + if (!o) + throw new TypeError( + 'Expected Array or iterable object of [k, v] entries, or keyed object: ' + s + ); + return o; + } + function indexedSeqFromValue(s) { + var o = maybeIndexedSeqFromValue(s); + if (!o) throw new TypeError('Expected Array or iterable object of values: ' + s); + return o; + } + function seqFromValue(s) { + var o = maybeIndexedSeqFromValue(s) || ('object' == typeof s && new ObjectSeq(s)); + if (!o) + throw new TypeError( + 'Expected Array or iterable object of values, or keyed object: ' + s + ); + return o; + } + function maybeIndexedSeqFromValue(s) { + return isArrayLike(s) + ? new ArraySeq(s) + : isIterator(s) + ? new IteratorSeq(s) + : hasIterator(s) + ? new IterableSeq(s) + : void 0; + } + function seqIterate(s, o, i, u) { + var _ = s._cache; + if (_) { + for (var w = _.length - 1, x = 0; x <= w; x++) { + var C = _[i ? w - x : x]; + if (!1 === o(C[1], u ? C[0] : x, s)) return x + 1; + } + return x; + } + return s.__iterateUncached(o, i); + } + function seqIterator(s, o, i, u) { + var _ = s._cache; + if (_) { + var w = _.length - 1, + x = 0; + return new Iterator(function () { + var s = _[i ? w - x : x]; + return x++ > w ? iteratorDone() : iteratorValue(o, u ? s[0] : x - 1, s[1]); + }); + } + return s.__iteratorUncached(o, i); + } + function fromJS(s, o) { + return o ? fromJSWith(o, s, '', { '': s }) : fromJSDefault(s); + } + function fromJSWith(s, o, i, u) { + return Array.isArray(o) + ? s.call( + u, + i, + IndexedSeq(o).map(function (i, u) { + return fromJSWith(s, i, u, o); + }) + ) + : isPlainObj(o) + ? s.call( + u, + i, + KeyedSeq(o).map(function (i, u) { + return fromJSWith(s, i, u, o); + }) + ) + : o; + } + function fromJSDefault(s) { + return Array.isArray(s) + ? IndexedSeq(s).map(fromJSDefault).toList() + : isPlainObj(s) + ? KeyedSeq(s).map(fromJSDefault).toMap() + : s; + } + function isPlainObj(s) { + return s && (s.constructor === Object || void 0 === s.constructor); + } + function is(s, o) { + if (s === o || (s != s && o != o)) return !0; + if (!s || !o) return !1; + if ('function' == typeof s.valueOf && 'function' == typeof o.valueOf) { + if ((s = s.valueOf()) === (o = o.valueOf()) || (s != s && o != o)) return !0; + if (!s || !o) return !1; + } + return !( + 'function' != typeof s.equals || + 'function' != typeof o.equals || + !s.equals(o) + ); + } + function deepEqual(s, o) { + if (s === o) return !0; + if ( + !isIterable(o) || + (void 0 !== s.size && void 0 !== o.size && s.size !== o.size) || + (void 0 !== s.__hash && void 0 !== o.__hash && s.__hash !== o.__hash) || + isKeyed(s) !== isKeyed(o) || + isIndexed(s) !== isIndexed(o) || + isOrdered(s) !== isOrdered(o) + ) + return !1; + if (0 === s.size && 0 === o.size) return !0; + var i = !isAssociative(s); + if (isOrdered(s)) { + var u = s.entries(); + return ( + o.every(function (s, o) { + var _ = u.next().value; + return _ && is(_[1], s) && (i || is(_[0], o)); + }) && u.next().done + ); + } + var _ = !1; + if (void 0 === s.size) + if (void 0 === o.size) 'function' == typeof s.cacheResult && s.cacheResult(); + else { + _ = !0; + var w = s; + (s = o), (o = w); + } + var x = !0, + C = o.__iterate(function (o, u) { + if (i ? !s.has(o) : _ ? !is(o, s.get(u, L)) : !is(s.get(u, L), o)) + return (x = !1), !1; + }); + return x && s.size === C; + } + function Repeat(s, o) { + if (!(this instanceof Repeat)) return new Repeat(s, o); + if ( + ((this._value = s), + (this.size = void 0 === o ? 1 / 0 : Math.max(0, o)), + 0 === this.size) + ) { + if (ae) return ae; + ae = this; + } + } + function invariant(s, o) { + if (!s) throw new Error(o); + } + function Range(s, o, i) { + if (!(this instanceof Range)) return new Range(s, o, i); + if ( + (invariant(0 !== i, 'Cannot step a Range by 0'), + (s = s || 0), + void 0 === o && (o = 1 / 0), + (i = void 0 === i ? 1 : Math.abs(i)), + o < s && (i = -i), + (this._start = s), + (this._end = o), + (this._step = i), + (this.size = Math.max(0, Math.ceil((o - s) / i - 1) + 1)), + 0 === this.size) + ) { + if (le) return le; + le = this; + } + } + function Collection() { + throw TypeError('Abstract'); + } + function KeyedCollection() {} + function IndexedCollection() {} + function SetCollection() {} + (Seq.prototype[ce] = !0), + createClass(ArraySeq, IndexedSeq), + (ArraySeq.prototype.get = function (s, o) { + return this.has(s) ? this._array[wrapIndex(this, s)] : o; + }), + (ArraySeq.prototype.__iterate = function (s, o) { + for (var i = this._array, u = i.length - 1, _ = 0; _ <= u; _++) + if (!1 === s(i[o ? u - _ : _], _, this)) return _ + 1; + return _; + }), + (ArraySeq.prototype.__iterator = function (s, o) { + var i = this._array, + u = i.length - 1, + _ = 0; + return new Iterator(function () { + return _ > u ? iteratorDone() : iteratorValue(s, _, i[o ? u - _++ : _++]); + }); + }), + createClass(ObjectSeq, KeyedSeq), + (ObjectSeq.prototype.get = function (s, o) { + return void 0 === o || this.has(s) ? this._object[s] : o; + }), + (ObjectSeq.prototype.has = function (s) { + return this._object.hasOwnProperty(s); + }), + (ObjectSeq.prototype.__iterate = function (s, o) { + for (var i = this._object, u = this._keys, _ = u.length - 1, w = 0; w <= _; w++) { + var x = u[o ? _ - w : w]; + if (!1 === s(i[x], x, this)) return w + 1; + } + return w; + }), + (ObjectSeq.prototype.__iterator = function (s, o) { + var i = this._object, + u = this._keys, + _ = u.length - 1, + w = 0; + return new Iterator(function () { + var x = u[o ? _ - w : w]; + return w++ > _ ? iteratorDone() : iteratorValue(s, x, i[x]); + }); + }), + (ObjectSeq.prototype[_] = !0), + createClass(IterableSeq, IndexedSeq), + (IterableSeq.prototype.__iterateUncached = function (s, o) { + if (o) return this.cacheResult().__iterate(s, o); + var i = getIterator(this._iterable), + u = 0; + if (isIterator(i)) + for (var _; !(_ = i.next()).done && !1 !== s(_.value, u++, this); ); + return u; + }), + (IterableSeq.prototype.__iteratorUncached = function (s, o) { + if (o) return this.cacheResult().__iterator(s, o); + var i = getIterator(this._iterable); + if (!isIterator(i)) return new Iterator(iteratorDone); + var u = 0; + return new Iterator(function () { + var o = i.next(); + return o.done ? o : iteratorValue(s, u++, o.value); + }); + }), + createClass(IteratorSeq, IndexedSeq), + (IteratorSeq.prototype.__iterateUncached = function (s, o) { + if (o) return this.cacheResult().__iterate(s, o); + for (var i, u = this._iterator, _ = this._iteratorCache, w = 0; w < _.length; ) + if (!1 === s(_[w], w++, this)) return w; + for (; !(i = u.next()).done; ) { + var x = i.value; + if (((_[w] = x), !1 === s(x, w++, this))) break; + } + return w; + }), + (IteratorSeq.prototype.__iteratorUncached = function (s, o) { + if (o) return this.cacheResult().__iterator(s, o); + var i = this._iterator, + u = this._iteratorCache, + _ = 0; + return new Iterator(function () { + if (_ >= u.length) { + var o = i.next(); + if (o.done) return o; + u[_] = o.value; + } + return iteratorValue(s, _, u[_++]); + }); + }), + createClass(Repeat, IndexedSeq), + (Repeat.prototype.toString = function () { + return 0 === this.size + ? 'Repeat []' + : 'Repeat [ ' + this._value + ' ' + this.size + ' times ]'; + }), + (Repeat.prototype.get = function (s, o) { + return this.has(s) ? this._value : o; + }), + (Repeat.prototype.includes = function (s) { + return is(this._value, s); + }), + (Repeat.prototype.slice = function (s, o) { + var i = this.size; + return wholeSlice(s, o, i) + ? this + : new Repeat(this._value, resolveEnd(o, i) - resolveBegin(s, i)); + }), + (Repeat.prototype.reverse = function () { + return this; + }), + (Repeat.prototype.indexOf = function (s) { + return is(this._value, s) ? 0 : -1; + }), + (Repeat.prototype.lastIndexOf = function (s) { + return is(this._value, s) ? this.size : -1; + }), + (Repeat.prototype.__iterate = function (s, o) { + for (var i = 0; i < this.size; i++) + if (!1 === s(this._value, i, this)) return i + 1; + return i; + }), + (Repeat.prototype.__iterator = function (s, o) { + var i = this, + u = 0; + return new Iterator(function () { + return u < i.size ? iteratorValue(s, u++, i._value) : iteratorDone(); + }); + }), + (Repeat.prototype.equals = function (s) { + return s instanceof Repeat ? is(this._value, s._value) : deepEqual(s); + }), + createClass(Range, IndexedSeq), + (Range.prototype.toString = function () { + return 0 === this.size + ? 'Range []' + : 'Range [ ' + + this._start + + '...' + + this._end + + (1 !== this._step ? ' by ' + this._step : '') + + ' ]'; + }), + (Range.prototype.get = function (s, o) { + return this.has(s) ? this._start + wrapIndex(this, s) * this._step : o; + }), + (Range.prototype.includes = function (s) { + var o = (s - this._start) / this._step; + return o >= 0 && o < this.size && o === Math.floor(o); + }), + (Range.prototype.slice = function (s, o) { + return wholeSlice(s, o, this.size) + ? this + : ((s = resolveBegin(s, this.size)), + (o = resolveEnd(o, this.size)) <= s + ? new Range(0, 0) + : new Range(this.get(s, this._end), this.get(o, this._end), this._step)); + }), + (Range.prototype.indexOf = function (s) { + var o = s - this._start; + if (o % this._step == 0) { + var i = o / this._step; + if (i >= 0 && i < this.size) return i; + } + return -1; + }), + (Range.prototype.lastIndexOf = function (s) { + return this.indexOf(s); + }), + (Range.prototype.__iterate = function (s, o) { + for ( + var i = this.size - 1, + u = this._step, + _ = o ? this._start + i * u : this._start, + w = 0; + w <= i; + w++ + ) { + if (!1 === s(_, w, this)) return w + 1; + _ += o ? -u : u; + } + return w; + }), + (Range.prototype.__iterator = function (s, o) { + var i = this.size - 1, + u = this._step, + _ = o ? this._start + i * u : this._start, + w = 0; + return new Iterator(function () { + var x = _; + return (_ += o ? -u : u), w > i ? iteratorDone() : iteratorValue(s, w++, x); + }); + }), + (Range.prototype.equals = function (s) { + return s instanceof Range + ? this._start === s._start && this._end === s._end && this._step === s._step + : deepEqual(this, s); + }), + createClass(Collection, Iterable), + createClass(KeyedCollection, Collection), + createClass(IndexedCollection, Collection), + createClass(SetCollection, Collection), + (Collection.Keyed = KeyedCollection), + (Collection.Indexed = IndexedCollection), + (Collection.Set = SetCollection); + var pe = + 'function' == typeof Math.imul && -2 === Math.imul(4294967295, 2) + ? Math.imul + : function imul(s, o) { + var i = 65535 & (s |= 0), + u = 65535 & (o |= 0); + return (i * u + ((((s >>> 16) * u + i * (o >>> 16)) << 16) >>> 0)) | 0; + }; + function smi(s) { + return ((s >>> 1) & 1073741824) | (3221225471 & s); + } + function hash(s) { + if (!1 === s || null == s) return 0; + if ('function' == typeof s.valueOf && (!1 === (s = s.valueOf()) || null == s)) + return 0; + if (!0 === s) return 1; + var o = typeof s; + if ('number' === o) { + if (s != s || s === 1 / 0) return 0; + var i = 0 | s; + for (i !== s && (i ^= 4294967295 * s); s > 4294967295; ) i ^= s /= 4294967295; + return smi(i); + } + if ('string' === o) return s.length > Se ? cachedHashString(s) : hashString(s); + if ('function' == typeof s.hashCode) return s.hashCode(); + if ('object' === o) return hashJSObj(s); + if ('function' == typeof s.toString) return hashString(s.toString()); + throw new Error('Value type ' + o + ' cannot be hashed.'); + } + function cachedHashString(s) { + var o = Te[s]; + return ( + void 0 === o && + ((o = hashString(s)), Pe === xe && ((Pe = 0), (Te = {})), Pe++, (Te[s] = o)), + o + ); + } + function hashString(s) { + for (var o = 0, i = 0; i < s.length; i++) o = (31 * o + s.charCodeAt(i)) | 0; + return smi(o); + } + function hashJSObj(s) { + var o; + if (be && void 0 !== (o = ye.get(s))) return o; + if (void 0 !== (o = s[we])) return o; + if (!fe) { + if (void 0 !== (o = s.propertyIsEnumerable && s.propertyIsEnumerable[we])) return o; + if (void 0 !== (o = getIENodeHash(s))) return o; + } + if (((o = ++_e), 1073741824 & _e && (_e = 0), be)) ye.set(s, o); + else { + if (void 0 !== de && !1 === de(s)) + throw new Error('Non-extensible objects are not allowed as keys.'); + if (fe) + Object.defineProperty(s, we, { + enumerable: !1, + configurable: !1, + writable: !1, + value: o + }); + else if ( + void 0 !== s.propertyIsEnumerable && + s.propertyIsEnumerable === s.constructor.prototype.propertyIsEnumerable + ) + (s.propertyIsEnumerable = function () { + return this.constructor.prototype.propertyIsEnumerable.apply(this, arguments); + }), + (s.propertyIsEnumerable[we] = o); + else { + if (void 0 === s.nodeType) + throw new Error('Unable to set a non-enumerable property on object.'); + s[we] = o; + } + } + return o; + } + var de = Object.isExtensible, + fe = (function () { + try { + return Object.defineProperty({}, '@', {}), !0; + } catch (s) { + return !1; + } + })(); + function getIENodeHash(s) { + if (s && s.nodeType > 0) + switch (s.nodeType) { + case 1: + return s.uniqueID; + case 9: + return s.documentElement && s.documentElement.uniqueID; + } + } + var ye, + be = 'function' == typeof WeakMap; + be && (ye = new WeakMap()); + var _e = 0, + we = '__immutablehash__'; + 'function' == typeof Symbol && (we = Symbol(we)); + var Se = 16, + xe = 255, + Pe = 0, + Te = {}; + function assertNotInfinite(s) { + invariant(s !== 1 / 0, 'Cannot perform this action with an infinite size.'); + } + function Map(s) { + return null == s + ? emptyMap() + : isMap(s) && !isOrdered(s) + ? s + : emptyMap().withMutations(function (o) { + var i = KeyedIterable(s); + assertNotInfinite(i.size), + i.forEach(function (s, i) { + return o.set(i, s); + }); + }); + } + function isMap(s) { + return !(!s || !s[qe]); + } + createClass(Map, KeyedCollection), + (Map.of = function () { + var o = s.call(arguments, 0); + return emptyMap().withMutations(function (s) { + for (var i = 0; i < o.length; i += 2) { + if (i + 1 >= o.length) throw new Error('Missing value for key: ' + o[i]); + s.set(o[i], o[i + 1]); + } + }); + }), + (Map.prototype.toString = function () { + return this.__toString('Map {', '}'); + }), + (Map.prototype.get = function (s, o) { + return this._root ? this._root.get(0, void 0, s, o) : o; + }), + (Map.prototype.set = function (s, o) { + return updateMap(this, s, o); + }), + (Map.prototype.setIn = function (s, o) { + return this.updateIn(s, L, function () { + return o; + }); + }), + (Map.prototype.remove = function (s) { + return updateMap(this, s, L); + }), + (Map.prototype.deleteIn = function (s) { + return this.updateIn(s, function () { + return L; + }); + }), + (Map.prototype.update = function (s, o, i) { + return 1 === arguments.length ? s(this) : this.updateIn([s], o, i); + }), + (Map.prototype.updateIn = function (s, o, i) { + i || ((i = o), (o = void 0)); + var u = updateInDeepMap(this, forceIterator(s), o, i); + return u === L ? void 0 : u; + }), + (Map.prototype.clear = function () { + return 0 === this.size + ? this + : this.__ownerID + ? ((this.size = 0), + (this._root = null), + (this.__hash = void 0), + (this.__altered = !0), + this) + : emptyMap(); + }), + (Map.prototype.merge = function () { + return mergeIntoMapWith(this, void 0, arguments); + }), + (Map.prototype.mergeWith = function (o) { + return mergeIntoMapWith(this, o, s.call(arguments, 1)); + }), + (Map.prototype.mergeIn = function (o) { + var i = s.call(arguments, 1); + return this.updateIn(o, emptyMap(), function (s) { + return 'function' == typeof s.merge ? s.merge.apply(s, i) : i[i.length - 1]; + }); + }), + (Map.prototype.mergeDeep = function () { + return mergeIntoMapWith(this, deepMerger, arguments); + }), + (Map.prototype.mergeDeepWith = function (o) { + var i = s.call(arguments, 1); + return mergeIntoMapWith(this, deepMergerWith(o), i); + }), + (Map.prototype.mergeDeepIn = function (o) { + var i = s.call(arguments, 1); + return this.updateIn(o, emptyMap(), function (s) { + return 'function' == typeof s.mergeDeep + ? s.mergeDeep.apply(s, i) + : i[i.length - 1]; + }); + }), + (Map.prototype.sort = function (s) { + return OrderedMap(sortFactory(this, s)); + }), + (Map.prototype.sortBy = function (s, o) { + return OrderedMap(sortFactory(this, o, s)); + }), + (Map.prototype.withMutations = function (s) { + var o = this.asMutable(); + return s(o), o.wasAltered() ? o.__ensureOwner(this.__ownerID) : this; + }), + (Map.prototype.asMutable = function () { + return this.__ownerID ? this : this.__ensureOwner(new OwnerID()); + }), + (Map.prototype.asImmutable = function () { + return this.__ensureOwner(); + }), + (Map.prototype.wasAltered = function () { + return this.__altered; + }), + (Map.prototype.__iterator = function (s, o) { + return new MapIterator(this, s, o); + }), + (Map.prototype.__iterate = function (s, o) { + var i = this, + u = 0; + return ( + this._root && + this._root.iterate(function (o) { + return u++, s(o[1], o[0], i); + }, o), + u + ); + }), + (Map.prototype.__ensureOwner = function (s) { + return s === this.__ownerID + ? this + : s + ? makeMap(this.size, this._root, s, this.__hash) + : ((this.__ownerID = s), (this.__altered = !1), this); + }), + (Map.isMap = isMap); + var Re, + qe = '@@__IMMUTABLE_MAP__@@', + $e = Map.prototype; + function ArrayMapNode(s, o) { + (this.ownerID = s), (this.entries = o); + } + function BitmapIndexedNode(s, o, i) { + (this.ownerID = s), (this.bitmap = o), (this.nodes = i); + } + function HashArrayMapNode(s, o, i) { + (this.ownerID = s), (this.count = o), (this.nodes = i); + } + function HashCollisionNode(s, o, i) { + (this.ownerID = s), (this.keyHash = o), (this.entries = i); + } + function ValueNode(s, o, i) { + (this.ownerID = s), (this.keyHash = o), (this.entry = i); + } + function MapIterator(s, o, i) { + (this._type = o), + (this._reverse = i), + (this._stack = s._root && mapIteratorFrame(s._root)); + } + function mapIteratorValue(s, o) { + return iteratorValue(s, o[0], o[1]); + } + function mapIteratorFrame(s, o) { + return { node: s, index: 0, __prev: o }; + } + function makeMap(s, o, i, u) { + var _ = Object.create($e); + return ( + (_.size = s), + (_._root = o), + (_.__ownerID = i), + (_.__hash = u), + (_.__altered = !1), + _ + ); + } + function emptyMap() { + return Re || (Re = makeMap(0)); + } + function updateMap(s, o, i) { + var u, _; + if (s._root) { + var w = MakeRef(B), + x = MakeRef($); + if (((u = updateNode(s._root, s.__ownerID, 0, void 0, o, i, w, x)), !x.value)) + return s; + _ = s.size + (w.value ? (i === L ? -1 : 1) : 0); + } else { + if (i === L) return s; + (_ = 1), (u = new ArrayMapNode(s.__ownerID, [[o, i]])); + } + return s.__ownerID + ? ((s.size = _), (s._root = u), (s.__hash = void 0), (s.__altered = !0), s) + : u + ? makeMap(_, u) + : emptyMap(); + } + function updateNode(s, o, i, u, _, w, x, C) { + return s + ? s.update(o, i, u, _, w, x, C) + : w === L + ? s + : (SetRef(C), SetRef(x), new ValueNode(o, u, [_, w])); + } + function isLeafNode(s) { + return s.constructor === ValueNode || s.constructor === HashCollisionNode; + } + function mergeIntoNode(s, o, i, u, _) { + if (s.keyHash === u) return new HashCollisionNode(o, u, [s.entry, _]); + var w, + C = (0 === i ? s.keyHash : s.keyHash >>> i) & j, + L = (0 === i ? u : u >>> i) & j; + return new BitmapIndexedNode( + o, + (1 << C) | (1 << L), + C === L + ? [mergeIntoNode(s, o, i + x, u, _)] + : ((w = new ValueNode(o, u, _)), C < L ? [s, w] : [w, s]) + ); + } + function createNodes(s, o, i, u) { + s || (s = new OwnerID()); + for (var _ = new ValueNode(s, hash(i), [i, u]), w = 0; w < o.length; w++) { + var x = o[w]; + _ = _.update(s, 0, void 0, x[0], x[1]); + } + return _; + } + function packNodes(s, o, i, u) { + for ( + var _ = 0, w = 0, x = new Array(i), C = 0, j = 1, L = o.length; + C < L; + C++, j <<= 1 + ) { + var B = o[C]; + void 0 !== B && C !== u && ((_ |= j), (x[w++] = B)); + } + return new BitmapIndexedNode(s, _, x); + } + function expandNodes(s, o, i, u, _) { + for (var w = 0, x = new Array(C), j = 0; 0 !== i; j++, i >>>= 1) + x[j] = 1 & i ? o[w++] : void 0; + return (x[u] = _), new HashArrayMapNode(s, w + 1, x); + } + function mergeIntoMapWith(s, o, i) { + for (var u = [], _ = 0; _ < i.length; _++) { + var w = i[_], + x = KeyedIterable(w); + isIterable(w) || + (x = x.map(function (s) { + return fromJS(s); + })), + u.push(x); + } + return mergeIntoCollectionWith(s, o, u); + } + function deepMerger(s, o, i) { + return s && s.mergeDeep && isIterable(o) ? s.mergeDeep(o) : is(s, o) ? s : o; + } + function deepMergerWith(s) { + return function (o, i, u) { + if (o && o.mergeDeepWith && isIterable(i)) return o.mergeDeepWith(s, i); + var _ = s(o, i, u); + return is(o, _) ? o : _; + }; + } + function mergeIntoCollectionWith(s, o, i) { + return 0 === + (i = i.filter(function (s) { + return 0 !== s.size; + })).length + ? s + : 0 !== s.size || s.__ownerID || 1 !== i.length + ? s.withMutations(function (s) { + for ( + var u = o + ? function (i, u) { + s.update(u, L, function (s) { + return s === L ? i : o(s, i, u); + }); + } + : function (o, i) { + s.set(i, o); + }, + _ = 0; + _ < i.length; + _++ + ) + i[_].forEach(u); + }) + : s.constructor(i[0]); + } + function updateInDeepMap(s, o, i, u) { + var _ = s === L, + w = o.next(); + if (w.done) { + var x = _ ? i : s, + C = u(x); + return C === x ? s : C; + } + invariant(_ || (s && s.set), 'invalid keyPath'); + var j = w.value, + B = _ ? L : s.get(j, L), + $ = updateInDeepMap(B, o, i, u); + return $ === B ? s : $ === L ? s.remove(j) : (_ ? emptyMap() : s).set(j, $); + } + function popCount(s) { + return ( + (s = + ((s = (858993459 & (s -= (s >> 1) & 1431655765)) + ((s >> 2) & 858993459)) + + (s >> 4)) & + 252645135), + (s += s >> 8), + 127 & (s += s >> 16) + ); + } + function setIn(s, o, i, u) { + var _ = u ? s : arrCopy(s); + return (_[o] = i), _; + } + function spliceIn(s, o, i, u) { + var _ = s.length + 1; + if (u && o + 1 === _) return (s[o] = i), s; + for (var w = new Array(_), x = 0, C = 0; C < _; C++) + C === o ? ((w[C] = i), (x = -1)) : (w[C] = s[C + x]); + return w; + } + function spliceOut(s, o, i) { + var u = s.length - 1; + if (i && o === u) return s.pop(), s; + for (var _ = new Array(u), w = 0, x = 0; x < u; x++) + x === o && (w = 1), (_[x] = s[x + w]); + return _; + } + ($e[qe] = !0), + ($e[w] = $e.remove), + ($e.removeIn = $e.deleteIn), + (ArrayMapNode.prototype.get = function (s, o, i, u) { + for (var _ = this.entries, w = 0, x = _.length; w < x; w++) + if (is(i, _[w][0])) return _[w][1]; + return u; + }), + (ArrayMapNode.prototype.update = function (s, o, i, u, _, w, x) { + for ( + var C = _ === L, j = this.entries, B = 0, $ = j.length; + B < $ && !is(u, j[B][0]); + B++ + ); + var V = B < $; + if (V ? j[B][1] === _ : C) return this; + if ((SetRef(x), (C || !V) && SetRef(w), !C || 1 !== j.length)) { + if (!V && !C && j.length >= ze) return createNodes(s, j, u, _); + var U = s && s === this.ownerID, + z = U ? j : arrCopy(j); + return ( + V + ? C + ? B === $ - 1 + ? z.pop() + : (z[B] = z.pop()) + : (z[B] = [u, _]) + : z.push([u, _]), + U ? ((this.entries = z), this) : new ArrayMapNode(s, z) + ); + } + }), + (BitmapIndexedNode.prototype.get = function (s, o, i, u) { + void 0 === o && (o = hash(i)); + var _ = 1 << ((0 === s ? o : o >>> s) & j), + w = this.bitmap; + return w & _ ? this.nodes[popCount(w & (_ - 1))].get(s + x, o, i, u) : u; + }), + (BitmapIndexedNode.prototype.update = function (s, o, i, u, _, w, C) { + void 0 === i && (i = hash(u)); + var B = (0 === o ? i : i >>> o) & j, + $ = 1 << B, + V = this.bitmap, + U = !!(V & $); + if (!U && _ === L) return this; + var z = popCount(V & ($ - 1)), + Y = this.nodes, + Z = U ? Y[z] : void 0, + ee = updateNode(Z, s, o + x, i, u, _, w, C); + if (ee === Z) return this; + if (!U && ee && Y.length >= We) return expandNodes(s, Y, V, B, ee); + if (U && !ee && 2 === Y.length && isLeafNode(Y[1 ^ z])) return Y[1 ^ z]; + if (U && ee && 1 === Y.length && isLeafNode(ee)) return ee; + var ie = s && s === this.ownerID, + ae = U ? (ee ? V : V ^ $) : V | $, + le = U + ? ee + ? setIn(Y, z, ee, ie) + : spliceOut(Y, z, ie) + : spliceIn(Y, z, ee, ie); + return ie + ? ((this.bitmap = ae), (this.nodes = le), this) + : new BitmapIndexedNode(s, ae, le); + }), + (HashArrayMapNode.prototype.get = function (s, o, i, u) { + void 0 === o && (o = hash(i)); + var _ = (0 === s ? o : o >>> s) & j, + w = this.nodes[_]; + return w ? w.get(s + x, o, i, u) : u; + }), + (HashArrayMapNode.prototype.update = function (s, o, i, u, _, w, C) { + void 0 === i && (i = hash(u)); + var B = (0 === o ? i : i >>> o) & j, + $ = _ === L, + V = this.nodes, + U = V[B]; + if ($ && !U) return this; + var z = updateNode(U, s, o + x, i, u, _, w, C); + if (z === U) return this; + var Y = this.count; + if (U) { + if (!z && --Y < He) return packNodes(s, V, Y, B); + } else Y++; + var Z = s && s === this.ownerID, + ee = setIn(V, B, z, Z); + return Z + ? ((this.count = Y), (this.nodes = ee), this) + : new HashArrayMapNode(s, Y, ee); + }), + (HashCollisionNode.prototype.get = function (s, o, i, u) { + for (var _ = this.entries, w = 0, x = _.length; w < x; w++) + if (is(i, _[w][0])) return _[w][1]; + return u; + }), + (HashCollisionNode.prototype.update = function (s, o, i, u, _, w, x) { + void 0 === i && (i = hash(u)); + var C = _ === L; + if (i !== this.keyHash) + return C ? this : (SetRef(x), SetRef(w), mergeIntoNode(this, s, o, i, [u, _])); + for (var j = this.entries, B = 0, $ = j.length; B < $ && !is(u, j[B][0]); B++); + var V = B < $; + if (V ? j[B][1] === _ : C) return this; + if ((SetRef(x), (C || !V) && SetRef(w), C && 2 === $)) + return new ValueNode(s, this.keyHash, j[1 ^ B]); + var U = s && s === this.ownerID, + z = U ? j : arrCopy(j); + return ( + V + ? C + ? B === $ - 1 + ? z.pop() + : (z[B] = z.pop()) + : (z[B] = [u, _]) + : z.push([u, _]), + U ? ((this.entries = z), this) : new HashCollisionNode(s, this.keyHash, z) + ); + }), + (ValueNode.prototype.get = function (s, o, i, u) { + return is(i, this.entry[0]) ? this.entry[1] : u; + }), + (ValueNode.prototype.update = function (s, o, i, u, _, w, x) { + var C = _ === L, + j = is(u, this.entry[0]); + return (j ? _ === this.entry[1] : C) + ? this + : (SetRef(x), + C + ? void SetRef(w) + : j + ? s && s === this.ownerID + ? ((this.entry[1] = _), this) + : new ValueNode(s, this.keyHash, [u, _]) + : (SetRef(w), mergeIntoNode(this, s, o, hash(u), [u, _]))); + }), + (ArrayMapNode.prototype.iterate = HashCollisionNode.prototype.iterate = + function (s, o) { + for (var i = this.entries, u = 0, _ = i.length - 1; u <= _; u++) + if (!1 === s(i[o ? _ - u : u])) return !1; + }), + (BitmapIndexedNode.prototype.iterate = HashArrayMapNode.prototype.iterate = + function (s, o) { + for (var i = this.nodes, u = 0, _ = i.length - 1; u <= _; u++) { + var w = i[o ? _ - u : u]; + if (w && !1 === w.iterate(s, o)) return !1; + } + }), + (ValueNode.prototype.iterate = function (s, o) { + return s(this.entry); + }), + createClass(MapIterator, Iterator), + (MapIterator.prototype.next = function () { + for (var s = this._type, o = this._stack; o; ) { + var i, + u = o.node, + _ = o.index++; + if (u.entry) { + if (0 === _) return mapIteratorValue(s, u.entry); + } else if (u.entries) { + if (_ <= (i = u.entries.length - 1)) + return mapIteratorValue(s, u.entries[this._reverse ? i - _ : _]); + } else if (_ <= (i = u.nodes.length - 1)) { + var w = u.nodes[this._reverse ? i - _ : _]; + if (w) { + if (w.entry) return mapIteratorValue(s, w.entry); + o = this._stack = mapIteratorFrame(w, o); + } + continue; + } + o = this._stack = this._stack.__prev; + } + return iteratorDone(); + }); + var ze = C / 4, + We = C / 2, + He = C / 4; + function List(s) { + var o = emptyList(); + if (null == s) return o; + if (isList(s)) return s; + var i = IndexedIterable(s), + u = i.size; + return 0 === u + ? o + : (assertNotInfinite(u), + u > 0 && u < C + ? makeList(0, u, x, null, new VNode(i.toArray())) + : o.withMutations(function (s) { + s.setSize(u), + i.forEach(function (o, i) { + return s.set(i, o); + }); + })); + } + function isList(s) { + return !(!s || !s[Ye]); + } + createClass(List, IndexedCollection), + (List.of = function () { + return this(arguments); + }), + (List.prototype.toString = function () { + return this.__toString('List [', ']'); + }), + (List.prototype.get = function (s, o) { + if ((s = wrapIndex(this, s)) >= 0 && s < this.size) { + var i = listNodeFor(this, (s += this._origin)); + return i && i.array[s & j]; + } + return o; + }), + (List.prototype.set = function (s, o) { + return updateList(this, s, o); + }), + (List.prototype.remove = function (s) { + return this.has(s) + ? 0 === s + ? this.shift() + : s === this.size - 1 + ? this.pop() + : this.splice(s, 1) + : this; + }), + (List.prototype.insert = function (s, o) { + return this.splice(s, 0, o); + }), + (List.prototype.clear = function () { + return 0 === this.size + ? this + : this.__ownerID + ? ((this.size = this._origin = this._capacity = 0), + (this._level = x), + (this._root = this._tail = null), + (this.__hash = void 0), + (this.__altered = !0), + this) + : emptyList(); + }), + (List.prototype.push = function () { + var s = arguments, + o = this.size; + return this.withMutations(function (i) { + setListBounds(i, 0, o + s.length); + for (var u = 0; u < s.length; u++) i.set(o + u, s[u]); + }); + }), + (List.prototype.pop = function () { + return setListBounds(this, 0, -1); + }), + (List.prototype.unshift = function () { + var s = arguments; + return this.withMutations(function (o) { + setListBounds(o, -s.length); + for (var i = 0; i < s.length; i++) o.set(i, s[i]); + }); + }), + (List.prototype.shift = function () { + return setListBounds(this, 1); + }), + (List.prototype.merge = function () { + return mergeIntoListWith(this, void 0, arguments); + }), + (List.prototype.mergeWith = function (o) { + return mergeIntoListWith(this, o, s.call(arguments, 1)); + }), + (List.prototype.mergeDeep = function () { + return mergeIntoListWith(this, deepMerger, arguments); + }), + (List.prototype.mergeDeepWith = function (o) { + var i = s.call(arguments, 1); + return mergeIntoListWith(this, deepMergerWith(o), i); + }), + (List.prototype.setSize = function (s) { + return setListBounds(this, 0, s); + }), + (List.prototype.slice = function (s, o) { + var i = this.size; + return wholeSlice(s, o, i) + ? this + : setListBounds(this, resolveBegin(s, i), resolveEnd(o, i)); + }), + (List.prototype.__iterator = function (s, o) { + var i = 0, + u = iterateList(this, o); + return new Iterator(function () { + var o = u(); + return o === tt ? iteratorDone() : iteratorValue(s, i++, o); + }); + }), + (List.prototype.__iterate = function (s, o) { + for ( + var i, u = 0, _ = iterateList(this, o); + (i = _()) !== tt && !1 !== s(i, u++, this); + + ); + return u; + }), + (List.prototype.__ensureOwner = function (s) { + return s === this.__ownerID + ? this + : s + ? makeList( + this._origin, + this._capacity, + this._level, + this._root, + this._tail, + s, + this.__hash + ) + : ((this.__ownerID = s), this); + }), + (List.isList = isList); + var Ye = '@@__IMMUTABLE_LIST__@@', + Xe = List.prototype; + function VNode(s, o) { + (this.array = s), (this.ownerID = o); + } + (Xe[Ye] = !0), + (Xe[w] = Xe.remove), + (Xe.setIn = $e.setIn), + (Xe.deleteIn = Xe.removeIn = $e.removeIn), + (Xe.update = $e.update), + (Xe.updateIn = $e.updateIn), + (Xe.mergeIn = $e.mergeIn), + (Xe.mergeDeepIn = $e.mergeDeepIn), + (Xe.withMutations = $e.withMutations), + (Xe.asMutable = $e.asMutable), + (Xe.asImmutable = $e.asImmutable), + (Xe.wasAltered = $e.wasAltered), + (VNode.prototype.removeBefore = function (s, o, i) { + if (i === o ? 1 << o : 0 === this.array.length) return this; + var u = (i >>> o) & j; + if (u >= this.array.length) return new VNode([], s); + var _, + w = 0 === u; + if (o > 0) { + var C = this.array[u]; + if ((_ = C && C.removeBefore(s, o - x, i)) === C && w) return this; + } + if (w && !_) return this; + var L = editableVNode(this, s); + if (!w) for (var B = 0; B < u; B++) L.array[B] = void 0; + return _ && (L.array[u] = _), L; + }), + (VNode.prototype.removeAfter = function (s, o, i) { + if (i === (o ? 1 << o : 0) || 0 === this.array.length) return this; + var u, + _ = ((i - 1) >>> o) & j; + if (_ >= this.array.length) return this; + if (o > 0) { + var w = this.array[_]; + if ((u = w && w.removeAfter(s, o - x, i)) === w && _ === this.array.length - 1) + return this; + } + var C = editableVNode(this, s); + return C.array.splice(_ + 1), u && (C.array[_] = u), C; + }); + var Qe, + et, + tt = {}; + function iterateList(s, o) { + var i = s._origin, + u = s._capacity, + _ = getTailOffset(u), + w = s._tail; + return iterateNodeOrLeaf(s._root, s._level, 0); + function iterateNodeOrLeaf(s, o, i) { + return 0 === o ? iterateLeaf(s, i) : iterateNode(s, o, i); + } + function iterateLeaf(s, x) { + var j = x === _ ? w && w.array : s && s.array, + L = x > i ? 0 : i - x, + B = u - x; + return ( + B > C && (B = C), + function () { + if (L === B) return tt; + var s = o ? --B : L++; + return j && j[s]; + } + ); + } + function iterateNode(s, _, w) { + var j, + L = s && s.array, + B = w > i ? 0 : (i - w) >> _, + $ = 1 + ((u - w) >> _); + return ( + $ > C && ($ = C), + function () { + for (;;) { + if (j) { + var s = j(); + if (s !== tt) return s; + j = null; + } + if (B === $) return tt; + var i = o ? --$ : B++; + j = iterateNodeOrLeaf(L && L[i], _ - x, w + (i << _)); + } + } + ); + } + } + function makeList(s, o, i, u, _, w, x) { + var C = Object.create(Xe); + return ( + (C.size = o - s), + (C._origin = s), + (C._capacity = o), + (C._level = i), + (C._root = u), + (C._tail = _), + (C.__ownerID = w), + (C.__hash = x), + (C.__altered = !1), + C + ); + } + function emptyList() { + return Qe || (Qe = makeList(0, 0, x)); + } + function updateList(s, o, i) { + if ((o = wrapIndex(s, o)) != o) return s; + if (o >= s.size || o < 0) + return s.withMutations(function (s) { + o < 0 ? setListBounds(s, o).set(0, i) : setListBounds(s, 0, o + 1).set(o, i); + }); + o += s._origin; + var u = s._tail, + _ = s._root, + w = MakeRef($); + return ( + o >= getTailOffset(s._capacity) + ? (u = updateVNode(u, s.__ownerID, 0, o, i, w)) + : (_ = updateVNode(_, s.__ownerID, s._level, o, i, w)), + w.value + ? s.__ownerID + ? ((s._root = _), (s._tail = u), (s.__hash = void 0), (s.__altered = !0), s) + : makeList(s._origin, s._capacity, s._level, _, u) + : s + ); + } + function updateVNode(s, o, i, u, _, w) { + var C, + L = (u >>> i) & j, + B = s && L < s.array.length; + if (!B && void 0 === _) return s; + if (i > 0) { + var $ = s && s.array[L], + V = updateVNode($, o, i - x, u, _, w); + return V === $ ? s : (((C = editableVNode(s, o)).array[L] = V), C); + } + return B && s.array[L] === _ + ? s + : (SetRef(w), + (C = editableVNode(s, o)), + void 0 === _ && L === C.array.length - 1 ? C.array.pop() : (C.array[L] = _), + C); + } + function editableVNode(s, o) { + return o && s && o === s.ownerID ? s : new VNode(s ? s.array.slice() : [], o); + } + function listNodeFor(s, o) { + if (o >= getTailOffset(s._capacity)) return s._tail; + if (o < 1 << (s._level + x)) { + for (var i = s._root, u = s._level; i && u > 0; ) + (i = i.array[(o >>> u) & j]), (u -= x); + return i; + } + } + function setListBounds(s, o, i) { + void 0 !== o && (o |= 0), void 0 !== i && (i |= 0); + var u = s.__ownerID || new OwnerID(), + _ = s._origin, + w = s._capacity, + C = _ + o, + L = void 0 === i ? w : i < 0 ? w + i : _ + i; + if (C === _ && L === w) return s; + if (C >= L) return s.clear(); + for (var B = s._level, $ = s._root, V = 0; C + V < 0; ) + ($ = new VNode($ && $.array.length ? [void 0, $] : [], u)), (V += 1 << (B += x)); + V && ((C += V), (_ += V), (L += V), (w += V)); + for (var U = getTailOffset(w), z = getTailOffset(L); z >= 1 << (B + x); ) + ($ = new VNode($ && $.array.length ? [$] : [], u)), (B += x); + var Y = s._tail, + Z = z < U ? listNodeFor(s, L - 1) : z > U ? new VNode([], u) : Y; + if (Y && z > U && C < w && Y.array.length) { + for (var ee = ($ = editableVNode($, u)), ie = B; ie > x; ie -= x) { + var ae = (U >>> ie) & j; + ee = ee.array[ae] = editableVNode(ee.array[ae], u); + } + ee.array[(U >>> x) & j] = Y; + } + if ((L < w && (Z = Z && Z.removeAfter(u, 0, L)), C >= z)) + (C -= z), (L -= z), (B = x), ($ = null), (Z = Z && Z.removeBefore(u, 0, C)); + else if (C > _ || z < U) { + for (V = 0; $; ) { + var le = (C >>> B) & j; + if ((le !== z >>> B) & j) break; + le && (V += (1 << B) * le), (B -= x), ($ = $.array[le]); + } + $ && C > _ && ($ = $.removeBefore(u, B, C - V)), + $ && z < U && ($ = $.removeAfter(u, B, z - V)), + V && ((C -= V), (L -= V)); + } + return s.__ownerID + ? ((s.size = L - C), + (s._origin = C), + (s._capacity = L), + (s._level = B), + (s._root = $), + (s._tail = Z), + (s.__hash = void 0), + (s.__altered = !0), + s) + : makeList(C, L, B, $, Z); + } + function mergeIntoListWith(s, o, i) { + for (var u = [], _ = 0, w = 0; w < i.length; w++) { + var x = i[w], + C = IndexedIterable(x); + C.size > _ && (_ = C.size), + isIterable(x) || + (C = C.map(function (s) { + return fromJS(s); + })), + u.push(C); + } + return _ > s.size && (s = s.setSize(_)), mergeIntoCollectionWith(s, o, u); + } + function getTailOffset(s) { + return s < C ? 0 : ((s - 1) >>> x) << x; + } + function OrderedMap(s) { + return null == s + ? emptyOrderedMap() + : isOrderedMap(s) + ? s + : emptyOrderedMap().withMutations(function (o) { + var i = KeyedIterable(s); + assertNotInfinite(i.size), + i.forEach(function (s, i) { + return o.set(i, s); + }); + }); + } + function isOrderedMap(s) { + return isMap(s) && isOrdered(s); + } + function makeOrderedMap(s, o, i, u) { + var _ = Object.create(OrderedMap.prototype); + return ( + (_.size = s ? s.size : 0), + (_._map = s), + (_._list = o), + (_.__ownerID = i), + (_.__hash = u), + _ + ); + } + function emptyOrderedMap() { + return et || (et = makeOrderedMap(emptyMap(), emptyList())); + } + function updateOrderedMap(s, o, i) { + var u, + _, + w = s._map, + x = s._list, + j = w.get(o), + B = void 0 !== j; + if (i === L) { + if (!B) return s; + x.size >= C && x.size >= 2 * w.size + ? ((u = (_ = x.filter(function (s, o) { + return void 0 !== s && j !== o; + })) + .toKeyedSeq() + .map(function (s) { + return s[0]; + }) + .flip() + .toMap()), + s.__ownerID && (u.__ownerID = _.__ownerID = s.__ownerID)) + : ((u = w.remove(o)), (_ = j === x.size - 1 ? x.pop() : x.set(j, void 0))); + } else if (B) { + if (i === x.get(j)[1]) return s; + (u = w), (_ = x.set(j, [o, i])); + } else (u = w.set(o, x.size)), (_ = x.set(x.size, [o, i])); + return s.__ownerID + ? ((s.size = u.size), (s._map = u), (s._list = _), (s.__hash = void 0), s) + : makeOrderedMap(u, _); + } + function ToKeyedSequence(s, o) { + (this._iter = s), (this._useKeys = o), (this.size = s.size); + } + function ToIndexedSequence(s) { + (this._iter = s), (this.size = s.size); + } + function ToSetSequence(s) { + (this._iter = s), (this.size = s.size); + } + function FromEntriesSequence(s) { + (this._iter = s), (this.size = s.size); + } + function flipFactory(s) { + var o = makeSequence(s); + return ( + (o._iter = s), + (o.size = s.size), + (o.flip = function () { + return s; + }), + (o.reverse = function () { + var o = s.reverse.apply(this); + return ( + (o.flip = function () { + return s.reverse(); + }), + o + ); + }), + (o.has = function (o) { + return s.includes(o); + }), + (o.includes = function (o) { + return s.has(o); + }), + (o.cacheResult = cacheResultThrough), + (o.__iterateUncached = function (o, i) { + var u = this; + return s.__iterate(function (s, i) { + return !1 !== o(i, s, u); + }, i); + }), + (o.__iteratorUncached = function (o, i) { + if (o === z) { + var u = s.__iterator(o, i); + return new Iterator(function () { + var s = u.next(); + if (!s.done) { + var o = s.value[0]; + (s.value[0] = s.value[1]), (s.value[1] = o); + } + return s; + }); + } + return s.__iterator(o === U ? V : U, i); + }), + o + ); + } + function mapFactory(s, o, i) { + var u = makeSequence(s); + return ( + (u.size = s.size), + (u.has = function (o) { + return s.has(o); + }), + (u.get = function (u, _) { + var w = s.get(u, L); + return w === L ? _ : o.call(i, w, u, s); + }), + (u.__iterateUncached = function (u, _) { + var w = this; + return s.__iterate(function (s, _, x) { + return !1 !== u(o.call(i, s, _, x), _, w); + }, _); + }), + (u.__iteratorUncached = function (u, _) { + var w = s.__iterator(z, _); + return new Iterator(function () { + var _ = w.next(); + if (_.done) return _; + var x = _.value, + C = x[0]; + return iteratorValue(u, C, o.call(i, x[1], C, s), _); + }); + }), + u + ); + } + function reverseFactory(s, o) { + var i = makeSequence(s); + return ( + (i._iter = s), + (i.size = s.size), + (i.reverse = function () { + return s; + }), + s.flip && + (i.flip = function () { + var o = flipFactory(s); + return ( + (o.reverse = function () { + return s.flip(); + }), + o + ); + }), + (i.get = function (i, u) { + return s.get(o ? i : -1 - i, u); + }), + (i.has = function (i) { + return s.has(o ? i : -1 - i); + }), + (i.includes = function (o) { + return s.includes(o); + }), + (i.cacheResult = cacheResultThrough), + (i.__iterate = function (o, i) { + var u = this; + return s.__iterate(function (s, i) { + return o(s, i, u); + }, !i); + }), + (i.__iterator = function (o, i) { + return s.__iterator(o, !i); + }), + i + ); + } + function filterFactory(s, o, i, u) { + var _ = makeSequence(s); + return ( + u && + ((_.has = function (u) { + var _ = s.get(u, L); + return _ !== L && !!o.call(i, _, u, s); + }), + (_.get = function (u, _) { + var w = s.get(u, L); + return w !== L && o.call(i, w, u, s) ? w : _; + })), + (_.__iterateUncached = function (_, w) { + var x = this, + C = 0; + return ( + s.__iterate(function (s, w, j) { + if (o.call(i, s, w, j)) return C++, _(s, u ? w : C - 1, x); + }, w), + C + ); + }), + (_.__iteratorUncached = function (_, w) { + var x = s.__iterator(z, w), + C = 0; + return new Iterator(function () { + for (;;) { + var w = x.next(); + if (w.done) return w; + var j = w.value, + L = j[0], + B = j[1]; + if (o.call(i, B, L, s)) return iteratorValue(_, u ? L : C++, B, w); + } + }); + }), + _ + ); + } + function countByFactory(s, o, i) { + var u = Map().asMutable(); + return ( + s.__iterate(function (_, w) { + u.update(o.call(i, _, w, s), 0, function (s) { + return s + 1; + }); + }), + u.asImmutable() + ); + } + function groupByFactory(s, o, i) { + var u = isKeyed(s), + _ = (isOrdered(s) ? OrderedMap() : Map()).asMutable(); + s.__iterate(function (w, x) { + _.update(o.call(i, w, x, s), function (s) { + return (s = s || []).push(u ? [x, w] : w), s; + }); + }); + var w = iterableClass(s); + return _.map(function (o) { + return reify(s, w(o)); + }); + } + function sliceFactory(s, o, i, u) { + var _ = s.size; + if ( + (void 0 !== o && (o |= 0), + void 0 !== i && (i === 1 / 0 ? (i = _) : (i |= 0)), + wholeSlice(o, i, _)) + ) + return s; + var w = resolveBegin(o, _), + x = resolveEnd(i, _); + if (w != w || x != x) return sliceFactory(s.toSeq().cacheResult(), o, i, u); + var C, + j = x - w; + j == j && (C = j < 0 ? 0 : j); + var L = makeSequence(s); + return ( + (L.size = 0 === C ? C : (s.size && C) || void 0), + !u && + isSeq(s) && + C >= 0 && + (L.get = function (o, i) { + return (o = wrapIndex(this, o)) >= 0 && o < C ? s.get(o + w, i) : i; + }), + (L.__iterateUncached = function (o, i) { + var _ = this; + if (0 === C) return 0; + if (i) return this.cacheResult().__iterate(o, i); + var x = 0, + j = !0, + L = 0; + return ( + s.__iterate(function (s, i) { + if (!j || !(j = x++ < w)) + return L++, !1 !== o(s, u ? i : L - 1, _) && L !== C; + }), + L + ); + }), + (L.__iteratorUncached = function (o, i) { + if (0 !== C && i) return this.cacheResult().__iterator(o, i); + var _ = 0 !== C && s.__iterator(o, i), + x = 0, + j = 0; + return new Iterator(function () { + for (; x++ < w; ) _.next(); + if (++j > C) return iteratorDone(); + var s = _.next(); + return u || o === U + ? s + : iteratorValue(o, j - 1, o === V ? void 0 : s.value[1], s); + }); + }), + L + ); + } + function takeWhileFactory(s, o, i) { + var u = makeSequence(s); + return ( + (u.__iterateUncached = function (u, _) { + var w = this; + if (_) return this.cacheResult().__iterate(u, _); + var x = 0; + return ( + s.__iterate(function (s, _, C) { + return o.call(i, s, _, C) && ++x && u(s, _, w); + }), + x + ); + }), + (u.__iteratorUncached = function (u, _) { + var w = this; + if (_) return this.cacheResult().__iterator(u, _); + var x = s.__iterator(z, _), + C = !0; + return new Iterator(function () { + if (!C) return iteratorDone(); + var s = x.next(); + if (s.done) return s; + var _ = s.value, + j = _[0], + L = _[1]; + return o.call(i, L, j, w) + ? u === z + ? s + : iteratorValue(u, j, L, s) + : ((C = !1), iteratorDone()); + }); + }), + u + ); + } + function skipWhileFactory(s, o, i, u) { + var _ = makeSequence(s); + return ( + (_.__iterateUncached = function (_, w) { + var x = this; + if (w) return this.cacheResult().__iterate(_, w); + var C = !0, + j = 0; + return ( + s.__iterate(function (s, w, L) { + if (!C || !(C = o.call(i, s, w, L))) return j++, _(s, u ? w : j - 1, x); + }), + j + ); + }), + (_.__iteratorUncached = function (_, w) { + var x = this; + if (w) return this.cacheResult().__iterator(_, w); + var C = s.__iterator(z, w), + j = !0, + L = 0; + return new Iterator(function () { + var s, w, B; + do { + if ((s = C.next()).done) + return u || _ === U + ? s + : iteratorValue(_, L++, _ === V ? void 0 : s.value[1], s); + var $ = s.value; + (w = $[0]), (B = $[1]), j && (j = o.call(i, B, w, x)); + } while (j); + return _ === z ? s : iteratorValue(_, w, B, s); + }); + }), + _ + ); + } + function concatFactory(s, o) { + var i = isKeyed(s), + u = [s] + .concat(o) + .map(function (s) { + return ( + isIterable(s) + ? i && (s = KeyedIterable(s)) + : (s = i + ? keyedSeqFromValue(s) + : indexedSeqFromValue(Array.isArray(s) ? s : [s])), + s + ); + }) + .filter(function (s) { + return 0 !== s.size; + }); + if (0 === u.length) return s; + if (1 === u.length) { + var _ = u[0]; + if (_ === s || (i && isKeyed(_)) || (isIndexed(s) && isIndexed(_))) return _; + } + var w = new ArraySeq(u); + return ( + i ? (w = w.toKeyedSeq()) : isIndexed(s) || (w = w.toSetSeq()), + ((w = w.flatten(!0)).size = u.reduce(function (s, o) { + if (void 0 !== s) { + var i = o.size; + if (void 0 !== i) return s + i; + } + }, 0)), + w + ); + } + function flattenFactory(s, o, i) { + var u = makeSequence(s); + return ( + (u.__iterateUncached = function (u, _) { + var w = 0, + x = !1; + function flatDeep(s, C) { + var j = this; + s.__iterate(function (s, _) { + return ( + (!o || C < o) && isIterable(s) + ? flatDeep(s, C + 1) + : !1 === u(s, i ? _ : w++, j) && (x = !0), + !x + ); + }, _); + } + return flatDeep(s, 0), w; + }), + (u.__iteratorUncached = function (u, _) { + var w = s.__iterator(u, _), + x = [], + C = 0; + return new Iterator(function () { + for (; w; ) { + var s = w.next(); + if (!1 === s.done) { + var j = s.value; + if ((u === z && (j = j[1]), (o && !(x.length < o)) || !isIterable(j))) + return i ? s : iteratorValue(u, C++, j, s); + x.push(w), (w = j.__iterator(u, _)); + } else w = x.pop(); + } + return iteratorDone(); + }); + }), + u + ); + } + function flatMapFactory(s, o, i) { + var u = iterableClass(s); + return s + .toSeq() + .map(function (_, w) { + return u(o.call(i, _, w, s)); + }) + .flatten(!0); + } + function interposeFactory(s, o) { + var i = makeSequence(s); + return ( + (i.size = s.size && 2 * s.size - 1), + (i.__iterateUncached = function (i, u) { + var _ = this, + w = 0; + return ( + s.__iterate(function (s, u) { + return (!w || !1 !== i(o, w++, _)) && !1 !== i(s, w++, _); + }, u), + w + ); + }), + (i.__iteratorUncached = function (i, u) { + var _, + w = s.__iterator(U, u), + x = 0; + return new Iterator(function () { + return (!_ || x % 2) && (_ = w.next()).done + ? _ + : x % 2 + ? iteratorValue(i, x++, o) + : iteratorValue(i, x++, _.value, _); + }); + }), + i + ); + } + function sortFactory(s, o, i) { + o || (o = defaultComparator); + var u = isKeyed(s), + _ = 0, + w = s + .toSeq() + .map(function (o, u) { + return [u, o, _++, i ? i(o, u, s) : o]; + }) + .toArray(); + return ( + w + .sort(function (s, i) { + return o(s[3], i[3]) || s[2] - i[2]; + }) + .forEach( + u + ? function (s, o) { + w[o].length = 2; + } + : function (s, o) { + w[o] = s[1]; + } + ), + u ? KeyedSeq(w) : isIndexed(s) ? IndexedSeq(w) : SetSeq(w) + ); + } + function maxFactory(s, o, i) { + if ((o || (o = defaultComparator), i)) { + var u = s + .toSeq() + .map(function (o, u) { + return [o, i(o, u, s)]; + }) + .reduce(function (s, i) { + return maxCompare(o, s[1], i[1]) ? i : s; + }); + return u && u[0]; + } + return s.reduce(function (s, i) { + return maxCompare(o, s, i) ? i : s; + }); + } + function maxCompare(s, o, i) { + var u = s(i, o); + return (0 === u && i !== o && (null == i || i != i)) || u > 0; + } + function zipWithFactory(s, o, i) { + var u = makeSequence(s); + return ( + (u.size = new ArraySeq(i) + .map(function (s) { + return s.size; + }) + .min()), + (u.__iterate = function (s, o) { + for ( + var i, u = this.__iterator(U, o), _ = 0; + !(i = u.next()).done && !1 !== s(i.value, _++, this); + + ); + return _; + }), + (u.__iteratorUncached = function (s, u) { + var _ = i.map(function (s) { + return (s = Iterable(s)), getIterator(u ? s.reverse() : s); + }), + w = 0, + x = !1; + return new Iterator(function () { + var i; + return ( + x || + ((i = _.map(function (s) { + return s.next(); + })), + (x = i.some(function (s) { + return s.done; + }))), + x + ? iteratorDone() + : iteratorValue( + s, + w++, + o.apply( + null, + i.map(function (s) { + return s.value; + }) + ) + ) + ); + }); + }), + u + ); + } + function reify(s, o) { + return isSeq(s) ? o : s.constructor(o); + } + function validateEntry(s) { + if (s !== Object(s)) throw new TypeError('Expected [K, V] tuple: ' + s); + } + function resolveSize(s) { + return assertNotInfinite(s.size), ensureSize(s); + } + function iterableClass(s) { + return isKeyed(s) ? KeyedIterable : isIndexed(s) ? IndexedIterable : SetIterable; + } + function makeSequence(s) { + return Object.create( + (isKeyed(s) ? KeyedSeq : isIndexed(s) ? IndexedSeq : SetSeq).prototype + ); + } + function cacheResultThrough() { + return this._iter.cacheResult + ? (this._iter.cacheResult(), (this.size = this._iter.size), this) + : Seq.prototype.cacheResult.call(this); + } + function defaultComparator(s, o) { + return s > o ? 1 : s < o ? -1 : 0; + } + function forceIterator(s) { + var o = getIterator(s); + if (!o) { + if (!isArrayLike(s)) throw new TypeError('Expected iterable or array-like: ' + s); + o = getIterator(Iterable(s)); + } + return o; + } + function Record(s, o) { + var i, + u = function Record(w) { + if (w instanceof u) return w; + if (!(this instanceof u)) return new u(w); + if (!i) { + i = !0; + var x = Object.keys(s); + setProps(_, x), + (_.size = x.length), + (_._name = o), + (_._keys = x), + (_._defaultValues = s); + } + this._map = Map(w); + }, + _ = (u.prototype = Object.create(rt)); + return (_.constructor = u), u; + } + createClass(OrderedMap, Map), + (OrderedMap.of = function () { + return this(arguments); + }), + (OrderedMap.prototype.toString = function () { + return this.__toString('OrderedMap {', '}'); + }), + (OrderedMap.prototype.get = function (s, o) { + var i = this._map.get(s); + return void 0 !== i ? this._list.get(i)[1] : o; + }), + (OrderedMap.prototype.clear = function () { + return 0 === this.size + ? this + : this.__ownerID + ? ((this.size = 0), this._map.clear(), this._list.clear(), this) + : emptyOrderedMap(); + }), + (OrderedMap.prototype.set = function (s, o) { + return updateOrderedMap(this, s, o); + }), + (OrderedMap.prototype.remove = function (s) { + return updateOrderedMap(this, s, L); + }), + (OrderedMap.prototype.wasAltered = function () { + return this._map.wasAltered() || this._list.wasAltered(); + }), + (OrderedMap.prototype.__iterate = function (s, o) { + var i = this; + return this._list.__iterate(function (o) { + return o && s(o[1], o[0], i); + }, o); + }), + (OrderedMap.prototype.__iterator = function (s, o) { + return this._list.fromEntrySeq().__iterator(s, o); + }), + (OrderedMap.prototype.__ensureOwner = function (s) { + if (s === this.__ownerID) return this; + var o = this._map.__ensureOwner(s), + i = this._list.__ensureOwner(s); + return s + ? makeOrderedMap(o, i, s, this.__hash) + : ((this.__ownerID = s), (this._map = o), (this._list = i), this); + }), + (OrderedMap.isOrderedMap = isOrderedMap), + (OrderedMap.prototype[_] = !0), + (OrderedMap.prototype[w] = OrderedMap.prototype.remove), + createClass(ToKeyedSequence, KeyedSeq), + (ToKeyedSequence.prototype.get = function (s, o) { + return this._iter.get(s, o); + }), + (ToKeyedSequence.prototype.has = function (s) { + return this._iter.has(s); + }), + (ToKeyedSequence.prototype.valueSeq = function () { + return this._iter.valueSeq(); + }), + (ToKeyedSequence.prototype.reverse = function () { + var s = this, + o = reverseFactory(this, !0); + return ( + this._useKeys || + (o.valueSeq = function () { + return s._iter.toSeq().reverse(); + }), + o + ); + }), + (ToKeyedSequence.prototype.map = function (s, o) { + var i = this, + u = mapFactory(this, s, o); + return ( + this._useKeys || + (u.valueSeq = function () { + return i._iter.toSeq().map(s, o); + }), + u + ); + }), + (ToKeyedSequence.prototype.__iterate = function (s, o) { + var i, + u = this; + return this._iter.__iterate( + this._useKeys + ? function (o, i) { + return s(o, i, u); + } + : ((i = o ? resolveSize(this) : 0), + function (_) { + return s(_, o ? --i : i++, u); + }), + o + ); + }), + (ToKeyedSequence.prototype.__iterator = function (s, o) { + if (this._useKeys) return this._iter.__iterator(s, o); + var i = this._iter.__iterator(U, o), + u = o ? resolveSize(this) : 0; + return new Iterator(function () { + var _ = i.next(); + return _.done ? _ : iteratorValue(s, o ? --u : u++, _.value, _); + }); + }), + (ToKeyedSequence.prototype[_] = !0), + createClass(ToIndexedSequence, IndexedSeq), + (ToIndexedSequence.prototype.includes = function (s) { + return this._iter.includes(s); + }), + (ToIndexedSequence.prototype.__iterate = function (s, o) { + var i = this, + u = 0; + return this._iter.__iterate(function (o) { + return s(o, u++, i); + }, o); + }), + (ToIndexedSequence.prototype.__iterator = function (s, o) { + var i = this._iter.__iterator(U, o), + u = 0; + return new Iterator(function () { + var o = i.next(); + return o.done ? o : iteratorValue(s, u++, o.value, o); + }); + }), + createClass(ToSetSequence, SetSeq), + (ToSetSequence.prototype.has = function (s) { + return this._iter.includes(s); + }), + (ToSetSequence.prototype.__iterate = function (s, o) { + var i = this; + return this._iter.__iterate(function (o) { + return s(o, o, i); + }, o); + }), + (ToSetSequence.prototype.__iterator = function (s, o) { + var i = this._iter.__iterator(U, o); + return new Iterator(function () { + var o = i.next(); + return o.done ? o : iteratorValue(s, o.value, o.value, o); + }); + }), + createClass(FromEntriesSequence, KeyedSeq), + (FromEntriesSequence.prototype.entrySeq = function () { + return this._iter.toSeq(); + }), + (FromEntriesSequence.prototype.__iterate = function (s, o) { + var i = this; + return this._iter.__iterate(function (o) { + if (o) { + validateEntry(o); + var u = isIterable(o); + return s(u ? o.get(1) : o[1], u ? o.get(0) : o[0], i); + } + }, o); + }), + (FromEntriesSequence.prototype.__iterator = function (s, o) { + var i = this._iter.__iterator(U, o); + return new Iterator(function () { + for (;;) { + var o = i.next(); + if (o.done) return o; + var u = o.value; + if (u) { + validateEntry(u); + var _ = isIterable(u); + return iteratorValue(s, _ ? u.get(0) : u[0], _ ? u.get(1) : u[1], o); + } + } + }); + }), + (ToIndexedSequence.prototype.cacheResult = + ToKeyedSequence.prototype.cacheResult = + ToSetSequence.prototype.cacheResult = + FromEntriesSequence.prototype.cacheResult = + cacheResultThrough), + createClass(Record, KeyedCollection), + (Record.prototype.toString = function () { + return this.__toString(recordName(this) + ' {', '}'); + }), + (Record.prototype.has = function (s) { + return this._defaultValues.hasOwnProperty(s); + }), + (Record.prototype.get = function (s, o) { + if (!this.has(s)) return o; + var i = this._defaultValues[s]; + return this._map ? this._map.get(s, i) : i; + }), + (Record.prototype.clear = function () { + if (this.__ownerID) return this._map && this._map.clear(), this; + var s = this.constructor; + return s._empty || (s._empty = makeRecord(this, emptyMap())); + }), + (Record.prototype.set = function (s, o) { + if (!this.has(s)) + throw new Error('Cannot set unknown key "' + s + '" on ' + recordName(this)); + if (this._map && !this._map.has(s) && o === this._defaultValues[s]) return this; + var i = this._map && this._map.set(s, o); + return this.__ownerID || i === this._map ? this : makeRecord(this, i); + }), + (Record.prototype.remove = function (s) { + if (!this.has(s)) return this; + var o = this._map && this._map.remove(s); + return this.__ownerID || o === this._map ? this : makeRecord(this, o); + }), + (Record.prototype.wasAltered = function () { + return this._map.wasAltered(); + }), + (Record.prototype.__iterator = function (s, o) { + var i = this; + return KeyedIterable(this._defaultValues) + .map(function (s, o) { + return i.get(o); + }) + .__iterator(s, o); + }), + (Record.prototype.__iterate = function (s, o) { + var i = this; + return KeyedIterable(this._defaultValues) + .map(function (s, o) { + return i.get(o); + }) + .__iterate(s, o); + }), + (Record.prototype.__ensureOwner = function (s) { + if (s === this.__ownerID) return this; + var o = this._map && this._map.__ensureOwner(s); + return s ? makeRecord(this, o, s) : ((this.__ownerID = s), (this._map = o), this); + }); + var rt = Record.prototype; + function makeRecord(s, o, i) { + var u = Object.create(Object.getPrototypeOf(s)); + return (u._map = o), (u.__ownerID = i), u; + } + function recordName(s) { + return s._name || s.constructor.name || 'Record'; + } + function setProps(s, o) { + try { + o.forEach(setProp.bind(void 0, s)); + } catch (s) {} + } + function setProp(s, o) { + Object.defineProperty(s, o, { + get: function () { + return this.get(o); + }, + set: function (s) { + invariant(this.__ownerID, 'Cannot set on an immutable record.'), this.set(o, s); + } + }); + } + function Set(s) { + return null == s + ? emptySet() + : isSet(s) && !isOrdered(s) + ? s + : emptySet().withMutations(function (o) { + var i = SetIterable(s); + assertNotInfinite(i.size), + i.forEach(function (s) { + return o.add(s); + }); + }); + } + function isSet(s) { + return !(!s || !s[st]); + } + (rt[w] = rt.remove), + (rt.deleteIn = rt.removeIn = $e.removeIn), + (rt.merge = $e.merge), + (rt.mergeWith = $e.mergeWith), + (rt.mergeIn = $e.mergeIn), + (rt.mergeDeep = $e.mergeDeep), + (rt.mergeDeepWith = $e.mergeDeepWith), + (rt.mergeDeepIn = $e.mergeDeepIn), + (rt.setIn = $e.setIn), + (rt.update = $e.update), + (rt.updateIn = $e.updateIn), + (rt.withMutations = $e.withMutations), + (rt.asMutable = $e.asMutable), + (rt.asImmutable = $e.asImmutable), + createClass(Set, SetCollection), + (Set.of = function () { + return this(arguments); + }), + (Set.fromKeys = function (s) { + return this(KeyedIterable(s).keySeq()); + }), + (Set.prototype.toString = function () { + return this.__toString('Set {', '}'); + }), + (Set.prototype.has = function (s) { + return this._map.has(s); + }), + (Set.prototype.add = function (s) { + return updateSet(this, this._map.set(s, !0)); + }), + (Set.prototype.remove = function (s) { + return updateSet(this, this._map.remove(s)); + }), + (Set.prototype.clear = function () { + return updateSet(this, this._map.clear()); + }), + (Set.prototype.union = function () { + var o = s.call(arguments, 0); + return 0 === + (o = o.filter(function (s) { + return 0 !== s.size; + })).length + ? this + : 0 !== this.size || this.__ownerID || 1 !== o.length + ? this.withMutations(function (s) { + for (var i = 0; i < o.length; i++) + SetIterable(o[i]).forEach(function (o) { + return s.add(o); + }); + }) + : this.constructor(o[0]); + }), + (Set.prototype.intersect = function () { + var o = s.call(arguments, 0); + if (0 === o.length) return this; + o = o.map(function (s) { + return SetIterable(s); + }); + var i = this; + return this.withMutations(function (s) { + i.forEach(function (i) { + o.every(function (s) { + return s.includes(i); + }) || s.remove(i); + }); + }); + }), + (Set.prototype.subtract = function () { + var o = s.call(arguments, 0); + if (0 === o.length) return this; + o = o.map(function (s) { + return SetIterable(s); + }); + var i = this; + return this.withMutations(function (s) { + i.forEach(function (i) { + o.some(function (s) { + return s.includes(i); + }) && s.remove(i); + }); + }); + }), + (Set.prototype.merge = function () { + return this.union.apply(this, arguments); + }), + (Set.prototype.mergeWith = function (o) { + var i = s.call(arguments, 1); + return this.union.apply(this, i); + }), + (Set.prototype.sort = function (s) { + return OrderedSet(sortFactory(this, s)); + }), + (Set.prototype.sortBy = function (s, o) { + return OrderedSet(sortFactory(this, o, s)); + }), + (Set.prototype.wasAltered = function () { + return this._map.wasAltered(); + }), + (Set.prototype.__iterate = function (s, o) { + var i = this; + return this._map.__iterate(function (o, u) { + return s(u, u, i); + }, o); + }), + (Set.prototype.__iterator = function (s, o) { + return this._map + .map(function (s, o) { + return o; + }) + .__iterator(s, o); + }), + (Set.prototype.__ensureOwner = function (s) { + if (s === this.__ownerID) return this; + var o = this._map.__ensureOwner(s); + return s ? this.__make(o, s) : ((this.__ownerID = s), (this._map = o), this); + }), + (Set.isSet = isSet); + var nt, + st = '@@__IMMUTABLE_SET__@@', + ot = Set.prototype; + function updateSet(s, o) { + return s.__ownerID + ? ((s.size = o.size), (s._map = o), s) + : o === s._map + ? s + : 0 === o.size + ? s.__empty() + : s.__make(o); + } + function makeSet(s, o) { + var i = Object.create(ot); + return (i.size = s ? s.size : 0), (i._map = s), (i.__ownerID = o), i; + } + function emptySet() { + return nt || (nt = makeSet(emptyMap())); + } + function OrderedSet(s) { + return null == s + ? emptyOrderedSet() + : isOrderedSet(s) + ? s + : emptyOrderedSet().withMutations(function (o) { + var i = SetIterable(s); + assertNotInfinite(i.size), + i.forEach(function (s) { + return o.add(s); + }); + }); + } + function isOrderedSet(s) { + return isSet(s) && isOrdered(s); + } + (ot[st] = !0), + (ot[w] = ot.remove), + (ot.mergeDeep = ot.merge), + (ot.mergeDeepWith = ot.mergeWith), + (ot.withMutations = $e.withMutations), + (ot.asMutable = $e.asMutable), + (ot.asImmutable = $e.asImmutable), + (ot.__empty = emptySet), + (ot.__make = makeSet), + createClass(OrderedSet, Set), + (OrderedSet.of = function () { + return this(arguments); + }), + (OrderedSet.fromKeys = function (s) { + return this(KeyedIterable(s).keySeq()); + }), + (OrderedSet.prototype.toString = function () { + return this.__toString('OrderedSet {', '}'); + }), + (OrderedSet.isOrderedSet = isOrderedSet); + var it, + at = OrderedSet.prototype; + function makeOrderedSet(s, o) { + var i = Object.create(at); + return (i.size = s ? s.size : 0), (i._map = s), (i.__ownerID = o), i; + } + function emptyOrderedSet() { + return it || (it = makeOrderedSet(emptyOrderedMap())); + } + function Stack(s) { + return null == s ? emptyStack() : isStack(s) ? s : emptyStack().unshiftAll(s); + } + function isStack(s) { + return !(!s || !s[ct]); + } + (at[_] = !0), + (at.__empty = emptyOrderedSet), + (at.__make = makeOrderedSet), + createClass(Stack, IndexedCollection), + (Stack.of = function () { + return this(arguments); + }), + (Stack.prototype.toString = function () { + return this.__toString('Stack [', ']'); + }), + (Stack.prototype.get = function (s, o) { + var i = this._head; + for (s = wrapIndex(this, s); i && s--; ) i = i.next; + return i ? i.value : o; + }), + (Stack.prototype.peek = function () { + return this._head && this._head.value; + }), + (Stack.prototype.push = function () { + if (0 === arguments.length) return this; + for ( + var s = this.size + arguments.length, o = this._head, i = arguments.length - 1; + i >= 0; + i-- + ) + o = { value: arguments[i], next: o }; + return this.__ownerID + ? ((this.size = s), + (this._head = o), + (this.__hash = void 0), + (this.__altered = !0), + this) + : makeStack(s, o); + }), + (Stack.prototype.pushAll = function (s) { + if (0 === (s = IndexedIterable(s)).size) return this; + assertNotInfinite(s.size); + var o = this.size, + i = this._head; + return ( + s.reverse().forEach(function (s) { + o++, (i = { value: s, next: i }); + }), + this.__ownerID + ? ((this.size = o), + (this._head = i), + (this.__hash = void 0), + (this.__altered = !0), + this) + : makeStack(o, i) + ); + }), + (Stack.prototype.pop = function () { + return this.slice(1); + }), + (Stack.prototype.unshift = function () { + return this.push.apply(this, arguments); + }), + (Stack.prototype.unshiftAll = function (s) { + return this.pushAll(s); + }), + (Stack.prototype.shift = function () { + return this.pop.apply(this, arguments); + }), + (Stack.prototype.clear = function () { + return 0 === this.size + ? this + : this.__ownerID + ? ((this.size = 0), + (this._head = void 0), + (this.__hash = void 0), + (this.__altered = !0), + this) + : emptyStack(); + }), + (Stack.prototype.slice = function (s, o) { + if (wholeSlice(s, o, this.size)) return this; + var i = resolveBegin(s, this.size); + if (resolveEnd(o, this.size) !== this.size) + return IndexedCollection.prototype.slice.call(this, s, o); + for (var u = this.size - i, _ = this._head; i--; ) _ = _.next; + return this.__ownerID + ? ((this.size = u), + (this._head = _), + (this.__hash = void 0), + (this.__altered = !0), + this) + : makeStack(u, _); + }), + (Stack.prototype.__ensureOwner = function (s) { + return s === this.__ownerID + ? this + : s + ? makeStack(this.size, this._head, s, this.__hash) + : ((this.__ownerID = s), (this.__altered = !1), this); + }), + (Stack.prototype.__iterate = function (s, o) { + if (o) return this.reverse().__iterate(s); + for (var i = 0, u = this._head; u && !1 !== s(u.value, i++, this); ) u = u.next; + return i; + }), + (Stack.prototype.__iterator = function (s, o) { + if (o) return this.reverse().__iterator(s); + var i = 0, + u = this._head; + return new Iterator(function () { + if (u) { + var o = u.value; + return (u = u.next), iteratorValue(s, i++, o); + } + return iteratorDone(); + }); + }), + (Stack.isStack = isStack); + var lt, + ct = '@@__IMMUTABLE_STACK__@@', + ut = Stack.prototype; + function makeStack(s, o, i, u) { + var _ = Object.create(ut); + return ( + (_.size = s), + (_._head = o), + (_.__ownerID = i), + (_.__hash = u), + (_.__altered = !1), + _ + ); + } + function emptyStack() { + return lt || (lt = makeStack(0)); + } + function mixin(s, o) { + var keyCopier = function (i) { + s.prototype[i] = o[i]; + }; + return ( + Object.keys(o).forEach(keyCopier), + Object.getOwnPropertySymbols && Object.getOwnPropertySymbols(o).forEach(keyCopier), + s + ); + } + (ut[ct] = !0), + (ut.withMutations = $e.withMutations), + (ut.asMutable = $e.asMutable), + (ut.asImmutable = $e.asImmutable), + (ut.wasAltered = $e.wasAltered), + (Iterable.Iterator = Iterator), + mixin(Iterable, { + toArray: function () { + assertNotInfinite(this.size); + var s = new Array(this.size || 0); + return ( + this.valueSeq().__iterate(function (o, i) { + s[i] = o; + }), + s + ); + }, + toIndexedSeq: function () { + return new ToIndexedSequence(this); + }, + toJS: function () { + return this.toSeq() + .map(function (s) { + return s && 'function' == typeof s.toJS ? s.toJS() : s; + }) + .__toJS(); + }, + toJSON: function () { + return this.toSeq() + .map(function (s) { + return s && 'function' == typeof s.toJSON ? s.toJSON() : s; + }) + .__toJS(); + }, + toKeyedSeq: function () { + return new ToKeyedSequence(this, !0); + }, + toMap: function () { + return Map(this.toKeyedSeq()); + }, + toObject: function () { + assertNotInfinite(this.size); + var s = {}; + return ( + this.__iterate(function (o, i) { + s[i] = o; + }), + s + ); + }, + toOrderedMap: function () { + return OrderedMap(this.toKeyedSeq()); + }, + toOrderedSet: function () { + return OrderedSet(isKeyed(this) ? this.valueSeq() : this); + }, + toSet: function () { + return Set(isKeyed(this) ? this.valueSeq() : this); + }, + toSetSeq: function () { + return new ToSetSequence(this); + }, + toSeq: function () { + return isIndexed(this) + ? this.toIndexedSeq() + : isKeyed(this) + ? this.toKeyedSeq() + : this.toSetSeq(); + }, + toStack: function () { + return Stack(isKeyed(this) ? this.valueSeq() : this); + }, + toList: function () { + return List(isKeyed(this) ? this.valueSeq() : this); + }, + toString: function () { + return '[Iterable]'; + }, + __toString: function (s, o) { + return 0 === this.size + ? s + o + : s + ' ' + this.toSeq().map(this.__toStringMapper).join(', ') + ' ' + o; + }, + concat: function () { + return reify(this, concatFactory(this, s.call(arguments, 0))); + }, + includes: function (s) { + return this.some(function (o) { + return is(o, s); + }); + }, + entries: function () { + return this.__iterator(z); + }, + every: function (s, o) { + assertNotInfinite(this.size); + var i = !0; + return ( + this.__iterate(function (u, _, w) { + if (!s.call(o, u, _, w)) return (i = !1), !1; + }), + i + ); + }, + filter: function (s, o) { + return reify(this, filterFactory(this, s, o, !0)); + }, + find: function (s, o, i) { + var u = this.findEntry(s, o); + return u ? u[1] : i; + }, + forEach: function (s, o) { + return assertNotInfinite(this.size), this.__iterate(o ? s.bind(o) : s); + }, + join: function (s) { + assertNotInfinite(this.size), (s = void 0 !== s ? '' + s : ','); + var o = '', + i = !0; + return ( + this.__iterate(function (u) { + i ? (i = !1) : (o += s), (o += null != u ? u.toString() : ''); + }), + o + ); + }, + keys: function () { + return this.__iterator(V); + }, + map: function (s, o) { + return reify(this, mapFactory(this, s, o)); + }, + reduce: function (s, o, i) { + var u, _; + return ( + assertNotInfinite(this.size), + arguments.length < 2 ? (_ = !0) : (u = o), + this.__iterate(function (o, w, x) { + _ ? ((_ = !1), (u = o)) : (u = s.call(i, u, o, w, x)); + }), + u + ); + }, + reduceRight: function (s, o, i) { + var u = this.toKeyedSeq().reverse(); + return u.reduce.apply(u, arguments); + }, + reverse: function () { + return reify(this, reverseFactory(this, !0)); + }, + slice: function (s, o) { + return reify(this, sliceFactory(this, s, o, !0)); + }, + some: function (s, o) { + return !this.every(not(s), o); + }, + sort: function (s) { + return reify(this, sortFactory(this, s)); + }, + values: function () { + return this.__iterator(U); + }, + butLast: function () { + return this.slice(0, -1); + }, + isEmpty: function () { + return void 0 !== this.size + ? 0 === this.size + : !this.some(function () { + return !0; + }); + }, + count: function (s, o) { + return ensureSize(s ? this.toSeq().filter(s, o) : this); + }, + countBy: function (s, o) { + return countByFactory(this, s, o); + }, + equals: function (s) { + return deepEqual(this, s); + }, + entrySeq: function () { + var s = this; + if (s._cache) return new ArraySeq(s._cache); + var o = s.toSeq().map(entryMapper).toIndexedSeq(); + return ( + (o.fromEntrySeq = function () { + return s.toSeq(); + }), + o + ); + }, + filterNot: function (s, o) { + return this.filter(not(s), o); + }, + findEntry: function (s, o, i) { + var u = i; + return ( + this.__iterate(function (i, _, w) { + if (s.call(o, i, _, w)) return (u = [_, i]), !1; + }), + u + ); + }, + findKey: function (s, o) { + var i = this.findEntry(s, o); + return i && i[0]; + }, + findLast: function (s, o, i) { + return this.toKeyedSeq().reverse().find(s, o, i); + }, + findLastEntry: function (s, o, i) { + return this.toKeyedSeq().reverse().findEntry(s, o, i); + }, + findLastKey: function (s, o) { + return this.toKeyedSeq().reverse().findKey(s, o); + }, + first: function () { + return this.find(returnTrue); + }, + flatMap: function (s, o) { + return reify(this, flatMapFactory(this, s, o)); + }, + flatten: function (s) { + return reify(this, flattenFactory(this, s, !0)); + }, + fromEntrySeq: function () { + return new FromEntriesSequence(this); + }, + get: function (s, o) { + return this.find( + function (o, i) { + return is(i, s); + }, + void 0, + o + ); + }, + getIn: function (s, o) { + for (var i, u = this, _ = forceIterator(s); !(i = _.next()).done; ) { + var w = i.value; + if ((u = u && u.get ? u.get(w, L) : L) === L) return o; + } + return u; + }, + groupBy: function (s, o) { + return groupByFactory(this, s, o); + }, + has: function (s) { + return this.get(s, L) !== L; + }, + hasIn: function (s) { + return this.getIn(s, L) !== L; + }, + isSubset: function (s) { + return ( + (s = 'function' == typeof s.includes ? s : Iterable(s)), + this.every(function (o) { + return s.includes(o); + }) + ); + }, + isSuperset: function (s) { + return (s = 'function' == typeof s.isSubset ? s : Iterable(s)).isSubset(this); + }, + keyOf: function (s) { + return this.findKey(function (o) { + return is(o, s); + }); + }, + keySeq: function () { + return this.toSeq().map(keyMapper).toIndexedSeq(); + }, + last: function () { + return this.toSeq().reverse().first(); + }, + lastKeyOf: function (s) { + return this.toKeyedSeq().reverse().keyOf(s); + }, + max: function (s) { + return maxFactory(this, s); + }, + maxBy: function (s, o) { + return maxFactory(this, o, s); + }, + min: function (s) { + return maxFactory(this, s ? neg(s) : defaultNegComparator); + }, + minBy: function (s, o) { + return maxFactory(this, o ? neg(o) : defaultNegComparator, s); + }, + rest: function () { + return this.slice(1); + }, + skip: function (s) { + return this.slice(Math.max(0, s)); + }, + skipLast: function (s) { + return reify(this, this.toSeq().reverse().skip(s).reverse()); + }, + skipWhile: function (s, o) { + return reify(this, skipWhileFactory(this, s, o, !0)); + }, + skipUntil: function (s, o) { + return this.skipWhile(not(s), o); + }, + sortBy: function (s, o) { + return reify(this, sortFactory(this, o, s)); + }, + take: function (s) { + return this.slice(0, Math.max(0, s)); + }, + takeLast: function (s) { + return reify(this, this.toSeq().reverse().take(s).reverse()); + }, + takeWhile: function (s, o) { + return reify(this, takeWhileFactory(this, s, o)); + }, + takeUntil: function (s, o) { + return this.takeWhile(not(s), o); + }, + valueSeq: function () { + return this.toIndexedSeq(); + }, + hashCode: function () { + return this.__hash || (this.__hash = hashIterable(this)); + } + }); + var pt = Iterable.prototype; + (pt[o] = !0), + (pt[ee] = pt.values), + (pt.__toJS = pt.toArray), + (pt.__toStringMapper = quoteString), + (pt.inspect = pt.toSource = + function () { + return this.toString(); + }), + (pt.chain = pt.flatMap), + (pt.contains = pt.includes), + mixin(KeyedIterable, { + flip: function () { + return reify(this, flipFactory(this)); + }, + mapEntries: function (s, o) { + var i = this, + u = 0; + return reify( + this, + this.toSeq() + .map(function (_, w) { + return s.call(o, [w, _], u++, i); + }) + .fromEntrySeq() + ); + }, + mapKeys: function (s, o) { + var i = this; + return reify( + this, + this.toSeq() + .flip() + .map(function (u, _) { + return s.call(o, u, _, i); + }) + .flip() + ); + } + }); + var ht = KeyedIterable.prototype; + function keyMapper(s, o) { + return o; + } + function entryMapper(s, o) { + return [o, s]; + } + function not(s) { + return function () { + return !s.apply(this, arguments); + }; + } + function neg(s) { + return function () { + return -s.apply(this, arguments); + }; + } + function quoteString(s) { + return 'string' == typeof s ? JSON.stringify(s) : String(s); + } + function defaultZipper() { + return arrCopy(arguments); + } + function defaultNegComparator(s, o) { + return s < o ? 1 : s > o ? -1 : 0; + } + function hashIterable(s) { + if (s.size === 1 / 0) return 0; + var o = isOrdered(s), + i = isKeyed(s), + u = o ? 1 : 0; + return murmurHashOfSize( + s.__iterate( + i + ? o + ? function (s, o) { + u = (31 * u + hashMerge(hash(s), hash(o))) | 0; + } + : function (s, o) { + u = (u + hashMerge(hash(s), hash(o))) | 0; + } + : o + ? function (s) { + u = (31 * u + hash(s)) | 0; + } + : function (s) { + u = (u + hash(s)) | 0; + } + ), + u + ); + } + function murmurHashOfSize(s, o) { + return ( + (o = pe(o, 3432918353)), + (o = pe((o << 15) | (o >>> -15), 461845907)), + (o = pe((o << 13) | (o >>> -13), 5)), + (o = pe((o = (o + 3864292196) ^ s) ^ (o >>> 16), 2246822507)), + (o = smi((o = pe(o ^ (o >>> 13), 3266489909)) ^ (o >>> 16))) + ); + } + function hashMerge(s, o) { + return s ^ (o + 2654435769 + (s << 6) + (s >> 2)); + } + return ( + (ht[i] = !0), + (ht[ee] = pt.entries), + (ht.__toJS = pt.toObject), + (ht.__toStringMapper = function (s, o) { + return JSON.stringify(o) + ': ' + quoteString(s); + }), + mixin(IndexedIterable, { + toKeyedSeq: function () { + return new ToKeyedSequence(this, !1); + }, + filter: function (s, o) { + return reify(this, filterFactory(this, s, o, !1)); + }, + findIndex: function (s, o) { + var i = this.findEntry(s, o); + return i ? i[0] : -1; + }, + indexOf: function (s) { + var o = this.keyOf(s); + return void 0 === o ? -1 : o; + }, + lastIndexOf: function (s) { + var o = this.lastKeyOf(s); + return void 0 === o ? -1 : o; + }, + reverse: function () { + return reify(this, reverseFactory(this, !1)); + }, + slice: function (s, o) { + return reify(this, sliceFactory(this, s, o, !1)); + }, + splice: function (s, o) { + var i = arguments.length; + if (((o = Math.max(0 | o, 0)), 0 === i || (2 === i && !o))) return this; + s = resolveBegin(s, s < 0 ? this.count() : this.size); + var u = this.slice(0, s); + return reify( + this, + 1 === i ? u : u.concat(arrCopy(arguments, 2), this.slice(s + o)) + ); + }, + findLastIndex: function (s, o) { + var i = this.findLastEntry(s, o); + return i ? i[0] : -1; + }, + first: function () { + return this.get(0); + }, + flatten: function (s) { + return reify(this, flattenFactory(this, s, !1)); + }, + get: function (s, o) { + return (s = wrapIndex(this, s)) < 0 || + this.size === 1 / 0 || + (void 0 !== this.size && s > this.size) + ? o + : this.find( + function (o, i) { + return i === s; + }, + void 0, + o + ); + }, + has: function (s) { + return ( + (s = wrapIndex(this, s)) >= 0 && + (void 0 !== this.size + ? this.size === 1 / 0 || s < this.size + : -1 !== this.indexOf(s)) + ); + }, + interpose: function (s) { + return reify(this, interposeFactory(this, s)); + }, + interleave: function () { + var s = [this].concat(arrCopy(arguments)), + o = zipWithFactory(this.toSeq(), IndexedSeq.of, s), + i = o.flatten(!0); + return o.size && (i.size = o.size * s.length), reify(this, i); + }, + keySeq: function () { + return Range(0, this.size); + }, + last: function () { + return this.get(-1); + }, + skipWhile: function (s, o) { + return reify(this, skipWhileFactory(this, s, o, !1)); + }, + zip: function () { + return reify( + this, + zipWithFactory(this, defaultZipper, [this].concat(arrCopy(arguments))) + ); + }, + zipWith: function (s) { + var o = arrCopy(arguments); + return (o[0] = this), reify(this, zipWithFactory(this, s, o)); + } + }), + (IndexedIterable.prototype[u] = !0), + (IndexedIterable.prototype[_] = !0), + mixin(SetIterable, { + get: function (s, o) { + return this.has(s) ? s : o; + }, + includes: function (s) { + return this.has(s); + }, + keySeq: function () { + return this.valueSeq(); + } + }), + (SetIterable.prototype.has = pt.includes), + (SetIterable.prototype.contains = SetIterable.prototype.includes), + mixin(KeyedSeq, KeyedIterable.prototype), + mixin(IndexedSeq, IndexedIterable.prototype), + mixin(SetSeq, SetIterable.prototype), + mixin(KeyedCollection, KeyedIterable.prototype), + mixin(IndexedCollection, IndexedIterable.prototype), + mixin(SetCollection, SetIterable.prototype), + { + Iterable, + Seq, + Collection, + Map, + OrderedMap, + List, + Stack, + Set, + OrderedSet, + Record, + Range, + Repeat, + is, + fromJS + } + ); + })(); + }, + 56698: (s) => { + 'function' == typeof Object.create + ? (s.exports = function inherits(s, o) { + o && + ((s.super_ = o), + (s.prototype = Object.create(o.prototype, { + constructor: { value: s, enumerable: !1, writable: !0, configurable: !0 } + }))); + }) + : (s.exports = function inherits(s, o) { + if (o) { + s.super_ = o; + var TempCtor = function () {}; + (TempCtor.prototype = o.prototype), + (s.prototype = new TempCtor()), + (s.prototype.constructor = s); + } + }); + }, + 5419: (s) => { + s.exports = function (s, o, i, u) { + var _ = new Blob(void 0 !== u ? [u, s] : [s], { + type: i || 'application/octet-stream' + }); + if (void 0 !== window.navigator.msSaveBlob) window.navigator.msSaveBlob(_, o); + else { + var w = + window.URL && window.URL.createObjectURL + ? window.URL.createObjectURL(_) + : window.webkitURL.createObjectURL(_), + x = document.createElement('a'); + (x.style.display = 'none'), + (x.href = w), + x.setAttribute('download', o), + void 0 === x.download && x.setAttribute('target', '_blank'), + document.body.appendChild(x), + x.click(), + setTimeout(function () { + document.body.removeChild(x), window.URL.revokeObjectURL(w); + }, 200); + } + }; + }, + 20181: (s, o, i) => { + var u = /^\s+|\s+$/g, + _ = /^[-+]0x[0-9a-f]+$/i, + w = /^0b[01]+$/i, + x = /^0o[0-7]+$/i, + C = parseInt, + j = 'object' == typeof i.g && i.g && i.g.Object === Object && i.g, + L = 'object' == typeof self && self && self.Object === Object && self, + B = j || L || Function('return this')(), + $ = Object.prototype.toString, + V = Math.max, + U = Math.min, + now = function () { + return B.Date.now(); + }; + function isObject(s) { + var o = typeof s; + return !!s && ('object' == o || 'function' == o); + } + function toNumber(s) { + if ('number' == typeof s) return s; + if ( + (function isSymbol(s) { + return ( + 'symbol' == typeof s || + ((function isObjectLike(s) { + return !!s && 'object' == typeof s; + })(s) && + '[object Symbol]' == $.call(s)) + ); + })(s) + ) + return NaN; + if (isObject(s)) { + var o = 'function' == typeof s.valueOf ? s.valueOf() : s; + s = isObject(o) ? o + '' : o; + } + if ('string' != typeof s) return 0 === s ? s : +s; + s = s.replace(u, ''); + var i = w.test(s); + return i || x.test(s) ? C(s.slice(2), i ? 2 : 8) : _.test(s) ? NaN : +s; + } + s.exports = function debounce(s, o, i) { + var u, + _, + w, + x, + C, + j, + L = 0, + B = !1, + $ = !1, + z = !0; + if ('function' != typeof s) throw new TypeError('Expected a function'); + function invokeFunc(o) { + var i = u, + w = _; + return (u = _ = void 0), (L = o), (x = s.apply(w, i)); + } + function shouldInvoke(s) { + var i = s - j; + return void 0 === j || i >= o || i < 0 || ($ && s - L >= w); + } + function timerExpired() { + var s = now(); + if (shouldInvoke(s)) return trailingEdge(s); + C = setTimeout( + timerExpired, + (function remainingWait(s) { + var i = o - (s - j); + return $ ? U(i, w - (s - L)) : i; + })(s) + ); + } + function trailingEdge(s) { + return (C = void 0), z && u ? invokeFunc(s) : ((u = _ = void 0), x); + } + function debounced() { + var s = now(), + i = shouldInvoke(s); + if (((u = arguments), (_ = this), (j = s), i)) { + if (void 0 === C) + return (function leadingEdge(s) { + return (L = s), (C = setTimeout(timerExpired, o)), B ? invokeFunc(s) : x; + })(j); + if ($) return (C = setTimeout(timerExpired, o)), invokeFunc(j); + } + return void 0 === C && (C = setTimeout(timerExpired, o)), x; + } + return ( + (o = toNumber(o) || 0), + isObject(i) && + ((B = !!i.leading), + (w = ($ = 'maxWait' in i) ? V(toNumber(i.maxWait) || 0, o) : w), + (z = 'trailing' in i ? !!i.trailing : z)), + (debounced.cancel = function cancel() { + void 0 !== C && clearTimeout(C), (L = 0), (u = j = _ = C = void 0); + }), + (debounced.flush = function flush() { + return void 0 === C ? x : trailingEdge(now()); + }), + debounced + ); + }; + }, + 55580: (s, o, i) => { + var u = i(56110)(i(9325), 'DataView'); + s.exports = u; + }, + 21549: (s, o, i) => { + var u = i(22032), + _ = i(63862), + w = i(66721), + x = i(12749), + C = i(35749); + function Hash(s) { + var o = -1, + i = null == s ? 0 : s.length; + for (this.clear(); ++o < i; ) { + var u = s[o]; + this.set(u[0], u[1]); + } + } + (Hash.prototype.clear = u), + (Hash.prototype.delete = _), + (Hash.prototype.get = w), + (Hash.prototype.has = x), + (Hash.prototype.set = C), + (s.exports = Hash); + }, + 30980: (s, o, i) => { + var u = i(39344), + _ = i(94033); + function LazyWrapper(s) { + (this.__wrapped__ = s), + (this.__actions__ = []), + (this.__dir__ = 1), + (this.__filtered__ = !1), + (this.__iteratees__ = []), + (this.__takeCount__ = 4294967295), + (this.__views__ = []); + } + (LazyWrapper.prototype = u(_.prototype)), + (LazyWrapper.prototype.constructor = LazyWrapper), + (s.exports = LazyWrapper); + }, + 80079: (s, o, i) => { + var u = i(63702), + _ = i(70080), + w = i(24739), + x = i(48655), + C = i(31175); + function ListCache(s) { + var o = -1, + i = null == s ? 0 : s.length; + for (this.clear(); ++o < i; ) { + var u = s[o]; + this.set(u[0], u[1]); + } + } + (ListCache.prototype.clear = u), + (ListCache.prototype.delete = _), + (ListCache.prototype.get = w), + (ListCache.prototype.has = x), + (ListCache.prototype.set = C), + (s.exports = ListCache); + }, + 56017: (s, o, i) => { + var u = i(39344), + _ = i(94033); + function LodashWrapper(s, o) { + (this.__wrapped__ = s), + (this.__actions__ = []), + (this.__chain__ = !!o), + (this.__index__ = 0), + (this.__values__ = void 0); + } + (LodashWrapper.prototype = u(_.prototype)), + (LodashWrapper.prototype.constructor = LodashWrapper), + (s.exports = LodashWrapper); + }, + 68223: (s, o, i) => { + var u = i(56110)(i(9325), 'Map'); + s.exports = u; + }, + 53661: (s, o, i) => { + var u = i(63040), + _ = i(17670), + w = i(90289), + x = i(4509), + C = i(72949); + function MapCache(s) { + var o = -1, + i = null == s ? 0 : s.length; + for (this.clear(); ++o < i; ) { + var u = s[o]; + this.set(u[0], u[1]); + } + } + (MapCache.prototype.clear = u), + (MapCache.prototype.delete = _), + (MapCache.prototype.get = w), + (MapCache.prototype.has = x), + (MapCache.prototype.set = C), + (s.exports = MapCache); + }, + 32804: (s, o, i) => { + var u = i(56110)(i(9325), 'Promise'); + s.exports = u; + }, + 76545: (s, o, i) => { + var u = i(56110)(i(9325), 'Set'); + s.exports = u; + }, + 38859: (s, o, i) => { + var u = i(53661), + _ = i(31380), + w = i(51459); + function SetCache(s) { + var o = -1, + i = null == s ? 0 : s.length; + for (this.__data__ = new u(); ++o < i; ) this.add(s[o]); + } + (SetCache.prototype.add = SetCache.prototype.push = _), + (SetCache.prototype.has = w), + (s.exports = SetCache); + }, + 37217: (s, o, i) => { + var u = i(80079), + _ = i(51420), + w = i(90938), + x = i(63605), + C = i(29817), + j = i(80945); + function Stack(s) { + var o = (this.__data__ = new u(s)); + this.size = o.size; + } + (Stack.prototype.clear = _), + (Stack.prototype.delete = w), + (Stack.prototype.get = x), + (Stack.prototype.has = C), + (Stack.prototype.set = j), + (s.exports = Stack); + }, + 51873: (s, o, i) => { + var u = i(9325).Symbol; + s.exports = u; + }, + 37828: (s, o, i) => { + var u = i(9325).Uint8Array; + s.exports = u; + }, + 28303: (s, o, i) => { + var u = i(56110)(i(9325), 'WeakMap'); + s.exports = u; + }, + 91033: (s) => { + s.exports = function apply(s, o, i) { + switch (i.length) { + case 0: + return s.call(o); + case 1: + return s.call(o, i[0]); + case 2: + return s.call(o, i[0], i[1]); + case 3: + return s.call(o, i[0], i[1], i[2]); + } + return s.apply(o, i); + }; + }, + 83729: (s) => { + s.exports = function arrayEach(s, o) { + for (var i = -1, u = null == s ? 0 : s.length; ++i < u && !1 !== o(s[i], i, s); ); + return s; + }; + }, + 79770: (s) => { + s.exports = function arrayFilter(s, o) { + for (var i = -1, u = null == s ? 0 : s.length, _ = 0, w = []; ++i < u; ) { + var x = s[i]; + o(x, i, s) && (w[_++] = x); + } + return w; + }; + }, + 15325: (s, o, i) => { + var u = i(96131); + s.exports = function arrayIncludes(s, o) { + return !!(null == s ? 0 : s.length) && u(s, o, 0) > -1; + }; + }, + 70695: (s, o, i) => { + var u = i(78096), + _ = i(72428), + w = i(56449), + x = i(3656), + C = i(30361), + j = i(37167), + L = Object.prototype.hasOwnProperty; + s.exports = function arrayLikeKeys(s, o) { + var i = w(s), + B = !i && _(s), + $ = !i && !B && x(s), + V = !i && !B && !$ && j(s), + U = i || B || $ || V, + z = U ? u(s.length, String) : [], + Y = z.length; + for (var Z in s) + (!o && !L.call(s, Z)) || + (U && + ('length' == Z || + ($ && ('offset' == Z || 'parent' == Z)) || + (V && ('buffer' == Z || 'byteLength' == Z || 'byteOffset' == Z)) || + C(Z, Y))) || + z.push(Z); + return z; + }; + }, + 34932: (s) => { + s.exports = function arrayMap(s, o) { + for (var i = -1, u = null == s ? 0 : s.length, _ = Array(u); ++i < u; ) + _[i] = o(s[i], i, s); + return _; + }; + }, + 14528: (s) => { + s.exports = function arrayPush(s, o) { + for (var i = -1, u = o.length, _ = s.length; ++i < u; ) s[_ + i] = o[i]; + return s; + }; + }, + 40882: (s) => { + s.exports = function arrayReduce(s, o, i, u) { + var _ = -1, + w = null == s ? 0 : s.length; + for (u && w && (i = s[++_]); ++_ < w; ) i = o(i, s[_], _, s); + return i; + }; + }, + 14248: (s) => { + s.exports = function arraySome(s, o) { + for (var i = -1, u = null == s ? 0 : s.length; ++i < u; ) if (o(s[i], i, s)) return !0; + return !1; + }; + }, + 61074: (s) => { + s.exports = function asciiToArray(s) { + return s.split(''); + }; + }, + 1733: (s) => { + var o = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g; + s.exports = function asciiWords(s) { + return s.match(o) || []; + }; + }, + 87805: (s, o, i) => { + var u = i(43360), + _ = i(75288); + s.exports = function assignMergeValue(s, o, i) { + ((void 0 !== i && !_(s[o], i)) || (void 0 === i && !(o in s))) && u(s, o, i); + }; + }, + 16547: (s, o, i) => { + var u = i(43360), + _ = i(75288), + w = Object.prototype.hasOwnProperty; + s.exports = function assignValue(s, o, i) { + var x = s[o]; + (w.call(s, o) && _(x, i) && (void 0 !== i || o in s)) || u(s, o, i); + }; + }, + 26025: (s, o, i) => { + var u = i(75288); + s.exports = function assocIndexOf(s, o) { + for (var i = s.length; i--; ) if (u(s[i][0], o)) return i; + return -1; + }; + }, + 74733: (s, o, i) => { + var u = i(21791), + _ = i(95950); + s.exports = function baseAssign(s, o) { + return s && u(o, _(o), s); + }; + }, + 43838: (s, o, i) => { + var u = i(21791), + _ = i(37241); + s.exports = function baseAssignIn(s, o) { + return s && u(o, _(o), s); + }; + }, + 43360: (s, o, i) => { + var u = i(93243); + s.exports = function baseAssignValue(s, o, i) { + '__proto__' == o && u + ? u(s, o, { configurable: !0, enumerable: !0, value: i, writable: !0 }) + : (s[o] = i); + }; + }, + 9999: (s, o, i) => { + var u = i(37217), + _ = i(83729), + w = i(16547), + x = i(74733), + C = i(43838), + j = i(93290), + L = i(23007), + B = i(92271), + $ = i(48948), + V = i(50002), + U = i(83349), + z = i(5861), + Y = i(76189), + Z = i(77199), + ee = i(35529), + ie = i(56449), + ae = i(3656), + le = i(87730), + ce = i(23805), + pe = i(38440), + de = i(95950), + fe = i(37241), + ye = '[object Arguments]', + be = '[object Function]', + _e = '[object Object]', + we = {}; + (we[ye] = + we['[object Array]'] = + we['[object ArrayBuffer]'] = + we['[object DataView]'] = + we['[object Boolean]'] = + we['[object Date]'] = + we['[object Float32Array]'] = + we['[object Float64Array]'] = + we['[object Int8Array]'] = + we['[object Int16Array]'] = + we['[object Int32Array]'] = + we['[object Map]'] = + we['[object Number]'] = + we[_e] = + we['[object RegExp]'] = + we['[object Set]'] = + we['[object String]'] = + we['[object Symbol]'] = + we['[object Uint8Array]'] = + we['[object Uint8ClampedArray]'] = + we['[object Uint16Array]'] = + we['[object Uint32Array]'] = + !0), + (we['[object Error]'] = we[be] = we['[object WeakMap]'] = !1), + (s.exports = function baseClone(s, o, i, Se, xe, Pe) { + var Te, + Re = 1 & o, + qe = 2 & o, + $e = 4 & o; + if ((i && (Te = xe ? i(s, Se, xe, Pe) : i(s)), void 0 !== Te)) return Te; + if (!ce(s)) return s; + var ze = ie(s); + if (ze) { + if (((Te = Y(s)), !Re)) return L(s, Te); + } else { + var We = z(s), + He = We == be || '[object GeneratorFunction]' == We; + if (ae(s)) return j(s, Re); + if (We == _e || We == ye || (He && !xe)) { + if (((Te = qe || He ? {} : ee(s)), !Re)) + return qe ? $(s, C(Te, s)) : B(s, x(Te, s)); + } else { + if (!we[We]) return xe ? s : {}; + Te = Z(s, We, Re); + } + } + Pe || (Pe = new u()); + var Ye = Pe.get(s); + if (Ye) return Ye; + Pe.set(s, Te), + pe(s) + ? s.forEach(function (u) { + Te.add(baseClone(u, o, i, u, s, Pe)); + }) + : le(s) && + s.forEach(function (u, _) { + Te.set(_, baseClone(u, o, i, _, s, Pe)); + }); + var Xe = ze ? void 0 : ($e ? (qe ? U : V) : qe ? fe : de)(s); + return ( + _(Xe || s, function (u, _) { + Xe && (u = s[(_ = u)]), w(Te, _, baseClone(u, o, i, _, s, Pe)); + }), + Te + ); + }); + }, + 39344: (s, o, i) => { + var u = i(23805), + _ = Object.create, + w = (function () { + function object() {} + return function (s) { + if (!u(s)) return {}; + if (_) return _(s); + object.prototype = s; + var o = new object(); + return (object.prototype = void 0), o; + }; + })(); + s.exports = w; + }, + 80909: (s, o, i) => { + var u = i(30641), + _ = i(38329)(u); + s.exports = _; + }, + 2523: (s) => { + s.exports = function baseFindIndex(s, o, i, u) { + for (var _ = s.length, w = i + (u ? 1 : -1); u ? w-- : ++w < _; ) + if (o(s[w], w, s)) return w; + return -1; + }; + }, + 83120: (s, o, i) => { + var u = i(14528), + _ = i(45891); + s.exports = function baseFlatten(s, o, i, w, x) { + var C = -1, + j = s.length; + for (i || (i = _), x || (x = []); ++C < j; ) { + var L = s[C]; + o > 0 && i(L) + ? o > 1 + ? baseFlatten(L, o - 1, i, w, x) + : u(x, L) + : w || (x[x.length] = L); + } + return x; + }; + }, + 86649: (s, o, i) => { + var u = i(83221)(); + s.exports = u; + }, + 30641: (s, o, i) => { + var u = i(86649), + _ = i(95950); + s.exports = function baseForOwn(s, o) { + return s && u(s, o, _); + }; + }, + 47422: (s, o, i) => { + var u = i(31769), + _ = i(77797); + s.exports = function baseGet(s, o) { + for (var i = 0, w = (o = u(o, s)).length; null != s && i < w; ) s = s[_(o[i++])]; + return i && i == w ? s : void 0; + }; + }, + 82199: (s, o, i) => { + var u = i(14528), + _ = i(56449); + s.exports = function baseGetAllKeys(s, o, i) { + var w = o(s); + return _(s) ? w : u(w, i(s)); + }; + }, + 72552: (s, o, i) => { + var u = i(51873), + _ = i(659), + w = i(59350), + x = u ? u.toStringTag : void 0; + s.exports = function baseGetTag(s) { + return null == s + ? void 0 === s + ? '[object Undefined]' + : '[object Null]' + : x && x in Object(s) + ? _(s) + : w(s); + }; + }, + 20426: (s) => { + var o = Object.prototype.hasOwnProperty; + s.exports = function baseHas(s, i) { + return null != s && o.call(s, i); + }; + }, + 28077: (s) => { + s.exports = function baseHasIn(s, o) { + return null != s && o in Object(s); + }; + }, + 96131: (s, o, i) => { + var u = i(2523), + _ = i(85463), + w = i(76959); + s.exports = function baseIndexOf(s, o, i) { + return o == o ? w(s, o, i) : u(s, _, i); + }; + }, + 27534: (s, o, i) => { + var u = i(72552), + _ = i(40346); + s.exports = function baseIsArguments(s) { + return _(s) && '[object Arguments]' == u(s); + }; + }, + 60270: (s, o, i) => { + var u = i(87068), + _ = i(40346); + s.exports = function baseIsEqual(s, o, i, w, x) { + return ( + s === o || + (null == s || null == o || (!_(s) && !_(o)) + ? s != s && o != o + : u(s, o, i, w, baseIsEqual, x)) + ); + }; + }, + 87068: (s, o, i) => { + var u = i(37217), + _ = i(25911), + w = i(21986), + x = i(50689), + C = i(5861), + j = i(56449), + L = i(3656), + B = i(37167), + $ = '[object Arguments]', + V = '[object Array]', + U = '[object Object]', + z = Object.prototype.hasOwnProperty; + s.exports = function baseIsEqualDeep(s, o, i, Y, Z, ee) { + var ie = j(s), + ae = j(o), + le = ie ? V : C(s), + ce = ae ? V : C(o), + pe = (le = le == $ ? U : le) == U, + de = (ce = ce == $ ? U : ce) == U, + fe = le == ce; + if (fe && L(s)) { + if (!L(o)) return !1; + (ie = !0), (pe = !1); + } + if (fe && !pe) + return ( + ee || (ee = new u()), ie || B(s) ? _(s, o, i, Y, Z, ee) : w(s, o, le, i, Y, Z, ee) + ); + if (!(1 & i)) { + var ye = pe && z.call(s, '__wrapped__'), + be = de && z.call(o, '__wrapped__'); + if (ye || be) { + var _e = ye ? s.value() : s, + we = be ? o.value() : o; + return ee || (ee = new u()), Z(_e, we, i, Y, ee); + } + } + return !!fe && (ee || (ee = new u()), x(s, o, i, Y, Z, ee)); + }; + }, + 29172: (s, o, i) => { + var u = i(5861), + _ = i(40346); + s.exports = function baseIsMap(s) { + return _(s) && '[object Map]' == u(s); + }; + }, + 41799: (s, o, i) => { + var u = i(37217), + _ = i(60270); + s.exports = function baseIsMatch(s, o, i, w) { + var x = i.length, + C = x, + j = !w; + if (null == s) return !C; + for (s = Object(s); x--; ) { + var L = i[x]; + if (j && L[2] ? L[1] !== s[L[0]] : !(L[0] in s)) return !1; + } + for (; ++x < C; ) { + var B = (L = i[x])[0], + $ = s[B], + V = L[1]; + if (j && L[2]) { + if (void 0 === $ && !(B in s)) return !1; + } else { + var U = new u(); + if (w) var z = w($, V, B, s, o, U); + if (!(void 0 === z ? _(V, $, 3, w, U) : z)) return !1; + } + } + return !0; + }; + }, + 85463: (s) => { + s.exports = function baseIsNaN(s) { + return s != s; + }; + }, + 45083: (s, o, i) => { + var u = i(1882), + _ = i(87296), + w = i(23805), + x = i(47473), + C = /^\[object .+?Constructor\]$/, + j = Function.prototype, + L = Object.prototype, + B = j.toString, + $ = L.hasOwnProperty, + V = RegExp( + '^' + + B.call($) + .replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + + '$' + ); + s.exports = function baseIsNative(s) { + return !(!w(s) || _(s)) && (u(s) ? V : C).test(x(s)); + }; + }, + 16038: (s, o, i) => { + var u = i(5861), + _ = i(40346); + s.exports = function baseIsSet(s) { + return _(s) && '[object Set]' == u(s); + }; + }, + 4901: (s, o, i) => { + var u = i(72552), + _ = i(30294), + w = i(40346), + x = {}; + (x['[object Float32Array]'] = + x['[object Float64Array]'] = + x['[object Int8Array]'] = + x['[object Int16Array]'] = + x['[object Int32Array]'] = + x['[object Uint8Array]'] = + x['[object Uint8ClampedArray]'] = + x['[object Uint16Array]'] = + x['[object Uint32Array]'] = + !0), + (x['[object Arguments]'] = + x['[object Array]'] = + x['[object ArrayBuffer]'] = + x['[object Boolean]'] = + x['[object DataView]'] = + x['[object Date]'] = + x['[object Error]'] = + x['[object Function]'] = + x['[object Map]'] = + x['[object Number]'] = + x['[object Object]'] = + x['[object RegExp]'] = + x['[object Set]'] = + x['[object String]'] = + x['[object WeakMap]'] = + !1), + (s.exports = function baseIsTypedArray(s) { + return w(s) && _(s.length) && !!x[u(s)]; + }); + }, + 15389: (s, o, i) => { + var u = i(93663), + _ = i(87978), + w = i(83488), + x = i(56449), + C = i(50583); + s.exports = function baseIteratee(s) { + return 'function' == typeof s + ? s + : null == s + ? w + : 'object' == typeof s + ? x(s) + ? _(s[0], s[1]) + : u(s) + : C(s); + }; + }, + 88984: (s, o, i) => { + var u = i(55527), + _ = i(3650), + w = Object.prototype.hasOwnProperty; + s.exports = function baseKeys(s) { + if (!u(s)) return _(s); + var o = []; + for (var i in Object(s)) w.call(s, i) && 'constructor' != i && o.push(i); + return o; + }; + }, + 72903: (s, o, i) => { + var u = i(23805), + _ = i(55527), + w = i(90181), + x = Object.prototype.hasOwnProperty; + s.exports = function baseKeysIn(s) { + if (!u(s)) return w(s); + var o = _(s), + i = []; + for (var C in s) ('constructor' != C || (!o && x.call(s, C))) && i.push(C); + return i; + }; + }, + 94033: (s) => { + s.exports = function baseLodash() {}; + }, + 93663: (s, o, i) => { + var u = i(41799), + _ = i(10776), + w = i(67197); + s.exports = function baseMatches(s) { + var o = _(s); + return 1 == o.length && o[0][2] + ? w(o[0][0], o[0][1]) + : function (i) { + return i === s || u(i, s, o); + }; + }; + }, + 87978: (s, o, i) => { + var u = i(60270), + _ = i(58156), + w = i(80631), + x = i(28586), + C = i(30756), + j = i(67197), + L = i(77797); + s.exports = function baseMatchesProperty(s, o) { + return x(s) && C(o) + ? j(L(s), o) + : function (i) { + var x = _(i, s); + return void 0 === x && x === o ? w(i, s) : u(o, x, 3); + }; + }; + }, + 85250: (s, o, i) => { + var u = i(37217), + _ = i(87805), + w = i(86649), + x = i(42824), + C = i(23805), + j = i(37241), + L = i(14974); + s.exports = function baseMerge(s, o, i, B, $) { + s !== o && + w( + o, + function (w, j) { + if (($ || ($ = new u()), C(w))) x(s, o, j, i, baseMerge, B, $); + else { + var V = B ? B(L(s, j), w, j + '', s, o, $) : void 0; + void 0 === V && (V = w), _(s, j, V); + } + }, + j + ); + }; + }, + 42824: (s, o, i) => { + var u = i(87805), + _ = i(93290), + w = i(71961), + x = i(23007), + C = i(35529), + j = i(72428), + L = i(56449), + B = i(83693), + $ = i(3656), + V = i(1882), + U = i(23805), + z = i(11331), + Y = i(37167), + Z = i(14974), + ee = i(69884); + s.exports = function baseMergeDeep(s, o, i, ie, ae, le, ce) { + var pe = Z(s, i), + de = Z(o, i), + fe = ce.get(de); + if (fe) u(s, i, fe); + else { + var ye = le ? le(pe, de, i + '', s, o, ce) : void 0, + be = void 0 === ye; + if (be) { + var _e = L(de), + we = !_e && $(de), + Se = !_e && !we && Y(de); + (ye = de), + _e || we || Se + ? L(pe) + ? (ye = pe) + : B(pe) + ? (ye = x(pe)) + : we + ? ((be = !1), (ye = _(de, !0))) + : Se + ? ((be = !1), (ye = w(de, !0))) + : (ye = []) + : z(de) || j(de) + ? ((ye = pe), j(pe) ? (ye = ee(pe)) : (U(pe) && !V(pe)) || (ye = C(de))) + : (be = !1); + } + be && (ce.set(de, ye), ae(ye, de, ie, le, ce), ce.delete(de)), u(s, i, ye); + } + }; + }, + 47237: (s) => { + s.exports = function baseProperty(s) { + return function (o) { + return null == o ? void 0 : o[s]; + }; + }; + }, + 17255: (s, o, i) => { + var u = i(47422); + s.exports = function basePropertyDeep(s) { + return function (o) { + return u(o, s); + }; + }; + }, + 54552: (s) => { + s.exports = function basePropertyOf(s) { + return function (o) { + return null == s ? void 0 : s[o]; + }; + }; + }, + 85558: (s) => { + s.exports = function baseReduce(s, o, i, u, _) { + return ( + _(s, function (s, _, w) { + i = u ? ((u = !1), s) : o(i, s, _, w); + }), + i + ); + }; + }, + 69302: (s, o, i) => { + var u = i(83488), + _ = i(56757), + w = i(32865); + s.exports = function baseRest(s, o) { + return w(_(s, o, u), s + ''); + }; + }, + 73170: (s, o, i) => { + var u = i(16547), + _ = i(31769), + w = i(30361), + x = i(23805), + C = i(77797); + s.exports = function baseSet(s, o, i, j) { + if (!x(s)) return s; + for (var L = -1, B = (o = _(o, s)).length, $ = B - 1, V = s; null != V && ++L < B; ) { + var U = C(o[L]), + z = i; + if ('__proto__' === U || 'constructor' === U || 'prototype' === U) return s; + if (L != $) { + var Y = V[U]; + void 0 === (z = j ? j(Y, U, V) : void 0) && (z = x(Y) ? Y : w(o[L + 1]) ? [] : {}); + } + u(V, U, z), (V = V[U]); + } + return s; + }; + }, + 68882: (s, o, i) => { + var u = i(83488), + _ = i(48152), + w = _ + ? function (s, o) { + return _.set(s, o), s; + } + : u; + s.exports = w; + }, + 19570: (s, o, i) => { + var u = i(37334), + _ = i(93243), + w = i(83488), + x = _ + ? function (s, o) { + return _(s, 'toString', { + configurable: !0, + enumerable: !1, + value: u(o), + writable: !0 + }); + } + : w; + s.exports = x; + }, + 25160: (s) => { + s.exports = function baseSlice(s, o, i) { + var u = -1, + _ = s.length; + o < 0 && (o = -o > _ ? 0 : _ + o), + (i = i > _ ? _ : i) < 0 && (i += _), + (_ = o > i ? 0 : (i - o) >>> 0), + (o >>>= 0); + for (var w = Array(_); ++u < _; ) w[u] = s[u + o]; + return w; + }; + }, + 90916: (s, o, i) => { + var u = i(80909); + s.exports = function baseSome(s, o) { + var i; + return ( + u(s, function (s, u, _) { + return !(i = o(s, u, _)); + }), + !!i + ); + }; + }, + 78096: (s) => { + s.exports = function baseTimes(s, o) { + for (var i = -1, u = Array(s); ++i < s; ) u[i] = o(i); + return u; + }; + }, + 77556: (s, o, i) => { + var u = i(51873), + _ = i(34932), + w = i(56449), + x = i(44394), + C = u ? u.prototype : void 0, + j = C ? C.toString : void 0; + s.exports = function baseToString(s) { + if ('string' == typeof s) return s; + if (w(s)) return _(s, baseToString) + ''; + if (x(s)) return j ? j.call(s) : ''; + var o = s + ''; + return '0' == o && 1 / s == -1 / 0 ? '-0' : o; + }; + }, + 54128: (s, o, i) => { + var u = i(31800), + _ = /^\s+/; + s.exports = function baseTrim(s) { + return s ? s.slice(0, u(s) + 1).replace(_, '') : s; + }; + }, + 27301: (s) => { + s.exports = function baseUnary(s) { + return function (o) { + return s(o); + }; + }; + }, + 19931: (s, o, i) => { + var u = i(31769), + _ = i(68090), + w = i(68969), + x = i(77797); + s.exports = function baseUnset(s, o) { + return (o = u(o, s)), null == (s = w(s, o)) || delete s[x(_(o))]; + }; + }, + 51234: (s) => { + s.exports = function baseZipObject(s, o, i) { + for (var u = -1, _ = s.length, w = o.length, x = {}; ++u < _; ) { + var C = u < w ? o[u] : void 0; + i(x, s[u], C); + } + return x; + }; + }, + 19219: (s) => { + s.exports = function cacheHas(s, o) { + return s.has(o); + }; + }, + 31769: (s, o, i) => { + var u = i(56449), + _ = i(28586), + w = i(61802), + x = i(13222); + s.exports = function castPath(s, o) { + return u(s) ? s : _(s, o) ? [s] : w(x(s)); + }; + }, + 28754: (s, o, i) => { + var u = i(25160); + s.exports = function castSlice(s, o, i) { + var _ = s.length; + return (i = void 0 === i ? _ : i), !o && i >= _ ? s : u(s, o, i); + }; + }, + 49653: (s, o, i) => { + var u = i(37828); + s.exports = function cloneArrayBuffer(s) { + var o = new s.constructor(s.byteLength); + return new u(o).set(new u(s)), o; + }; + }, + 93290: (s, o, i) => { + s = i.nmd(s); + var u = i(9325), + _ = o && !o.nodeType && o, + w = _ && s && !s.nodeType && s, + x = w && w.exports === _ ? u.Buffer : void 0, + C = x ? x.allocUnsafe : void 0; + s.exports = function cloneBuffer(s, o) { + if (o) return s.slice(); + var i = s.length, + u = C ? C(i) : new s.constructor(i); + return s.copy(u), u; + }; + }, + 76169: (s, o, i) => { + var u = i(49653); + s.exports = function cloneDataView(s, o) { + var i = o ? u(s.buffer) : s.buffer; + return new s.constructor(i, s.byteOffset, s.byteLength); + }; + }, + 73201: (s) => { + var o = /\w*$/; + s.exports = function cloneRegExp(s) { + var i = new s.constructor(s.source, o.exec(s)); + return (i.lastIndex = s.lastIndex), i; + }; + }, + 93736: (s, o, i) => { + var u = i(51873), + _ = u ? u.prototype : void 0, + w = _ ? _.valueOf : void 0; + s.exports = function cloneSymbol(s) { + return w ? Object(w.call(s)) : {}; + }; + }, + 71961: (s, o, i) => { + var u = i(49653); + s.exports = function cloneTypedArray(s, o) { + var i = o ? u(s.buffer) : s.buffer; + return new s.constructor(i, s.byteOffset, s.length); + }; + }, + 91596: (s) => { + var o = Math.max; + s.exports = function composeArgs(s, i, u, _) { + for ( + var w = -1, + x = s.length, + C = u.length, + j = -1, + L = i.length, + B = o(x - C, 0), + $ = Array(L + B), + V = !_; + ++j < L; + + ) + $[j] = i[j]; + for (; ++w < C; ) (V || w < x) && ($[u[w]] = s[w]); + for (; B--; ) $[j++] = s[w++]; + return $; + }; + }, + 53320: (s) => { + var o = Math.max; + s.exports = function composeArgsRight(s, i, u, _) { + for ( + var w = -1, + x = s.length, + C = -1, + j = u.length, + L = -1, + B = i.length, + $ = o(x - j, 0), + V = Array($ + B), + U = !_; + ++w < $; + + ) + V[w] = s[w]; + for (var z = w; ++L < B; ) V[z + L] = i[L]; + for (; ++C < j; ) (U || w < x) && (V[z + u[C]] = s[w++]); + return V; + }; + }, + 23007: (s) => { + s.exports = function copyArray(s, o) { + var i = -1, + u = s.length; + for (o || (o = Array(u)); ++i < u; ) o[i] = s[i]; + return o; + }; + }, + 21791: (s, o, i) => { + var u = i(16547), + _ = i(43360); + s.exports = function copyObject(s, o, i, w) { + var x = !i; + i || (i = {}); + for (var C = -1, j = o.length; ++C < j; ) { + var L = o[C], + B = w ? w(i[L], s[L], L, i, s) : void 0; + void 0 === B && (B = s[L]), x ? _(i, L, B) : u(i, L, B); + } + return i; + }; + }, + 92271: (s, o, i) => { + var u = i(21791), + _ = i(4664); + s.exports = function copySymbols(s, o) { + return u(s, _(s), o); + }; + }, + 48948: (s, o, i) => { + var u = i(21791), + _ = i(86375); + s.exports = function copySymbolsIn(s, o) { + return u(s, _(s), o); + }; + }, + 55481: (s, o, i) => { + var u = i(9325)['__core-js_shared__']; + s.exports = u; + }, + 58523: (s) => { + s.exports = function countHolders(s, o) { + for (var i = s.length, u = 0; i--; ) s[i] === o && ++u; + return u; + }; + }, + 20999: (s, o, i) => { + var u = i(69302), + _ = i(36800); + s.exports = function createAssigner(s) { + return u(function (o, i) { + var u = -1, + w = i.length, + x = w > 1 ? i[w - 1] : void 0, + C = w > 2 ? i[2] : void 0; + for ( + x = s.length > 3 && 'function' == typeof x ? (w--, x) : void 0, + C && _(i[0], i[1], C) && ((x = w < 3 ? void 0 : x), (w = 1)), + o = Object(o); + ++u < w; + + ) { + var j = i[u]; + j && s(o, j, u, x); + } + return o; + }); + }; + }, + 38329: (s, o, i) => { + var u = i(64894); + s.exports = function createBaseEach(s, o) { + return function (i, _) { + if (null == i) return i; + if (!u(i)) return s(i, _); + for ( + var w = i.length, x = o ? w : -1, C = Object(i); + (o ? x-- : ++x < w) && !1 !== _(C[x], x, C); + + ); + return i; + }; + }; + }, + 83221: (s) => { + s.exports = function createBaseFor(s) { + return function (o, i, u) { + for (var _ = -1, w = Object(o), x = u(o), C = x.length; C--; ) { + var j = x[s ? C : ++_]; + if (!1 === i(w[j], j, w)) break; + } + return o; + }; + }; + }, + 11842: (s, o, i) => { + var u = i(82819), + _ = i(9325); + s.exports = function createBind(s, o, i) { + var w = 1 & o, + x = u(s); + return function wrapper() { + return (this && this !== _ && this instanceof wrapper ? x : s).apply( + w ? i : this, + arguments + ); + }; + }; + }, + 12507: (s, o, i) => { + var u = i(28754), + _ = i(49698), + w = i(63912), + x = i(13222); + s.exports = function createCaseFirst(s) { + return function (o) { + o = x(o); + var i = _(o) ? w(o) : void 0, + C = i ? i[0] : o.charAt(0), + j = i ? u(i, 1).join('') : o.slice(1); + return C[s]() + j; + }; + }; + }, + 45539: (s, o, i) => { + var u = i(40882), + _ = i(50828), + w = i(66645), + x = RegExp("['’]", 'g'); + s.exports = function createCompounder(s) { + return function (o) { + return u(w(_(o).replace(x, '')), s, ''); + }; + }; + }, + 82819: (s, o, i) => { + var u = i(39344), + _ = i(23805); + s.exports = function createCtor(s) { + return function () { + var o = arguments; + switch (o.length) { + case 0: + return new s(); + case 1: + return new s(o[0]); + case 2: + return new s(o[0], o[1]); + case 3: + return new s(o[0], o[1], o[2]); + case 4: + return new s(o[0], o[1], o[2], o[3]); + case 5: + return new s(o[0], o[1], o[2], o[3], o[4]); + case 6: + return new s(o[0], o[1], o[2], o[3], o[4], o[5]); + case 7: + return new s(o[0], o[1], o[2], o[3], o[4], o[5], o[6]); + } + var i = u(s.prototype), + w = s.apply(i, o); + return _(w) ? w : i; + }; + }; + }, + 77078: (s, o, i) => { + var u = i(91033), + _ = i(82819), + w = i(37471), + x = i(18073), + C = i(11287), + j = i(36306), + L = i(9325); + s.exports = function createCurry(s, o, i) { + var B = _(s); + return function wrapper() { + for (var _ = arguments.length, $ = Array(_), V = _, U = C(wrapper); V--; ) + $[V] = arguments[V]; + var z = _ < 3 && $[0] !== U && $[_ - 1] !== U ? [] : j($, U); + return (_ -= z.length) < i + ? x(s, o, w, wrapper.placeholder, void 0, $, z, void 0, void 0, i - _) + : u(this && this !== L && this instanceof wrapper ? B : s, this, $); + }; + }; + }, + 62006: (s, o, i) => { + var u = i(15389), + _ = i(64894), + w = i(95950); + s.exports = function createFind(s) { + return function (o, i, x) { + var C = Object(o); + if (!_(o)) { + var j = u(i, 3); + (o = w(o)), + (i = function (s) { + return j(C[s], s, C); + }); + } + var L = s(o, i, x); + return L > -1 ? C[j ? o[L] : L] : void 0; + }; + }; + }, + 37471: (s, o, i) => { + var u = i(91596), + _ = i(53320), + w = i(58523), + x = i(82819), + C = i(18073), + j = i(11287), + L = i(68294), + B = i(36306), + $ = i(9325); + s.exports = function createHybrid(s, o, i, V, U, z, Y, Z, ee, ie) { + var ae = 128 & o, + le = 1 & o, + ce = 2 & o, + pe = 24 & o, + de = 512 & o, + fe = ce ? void 0 : x(s); + return function wrapper() { + for (var ye = arguments.length, be = Array(ye), _e = ye; _e--; ) + be[_e] = arguments[_e]; + if (pe) + var we = j(wrapper), + Se = w(be, we); + if ( + (V && (be = u(be, V, U, pe)), + z && (be = _(be, z, Y, pe)), + (ye -= Se), + pe && ye < ie) + ) { + var xe = B(be, we); + return C(s, o, createHybrid, wrapper.placeholder, i, be, xe, Z, ee, ie - ye); + } + var Pe = le ? i : this, + Te = ce ? Pe[s] : s; + return ( + (ye = be.length), + Z ? (be = L(be, Z)) : de && ye > 1 && be.reverse(), + ae && ee < ye && (be.length = ee), + this && this !== $ && this instanceof wrapper && (Te = fe || x(Te)), + Te.apply(Pe, be) + ); + }; + }; + }, + 24168: (s, o, i) => { + var u = i(91033), + _ = i(82819), + w = i(9325); + s.exports = function createPartial(s, o, i, x) { + var C = 1 & o, + j = _(s); + return function wrapper() { + for ( + var o = -1, + _ = arguments.length, + L = -1, + B = x.length, + $ = Array(B + _), + V = this && this !== w && this instanceof wrapper ? j : s; + ++L < B; + + ) + $[L] = x[L]; + for (; _--; ) $[L++] = arguments[++o]; + return u(V, C ? i : this, $); + }; + }; + }, + 18073: (s, o, i) => { + var u = i(85087), + _ = i(54641), + w = i(70981); + s.exports = function createRecurry(s, o, i, x, C, j, L, B, $, V) { + var U = 8 & o; + (o |= U ? 32 : 64), 4 & (o &= ~(U ? 64 : 32)) || (o &= -4); + var z = [ + s, + o, + C, + U ? j : void 0, + U ? L : void 0, + U ? void 0 : j, + U ? void 0 : L, + B, + $, + V + ], + Y = i.apply(void 0, z); + return u(s) && _(Y, z), (Y.placeholder = x), w(Y, s, o); + }; + }, + 66977: (s, o, i) => { + var u = i(68882), + _ = i(11842), + w = i(77078), + x = i(37471), + C = i(24168), + j = i(37381), + L = i(3209), + B = i(54641), + $ = i(70981), + V = i(61489), + U = Math.max; + s.exports = function createWrap(s, o, i, z, Y, Z, ee, ie) { + var ae = 2 & o; + if (!ae && 'function' != typeof s) throw new TypeError('Expected a function'); + var le = z ? z.length : 0; + if ( + (le || ((o &= -97), (z = Y = void 0)), + (ee = void 0 === ee ? ee : U(V(ee), 0)), + (ie = void 0 === ie ? ie : V(ie)), + (le -= Y ? Y.length : 0), + 64 & o) + ) { + var ce = z, + pe = Y; + z = Y = void 0; + } + var de = ae ? void 0 : j(s), + fe = [s, o, i, z, Y, ce, pe, Z, ee, ie]; + if ( + (de && L(fe, de), + (s = fe[0]), + (o = fe[1]), + (i = fe[2]), + (z = fe[3]), + (Y = fe[4]), + !(ie = fe[9] = void 0 === fe[9] ? (ae ? 0 : s.length) : U(fe[9] - le, 0)) && + 24 & o && + (o &= -25), + o && 1 != o) + ) + ye = + 8 == o || 16 == o + ? w(s, o, ie) + : (32 != o && 33 != o) || Y.length + ? x.apply(void 0, fe) + : C(s, o, i, z); + else var ye = _(s, o, i); + return $((de ? u : B)(ye, fe), s, o); + }; + }, + 53138: (s, o, i) => { + var u = i(11331); + s.exports = function customOmitClone(s) { + return u(s) ? void 0 : s; + }; + }, + 24647: (s, o, i) => { + var u = i(54552)({ + À: 'A', + Á: 'A', + Â: 'A', + Ã: 'A', + Ä: 'A', + Å: 'A', + à: 'a', + á: 'a', + â: 'a', + ã: 'a', + ä: 'a', + å: 'a', + Ç: 'C', + ç: 'c', + Ð: 'D', + ð: 'd', + È: 'E', + É: 'E', + Ê: 'E', + Ë: 'E', + è: 'e', + é: 'e', + ê: 'e', + ë: 'e', + Ì: 'I', + Í: 'I', + Î: 'I', + Ï: 'I', + ì: 'i', + í: 'i', + î: 'i', + ï: 'i', + Ñ: 'N', + ñ: 'n', + Ò: 'O', + Ó: 'O', + Ô: 'O', + Õ: 'O', + Ö: 'O', + Ø: 'O', + ò: 'o', + ó: 'o', + ô: 'o', + õ: 'o', + ö: 'o', + ø: 'o', + Ù: 'U', + Ú: 'U', + Û: 'U', + Ü: 'U', + ù: 'u', + ú: 'u', + û: 'u', + ü: 'u', + Ý: 'Y', + ý: 'y', + ÿ: 'y', + Æ: 'Ae', + æ: 'ae', + Þ: 'Th', + þ: 'th', + ß: 'ss', + Ā: 'A', + Ă: 'A', + Ą: 'A', + ā: 'a', + ă: 'a', + ą: 'a', + Ć: 'C', + Ĉ: 'C', + Ċ: 'C', + Č: 'C', + ć: 'c', + ĉ: 'c', + ċ: 'c', + č: 'c', + Ď: 'D', + Đ: 'D', + ď: 'd', + đ: 'd', + Ē: 'E', + Ĕ: 'E', + Ė: 'E', + Ę: 'E', + Ě: 'E', + ē: 'e', + ĕ: 'e', + ė: 'e', + ę: 'e', + ě: 'e', + Ĝ: 'G', + Ğ: 'G', + Ġ: 'G', + Ģ: 'G', + ĝ: 'g', + ğ: 'g', + ġ: 'g', + ģ: 'g', + Ĥ: 'H', + Ħ: 'H', + ĥ: 'h', + ħ: 'h', + Ĩ: 'I', + Ī: 'I', + Ĭ: 'I', + Į: 'I', + İ: 'I', + ĩ: 'i', + ī: 'i', + ĭ: 'i', + į: 'i', + ı: 'i', + Ĵ: 'J', + ĵ: 'j', + Ķ: 'K', + ķ: 'k', + ĸ: 'k', + Ĺ: 'L', + Ļ: 'L', + Ľ: 'L', + Ŀ: 'L', + Ł: 'L', + ĺ: 'l', + ļ: 'l', + ľ: 'l', + ŀ: 'l', + ł: 'l', + Ń: 'N', + Ņ: 'N', + Ň: 'N', + Ŋ: 'N', + ń: 'n', + ņ: 'n', + ň: 'n', + ŋ: 'n', + Ō: 'O', + Ŏ: 'O', + Ő: 'O', + ō: 'o', + ŏ: 'o', + ő: 'o', + Ŕ: 'R', + Ŗ: 'R', + Ř: 'R', + ŕ: 'r', + ŗ: 'r', + ř: 'r', + Ś: 'S', + Ŝ: 'S', + Ş: 'S', + Š: 'S', + ś: 's', + ŝ: 's', + ş: 's', + š: 's', + Ţ: 'T', + Ť: 'T', + Ŧ: 'T', + ţ: 't', + ť: 't', + ŧ: 't', + Ũ: 'U', + Ū: 'U', + Ŭ: 'U', + Ů: 'U', + Ű: 'U', + Ų: 'U', + ũ: 'u', + ū: 'u', + ŭ: 'u', + ů: 'u', + ű: 'u', + ų: 'u', + Ŵ: 'W', + ŵ: 'w', + Ŷ: 'Y', + ŷ: 'y', + Ÿ: 'Y', + Ź: 'Z', + Ż: 'Z', + Ž: 'Z', + ź: 'z', + ż: 'z', + ž: 'z', + IJ: 'IJ', + ij: 'ij', + Œ: 'Oe', + œ: 'oe', + ʼn: "'n", + ſ: 's' + }); + s.exports = u; + }, + 93243: (s, o, i) => { + var u = i(56110), + _ = (function () { + try { + var s = u(Object, 'defineProperty'); + return s({}, '', {}), s; + } catch (s) {} + })(); + s.exports = _; + }, + 25911: (s, o, i) => { + var u = i(38859), + _ = i(14248), + w = i(19219); + s.exports = function equalArrays(s, o, i, x, C, j) { + var L = 1 & i, + B = s.length, + $ = o.length; + if (B != $ && !(L && $ > B)) return !1; + var V = j.get(s), + U = j.get(o); + if (V && U) return V == o && U == s; + var z = -1, + Y = !0, + Z = 2 & i ? new u() : void 0; + for (j.set(s, o), j.set(o, s); ++z < B; ) { + var ee = s[z], + ie = o[z]; + if (x) var ae = L ? x(ie, ee, z, o, s, j) : x(ee, ie, z, s, o, j); + if (void 0 !== ae) { + if (ae) continue; + Y = !1; + break; + } + if (Z) { + if ( + !_(o, function (s, o) { + if (!w(Z, o) && (ee === s || C(ee, s, i, x, j))) return Z.push(o); + }) + ) { + Y = !1; + break; + } + } else if (ee !== ie && !C(ee, ie, i, x, j)) { + Y = !1; + break; + } + } + return j.delete(s), j.delete(o), Y; + }; + }, + 21986: (s, o, i) => { + var u = i(51873), + _ = i(37828), + w = i(75288), + x = i(25911), + C = i(20317), + j = i(84247), + L = u ? u.prototype : void 0, + B = L ? L.valueOf : void 0; + s.exports = function equalByTag(s, o, i, u, L, $, V) { + switch (i) { + case '[object DataView]': + if (s.byteLength != o.byteLength || s.byteOffset != o.byteOffset) return !1; + (s = s.buffer), (o = o.buffer); + case '[object ArrayBuffer]': + return !(s.byteLength != o.byteLength || !$(new _(s), new _(o))); + case '[object Boolean]': + case '[object Date]': + case '[object Number]': + return w(+s, +o); + case '[object Error]': + return s.name == o.name && s.message == o.message; + case '[object RegExp]': + case '[object String]': + return s == o + ''; + case '[object Map]': + var U = C; + case '[object Set]': + var z = 1 & u; + if ((U || (U = j), s.size != o.size && !z)) return !1; + var Y = V.get(s); + if (Y) return Y == o; + (u |= 2), V.set(s, o); + var Z = x(U(s), U(o), u, L, $, V); + return V.delete(s), Z; + case '[object Symbol]': + if (B) return B.call(s) == B.call(o); + } + return !1; + }; + }, + 50689: (s, o, i) => { + var u = i(50002), + _ = Object.prototype.hasOwnProperty; + s.exports = function equalObjects(s, o, i, w, x, C) { + var j = 1 & i, + L = u(s), + B = L.length; + if (B != u(o).length && !j) return !1; + for (var $ = B; $--; ) { + var V = L[$]; + if (!(j ? V in o : _.call(o, V))) return !1; + } + var U = C.get(s), + z = C.get(o); + if (U && z) return U == o && z == s; + var Y = !0; + C.set(s, o), C.set(o, s); + for (var Z = j; ++$ < B; ) { + var ee = s[(V = L[$])], + ie = o[V]; + if (w) var ae = j ? w(ie, ee, V, o, s, C) : w(ee, ie, V, s, o, C); + if (!(void 0 === ae ? ee === ie || x(ee, ie, i, w, C) : ae)) { + Y = !1; + break; + } + Z || (Z = 'constructor' == V); + } + if (Y && !Z) { + var le = s.constructor, + ce = o.constructor; + le == ce || + !('constructor' in s) || + !('constructor' in o) || + ('function' == typeof le && + le instanceof le && + 'function' == typeof ce && + ce instanceof ce) || + (Y = !1); + } + return C.delete(s), C.delete(o), Y; + }; + }, + 38816: (s, o, i) => { + var u = i(35970), + _ = i(56757), + w = i(32865); + s.exports = function flatRest(s) { + return w(_(s, void 0, u), s + ''); + }; + }, + 34840: (s, o, i) => { + var u = 'object' == typeof i.g && i.g && i.g.Object === Object && i.g; + s.exports = u; + }, + 50002: (s, o, i) => { + var u = i(82199), + _ = i(4664), + w = i(95950); + s.exports = function getAllKeys(s) { + return u(s, w, _); + }; + }, + 83349: (s, o, i) => { + var u = i(82199), + _ = i(86375), + w = i(37241); + s.exports = function getAllKeysIn(s) { + return u(s, w, _); + }; + }, + 37381: (s, o, i) => { + var u = i(48152), + _ = i(63950), + w = u + ? function (s) { + return u.get(s); + } + : _; + s.exports = w; + }, + 62284: (s, o, i) => { + var u = i(84629), + _ = Object.prototype.hasOwnProperty; + s.exports = function getFuncName(s) { + for (var o = s.name + '', i = u[o], w = _.call(u, o) ? i.length : 0; w--; ) { + var x = i[w], + C = x.func; + if (null == C || C == s) return x.name; + } + return o; + }; + }, + 11287: (s) => { + s.exports = function getHolder(s) { + return s.placeholder; + }; + }, + 12651: (s, o, i) => { + var u = i(74218); + s.exports = function getMapData(s, o) { + var i = s.__data__; + return u(o) ? i['string' == typeof o ? 'string' : 'hash'] : i.map; + }; + }, + 10776: (s, o, i) => { + var u = i(30756), + _ = i(95950); + s.exports = function getMatchData(s) { + for (var o = _(s), i = o.length; i--; ) { + var w = o[i], + x = s[w]; + o[i] = [w, x, u(x)]; + } + return o; + }; + }, + 56110: (s, o, i) => { + var u = i(45083), + _ = i(10392); + s.exports = function getNative(s, o) { + var i = _(s, o); + return u(i) ? i : void 0; + }; + }, + 28879: (s, o, i) => { + var u = i(74335)(Object.getPrototypeOf, Object); + s.exports = u; + }, + 659: (s, o, i) => { + var u = i(51873), + _ = Object.prototype, + w = _.hasOwnProperty, + x = _.toString, + C = u ? u.toStringTag : void 0; + s.exports = function getRawTag(s) { + var o = w.call(s, C), + i = s[C]; + try { + s[C] = void 0; + var u = !0; + } catch (s) {} + var _ = x.call(s); + return u && (o ? (s[C] = i) : delete s[C]), _; + }; + }, + 4664: (s, o, i) => { + var u = i(79770), + _ = i(63345), + w = Object.prototype.propertyIsEnumerable, + x = Object.getOwnPropertySymbols, + C = x + ? function (s) { + return null == s + ? [] + : ((s = Object(s)), + u(x(s), function (o) { + return w.call(s, o); + })); + } + : _; + s.exports = C; + }, + 86375: (s, o, i) => { + var u = i(14528), + _ = i(28879), + w = i(4664), + x = i(63345), + C = Object.getOwnPropertySymbols + ? function (s) { + for (var o = []; s; ) u(o, w(s)), (s = _(s)); + return o; + } + : x; + s.exports = C; + }, + 5861: (s, o, i) => { + var u = i(55580), + _ = i(68223), + w = i(32804), + x = i(76545), + C = i(28303), + j = i(72552), + L = i(47473), + B = '[object Map]', + $ = '[object Promise]', + V = '[object Set]', + U = '[object WeakMap]', + z = '[object DataView]', + Y = L(u), + Z = L(_), + ee = L(w), + ie = L(x), + ae = L(C), + le = j; + ((u && le(new u(new ArrayBuffer(1))) != z) || + (_ && le(new _()) != B) || + (w && le(w.resolve()) != $) || + (x && le(new x()) != V) || + (C && le(new C()) != U)) && + (le = function (s) { + var o = j(s), + i = '[object Object]' == o ? s.constructor : void 0, + u = i ? L(i) : ''; + if (u) + switch (u) { + case Y: + return z; + case Z: + return B; + case ee: + return $; + case ie: + return V; + case ae: + return U; + } + return o; + }), + (s.exports = le); + }, + 10392: (s) => { + s.exports = function getValue(s, o) { + return null == s ? void 0 : s[o]; + }; + }, + 75251: (s) => { + var o = /\{\n\/\* \[wrapped with (.+)\] \*/, + i = /,? & /; + s.exports = function getWrapDetails(s) { + var u = s.match(o); + return u ? u[1].split(i) : []; + }; + }, + 49326: (s, o, i) => { + var u = i(31769), + _ = i(72428), + w = i(56449), + x = i(30361), + C = i(30294), + j = i(77797); + s.exports = function hasPath(s, o, i) { + for (var L = -1, B = (o = u(o, s)).length, $ = !1; ++L < B; ) { + var V = j(o[L]); + if (!($ = null != s && i(s, V))) break; + s = s[V]; + } + return $ || ++L != B + ? $ + : !!(B = null == s ? 0 : s.length) && C(B) && x(V, B) && (w(s) || _(s)); + }; + }, + 49698: (s) => { + var o = RegExp( + '[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff\\ufe0e\\ufe0f]' + ); + s.exports = function hasUnicode(s) { + return o.test(s); + }; + }, + 45434: (s) => { + var o = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/; + s.exports = function hasUnicodeWord(s) { + return o.test(s); + }; + }, + 22032: (s, o, i) => { + var u = i(81042); + s.exports = function hashClear() { + (this.__data__ = u ? u(null) : {}), (this.size = 0); + }; + }, + 63862: (s) => { + s.exports = function hashDelete(s) { + var o = this.has(s) && delete this.__data__[s]; + return (this.size -= o ? 1 : 0), o; + }; + }, + 66721: (s, o, i) => { + var u = i(81042), + _ = Object.prototype.hasOwnProperty; + s.exports = function hashGet(s) { + var o = this.__data__; + if (u) { + var i = o[s]; + return '__lodash_hash_undefined__' === i ? void 0 : i; + } + return _.call(o, s) ? o[s] : void 0; + }; + }, + 12749: (s, o, i) => { + var u = i(81042), + _ = Object.prototype.hasOwnProperty; + s.exports = function hashHas(s) { + var o = this.__data__; + return u ? void 0 !== o[s] : _.call(o, s); + }; + }, + 35749: (s, o, i) => { + var u = i(81042); + s.exports = function hashSet(s, o) { + var i = this.__data__; + return ( + (this.size += this.has(s) ? 0 : 1), + (i[s] = u && void 0 === o ? '__lodash_hash_undefined__' : o), + this + ); + }; + }, + 76189: (s) => { + var o = Object.prototype.hasOwnProperty; + s.exports = function initCloneArray(s) { + var i = s.length, + u = new s.constructor(i); + return ( + i && + 'string' == typeof s[0] && + o.call(s, 'index') && + ((u.index = s.index), (u.input = s.input)), + u + ); + }; + }, + 77199: (s, o, i) => { + var u = i(49653), + _ = i(76169), + w = i(73201), + x = i(93736), + C = i(71961); + s.exports = function initCloneByTag(s, o, i) { + var j = s.constructor; + switch (o) { + case '[object ArrayBuffer]': + return u(s); + case '[object Boolean]': + case '[object Date]': + return new j(+s); + case '[object DataView]': + return _(s, i); + case '[object Float32Array]': + case '[object Float64Array]': + case '[object Int8Array]': + case '[object Int16Array]': + case '[object Int32Array]': + case '[object Uint8Array]': + case '[object Uint8ClampedArray]': + case '[object Uint16Array]': + case '[object Uint32Array]': + return C(s, i); + case '[object Map]': + case '[object Set]': + return new j(); + case '[object Number]': + case '[object String]': + return new j(s); + case '[object RegExp]': + return w(s); + case '[object Symbol]': + return x(s); + } + }; + }, + 35529: (s, o, i) => { + var u = i(39344), + _ = i(28879), + w = i(55527); + s.exports = function initCloneObject(s) { + return 'function' != typeof s.constructor || w(s) ? {} : u(_(s)); + }; + }, + 62060: (s) => { + var o = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/; + s.exports = function insertWrapDetails(s, i) { + var u = i.length; + if (!u) return s; + var _ = u - 1; + return ( + (i[_] = (u > 1 ? '& ' : '') + i[_]), + (i = i.join(u > 2 ? ', ' : ' ')), + s.replace(o, '{\n/* [wrapped with ' + i + '] */\n') + ); + }; + }, + 45891: (s, o, i) => { + var u = i(51873), + _ = i(72428), + w = i(56449), + x = u ? u.isConcatSpreadable : void 0; + s.exports = function isFlattenable(s) { + return w(s) || _(s) || !!(x && s && s[x]); + }; + }, + 30361: (s) => { + var o = /^(?:0|[1-9]\d*)$/; + s.exports = function isIndex(s, i) { + var u = typeof s; + return ( + !!(i = null == i ? 9007199254740991 : i) && + ('number' == u || ('symbol' != u && o.test(s))) && + s > -1 && + s % 1 == 0 && + s < i + ); + }; + }, + 36800: (s, o, i) => { + var u = i(75288), + _ = i(64894), + w = i(30361), + x = i(23805); + s.exports = function isIterateeCall(s, o, i) { + if (!x(i)) return !1; + var C = typeof o; + return ( + !!('number' == C ? _(i) && w(o, i.length) : 'string' == C && o in i) && u(i[o], s) + ); + }; + }, + 28586: (s, o, i) => { + var u = i(56449), + _ = i(44394), + w = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + x = /^\w*$/; + s.exports = function isKey(s, o) { + if (u(s)) return !1; + var i = typeof s; + return ( + !('number' != i && 'symbol' != i && 'boolean' != i && null != s && !_(s)) || + x.test(s) || + !w.test(s) || + (null != o && s in Object(o)) + ); + }; + }, + 74218: (s) => { + s.exports = function isKeyable(s) { + var o = typeof s; + return 'string' == o || 'number' == o || 'symbol' == o || 'boolean' == o + ? '__proto__' !== s + : null === s; + }; + }, + 85087: (s, o, i) => { + var u = i(30980), + _ = i(37381), + w = i(62284), + x = i(53758); + s.exports = function isLaziable(s) { + var o = w(s), + i = x[o]; + if ('function' != typeof i || !(o in u.prototype)) return !1; + if (s === i) return !0; + var C = _(i); + return !!C && s === C[0]; + }; + }, + 87296: (s, o, i) => { + var u, + _ = i(55481), + w = (u = /[^.]+$/.exec((_ && _.keys && _.keys.IE_PROTO) || '')) + ? 'Symbol(src)_1.' + u + : ''; + s.exports = function isMasked(s) { + return !!w && w in s; + }; + }, + 55527: (s) => { + var o = Object.prototype; + s.exports = function isPrototype(s) { + var i = s && s.constructor; + return s === (('function' == typeof i && i.prototype) || o); + }; + }, + 30756: (s, o, i) => { + var u = i(23805); + s.exports = function isStrictComparable(s) { + return s == s && !u(s); + }; + }, + 63702: (s) => { + s.exports = function listCacheClear() { + (this.__data__ = []), (this.size = 0); + }; + }, + 70080: (s, o, i) => { + var u = i(26025), + _ = Array.prototype.splice; + s.exports = function listCacheDelete(s) { + var o = this.__data__, + i = u(o, s); + return !(i < 0) && (i == o.length - 1 ? o.pop() : _.call(o, i, 1), --this.size, !0); + }; + }, + 24739: (s, o, i) => { + var u = i(26025); + s.exports = function listCacheGet(s) { + var o = this.__data__, + i = u(o, s); + return i < 0 ? void 0 : o[i][1]; + }; + }, + 48655: (s, o, i) => { + var u = i(26025); + s.exports = function listCacheHas(s) { + return u(this.__data__, s) > -1; + }; + }, + 31175: (s, o, i) => { + var u = i(26025); + s.exports = function listCacheSet(s, o) { + var i = this.__data__, + _ = u(i, s); + return _ < 0 ? (++this.size, i.push([s, o])) : (i[_][1] = o), this; + }; + }, + 63040: (s, o, i) => { + var u = i(21549), + _ = i(80079), + w = i(68223); + s.exports = function mapCacheClear() { + (this.size = 0), + (this.__data__ = { hash: new u(), map: new (w || _)(), string: new u() }); + }; + }, + 17670: (s, o, i) => { + var u = i(12651); + s.exports = function mapCacheDelete(s) { + var o = u(this, s).delete(s); + return (this.size -= o ? 1 : 0), o; + }; + }, + 90289: (s, o, i) => { + var u = i(12651); + s.exports = function mapCacheGet(s) { + return u(this, s).get(s); + }; + }, + 4509: (s, o, i) => { + var u = i(12651); + s.exports = function mapCacheHas(s) { + return u(this, s).has(s); + }; + }, + 72949: (s, o, i) => { + var u = i(12651); + s.exports = function mapCacheSet(s, o) { + var i = u(this, s), + _ = i.size; + return i.set(s, o), (this.size += i.size == _ ? 0 : 1), this; + }; + }, + 20317: (s) => { + s.exports = function mapToArray(s) { + var o = -1, + i = Array(s.size); + return ( + s.forEach(function (s, u) { + i[++o] = [u, s]; + }), + i + ); + }; + }, + 67197: (s) => { + s.exports = function matchesStrictComparable(s, o) { + return function (i) { + return null != i && i[s] === o && (void 0 !== o || s in Object(i)); + }; + }; + }, + 62224: (s, o, i) => { + var u = i(50104); + s.exports = function memoizeCapped(s) { + var o = u(s, function (s) { + return 500 === i.size && i.clear(), s; + }), + i = o.cache; + return o; + }; + }, + 3209: (s, o, i) => { + var u = i(91596), + _ = i(53320), + w = i(36306), + x = '__lodash_placeholder__', + C = 128, + j = Math.min; + s.exports = function mergeData(s, o) { + var i = s[1], + L = o[1], + B = i | L, + $ = B < 131, + V = + (L == C && 8 == i) || + (L == C && 256 == i && s[7].length <= o[8]) || + (384 == L && o[7].length <= o[8] && 8 == i); + if (!$ && !V) return s; + 1 & L && ((s[2] = o[2]), (B |= 1 & i ? 0 : 4)); + var U = o[3]; + if (U) { + var z = s[3]; + (s[3] = z ? u(z, U, o[4]) : U), (s[4] = z ? w(s[3], x) : o[4]); + } + return ( + (U = o[5]) && + ((z = s[5]), (s[5] = z ? _(z, U, o[6]) : U), (s[6] = z ? w(s[5], x) : o[6])), + (U = o[7]) && (s[7] = U), + L & C && (s[8] = null == s[8] ? o[8] : j(s[8], o[8])), + null == s[9] && (s[9] = o[9]), + (s[0] = o[0]), + (s[1] = B), + s + ); + }; + }, + 48152: (s, o, i) => { + var u = i(28303), + _ = u && new u(); + s.exports = _; + }, + 81042: (s, o, i) => { + var u = i(56110)(Object, 'create'); + s.exports = u; + }, + 3650: (s, o, i) => { + var u = i(74335)(Object.keys, Object); + s.exports = u; + }, + 90181: (s) => { + s.exports = function nativeKeysIn(s) { + var o = []; + if (null != s) for (var i in Object(s)) o.push(i); + return o; + }; + }, + 86009: (s, o, i) => { + s = i.nmd(s); + var u = i(34840), + _ = o && !o.nodeType && o, + w = _ && s && !s.nodeType && s, + x = w && w.exports === _ && u.process, + C = (function () { + try { + var s = w && w.require && w.require('util').types; + return s || (x && x.binding && x.binding('util')); + } catch (s) {} + })(); + s.exports = C; + }, + 59350: (s) => { + var o = Object.prototype.toString; + s.exports = function objectToString(s) { + return o.call(s); + }; + }, + 74335: (s) => { + s.exports = function overArg(s, o) { + return function (i) { + return s(o(i)); + }; + }; + }, + 56757: (s, o, i) => { + var u = i(91033), + _ = Math.max; + s.exports = function overRest(s, o, i) { + return ( + (o = _(void 0 === o ? s.length - 1 : o, 0)), + function () { + for (var w = arguments, x = -1, C = _(w.length - o, 0), j = Array(C); ++x < C; ) + j[x] = w[o + x]; + x = -1; + for (var L = Array(o + 1); ++x < o; ) L[x] = w[x]; + return (L[o] = i(j)), u(s, this, L); + } + ); + }; + }, + 68969: (s, o, i) => { + var u = i(47422), + _ = i(25160); + s.exports = function parent(s, o) { + return o.length < 2 ? s : u(s, _(o, 0, -1)); + }; + }, + 84629: (s) => { + s.exports = {}; + }, + 68294: (s, o, i) => { + var u = i(23007), + _ = i(30361), + w = Math.min; + s.exports = function reorder(s, o) { + for (var i = s.length, x = w(o.length, i), C = u(s); x--; ) { + var j = o[x]; + s[x] = _(j, i) ? C[j] : void 0; + } + return s; + }; + }, + 36306: (s) => { + var o = '__lodash_placeholder__'; + s.exports = function replaceHolders(s, i) { + for (var u = -1, _ = s.length, w = 0, x = []; ++u < _; ) { + var C = s[u]; + (C !== i && C !== o) || ((s[u] = o), (x[w++] = u)); + } + return x; + }; + }, + 9325: (s, o, i) => { + var u = i(34840), + _ = 'object' == typeof self && self && self.Object === Object && self, + w = u || _ || Function('return this')(); + s.exports = w; + }, + 14974: (s) => { + s.exports = function safeGet(s, o) { + if (('constructor' !== o || 'function' != typeof s[o]) && '__proto__' != o) return s[o]; + }; + }, + 31380: (s) => { + s.exports = function setCacheAdd(s) { + return this.__data__.set(s, '__lodash_hash_undefined__'), this; + }; + }, + 51459: (s) => { + s.exports = function setCacheHas(s) { + return this.__data__.has(s); + }; + }, + 54641: (s, o, i) => { + var u = i(68882), + _ = i(51811)(u); + s.exports = _; + }, + 84247: (s) => { + s.exports = function setToArray(s) { + var o = -1, + i = Array(s.size); + return ( + s.forEach(function (s) { + i[++o] = s; + }), + i + ); + }; + }, + 32865: (s, o, i) => { + var u = i(19570), + _ = i(51811)(u); + s.exports = _; + }, + 70981: (s, o, i) => { + var u = i(75251), + _ = i(62060), + w = i(32865), + x = i(75948); + s.exports = function setWrapToString(s, o, i) { + var C = o + ''; + return w(s, _(C, x(u(C), i))); + }; + }, + 51811: (s) => { + var o = Date.now; + s.exports = function shortOut(s) { + var i = 0, + u = 0; + return function () { + var _ = o(), + w = 16 - (_ - u); + if (((u = _), w > 0)) { + if (++i >= 800) return arguments[0]; + } else i = 0; + return s.apply(void 0, arguments); + }; + }; + }, + 51420: (s, o, i) => { + var u = i(80079); + s.exports = function stackClear() { + (this.__data__ = new u()), (this.size = 0); + }; + }, + 90938: (s) => { + s.exports = function stackDelete(s) { + var o = this.__data__, + i = o.delete(s); + return (this.size = o.size), i; + }; + }, + 63605: (s) => { + s.exports = function stackGet(s) { + return this.__data__.get(s); + }; + }, + 29817: (s) => { + s.exports = function stackHas(s) { + return this.__data__.has(s); + }; + }, + 80945: (s, o, i) => { + var u = i(80079), + _ = i(68223), + w = i(53661); + s.exports = function stackSet(s, o) { + var i = this.__data__; + if (i instanceof u) { + var x = i.__data__; + if (!_ || x.length < 199) return x.push([s, o]), (this.size = ++i.size), this; + i = this.__data__ = new w(x); + } + return i.set(s, o), (this.size = i.size), this; + }; + }, + 76959: (s) => { + s.exports = function strictIndexOf(s, o, i) { + for (var u = i - 1, _ = s.length; ++u < _; ) if (s[u] === o) return u; + return -1; + }; + }, + 63912: (s, o, i) => { + var u = i(61074), + _ = i(49698), + w = i(42054); + s.exports = function stringToArray(s) { + return _(s) ? w(s) : u(s); + }; + }, + 61802: (s, o, i) => { + var u = i(62224), + _ = + /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g, + w = /\\(\\)?/g, + x = u(function (s) { + var o = []; + return ( + 46 === s.charCodeAt(0) && o.push(''), + s.replace(_, function (s, i, u, _) { + o.push(u ? _.replace(w, '$1') : i || s); + }), + o + ); + }); + s.exports = x; + }, + 77797: (s, o, i) => { + var u = i(44394); + s.exports = function toKey(s) { + if ('string' == typeof s || u(s)) return s; + var o = s + ''; + return '0' == o && 1 / s == -1 / 0 ? '-0' : o; + }; + }, + 47473: (s) => { + var o = Function.prototype.toString; + s.exports = function toSource(s) { + if (null != s) { + try { + return o.call(s); + } catch (s) {} + try { + return s + ''; + } catch (s) {} + } + return ''; + }; + }, + 31800: (s) => { + var o = /\s/; + s.exports = function trimmedEndIndex(s) { + for (var i = s.length; i-- && o.test(s.charAt(i)); ); + return i; + }; + }, + 42054: (s) => { + var o = '\\ud800-\\udfff', + i = '[' + o + ']', + u = '[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]', + _ = '\\ud83c[\\udffb-\\udfff]', + w = '[^' + o + ']', + x = '(?:\\ud83c[\\udde6-\\uddff]){2}', + C = '[\\ud800-\\udbff][\\udc00-\\udfff]', + j = '(?:' + u + '|' + _ + ')' + '?', + L = '[\\ufe0e\\ufe0f]?', + B = L + j + ('(?:\\u200d(?:' + [w, x, C].join('|') + ')' + L + j + ')*'), + $ = '(?:' + [w + u + '?', u, x, C, i].join('|') + ')', + V = RegExp(_ + '(?=' + _ + ')|' + $ + B, 'g'); + s.exports = function unicodeToArray(s) { + return s.match(V) || []; + }; + }, + 22225: (s) => { + var o = '\\ud800-\\udfff', + i = '\\u2700-\\u27bf', + u = 'a-z\\xdf-\\xf6\\xf8-\\xff', + _ = 'A-Z\\xc0-\\xd6\\xd8-\\xde', + w = + '\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000', + x = '[' + w + ']', + C = '\\d+', + j = '[' + i + ']', + L = '[' + u + ']', + B = '[^' + o + w + C + i + u + _ + ']', + $ = '(?:\\ud83c[\\udde6-\\uddff]){2}', + V = '[\\ud800-\\udbff][\\udc00-\\udfff]', + U = '[' + _ + ']', + z = '(?:' + L + '|' + B + ')', + Y = '(?:' + U + '|' + B + ')', + Z = "(?:['’](?:d|ll|m|re|s|t|ve))?", + ee = "(?:['’](?:D|LL|M|RE|S|T|VE))?", + ie = '(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?', + ae = '[\\ufe0e\\ufe0f]?', + le = + ae + ie + ('(?:\\u200d(?:' + ['[^' + o + ']', $, V].join('|') + ')' + ae + ie + ')*'), + ce = '(?:' + [j, $, V].join('|') + ')' + le, + pe = RegExp( + [ + U + '?' + L + '+' + Z + '(?=' + [x, U, '$'].join('|') + ')', + Y + '+' + ee + '(?=' + [x, U + z, '$'].join('|') + ')', + U + '?' + z + '+' + Z, + U + '+' + ee, + '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])', + '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])', + C, + ce + ].join('|'), + 'g' + ); + s.exports = function unicodeWords(s) { + return s.match(pe) || []; + }; + }, + 75948: (s, o, i) => { + var u = i(83729), + _ = i(15325), + w = [ + ['ary', 128], + ['bind', 1], + ['bindKey', 2], + ['curry', 8], + ['curryRight', 16], + ['flip', 512], + ['partial', 32], + ['partialRight', 64], + ['rearg', 256] + ]; + s.exports = function updateWrapDetails(s, o) { + return ( + u(w, function (i) { + var u = '_.' + i[0]; + o & i[1] && !_(s, u) && s.push(u); + }), + s.sort() + ); + }; + }, + 80257: (s, o, i) => { + var u = i(30980), + _ = i(56017), + w = i(23007); + s.exports = function wrapperClone(s) { + if (s instanceof u) return s.clone(); + var o = new _(s.__wrapped__, s.__chain__); + return ( + (o.__actions__ = w(s.__actions__)), + (o.__index__ = s.__index__), + (o.__values__ = s.__values__), + o + ); + }; + }, + 64626: (s, o, i) => { + var u = i(66977); + s.exports = function ary(s, o, i) { + return ( + (o = i ? void 0 : o), + (o = s && null == o ? s.length : o), + u(s, 128, void 0, void 0, void 0, void 0, o) + ); + }; + }, + 84058: (s, o, i) => { + var u = i(14792), + _ = i(45539)(function (s, o, i) { + return (o = o.toLowerCase()), s + (i ? u(o) : o); + }); + s.exports = _; + }, + 14792: (s, o, i) => { + var u = i(13222), + _ = i(55808); + s.exports = function capitalize(s) { + return _(u(s).toLowerCase()); + }; + }, + 32629: (s, o, i) => { + var u = i(9999); + s.exports = function clone(s) { + return u(s, 4); + }; + }, + 37334: (s) => { + s.exports = function constant(s) { + return function () { + return s; + }; + }; + }, + 49747: (s, o, i) => { + var u = i(66977); + function curry(s, o, i) { + var _ = u(s, 8, void 0, void 0, void 0, void 0, void 0, (o = i ? void 0 : o)); + return (_.placeholder = curry.placeholder), _; + } + (curry.placeholder = {}), (s.exports = curry); + }, + 38221: (s, o, i) => { + var u = i(23805), + _ = i(10124), + w = i(99374), + x = Math.max, + C = Math.min; + s.exports = function debounce(s, o, i) { + var j, + L, + B, + $, + V, + U, + z = 0, + Y = !1, + Z = !1, + ee = !0; + if ('function' != typeof s) throw new TypeError('Expected a function'); + function invokeFunc(o) { + var i = j, + u = L; + return (j = L = void 0), (z = o), ($ = s.apply(u, i)); + } + function shouldInvoke(s) { + var i = s - U; + return void 0 === U || i >= o || i < 0 || (Z && s - z >= B); + } + function timerExpired() { + var s = _(); + if (shouldInvoke(s)) return trailingEdge(s); + V = setTimeout( + timerExpired, + (function remainingWait(s) { + var i = o - (s - U); + return Z ? C(i, B - (s - z)) : i; + })(s) + ); + } + function trailingEdge(s) { + return (V = void 0), ee && j ? invokeFunc(s) : ((j = L = void 0), $); + } + function debounced() { + var s = _(), + i = shouldInvoke(s); + if (((j = arguments), (L = this), (U = s), i)) { + if (void 0 === V) + return (function leadingEdge(s) { + return (z = s), (V = setTimeout(timerExpired, o)), Y ? invokeFunc(s) : $; + })(U); + if (Z) return clearTimeout(V), (V = setTimeout(timerExpired, o)), invokeFunc(U); + } + return void 0 === V && (V = setTimeout(timerExpired, o)), $; + } + return ( + (o = w(o) || 0), + u(i) && + ((Y = !!i.leading), + (B = (Z = 'maxWait' in i) ? x(w(i.maxWait) || 0, o) : B), + (ee = 'trailing' in i ? !!i.trailing : ee)), + (debounced.cancel = function cancel() { + void 0 !== V && clearTimeout(V), (z = 0), (j = U = L = V = void 0); + }), + (debounced.flush = function flush() { + return void 0 === V ? $ : trailingEdge(_()); + }), + debounced + ); + }; + }, + 50828: (s, o, i) => { + var u = i(24647), + _ = i(13222), + w = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g, + x = RegExp('[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]', 'g'); + s.exports = function deburr(s) { + return (s = _(s)) && s.replace(w, u).replace(x, ''); + }; + }, + 75288: (s) => { + s.exports = function eq(s, o) { + return s === o || (s != s && o != o); + }; + }, + 60680: (s, o, i) => { + var u = i(13222), + _ = /[\\^$.*+?()[\]{}|]/g, + w = RegExp(_.source); + s.exports = function escapeRegExp(s) { + return (s = u(s)) && w.test(s) ? s.replace(_, '\\$&') : s; + }; + }, + 7309: (s, o, i) => { + var u = i(62006)(i(24713)); + s.exports = u; + }, + 24713: (s, o, i) => { + var u = i(2523), + _ = i(15389), + w = i(61489), + x = Math.max; + s.exports = function findIndex(s, o, i) { + var C = null == s ? 0 : s.length; + if (!C) return -1; + var j = null == i ? 0 : w(i); + return j < 0 && (j = x(C + j, 0)), u(s, _(o, 3), j); + }; + }, + 35970: (s, o, i) => { + var u = i(83120); + s.exports = function flatten(s) { + return (null == s ? 0 : s.length) ? u(s, 1) : []; + }; + }, + 73424: (s, o, i) => { + var u = i(16962), + _ = i(2874), + w = Array.prototype.push; + function baseAry(s, o) { + return 2 == o + ? function (o, i) { + return s(o, i); + } + : function (o) { + return s(o); + }; + } + function cloneArray(s) { + for (var o = s ? s.length : 0, i = Array(o); o--; ) i[o] = s[o]; + return i; + } + function wrapImmutable(s, o) { + return function () { + var i = arguments.length; + if (i) { + for (var u = Array(i); i--; ) u[i] = arguments[i]; + var _ = (u[0] = o.apply(void 0, u)); + return s.apply(void 0, u), _; + } + }; + } + s.exports = function baseConvert(s, o, i, x) { + var C = 'function' == typeof o, + j = o === Object(o); + if ((j && ((x = i), (i = o), (o = void 0)), null == i)) throw new TypeError(); + x || (x = {}); + var L = !('cap' in x) || x.cap, + B = !('curry' in x) || x.curry, + $ = !('fixed' in x) || x.fixed, + V = !('immutable' in x) || x.immutable, + U = !('rearg' in x) || x.rearg, + z = C ? i : _, + Y = 'curry' in x && x.curry, + Z = 'fixed' in x && x.fixed, + ee = 'rearg' in x && x.rearg, + ie = C ? i.runInContext() : void 0, + ae = C + ? i + : { + ary: s.ary, + assign: s.assign, + clone: s.clone, + curry: s.curry, + forEach: s.forEach, + isArray: s.isArray, + isError: s.isError, + isFunction: s.isFunction, + isWeakMap: s.isWeakMap, + iteratee: s.iteratee, + keys: s.keys, + rearg: s.rearg, + toInteger: s.toInteger, + toPath: s.toPath + }, + le = ae.ary, + ce = ae.assign, + pe = ae.clone, + de = ae.curry, + fe = ae.forEach, + ye = ae.isArray, + be = ae.isError, + _e = ae.isFunction, + we = ae.isWeakMap, + Se = ae.keys, + xe = ae.rearg, + Pe = ae.toInteger, + Te = ae.toPath, + Re = Se(u.aryMethod), + qe = { + castArray: function (s) { + return function () { + var o = arguments[0]; + return ye(o) ? s(cloneArray(o)) : s.apply(void 0, arguments); + }; + }, + iteratee: function (s) { + return function () { + var o = arguments[1], + i = s(arguments[0], o), + u = i.length; + return L && 'number' == typeof o + ? ((o = o > 2 ? o - 2 : 1), u && u <= o ? i : baseAry(i, o)) + : i; + }; + }, + mixin: function (s) { + return function (o) { + var i = this; + if (!_e(i)) return s(i, Object(o)); + var u = []; + return ( + fe(Se(o), function (s) { + _e(o[s]) && u.push([s, i.prototype[s]]); + }), + s(i, Object(o)), + fe(u, function (s) { + var o = s[1]; + _e(o) ? (i.prototype[s[0]] = o) : delete i.prototype[s[0]]; + }), + i + ); + }; + }, + nthArg: function (s) { + return function (o) { + var i = o < 0 ? 1 : Pe(o) + 1; + return de(s(o), i); + }; + }, + rearg: function (s) { + return function (o, i) { + var u = i ? i.length : 0; + return de(s(o, i), u); + }; + }, + runInContext: function (o) { + return function (i) { + return baseConvert(s, o(i), x); + }; + } + }; + function castCap(s, o) { + if (L) { + var i = u.iterateeRearg[s]; + if (i) + return (function iterateeRearg(s, o) { + return overArg(s, function (s) { + var i = o.length; + return (function baseArity(s, o) { + return 2 == o + ? function (o, i) { + return s.apply(void 0, arguments); + } + : function (o) { + return s.apply(void 0, arguments); + }; + })(xe(baseAry(s, i), o), i); + }); + })(o, i); + var _ = !C && u.iterateeAry[s]; + if (_) + return (function iterateeAry(s, o) { + return overArg(s, function (s) { + return 'function' == typeof s ? baseAry(s, o) : s; + }); + })(o, _); + } + return o; + } + function castFixed(s, o, i) { + if ($ && (Z || !u.skipFixed[s])) { + var _ = u.methodSpread[s], + x = _ && _.start; + return void 0 === x + ? le(o, i) + : (function flatSpread(s, o) { + return function () { + for (var i = arguments.length, u = i - 1, _ = Array(i); i--; ) + _[i] = arguments[i]; + var x = _[o], + C = _.slice(0, o); + return ( + x && w.apply(C, x), o != u && w.apply(C, _.slice(o + 1)), s.apply(this, C) + ); + }; + })(o, x); + } + return o; + } + function castRearg(s, o, i) { + return U && i > 1 && (ee || !u.skipRearg[s]) + ? xe(o, u.methodRearg[s] || u.aryRearg[i]) + : o; + } + function cloneByPath(s, o) { + for ( + var i = -1, u = (o = Te(o)).length, _ = u - 1, w = pe(Object(s)), x = w; + null != x && ++i < u; + + ) { + var C = o[i], + j = x[C]; + null == j || _e(j) || be(j) || we(j) || (x[C] = pe(i == _ ? j : Object(j))), + (x = x[C]); + } + return w; + } + function createConverter(s, o) { + var i = u.aliasToReal[s] || s, + _ = u.remap[i] || i, + w = x; + return function (s) { + var u = C ? ie : ae, + x = C ? ie[_] : o, + j = ce(ce({}, w), s); + return baseConvert(u, i, x, j); + }; + } + function overArg(s, o) { + return function () { + var i = arguments.length; + if (!i) return s(); + for (var u = Array(i); i--; ) u[i] = arguments[i]; + var _ = U ? 0 : i - 1; + return (u[_] = o(u[_])), s.apply(void 0, u); + }; + } + function wrap(s, o, i) { + var _, + w = u.aliasToReal[s] || s, + x = o, + C = qe[w]; + return ( + C + ? (x = C(o)) + : V && + (u.mutate.array[w] + ? (x = wrapImmutable(o, cloneArray)) + : u.mutate.object[w] + ? (x = wrapImmutable( + o, + (function createCloner(s) { + return function (o) { + return s({}, o); + }; + })(o) + )) + : u.mutate.set[w] && (x = wrapImmutable(o, cloneByPath))), + fe(Re, function (s) { + return ( + fe(u.aryMethod[s], function (o) { + if (w == o) { + var i = u.methodSpread[w], + C = i && i.afterRearg; + return ( + (_ = C + ? castFixed(w, castRearg(w, x, s), s) + : castRearg(w, castFixed(w, x, s), s)), + (_ = (function castCurry(s, o, i) { + return Y || (B && i > 1) ? de(o, i) : o; + })(0, (_ = castCap(w, _)), s)), + !1 + ); + } + }), + !_ + ); + }), + _ || (_ = x), + _ == o && + (_ = Y + ? de(_, 1) + : function () { + return o.apply(this, arguments); + }), + (_.convert = createConverter(w, o)), + (_.placeholder = o.placeholder = i), + _ + ); + } + if (!j) return wrap(o, i, z); + var $e = i, + ze = []; + return ( + fe(Re, function (s) { + fe(u.aryMethod[s], function (s) { + var o = $e[u.remap[s] || s]; + o && ze.push([s, wrap(s, o, $e)]); + }); + }), + fe(Se($e), function (s) { + var o = $e[s]; + if ('function' == typeof o) { + for (var i = ze.length; i--; ) if (ze[i][0] == s) return; + (o.convert = createConverter(s, o)), ze.push([s, o]); + } + }), + fe(ze, function (s) { + $e[s[0]] = s[1]; + }), + ($e.convert = function convertLib(s) { + return $e.runInContext.convert(s)(void 0); + }), + ($e.placeholder = $e), + fe(Se($e), function (s) { + fe(u.realToAlias[s] || [], function (o) { + $e[o] = $e[s]; + }); + }), + $e + ); + }; + }, + 16962: (s, o) => { + (o.aliasToReal = { + each: 'forEach', + eachRight: 'forEachRight', + entries: 'toPairs', + entriesIn: 'toPairsIn', + extend: 'assignIn', + extendAll: 'assignInAll', + extendAllWith: 'assignInAllWith', + extendWith: 'assignInWith', + first: 'head', + conforms: 'conformsTo', + matches: 'isMatch', + property: 'get', + __: 'placeholder', + F: 'stubFalse', + T: 'stubTrue', + all: 'every', + allPass: 'overEvery', + always: 'constant', + any: 'some', + anyPass: 'overSome', + apply: 'spread', + assoc: 'set', + assocPath: 'set', + complement: 'negate', + compose: 'flowRight', + contains: 'includes', + dissoc: 'unset', + dissocPath: 'unset', + dropLast: 'dropRight', + dropLastWhile: 'dropRightWhile', + equals: 'isEqual', + identical: 'eq', + indexBy: 'keyBy', + init: 'initial', + invertObj: 'invert', + juxt: 'over', + omitAll: 'omit', + nAry: 'ary', + path: 'get', + pathEq: 'matchesProperty', + pathOr: 'getOr', + paths: 'at', + pickAll: 'pick', + pipe: 'flow', + pluck: 'map', + prop: 'get', + propEq: 'matchesProperty', + propOr: 'getOr', + props: 'at', + symmetricDifference: 'xor', + symmetricDifferenceBy: 'xorBy', + symmetricDifferenceWith: 'xorWith', + takeLast: 'takeRight', + takeLastWhile: 'takeRightWhile', + unapply: 'rest', + unnest: 'flatten', + useWith: 'overArgs', + where: 'conformsTo', + whereEq: 'isMatch', + zipObj: 'zipObject' + }), + (o.aryMethod = { + 1: [ + 'assignAll', + 'assignInAll', + 'attempt', + 'castArray', + 'ceil', + 'create', + 'curry', + 'curryRight', + 'defaultsAll', + 'defaultsDeepAll', + 'floor', + 'flow', + 'flowRight', + 'fromPairs', + 'invert', + 'iteratee', + 'memoize', + 'method', + 'mergeAll', + 'methodOf', + 'mixin', + 'nthArg', + 'over', + 'overEvery', + 'overSome', + 'rest', + 'reverse', + 'round', + 'runInContext', + 'spread', + 'template', + 'trim', + 'trimEnd', + 'trimStart', + 'uniqueId', + 'words', + 'zipAll' + ], + 2: [ + 'add', + 'after', + 'ary', + 'assign', + 'assignAllWith', + 'assignIn', + 'assignInAllWith', + 'at', + 'before', + 'bind', + 'bindAll', + 'bindKey', + 'chunk', + 'cloneDeepWith', + 'cloneWith', + 'concat', + 'conformsTo', + 'countBy', + 'curryN', + 'curryRightN', + 'debounce', + 'defaults', + 'defaultsDeep', + 'defaultTo', + 'delay', + 'difference', + 'divide', + 'drop', + 'dropRight', + 'dropRightWhile', + 'dropWhile', + 'endsWith', + 'eq', + 'every', + 'filter', + 'find', + 'findIndex', + 'findKey', + 'findLast', + 'findLastIndex', + 'findLastKey', + 'flatMap', + 'flatMapDeep', + 'flattenDepth', + 'forEach', + 'forEachRight', + 'forIn', + 'forInRight', + 'forOwn', + 'forOwnRight', + 'get', + 'groupBy', + 'gt', + 'gte', + 'has', + 'hasIn', + 'includes', + 'indexOf', + 'intersection', + 'invertBy', + 'invoke', + 'invokeMap', + 'isEqual', + 'isMatch', + 'join', + 'keyBy', + 'lastIndexOf', + 'lt', + 'lte', + 'map', + 'mapKeys', + 'mapValues', + 'matchesProperty', + 'maxBy', + 'meanBy', + 'merge', + 'mergeAllWith', + 'minBy', + 'multiply', + 'nth', + 'omit', + 'omitBy', + 'overArgs', + 'pad', + 'padEnd', + 'padStart', + 'parseInt', + 'partial', + 'partialRight', + 'partition', + 'pick', + 'pickBy', + 'propertyOf', + 'pull', + 'pullAll', + 'pullAt', + 'random', + 'range', + 'rangeRight', + 'rearg', + 'reject', + 'remove', + 'repeat', + 'restFrom', + 'result', + 'sampleSize', + 'some', + 'sortBy', + 'sortedIndex', + 'sortedIndexOf', + 'sortedLastIndex', + 'sortedLastIndexOf', + 'sortedUniqBy', + 'split', + 'spreadFrom', + 'startsWith', + 'subtract', + 'sumBy', + 'take', + 'takeRight', + 'takeRightWhile', + 'takeWhile', + 'tap', + 'throttle', + 'thru', + 'times', + 'trimChars', + 'trimCharsEnd', + 'trimCharsStart', + 'truncate', + 'union', + 'uniqBy', + 'uniqWith', + 'unset', + 'unzipWith', + 'without', + 'wrap', + 'xor', + 'zip', + 'zipObject', + 'zipObjectDeep' + ], + 3: [ + 'assignInWith', + 'assignWith', + 'clamp', + 'differenceBy', + 'differenceWith', + 'findFrom', + 'findIndexFrom', + 'findLastFrom', + 'findLastIndexFrom', + 'getOr', + 'includesFrom', + 'indexOfFrom', + 'inRange', + 'intersectionBy', + 'intersectionWith', + 'invokeArgs', + 'invokeArgsMap', + 'isEqualWith', + 'isMatchWith', + 'flatMapDepth', + 'lastIndexOfFrom', + 'mergeWith', + 'orderBy', + 'padChars', + 'padCharsEnd', + 'padCharsStart', + 'pullAllBy', + 'pullAllWith', + 'rangeStep', + 'rangeStepRight', + 'reduce', + 'reduceRight', + 'replace', + 'set', + 'slice', + 'sortedIndexBy', + 'sortedLastIndexBy', + 'transform', + 'unionBy', + 'unionWith', + 'update', + 'xorBy', + 'xorWith', + 'zipWith' + ], + 4: ['fill', 'setWith', 'updateWith'] + }), + (o.aryRearg = { 2: [1, 0], 3: [2, 0, 1], 4: [3, 2, 0, 1] }), + (o.iterateeAry = { + dropRightWhile: 1, + dropWhile: 1, + every: 1, + filter: 1, + find: 1, + findFrom: 1, + findIndex: 1, + findIndexFrom: 1, + findKey: 1, + findLast: 1, + findLastFrom: 1, + findLastIndex: 1, + findLastIndexFrom: 1, + findLastKey: 1, + flatMap: 1, + flatMapDeep: 1, + flatMapDepth: 1, + forEach: 1, + forEachRight: 1, + forIn: 1, + forInRight: 1, + forOwn: 1, + forOwnRight: 1, + map: 1, + mapKeys: 1, + mapValues: 1, + partition: 1, + reduce: 2, + reduceRight: 2, + reject: 1, + remove: 1, + some: 1, + takeRightWhile: 1, + takeWhile: 1, + times: 1, + transform: 2 + }), + (o.iterateeRearg = { mapKeys: [1], reduceRight: [1, 0] }), + (o.methodRearg = { + assignInAllWith: [1, 0], + assignInWith: [1, 2, 0], + assignAllWith: [1, 0], + assignWith: [1, 2, 0], + differenceBy: [1, 2, 0], + differenceWith: [1, 2, 0], + getOr: [2, 1, 0], + intersectionBy: [1, 2, 0], + intersectionWith: [1, 2, 0], + isEqualWith: [1, 2, 0], + isMatchWith: [2, 1, 0], + mergeAllWith: [1, 0], + mergeWith: [1, 2, 0], + padChars: [2, 1, 0], + padCharsEnd: [2, 1, 0], + padCharsStart: [2, 1, 0], + pullAllBy: [2, 1, 0], + pullAllWith: [2, 1, 0], + rangeStep: [1, 2, 0], + rangeStepRight: [1, 2, 0], + setWith: [3, 1, 2, 0], + sortedIndexBy: [2, 1, 0], + sortedLastIndexBy: [2, 1, 0], + unionBy: [1, 2, 0], + unionWith: [1, 2, 0], + updateWith: [3, 1, 2, 0], + xorBy: [1, 2, 0], + xorWith: [1, 2, 0], + zipWith: [1, 2, 0] + }), + (o.methodSpread = { + assignAll: { start: 0 }, + assignAllWith: { start: 0 }, + assignInAll: { start: 0 }, + assignInAllWith: { start: 0 }, + defaultsAll: { start: 0 }, + defaultsDeepAll: { start: 0 }, + invokeArgs: { start: 2 }, + invokeArgsMap: { start: 2 }, + mergeAll: { start: 0 }, + mergeAllWith: { start: 0 }, + partial: { start: 1 }, + partialRight: { start: 1 }, + without: { start: 1 }, + zipAll: { start: 0 } + }), + (o.mutate = { + array: { + fill: !0, + pull: !0, + pullAll: !0, + pullAllBy: !0, + pullAllWith: !0, + pullAt: !0, + remove: !0, + reverse: !0 + }, + object: { + assign: !0, + assignAll: !0, + assignAllWith: !0, + assignIn: !0, + assignInAll: !0, + assignInAllWith: !0, + assignInWith: !0, + assignWith: !0, + defaults: !0, + defaultsAll: !0, + defaultsDeep: !0, + defaultsDeepAll: !0, + merge: !0, + mergeAll: !0, + mergeAllWith: !0, + mergeWith: !0 + }, + set: { set: !0, setWith: !0, unset: !0, update: !0, updateWith: !0 } + }), + (o.realToAlias = (function () { + var s = Object.prototype.hasOwnProperty, + i = o.aliasToReal, + u = {}; + for (var _ in i) { + var w = i[_]; + s.call(u, w) ? u[w].push(_) : (u[w] = [_]); + } + return u; + })()), + (o.remap = { + assignAll: 'assign', + assignAllWith: 'assignWith', + assignInAll: 'assignIn', + assignInAllWith: 'assignInWith', + curryN: 'curry', + curryRightN: 'curryRight', + defaultsAll: 'defaults', + defaultsDeepAll: 'defaultsDeep', + findFrom: 'find', + findIndexFrom: 'findIndex', + findLastFrom: 'findLast', + findLastIndexFrom: 'findLastIndex', + getOr: 'get', + includesFrom: 'includes', + indexOfFrom: 'indexOf', + invokeArgs: 'invoke', + invokeArgsMap: 'invokeMap', + lastIndexOfFrom: 'lastIndexOf', + mergeAll: 'merge', + mergeAllWith: 'mergeWith', + padChars: 'pad', + padCharsEnd: 'padEnd', + padCharsStart: 'padStart', + propertyOf: 'get', + rangeStep: 'range', + rangeStepRight: 'rangeRight', + restFrom: 'rest', + spreadFrom: 'spread', + trimChars: 'trim', + trimCharsEnd: 'trimEnd', + trimCharsStart: 'trimStart', + zipAll: 'zip' + }), + (o.skipFixed = { + castArray: !0, + flow: !0, + flowRight: !0, + iteratee: !0, + mixin: !0, + rearg: !0, + runInContext: !0 + }), + (o.skipRearg = { + add: !0, + assign: !0, + assignIn: !0, + bind: !0, + bindKey: !0, + concat: !0, + difference: !0, + divide: !0, + eq: !0, + gt: !0, + gte: !0, + isEqual: !0, + lt: !0, + lte: !0, + matchesProperty: !0, + merge: !0, + multiply: !0, + overArgs: !0, + partial: !0, + partialRight: !0, + propertyOf: !0, + random: !0, + range: !0, + rangeRight: !0, + subtract: !0, + zip: !0, + zipObject: !0, + zipObjectDeep: !0 + }); + }, + 47934: (s, o, i) => { + s.exports = { + ary: i(64626), + assign: i(74733), + clone: i(32629), + curry: i(49747), + forEach: i(83729), + isArray: i(56449), + isError: i(23546), + isFunction: i(1882), + isWeakMap: i(47886), + iteratee: i(33855), + keys: i(88984), + rearg: i(84195), + toInteger: i(61489), + toPath: i(42072) + }; + }, + 56367: (s, o, i) => { + s.exports = i(77731); + }, + 79920: (s, o, i) => { + var u = i(73424), + _ = i(47934); + s.exports = function convert(s, o, i) { + return u(_, s, o, i); + }; + }, + 2874: (s) => { + s.exports = {}; + }, + 77731: (s, o, i) => { + var u = i(79920)('set', i(63560)); + (u.placeholder = i(2874)), (s.exports = u); + }, + 58156: (s, o, i) => { + var u = i(47422); + s.exports = function get(s, o, i) { + var _ = null == s ? void 0 : u(s, o); + return void 0 === _ ? i : _; + }; + }, + 61448: (s, o, i) => { + var u = i(20426), + _ = i(49326); + s.exports = function has(s, o) { + return null != s && _(s, o, u); + }; + }, + 80631: (s, o, i) => { + var u = i(28077), + _ = i(49326); + s.exports = function hasIn(s, o) { + return null != s && _(s, o, u); + }; + }, + 83488: (s) => { + s.exports = function identity(s) { + return s; + }; + }, + 72428: (s, o, i) => { + var u = i(27534), + _ = i(40346), + w = Object.prototype, + x = w.hasOwnProperty, + C = w.propertyIsEnumerable, + j = u( + (function () { + return arguments; + })() + ) + ? u + : function (s) { + return _(s) && x.call(s, 'callee') && !C.call(s, 'callee'); + }; + s.exports = j; + }, + 56449: (s) => { + var o = Array.isArray; + s.exports = o; + }, + 64894: (s, o, i) => { + var u = i(1882), + _ = i(30294); + s.exports = function isArrayLike(s) { + return null != s && _(s.length) && !u(s); + }; + }, + 83693: (s, o, i) => { + var u = i(64894), + _ = i(40346); + s.exports = function isArrayLikeObject(s) { + return _(s) && u(s); + }; + }, + 53812: (s, o, i) => { + var u = i(72552), + _ = i(40346); + s.exports = function isBoolean(s) { + return !0 === s || !1 === s || (_(s) && '[object Boolean]' == u(s)); + }; + }, + 3656: (s, o, i) => { + s = i.nmd(s); + var u = i(9325), + _ = i(89935), + w = o && !o.nodeType && o, + x = w && s && !s.nodeType && s, + C = x && x.exports === w ? u.Buffer : void 0, + j = (C ? C.isBuffer : void 0) || _; + s.exports = j; + }, + 62193: (s, o, i) => { + var u = i(88984), + _ = i(5861), + w = i(72428), + x = i(56449), + C = i(64894), + j = i(3656), + L = i(55527), + B = i(37167), + $ = Object.prototype.hasOwnProperty; + s.exports = function isEmpty(s) { + if (null == s) return !0; + if ( + C(s) && + (x(s) || + 'string' == typeof s || + 'function' == typeof s.splice || + j(s) || + B(s) || + w(s)) + ) + return !s.length; + var o = _(s); + if ('[object Map]' == o || '[object Set]' == o) return !s.size; + if (L(s)) return !u(s).length; + for (var i in s) if ($.call(s, i)) return !1; + return !0; + }; + }, + 2404: (s, o, i) => { + var u = i(60270); + s.exports = function isEqual(s, o) { + return u(s, o); + }; + }, + 23546: (s, o, i) => { + var u = i(72552), + _ = i(40346), + w = i(11331); + s.exports = function isError(s) { + if (!_(s)) return !1; + var o = u(s); + return ( + '[object Error]' == o || + '[object DOMException]' == o || + ('string' == typeof s.message && 'string' == typeof s.name && !w(s)) + ); + }; + }, + 1882: (s, o, i) => { + var u = i(72552), + _ = i(23805); + s.exports = function isFunction(s) { + if (!_(s)) return !1; + var o = u(s); + return ( + '[object Function]' == o || + '[object GeneratorFunction]' == o || + '[object AsyncFunction]' == o || + '[object Proxy]' == o + ); + }; + }, + 30294: (s) => { + s.exports = function isLength(s) { + return 'number' == typeof s && s > -1 && s % 1 == 0 && s <= 9007199254740991; + }; + }, + 87730: (s, o, i) => { + var u = i(29172), + _ = i(27301), + w = i(86009), + x = w && w.isMap, + C = x ? _(x) : u; + s.exports = C; + }, + 5187: (s) => { + s.exports = function isNull(s) { + return null === s; + }; + }, + 98023: (s, o, i) => { + var u = i(72552), + _ = i(40346); + s.exports = function isNumber(s) { + return 'number' == typeof s || (_(s) && '[object Number]' == u(s)); + }; + }, + 23805: (s) => { + s.exports = function isObject(s) { + var o = typeof s; + return null != s && ('object' == o || 'function' == o); + }; + }, + 40346: (s) => { + s.exports = function isObjectLike(s) { + return null != s && 'object' == typeof s; + }; + }, + 11331: (s, o, i) => { + var u = i(72552), + _ = i(28879), + w = i(40346), + x = Function.prototype, + C = Object.prototype, + j = x.toString, + L = C.hasOwnProperty, + B = j.call(Object); + s.exports = function isPlainObject(s) { + if (!w(s) || '[object Object]' != u(s)) return !1; + var o = _(s); + if (null === o) return !0; + var i = L.call(o, 'constructor') && o.constructor; + return 'function' == typeof i && i instanceof i && j.call(i) == B; + }; + }, + 38440: (s, o, i) => { + var u = i(16038), + _ = i(27301), + w = i(86009), + x = w && w.isSet, + C = x ? _(x) : u; + s.exports = C; + }, + 85015: (s, o, i) => { + var u = i(72552), + _ = i(56449), + w = i(40346); + s.exports = function isString(s) { + return 'string' == typeof s || (!_(s) && w(s) && '[object String]' == u(s)); + }; + }, + 44394: (s, o, i) => { + var u = i(72552), + _ = i(40346); + s.exports = function isSymbol(s) { + return 'symbol' == typeof s || (_(s) && '[object Symbol]' == u(s)); + }; + }, + 37167: (s, o, i) => { + var u = i(4901), + _ = i(27301), + w = i(86009), + x = w && w.isTypedArray, + C = x ? _(x) : u; + s.exports = C; + }, + 47886: (s, o, i) => { + var u = i(5861), + _ = i(40346); + s.exports = function isWeakMap(s) { + return _(s) && '[object WeakMap]' == u(s); + }; + }, + 33855: (s, o, i) => { + var u = i(9999), + _ = i(15389); + s.exports = function iteratee(s) { + return _('function' == typeof s ? s : u(s, 1)); + }; + }, + 95950: (s, o, i) => { + var u = i(70695), + _ = i(88984), + w = i(64894); + s.exports = function keys(s) { + return w(s) ? u(s) : _(s); + }; + }, + 37241: (s, o, i) => { + var u = i(70695), + _ = i(72903), + w = i(64894); + s.exports = function keysIn(s) { + return w(s) ? u(s, !0) : _(s); + }; + }, + 68090: (s) => { + s.exports = function last(s) { + var o = null == s ? 0 : s.length; + return o ? s[o - 1] : void 0; + }; + }, + 50104: (s, o, i) => { + var u = i(53661); + function memoize(s, o) { + if ('function' != typeof s || (null != o && 'function' != typeof o)) + throw new TypeError('Expected a function'); + var memoized = function () { + var i = arguments, + u = o ? o.apply(this, i) : i[0], + _ = memoized.cache; + if (_.has(u)) return _.get(u); + var w = s.apply(this, i); + return (memoized.cache = _.set(u, w) || _), w; + }; + return (memoized.cache = new (memoize.Cache || u)()), memoized; + } + (memoize.Cache = u), (s.exports = memoize); + }, + 55364: (s, o, i) => { + var u = i(85250), + _ = i(20999)(function (s, o, i) { + u(s, o, i); + }); + s.exports = _; + }, + 6048: (s) => { + s.exports = function negate(s) { + if ('function' != typeof s) throw new TypeError('Expected a function'); + return function () { + var o = arguments; + switch (o.length) { + case 0: + return !s.call(this); + case 1: + return !s.call(this, o[0]); + case 2: + return !s.call(this, o[0], o[1]); + case 3: + return !s.call(this, o[0], o[1], o[2]); + } + return !s.apply(this, o); + }; + }; + }, + 63950: (s) => { + s.exports = function noop() {}; + }, + 10124: (s, o, i) => { + var u = i(9325); + s.exports = function () { + return u.Date.now(); + }; + }, + 90179: (s, o, i) => { + var u = i(34932), + _ = i(9999), + w = i(19931), + x = i(31769), + C = i(21791), + j = i(53138), + L = i(38816), + B = i(83349), + $ = L(function (s, o) { + var i = {}; + if (null == s) return i; + var L = !1; + (o = u(o, function (o) { + return (o = x(o, s)), L || (L = o.length > 1), o; + })), + C(s, B(s), i), + L && (i = _(i, 7, j)); + for (var $ = o.length; $--; ) w(i, o[$]); + return i; + }); + s.exports = $; + }, + 50583: (s, o, i) => { + var u = i(47237), + _ = i(17255), + w = i(28586), + x = i(77797); + s.exports = function property(s) { + return w(s) ? u(x(s)) : _(s); + }; + }, + 84195: (s, o, i) => { + var u = i(66977), + _ = i(38816), + w = _(function (s, o) { + return u(s, 256, void 0, void 0, void 0, o); + }); + s.exports = w; + }, + 40860: (s, o, i) => { + var u = i(40882), + _ = i(80909), + w = i(15389), + x = i(85558), + C = i(56449); + s.exports = function reduce(s, o, i) { + var j = C(s) ? u : x, + L = arguments.length < 3; + return j(s, w(o, 4), i, L, _); + }; + }, + 63560: (s, o, i) => { + var u = i(73170); + s.exports = function set(s, o, i) { + return null == s ? s : u(s, o, i); + }; + }, + 42426: (s, o, i) => { + var u = i(14248), + _ = i(15389), + w = i(90916), + x = i(56449), + C = i(36800); + s.exports = function some(s, o, i) { + var j = x(s) ? u : w; + return i && C(s, o, i) && (o = void 0), j(s, _(o, 3)); + }; + }, + 63345: (s) => { + s.exports = function stubArray() { + return []; + }; + }, + 89935: (s) => { + s.exports = function stubFalse() { + return !1; + }; + }, + 17400: (s, o, i) => { + var u = i(99374), + _ = 1 / 0; + s.exports = function toFinite(s) { + return s + ? (s = u(s)) === _ || s === -1 / 0 + ? 17976931348623157e292 * (s < 0 ? -1 : 1) + : s == s + ? s + : 0 + : 0 === s + ? s + : 0; + }; + }, + 61489: (s, o, i) => { + var u = i(17400); + s.exports = function toInteger(s) { + var o = u(s), + i = o % 1; + return o == o ? (i ? o - i : o) : 0; + }; + }, + 80218: (s, o, i) => { + var u = i(13222); + s.exports = function toLower(s) { + return u(s).toLowerCase(); + }; + }, + 99374: (s, o, i) => { + var u = i(54128), + _ = i(23805), + w = i(44394), + x = /^[-+]0x[0-9a-f]+$/i, + C = /^0b[01]+$/i, + j = /^0o[0-7]+$/i, + L = parseInt; + s.exports = function toNumber(s) { + if ('number' == typeof s) return s; + if (w(s)) return NaN; + if (_(s)) { + var o = 'function' == typeof s.valueOf ? s.valueOf() : s; + s = _(o) ? o + '' : o; + } + if ('string' != typeof s) return 0 === s ? s : +s; + s = u(s); + var i = C.test(s); + return i || j.test(s) ? L(s.slice(2), i ? 2 : 8) : x.test(s) ? NaN : +s; + }; + }, + 42072: (s, o, i) => { + var u = i(34932), + _ = i(23007), + w = i(56449), + x = i(44394), + C = i(61802), + j = i(77797), + L = i(13222); + s.exports = function toPath(s) { + return w(s) ? u(s, j) : x(s) ? [s] : _(C(L(s))); + }; + }, + 69884: (s, o, i) => { + var u = i(21791), + _ = i(37241); + s.exports = function toPlainObject(s) { + return u(s, _(s)); + }; + }, + 13222: (s, o, i) => { + var u = i(77556); + s.exports = function toString(s) { + return null == s ? '' : u(s); + }; + }, + 55808: (s, o, i) => { + var u = i(12507)('toUpperCase'); + s.exports = u; + }, + 66645: (s, o, i) => { + var u = i(1733), + _ = i(45434), + w = i(13222), + x = i(22225); + s.exports = function words(s, o, i) { + return ( + (s = w(s)), void 0 === (o = i ? void 0 : o) ? (_(s) ? x(s) : u(s)) : s.match(o) || [] + ); + }; + }, + 53758: (s, o, i) => { + var u = i(30980), + _ = i(56017), + w = i(94033), + x = i(56449), + C = i(40346), + j = i(80257), + L = Object.prototype.hasOwnProperty; + function lodash(s) { + if (C(s) && !x(s) && !(s instanceof u)) { + if (s instanceof _) return s; + if (L.call(s, '__wrapped__')) return j(s); + } + return new _(s); + } + (lodash.prototype = w.prototype), + (lodash.prototype.constructor = lodash), + (s.exports = lodash); + }, + 47248: (s, o, i) => { + var u = i(16547), + _ = i(51234); + s.exports = function zipObject(s, o) { + return _(s || [], o || [], u); + }; + }, + 43768: (s, o, i) => { + 'use strict'; + var u = i(45981), + _ = i(85587); + (o.highlight = highlight), + (o.highlightAuto = function highlightAuto(s, o) { + var i, + x, + C, + j, + L = o || {}, + B = L.subset || u.listLanguages(), + $ = L.prefix, + V = B.length, + U = -1; + null == $ && ($ = w); + if ('string' != typeof s) throw _('Expected `string` for value, got `%s`', s); + (x = { relevance: 0, language: null, value: [] }), + (i = { relevance: 0, language: null, value: [] }); + for (; ++U < V; ) + (j = B[U]), + u.getLanguage(j) && + (((C = highlight(j, s, o)).language = j), + C.relevance > x.relevance && (x = C), + C.relevance > i.relevance && ((x = i), (i = C))); + x.language && (i.secondBest = x); + return i; + }), + (o.registerLanguage = function registerLanguage(s, o) { + u.registerLanguage(s, o); + }), + (o.listLanguages = function listLanguages() { + return u.listLanguages(); + }), + (o.registerAlias = function registerAlias(s, o) { + var i, + _ = s; + o && ((_ = {})[s] = o); + for (i in _) u.registerAliases(_[i], { languageName: i }); + }), + (Emitter.prototype.addText = function text(s) { + var o, + i, + u = this.stack; + if ('' === s) return; + (o = u[u.length - 1]), + (i = o.children[o.children.length - 1]) && 'text' === i.type + ? (i.value += s) + : o.children.push({ type: 'text', value: s }); + }), + (Emitter.prototype.addKeyword = function addKeyword(s, o) { + this.openNode(o), this.addText(s), this.closeNode(); + }), + (Emitter.prototype.addSublanguage = function addSublanguage(s, o) { + var i = this.stack, + u = i[i.length - 1], + _ = s.rootNode.children, + w = o + ? { + type: 'element', + tagName: 'span', + properties: { className: [o] }, + children: _ + } + : _; + u.children = u.children.concat(w); + }), + (Emitter.prototype.openNode = function open(s) { + var o = this.stack, + i = this.options.classPrefix + s, + u = o[o.length - 1], + _ = { + type: 'element', + tagName: 'span', + properties: { className: [i] }, + children: [] + }; + u.children.push(_), o.push(_); + }), + (Emitter.prototype.closeNode = function close() { + this.stack.pop(); + }), + (Emitter.prototype.closeAllNodes = noop), + (Emitter.prototype.finalize = noop), + (Emitter.prototype.toHTML = function toHtmlNoop() { + return ''; + }); + var w = 'hljs-'; + function highlight(s, o, i) { + var x, + C = u.configure({}), + j = (i || {}).prefix; + if ('string' != typeof s) throw _('Expected `string` for name, got `%s`', s); + if (!u.getLanguage(s)) throw _('Unknown language: `%s` is not registered', s); + if ('string' != typeof o) throw _('Expected `string` for value, got `%s`', o); + if ( + (null == j && (j = w), + u.configure({ __emitter: Emitter, classPrefix: j }), + (x = u.highlight(o, { language: s, ignoreIllegals: !0 })), + u.configure(C || {}), + x.errorRaised) + ) + throw x.errorRaised; + return { + relevance: x.relevance, + language: x.language, + value: x.emitter.rootNode.children + }; + } + function Emitter(s) { + (this.options = s), (this.rootNode = { children: [] }), (this.stack = [this.rootNode]); + } + function noop() {} + }, + 92340: (s, o, i) => { + const u = i(6048); + function coerceElementMatchingCallback(s) { + return 'string' == typeof s + ? (o) => o.element === s + : s.constructor && s.extend + ? (o) => o instanceof s + : s; + } + class ArraySlice { + constructor(s) { + this.elements = s || []; + } + toValue() { + return this.elements.map((s) => s.toValue()); + } + map(s, o) { + return this.elements.map(s, o); + } + flatMap(s, o) { + return this.map(s, o).reduce((s, o) => s.concat(o), []); + } + compactMap(s, o) { + const i = []; + return ( + this.forEach((u) => { + const _ = s.bind(o)(u); + _ && i.push(_); + }), + i + ); + } + filter(s, o) { + return ( + (s = coerceElementMatchingCallback(s)), new ArraySlice(this.elements.filter(s, o)) + ); + } + reject(s, o) { + return ( + (s = coerceElementMatchingCallback(s)), + new ArraySlice(this.elements.filter(u(s), o)) + ); + } + find(s, o) { + return (s = coerceElementMatchingCallback(s)), this.elements.find(s, o); + } + forEach(s, o) { + this.elements.forEach(s, o); + } + reduce(s, o) { + return this.elements.reduce(s, o); + } + includes(s) { + return this.elements.some((o) => o.equals(s)); + } + shift() { + return this.elements.shift(); + } + unshift(s) { + this.elements.unshift(this.refract(s)); + } + push(s) { + return this.elements.push(this.refract(s)), this; + } + add(s) { + this.push(s); + } + get(s) { + return this.elements[s]; + } + getValue(s) { + const o = this.elements[s]; + if (o) return o.toValue(); + } + get length() { + return this.elements.length; + } + get isEmpty() { + return 0 === this.elements.length; + } + get first() { + return this.elements[0]; + } + } + 'undefined' != typeof Symbol && + (ArraySlice.prototype[Symbol.iterator] = function symbol() { + return this.elements[Symbol.iterator](); + }), + (s.exports = ArraySlice); + }, + 55973: (s) => { + class KeyValuePair { + constructor(s, o) { + (this.key = s), (this.value = o); + } + clone() { + const s = new KeyValuePair(); + return ( + this.key && (s.key = this.key.clone()), + this.value && (s.value = this.value.clone()), + s + ); + } + } + s.exports = KeyValuePair; + }, + 3110: (s, o, i) => { + const u = i(5187), + _ = i(85015), + w = i(98023), + x = i(53812), + C = i(23805), + j = i(85105), + L = i(86804); + class Namespace { + constructor(s) { + (this.elementMap = {}), + (this.elementDetection = []), + (this.Element = L.Element), + (this.KeyValuePair = L.KeyValuePair), + (s && s.noDefault) || this.useDefault(), + (this._attributeElementKeys = []), + (this._attributeElementArrayKeys = []); + } + use(s) { + return ( + s.namespace && s.namespace({ base: this }), s.load && s.load({ base: this }), this + ); + } + useDefault() { + return ( + this.register('null', L.NullElement) + .register('string', L.StringElement) + .register('number', L.NumberElement) + .register('boolean', L.BooleanElement) + .register('array', L.ArrayElement) + .register('object', L.ObjectElement) + .register('member', L.MemberElement) + .register('ref', L.RefElement) + .register('link', L.LinkElement), + this.detect(u, L.NullElement, !1) + .detect(_, L.StringElement, !1) + .detect(w, L.NumberElement, !1) + .detect(x, L.BooleanElement, !1) + .detect(Array.isArray, L.ArrayElement, !1) + .detect(C, L.ObjectElement, !1), + this + ); + } + register(s, o) { + return (this._elements = void 0), (this.elementMap[s] = o), this; + } + unregister(s) { + return (this._elements = void 0), delete this.elementMap[s], this; + } + detect(s, o, i) { + return ( + void 0 === i || i + ? this.elementDetection.unshift([s, o]) + : this.elementDetection.push([s, o]), + this + ); + } + toElement(s) { + if (s instanceof this.Element) return s; + let o; + for (let i = 0; i < this.elementDetection.length; i += 1) { + const u = this.elementDetection[i][0], + _ = this.elementDetection[i][1]; + if (u(s)) { + o = new _(s); + break; + } + } + return o; + } + getElementClass(s) { + const o = this.elementMap[s]; + return void 0 === o ? this.Element : o; + } + fromRefract(s) { + return this.serialiser.deserialise(s); + } + toRefract(s) { + return this.serialiser.serialise(s); + } + get elements() { + return ( + void 0 === this._elements && + ((this._elements = { Element: this.Element }), + Object.keys(this.elementMap).forEach((s) => { + const o = s[0].toUpperCase() + s.substr(1); + this._elements[o] = this.elementMap[s]; + })), + this._elements + ); + } + get serialiser() { + return new j(this); + } + } + (j.prototype.Namespace = Namespace), (s.exports = Namespace); + }, + 10866: (s, o, i) => { + const u = i(6048), + _ = i(92340); + class ObjectSlice extends _ { + map(s, o) { + return this.elements.map((i) => s.bind(o)(i.value, i.key, i)); + } + filter(s, o) { + return new ObjectSlice(this.elements.filter((i) => s.bind(o)(i.value, i.key, i))); + } + reject(s, o) { + return this.filter(u(s.bind(o))); + } + forEach(s, o) { + return this.elements.forEach((i, u) => { + s.bind(o)(i.value, i.key, i, u); + }); + } + keys() { + return this.map((s, o) => o.toValue()); + } + values() { + return this.map((s) => s.toValue()); + } + } + s.exports = ObjectSlice; + }, + 86804: (s, o, i) => { + const u = i(10316), + _ = i(41067), + w = i(71167), + x = i(40239), + C = i(12242), + j = i(6233), + L = i(87726), + B = i(61045), + $ = i(86303), + V = i(14540), + U = i(92340), + z = i(10866), + Y = i(55973); + function refract(s) { + if (s instanceof u) return s; + if ('string' == typeof s) return new w(s); + if ('number' == typeof s) return new x(s); + if ('boolean' == typeof s) return new C(s); + if (null === s) return new _(); + if (Array.isArray(s)) return new j(s.map(refract)); + if ('object' == typeof s) { + return new B(s); + } + return s; + } + (u.prototype.ObjectElement = B), + (u.prototype.RefElement = V), + (u.prototype.MemberElement = L), + (u.prototype.refract = refract), + (U.prototype.refract = refract), + (s.exports = { + Element: u, + NullElement: _, + StringElement: w, + NumberElement: x, + BooleanElement: C, + ArrayElement: j, + MemberElement: L, + ObjectElement: B, + LinkElement: $, + RefElement: V, + refract, + ArraySlice: U, + ObjectSlice: z, + KeyValuePair: Y + }); + }, + 86303: (s, o, i) => { + const u = i(10316); + s.exports = class LinkElement extends u { + constructor(s, o, i) { + super(s || [], o, i), (this.element = 'link'); + } + get relation() { + return this.attributes.get('relation'); + } + set relation(s) { + this.attributes.set('relation', s); + } + get href() { + return this.attributes.get('href'); + } + set href(s) { + this.attributes.set('href', s); + } + }; + }, + 14540: (s, o, i) => { + const u = i(10316); + s.exports = class RefElement extends u { + constructor(s, o, i) { + super(s || [], o, i), (this.element = 'ref'), this.path || (this.path = 'element'); + } + get path() { + return this.attributes.get('path'); + } + set path(s) { + this.attributes.set('path', s); + } + }; + }, + 34035: (s, o, i) => { + const u = i(3110), + _ = i(86804); + (o.g$ = u), + (o.KeyValuePair = i(55973)), + (o.G6 = _.ArraySlice), + (o.ot = _.ObjectSlice), + (o.Hg = _.Element), + (o.Om = _.StringElement), + (o.kT = _.NumberElement), + (o.bd = _.BooleanElement), + (o.Os = _.NullElement), + (o.wE = _.ArrayElement), + (o.Sh = _.ObjectElement), + (o.Pr = _.MemberElement), + (o.sI = _.RefElement), + (o.Ft = _.LinkElement), + (o.e = _.refract), + i(85105), + i(75147); + }, + 6233: (s, o, i) => { + const u = i(6048), + _ = i(10316), + w = i(92340); + class ArrayElement extends _ { + constructor(s, o, i) { + super(s || [], o, i), (this.element = 'array'); + } + primitive() { + return 'array'; + } + get(s) { + return this.content[s]; + } + getValue(s) { + const o = this.get(s); + if (o) return o.toValue(); + } + getIndex(s) { + return this.content[s]; + } + set(s, o) { + return (this.content[s] = this.refract(o)), this; + } + remove(s) { + const o = this.content.splice(s, 1); + return o.length ? o[0] : null; + } + map(s, o) { + return this.content.map(s, o); + } + flatMap(s, o) { + return this.map(s, o).reduce((s, o) => s.concat(o), []); + } + compactMap(s, o) { + const i = []; + return ( + this.forEach((u) => { + const _ = s.bind(o)(u); + _ && i.push(_); + }), + i + ); + } + filter(s, o) { + return new w(this.content.filter(s, o)); + } + reject(s, o) { + return this.filter(u(s), o); + } + reduce(s, o) { + let i, u; + void 0 !== o + ? ((i = 0), (u = this.refract(o))) + : ((i = 1), (u = 'object' === this.primitive() ? this.first.value : this.first)); + for (let o = i; o < this.length; o += 1) { + const i = this.content[o]; + u = + 'object' === this.primitive() + ? this.refract(s(u, i.value, i.key, i, this)) + : this.refract(s(u, i, o, this)); + } + return u; + } + forEach(s, o) { + this.content.forEach((i, u) => { + s.bind(o)(i, this.refract(u)); + }); + } + shift() { + return this.content.shift(); + } + unshift(s) { + this.content.unshift(this.refract(s)); + } + push(s) { + return this.content.push(this.refract(s)), this; + } + add(s) { + this.push(s); + } + findElements(s, o) { + const i = o || {}, + u = !!i.recursive, + _ = void 0 === i.results ? [] : i.results; + return ( + this.forEach((o, i, w) => { + u && void 0 !== o.findElements && o.findElements(s, { results: _, recursive: u }), + s(o, i, w) && _.push(o); + }), + _ + ); + } + find(s) { + return new w(this.findElements(s, { recursive: !0 })); + } + findByElement(s) { + return this.find((o) => o.element === s); + } + findByClass(s) { + return this.find((o) => o.classes.includes(s)); + } + getById(s) { + return this.find((o) => o.id.toValue() === s).first; + } + includes(s) { + return this.content.some((o) => o.equals(s)); + } + contains(s) { + return this.includes(s); + } + empty() { + return new this.constructor([]); + } + 'fantasy-land/empty'() { + return this.empty(); + } + concat(s) { + return new this.constructor(this.content.concat(s.content)); + } + 'fantasy-land/concat'(s) { + return this.concat(s); + } + 'fantasy-land/map'(s) { + return new this.constructor(this.map(s)); + } + 'fantasy-land/chain'(s) { + return this.map((o) => s(o), this).reduce((s, o) => s.concat(o), this.empty()); + } + 'fantasy-land/filter'(s) { + return new this.constructor(this.content.filter(s)); + } + 'fantasy-land/reduce'(s, o) { + return this.content.reduce(s, o); + } + get length() { + return this.content.length; + } + get isEmpty() { + return 0 === this.content.length; + } + get first() { + return this.getIndex(0); + } + get second() { + return this.getIndex(1); + } + get last() { + return this.getIndex(this.length - 1); + } + } + (ArrayElement.empty = function empty() { + return new this(); + }), + (ArrayElement['fantasy-land/empty'] = ArrayElement.empty), + 'undefined' != typeof Symbol && + (ArrayElement.prototype[Symbol.iterator] = function symbol() { + return this.content[Symbol.iterator](); + }), + (s.exports = ArrayElement); + }, + 12242: (s, o, i) => { + const u = i(10316); + s.exports = class BooleanElement extends u { + constructor(s, o, i) { + super(s, o, i), (this.element = 'boolean'); + } + primitive() { + return 'boolean'; + } + }; + }, + 10316: (s, o, i) => { + const u = i(2404), + _ = i(55973), + w = i(92340); + class Element { + constructor(s, o, i) { + o && (this.meta = o), i && (this.attributes = i), (this.content = s); + } + freeze() { + Object.isFrozen(this) || + (this._meta && ((this.meta.parent = this), this.meta.freeze()), + this._attributes && ((this.attributes.parent = this), this.attributes.freeze()), + this.children.forEach((s) => { + (s.parent = this), s.freeze(); + }, this), + this.content && Array.isArray(this.content) && Object.freeze(this.content), + Object.freeze(this)); + } + primitive() {} + clone() { + const s = new this.constructor(); + return ( + (s.element = this.element), + this.meta.length && (s._meta = this.meta.clone()), + this.attributes.length && (s._attributes = this.attributes.clone()), + this.content + ? this.content.clone + ? (s.content = this.content.clone()) + : Array.isArray(this.content) + ? (s.content = this.content.map((s) => s.clone())) + : (s.content = this.content) + : (s.content = this.content), + s + ); + } + toValue() { + return this.content instanceof Element + ? this.content.toValue() + : this.content instanceof _ + ? { + key: this.content.key.toValue(), + value: this.content.value ? this.content.value.toValue() : void 0 + } + : this.content && this.content.map + ? this.content.map((s) => s.toValue(), this) + : this.content; + } + toRef(s) { + if ('' === this.id.toValue()) + throw Error('Cannot create reference to an element that does not contain an ID'); + const o = new this.RefElement(this.id.toValue()); + return s && (o.path = s), o; + } + findRecursive(...s) { + if (arguments.length > 1 && !this.isFrozen) + throw new Error( + 'Cannot find recursive with multiple element names without first freezing the element. Call `element.freeze()`' + ); + const o = s.pop(); + let i = new w(); + const append = (s, o) => (s.push(o), s), + checkElement = (s, i) => { + i.element === o && s.push(i); + const u = i.findRecursive(o); + return ( + u && u.reduce(append, s), + i.content instanceof _ && + (i.content.key && checkElement(s, i.content.key), + i.content.value && checkElement(s, i.content.value)), + s + ); + }; + return ( + this.content && + (this.content.element && checkElement(i, this.content), + Array.isArray(this.content) && this.content.reduce(checkElement, i)), + s.isEmpty || + (i = i.filter((o) => { + let i = o.parents.map((s) => s.element); + for (const o in s) { + const u = s[o], + _ = i.indexOf(u); + if (-1 === _) return !1; + i = i.splice(0, _); + } + return !0; + })), + i + ); + } + set(s) { + return (this.content = s), this; + } + equals(s) { + return u(this.toValue(), s); + } + getMetaProperty(s, o) { + if (!this.meta.hasKey(s)) { + if (this.isFrozen) { + const s = this.refract(o); + return s.freeze(), s; + } + this.meta.set(s, o); + } + return this.meta.get(s); + } + setMetaProperty(s, o) { + this.meta.set(s, o); + } + get element() { + return this._storedElement || 'element'; + } + set element(s) { + this._storedElement = s; + } + get content() { + return this._content; + } + set content(s) { + if (s instanceof Element) this._content = s; + else if (s instanceof w) this.content = s.elements; + else if ( + 'string' == typeof s || + 'number' == typeof s || + 'boolean' == typeof s || + 'null' === s || + null == s + ) + this._content = s; + else if (s instanceof _) this._content = s; + else if (Array.isArray(s)) this._content = s.map(this.refract); + else { + if ('object' != typeof s) throw new Error('Cannot set content to given value'); + this._content = Object.keys(s).map((o) => new this.MemberElement(o, s[o])); + } + } + get meta() { + if (!this._meta) { + if (this.isFrozen) { + const s = new this.ObjectElement(); + return s.freeze(), s; + } + this._meta = new this.ObjectElement(); + } + return this._meta; + } + set meta(s) { + s instanceof this.ObjectElement ? (this._meta = s) : this.meta.set(s || {}); + } + get attributes() { + if (!this._attributes) { + if (this.isFrozen) { + const s = new this.ObjectElement(); + return s.freeze(), s; + } + this._attributes = new this.ObjectElement(); + } + return this._attributes; + } + set attributes(s) { + s instanceof this.ObjectElement + ? (this._attributes = s) + : this.attributes.set(s || {}); + } + get id() { + return this.getMetaProperty('id', ''); + } + set id(s) { + this.setMetaProperty('id', s); + } + get classes() { + return this.getMetaProperty('classes', []); + } + set classes(s) { + this.setMetaProperty('classes', s); + } + get title() { + return this.getMetaProperty('title', ''); + } + set title(s) { + this.setMetaProperty('title', s); + } + get description() { + return this.getMetaProperty('description', ''); + } + set description(s) { + this.setMetaProperty('description', s); + } + get links() { + return this.getMetaProperty('links', []); + } + set links(s) { + this.setMetaProperty('links', s); + } + get isFrozen() { + return Object.isFrozen(this); + } + get parents() { + let { parent: s } = this; + const o = new w(); + for (; s; ) o.push(s), (s = s.parent); + return o; + } + get children() { + if (Array.isArray(this.content)) return new w(this.content); + if (this.content instanceof _) { + const s = new w([this.content.key]); + return this.content.value && s.push(this.content.value), s; + } + return this.content instanceof Element ? new w([this.content]) : new w(); + } + get recursiveChildren() { + const s = new w(); + return ( + this.children.forEach((o) => { + s.push(o), + o.recursiveChildren.forEach((o) => { + s.push(o); + }); + }), + s + ); + } + } + s.exports = Element; + }, + 87726: (s, o, i) => { + const u = i(55973), + _ = i(10316); + s.exports = class MemberElement extends _ { + constructor(s, o, i, _) { + super(new u(), i, _), (this.element = 'member'), (this.key = s), (this.value = o); + } + get key() { + return this.content.key; + } + set key(s) { + this.content.key = this.refract(s); + } + get value() { + return this.content.value; + } + set value(s) { + this.content.value = this.refract(s); + } + }; + }, + 41067: (s, o, i) => { + const u = i(10316); + s.exports = class NullElement extends u { + constructor(s, o, i) { + super(s || null, o, i), (this.element = 'null'); + } + primitive() { + return 'null'; + } + set() { + return new Error('Cannot set the value of null'); + } + }; + }, + 40239: (s, o, i) => { + const u = i(10316); + s.exports = class NumberElement extends u { + constructor(s, o, i) { + super(s, o, i), (this.element = 'number'); + } + primitive() { + return 'number'; + } + }; + }, + 61045: (s, o, i) => { + const u = i(6048), + _ = i(23805), + w = i(6233), + x = i(87726), + C = i(10866); + s.exports = class ObjectElement extends w { + constructor(s, o, i) { + super(s || [], o, i), (this.element = 'object'); + } + primitive() { + return 'object'; + } + toValue() { + return this.content.reduce( + (s, o) => ((s[o.key.toValue()] = o.value ? o.value.toValue() : void 0), s), + {} + ); + } + get(s) { + const o = this.getMember(s); + if (o) return o.value; + } + getMember(s) { + if (void 0 !== s) return this.content.find((o) => o.key.toValue() === s); + } + remove(s) { + let o = null; + return ( + (this.content = this.content.filter((i) => i.key.toValue() !== s || ((o = i), !1))), + o + ); + } + getKey(s) { + const o = this.getMember(s); + if (o) return o.key; + } + set(s, o) { + if (_(s)) + return ( + Object.keys(s).forEach((o) => { + this.set(o, s[o]); + }), + this + ); + const i = s, + u = this.getMember(i); + return u ? (u.value = o) : this.content.push(new x(i, o)), this; + } + keys() { + return this.content.map((s) => s.key.toValue()); + } + values() { + return this.content.map((s) => s.value.toValue()); + } + hasKey(s) { + return this.content.some((o) => o.key.equals(s)); + } + items() { + return this.content.map((s) => [s.key.toValue(), s.value.toValue()]); + } + map(s, o) { + return this.content.map((i) => s.bind(o)(i.value, i.key, i)); + } + compactMap(s, o) { + const i = []; + return ( + this.forEach((u, _, w) => { + const x = s.bind(o)(u, _, w); + x && i.push(x); + }), + i + ); + } + filter(s, o) { + return new C(this.content).filter(s, o); + } + reject(s, o) { + return this.filter(u(s), o); + } + forEach(s, o) { + return this.content.forEach((i) => s.bind(o)(i.value, i.key, i)); + } + }; + }, + 71167: (s, o, i) => { + const u = i(10316); + s.exports = class StringElement extends u { + constructor(s, o, i) { + super(s, o, i), (this.element = 'string'); + } + primitive() { + return 'string'; + } + get length() { + return this.content.length; + } + }; + }, + 75147: (s, o, i) => { + const u = i(85105); + s.exports = class JSON06Serialiser extends u { + serialise(s) { + if (!(s instanceof this.namespace.elements.Element)) + throw new TypeError(`Given element \`${s}\` is not an Element instance`); + let o; + s._attributes && s.attributes.get('variable') && (o = s.attributes.get('variable')); + const i = { element: s.element }; + s._meta && s._meta.length > 0 && (i.meta = this.serialiseObject(s.meta)); + const u = 'enum' === s.element || -1 !== s.attributes.keys().indexOf('enumerations'); + if (u) { + const o = this.enumSerialiseAttributes(s); + o && (i.attributes = o); + } else if (s._attributes && s._attributes.length > 0) { + let { attributes: u } = s; + u.get('metadata') && + ((u = u.clone()), u.set('meta', u.get('metadata')), u.remove('metadata')), + 'member' === s.element && o && ((u = u.clone()), u.remove('variable')), + u.length > 0 && (i.attributes = this.serialiseObject(u)); + } + if (u) i.content = this.enumSerialiseContent(s, i); + else if (this[`${s.element}SerialiseContent`]) + i.content = this[`${s.element}SerialiseContent`](s, i); + else if (void 0 !== s.content) { + let u; + o && s.content.key + ? ((u = s.content.clone()), + u.key.attributes.set('variable', o), + (u = this.serialiseContent(u))) + : (u = this.serialiseContent(s.content)), + this.shouldSerialiseContent(s, u) && (i.content = u); + } else + this.shouldSerialiseContent(s, s.content) && + s instanceof this.namespace.elements.Array && + (i.content = []); + return i; + } + shouldSerialiseContent(s, o) { + return ( + 'parseResult' === s.element || + 'httpRequest' === s.element || + 'httpResponse' === s.element || + 'category' === s.element || + 'link' === s.element || + (void 0 !== o && (!Array.isArray(o) || 0 !== o.length)) + ); + } + refSerialiseContent(s, o) { + return delete o.attributes, { href: s.toValue(), path: s.path.toValue() }; + } + sourceMapSerialiseContent(s) { + return s.toValue(); + } + dataStructureSerialiseContent(s) { + return [this.serialiseContent(s.content)]; + } + enumSerialiseAttributes(s) { + const o = s.attributes.clone(), + i = o.remove('enumerations') || new this.namespace.elements.Array([]), + u = o.get('default'); + let _ = o.get('samples') || new this.namespace.elements.Array([]); + if ( + (u && + u.content && + (u.content.attributes && u.content.attributes.remove('typeAttributes'), + o.set('default', new this.namespace.elements.Array([u.content]))), + _.forEach((s) => { + s.content && s.content.element && s.content.attributes.remove('typeAttributes'); + }), + s.content && 0 !== i.length && _.unshift(s.content), + (_ = _.map((s) => + s instanceof this.namespace.elements.Array + ? [s] + : new this.namespace.elements.Array([s.content]) + )), + _.length && o.set('samples', _), + o.length > 0) + ) + return this.serialiseObject(o); + } + enumSerialiseContent(s) { + if (s._attributes) { + const o = s.attributes.get('enumerations'); + if (o && o.length > 0) + return o.content.map((s) => { + const o = s.clone(); + return o.attributes.remove('typeAttributes'), this.serialise(o); + }); + } + if (s.content) { + const o = s.content.clone(); + return o.attributes.remove('typeAttributes'), [this.serialise(o)]; + } + return []; + } + deserialise(s) { + if ('string' == typeof s) return new this.namespace.elements.String(s); + if ('number' == typeof s) return new this.namespace.elements.Number(s); + if ('boolean' == typeof s) return new this.namespace.elements.Boolean(s); + if (null === s) return new this.namespace.elements.Null(); + if (Array.isArray(s)) + return new this.namespace.elements.Array(s.map(this.deserialise, this)); + const o = this.namespace.getElementClass(s.element), + i = new o(); + i.element !== s.element && (i.element = s.element), + s.meta && this.deserialiseObject(s.meta, i.meta), + s.attributes && this.deserialiseObject(s.attributes, i.attributes); + const u = this.deserialiseContent(s.content); + if (((void 0 === u && null !== i.content) || (i.content = u), 'enum' === i.element)) { + i.content && i.attributes.set('enumerations', i.content); + let s = i.attributes.get('samples'); + if ((i.attributes.remove('samples'), s)) { + const u = s; + (s = new this.namespace.elements.Array()), + u.forEach((u) => { + u.forEach((u) => { + const _ = new o(u); + (_.element = i.element), s.push(_); + }); + }); + const _ = s.shift(); + (i.content = _ ? _.content : void 0), i.attributes.set('samples', s); + } else i.content = void 0; + let u = i.attributes.get('default'); + if (u && u.length > 0) { + u = u.get(0); + const s = new o(u); + (s.element = i.element), i.attributes.set('default', s); + } + } else if ('dataStructure' === i.element && Array.isArray(i.content)) + [i.content] = i.content; + else if ('category' === i.element) { + const s = i.attributes.get('meta'); + s && (i.attributes.set('metadata', s), i.attributes.remove('meta')); + } else + 'member' === i.element && + i.key && + i.key._attributes && + i.key._attributes.getValue('variable') && + (i.attributes.set('variable', i.key.attributes.get('variable')), + i.key.attributes.remove('variable')); + return i; + } + serialiseContent(s) { + if (s instanceof this.namespace.elements.Element) return this.serialise(s); + if (s instanceof this.namespace.KeyValuePair) { + const o = { key: this.serialise(s.key) }; + return s.value && (o.value = this.serialise(s.value)), o; + } + return s && s.map ? s.map(this.serialise, this) : s; + } + deserialiseContent(s) { + if (s) { + if (s.element) return this.deserialise(s); + if (s.key) { + const o = new this.namespace.KeyValuePair(this.deserialise(s.key)); + return s.value && (o.value = this.deserialise(s.value)), o; + } + if (s.map) return s.map(this.deserialise, this); + } + return s; + } + shouldRefract(s) { + return ( + !!( + (s._attributes && s.attributes.keys().length) || + (s._meta && s.meta.keys().length) + ) || + ('enum' !== s.element && (s.element !== s.primitive() || 'member' === s.element)) + ); + } + convertKeyToRefract(s, o) { + return this.shouldRefract(o) + ? this.serialise(o) + : 'enum' === o.element + ? this.serialiseEnum(o) + : 'array' === o.element + ? o.map((o) => + this.shouldRefract(o) || 'default' === s + ? this.serialise(o) + : 'array' === o.element || 'object' === o.element || 'enum' === o.element + ? o.children.map((s) => this.serialise(s)) + : o.toValue() + ) + : 'object' === o.element + ? (o.content || []).map(this.serialise, this) + : o.toValue(); + } + serialiseEnum(s) { + return s.children.map((s) => this.serialise(s)); + } + serialiseObject(s) { + const o = {}; + return ( + s.forEach((s, i) => { + if (s) { + const u = i.toValue(); + o[u] = this.convertKeyToRefract(u, s); + } + }), + o + ); + } + deserialiseObject(s, o) { + Object.keys(s).forEach((i) => { + o.set(i, this.deserialise(s[i])); + }); + } + }; + }, + 85105: (s) => { + s.exports = class JSONSerialiser { + constructor(s) { + this.namespace = s || new this.Namespace(); + } + serialise(s) { + if (!(s instanceof this.namespace.elements.Element)) + throw new TypeError(`Given element \`${s}\` is not an Element instance`); + const o = { element: s.element }; + s._meta && s._meta.length > 0 && (o.meta = this.serialiseObject(s.meta)), + s._attributes && + s._attributes.length > 0 && + (o.attributes = this.serialiseObject(s.attributes)); + const i = this.serialiseContent(s.content); + return void 0 !== i && (o.content = i), o; + } + deserialise(s) { + if (!s.element) + throw new Error('Given value is not an object containing an element name'); + const o = new (this.namespace.getElementClass(s.element))(); + o.element !== s.element && (o.element = s.element), + s.meta && this.deserialiseObject(s.meta, o.meta), + s.attributes && this.deserialiseObject(s.attributes, o.attributes); + const i = this.deserialiseContent(s.content); + return (void 0 === i && null !== o.content) || (o.content = i), o; + } + serialiseContent(s) { + if (s instanceof this.namespace.elements.Element) return this.serialise(s); + if (s instanceof this.namespace.KeyValuePair) { + const o = { key: this.serialise(s.key) }; + return s.value && (o.value = this.serialise(s.value)), o; + } + if (s && s.map) { + if (0 === s.length) return; + return s.map(this.serialise, this); + } + return s; + } + deserialiseContent(s) { + if (s) { + if (s.element) return this.deserialise(s); + if (s.key) { + const o = new this.namespace.KeyValuePair(this.deserialise(s.key)); + return s.value && (o.value = this.deserialise(s.value)), o; + } + if (s.map) return s.map(this.deserialise, this); + } + return s; + } + serialiseObject(s) { + const o = {}; + if ( + (s.forEach((s, i) => { + s && (o[i.toValue()] = this.serialise(s)); + }), + 0 !== Object.keys(o).length) + ) + return o; + } + deserialiseObject(s, o) { + Object.keys(s).forEach((i) => { + o.set(i, this.deserialise(s[i])); + }); + } + }; + }, + 65606: (s) => { + var o, + i, + u = (s.exports = {}); + function defaultSetTimout() { + throw new Error('setTimeout has not been defined'); + } + function defaultClearTimeout() { + throw new Error('clearTimeout has not been defined'); + } + function runTimeout(s) { + if (o === setTimeout) return setTimeout(s, 0); + if ((o === defaultSetTimout || !o) && setTimeout) + return (o = setTimeout), setTimeout(s, 0); + try { + return o(s, 0); + } catch (i) { + try { + return o.call(null, s, 0); + } catch (i) { + return o.call(this, s, 0); + } + } + } + !(function () { + try { + o = 'function' == typeof setTimeout ? setTimeout : defaultSetTimout; + } catch (s) { + o = defaultSetTimout; + } + try { + i = 'function' == typeof clearTimeout ? clearTimeout : defaultClearTimeout; + } catch (s) { + i = defaultClearTimeout; + } + })(); + var _, + w = [], + x = !1, + C = -1; + function cleanUpNextTick() { + x && _ && ((x = !1), _.length ? (w = _.concat(w)) : (C = -1), w.length && drainQueue()); + } + function drainQueue() { + if (!x) { + var s = runTimeout(cleanUpNextTick); + x = !0; + for (var o = w.length; o; ) { + for (_ = w, w = []; ++C < o; ) _ && _[C].run(); + (C = -1), (o = w.length); + } + (_ = null), + (x = !1), + (function runClearTimeout(s) { + if (i === clearTimeout) return clearTimeout(s); + if ((i === defaultClearTimeout || !i) && clearTimeout) + return (i = clearTimeout), clearTimeout(s); + try { + return i(s); + } catch (o) { + try { + return i.call(null, s); + } catch (o) { + return i.call(this, s); + } + } + })(s); + } + } + function Item(s, o) { + (this.fun = s), (this.array = o); + } + function noop() {} + (u.nextTick = function (s) { + var o = new Array(arguments.length - 1); + if (arguments.length > 1) + for (var i = 1; i < arguments.length; i++) o[i - 1] = arguments[i]; + w.push(new Item(s, o)), 1 !== w.length || x || runTimeout(drainQueue); + }), + (Item.prototype.run = function () { + this.fun.apply(null, this.array); + }), + (u.title = 'browser'), + (u.browser = !0), + (u.env = {}), + (u.argv = []), + (u.version = ''), + (u.versions = {}), + (u.on = noop), + (u.addListener = noop), + (u.once = noop), + (u.off = noop), + (u.removeListener = noop), + (u.removeAllListeners = noop), + (u.emit = noop), + (u.prependListener = noop), + (u.prependOnceListener = noop), + (u.listeners = function (s) { + return []; + }), + (u.binding = function (s) { + throw new Error('process.binding is not supported'); + }), + (u.cwd = function () { + return '/'; + }), + (u.chdir = function (s) { + throw new Error('process.chdir is not supported'); + }), + (u.umask = function () { + return 0; + }); + }, + 2694: (s, o, i) => { + 'use strict'; + var u = i(6925); + function emptyFunction() {} + function emptyFunctionWithReset() {} + (emptyFunctionWithReset.resetWarningCache = emptyFunction), + (s.exports = function () { + function shim(s, o, i, _, w, x) { + if (x !== u) { + var C = new Error( + 'Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types' + ); + throw ((C.name = 'Invariant Violation'), C); + } + } + function getShim() { + return shim; + } + shim.isRequired = shim; + var s = { + array: shim, + bigint: shim, + bool: shim, + func: shim, + number: shim, + object: shim, + string: shim, + symbol: shim, + any: shim, + arrayOf: getShim, + element: shim, + elementType: shim, + instanceOf: getShim, + node: shim, + objectOf: getShim, + oneOf: getShim, + oneOfType: getShim, + shape: getShim, + exact: getShim, + checkPropTypes: emptyFunctionWithReset, + resetWarningCache: emptyFunction + }; + return (s.PropTypes = s), s; + }); + }, + 5556: (s, o, i) => { + s.exports = i(2694)(); + }, + 6925: (s) => { + 'use strict'; + s.exports = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED'; + }, + 73992: (s, o) => { + 'use strict'; + var i = Object.prototype.hasOwnProperty; + function decode(s) { + try { + return decodeURIComponent(s.replace(/\+/g, ' ')); + } catch (s) { + return null; + } + } + function encode(s) { + try { + return encodeURIComponent(s); + } catch (s) { + return null; + } + } + (o.stringify = function querystringify(s, o) { + o = o || ''; + var u, + _, + w = []; + for (_ in ('string' != typeof o && (o = '?'), s)) + if (i.call(s, _)) { + if ( + ((u = s[_]) || (null != u && !isNaN(u)) || (u = ''), + (_ = encode(_)), + (u = encode(u)), + null === _ || null === u) + ) + continue; + w.push(_ + '=' + u); + } + return w.length ? o + w.join('&') : ''; + }), + (o.parse = function querystring(s) { + for (var o, i = /([^=?#&]+)=?([^&]*)/g, u = {}; (o = i.exec(s)); ) { + var _ = decode(o[1]), + w = decode(o[2]); + null === _ || null === w || _ in u || (u[_] = w); + } + return u; + }); + }, + 41859: (s, o, i) => { + const u = i(27096), + _ = i(78004), + w = u.types; + s.exports = class RandExp { + constructor(s, o) { + if ((this._setDefaults(s), s instanceof RegExp)) + (this.ignoreCase = s.ignoreCase), (this.multiline = s.multiline), (s = s.source); + else { + if ('string' != typeof s) throw new Error('Expected a regexp or string'); + (this.ignoreCase = o && -1 !== o.indexOf('i')), + (this.multiline = o && -1 !== o.indexOf('m')); + } + this.tokens = u(s); + } + _setDefaults(s) { + (this.max = + null != s.max + ? s.max + : null != RandExp.prototype.max + ? RandExp.prototype.max + : 100), + (this.defaultRange = s.defaultRange ? s.defaultRange : this.defaultRange.clone()), + s.randInt && (this.randInt = s.randInt); + } + gen() { + return this._gen(this.tokens, []); + } + _gen(s, o) { + var i, u, _, x, C; + switch (s.type) { + case w.ROOT: + case w.GROUP: + if (s.followedBy || s.notFollowedBy) return ''; + for ( + s.remember && void 0 === s.groupNumber && (s.groupNumber = o.push(null) - 1), + u = '', + x = 0, + C = (i = s.options ? this._randSelect(s.options) : s.stack).length; + x < C; + x++ + ) + u += this._gen(i[x], o); + return s.remember && (o[s.groupNumber] = u), u; + case w.POSITION: + return ''; + case w.SET: + var j = this._expand(s); + return j.length ? String.fromCharCode(this._randSelect(j)) : ''; + case w.REPETITION: + for ( + _ = this.randInt(s.min, s.max === 1 / 0 ? s.min + this.max : s.max), + u = '', + x = 0; + x < _; + x++ + ) + u += this._gen(s.value, o); + return u; + case w.REFERENCE: + return o[s.value - 1] || ''; + case w.CHAR: + var L = + this.ignoreCase && this._randBool() ? this._toOtherCase(s.value) : s.value; + return String.fromCharCode(L); + } + } + _toOtherCase(s) { + return s + (97 <= s && s <= 122 ? -32 : 65 <= s && s <= 90 ? 32 : 0); + } + _randBool() { + return !this.randInt(0, 1); + } + _randSelect(s) { + return s instanceof _ + ? s.index(this.randInt(0, s.length - 1)) + : s[this.randInt(0, s.length - 1)]; + } + _expand(s) { + if (s.type === u.types.CHAR) return new _(s.value); + if (s.type === u.types.RANGE) return new _(s.from, s.to); + { + let o = new _(); + for (let i = 0; i < s.set.length; i++) { + let u = this._expand(s.set[i]); + if ((o.add(u), this.ignoreCase)) + for (let s = 0; s < u.length; s++) { + let i = u.index(s), + _ = this._toOtherCase(i); + i !== _ && o.add(_); + } + } + return s.not + ? this.defaultRange.clone().subtract(o) + : this.defaultRange.clone().intersect(o); + } + } + randInt(s, o) { + return s + Math.floor(Math.random() * (1 + o - s)); + } + get defaultRange() { + return (this._range = this._range || new _(32, 126)); + } + set defaultRange(s) { + this._range = s; + } + static randexp(s, o) { + var i; + return ( + 'string' == typeof s && (s = new RegExp(s, o)), + void 0 === s._randexp + ? ((i = new RandExp(s, o)), (s._randexp = i)) + : (i = s._randexp)._setDefaults(s), + i.gen() + ); + } + static sugar() { + RegExp.prototype.gen = function () { + return RandExp.randexp(this); + }; + } + }; + }, + 53209: (s, o, i) => { + 'use strict'; + var u = i(65606), + _ = 65536, + w = 4294967295; + var x = i(92861).Buffer, + C = i.g.crypto || i.g.msCrypto; + C && C.getRandomValues + ? (s.exports = function randomBytes(s, o) { + if (s > w) throw new RangeError('requested too many random bytes'); + var i = x.allocUnsafe(s); + if (s > 0) + if (s > _) for (var j = 0; j < s; j += _) C.getRandomValues(i.slice(j, j + _)); + else C.getRandomValues(i); + if ('function' == typeof o) + return u.nextTick(function () { + o(null, i); + }); + return i; + }) + : (s.exports = function oldBrowser() { + throw new Error( + 'Secure random number generation is not supported by this browser.\nUse Chrome, Firefox or Internet Explorer 11' + ); + }); + }, + 25264: (s, o, i) => { + 'use strict'; + function _typeof(s) { + return ( + (_typeof = + 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator + ? function (s) { + return typeof s; + } + : function (s) { + return s && + 'function' == typeof Symbol && + s.constructor === Symbol && + s !== Symbol.prototype + ? 'symbol' + : typeof s; + }), + _typeof(s) + ); + } + Object.defineProperty(o, '__esModule', { value: !0 }), (o.CopyToClipboard = void 0); + var u = _interopRequireDefault(i(96540)), + _ = _interopRequireDefault(i(17965)), + w = ['text', 'onCopy', 'options', 'children']; + function _interopRequireDefault(s) { + return s && s.__esModule ? s : { default: s }; + } + function ownKeys(s, o) { + var i = Object.keys(s); + if (Object.getOwnPropertySymbols) { + var u = Object.getOwnPropertySymbols(s); + o && + (u = u.filter(function (o) { + return Object.getOwnPropertyDescriptor(s, o).enumerable; + })), + i.push.apply(i, u); + } + return i; + } + function _objectSpread(s) { + for (var o = 1; o < arguments.length; o++) { + var i = null != arguments[o] ? arguments[o] : {}; + o % 2 + ? ownKeys(Object(i), !0).forEach(function (o) { + _defineProperty(s, o, i[o]); + }) + : Object.getOwnPropertyDescriptors + ? Object.defineProperties(s, Object.getOwnPropertyDescriptors(i)) + : ownKeys(Object(i)).forEach(function (o) { + Object.defineProperty(s, o, Object.getOwnPropertyDescriptor(i, o)); + }); + } + return s; + } + function _objectWithoutProperties(s, o) { + if (null == s) return {}; + var i, + u, + _ = (function _objectWithoutPropertiesLoose(s, o) { + if (null == s) return {}; + var i, + u, + _ = {}, + w = Object.keys(s); + for (u = 0; u < w.length; u++) (i = w[u]), o.indexOf(i) >= 0 || (_[i] = s[i]); + return _; + })(s, o); + if (Object.getOwnPropertySymbols) { + var w = Object.getOwnPropertySymbols(s); + for (u = 0; u < w.length; u++) + (i = w[u]), + o.indexOf(i) >= 0 || + (Object.prototype.propertyIsEnumerable.call(s, i) && (_[i] = s[i])); + } + return _; + } + function _defineProperties(s, o) { + for (var i = 0; i < o.length; i++) { + var u = o[i]; + (u.enumerable = u.enumerable || !1), + (u.configurable = !0), + 'value' in u && (u.writable = !0), + Object.defineProperty(s, u.key, u); + } + } + function _setPrototypeOf(s, o) { + return ( + (_setPrototypeOf = + Object.setPrototypeOf || + function _setPrototypeOf(s, o) { + return (s.__proto__ = o), s; + }), + _setPrototypeOf(s, o) + ); + } + function _createSuper(s) { + var o = (function _isNativeReflectConstruct() { + if ('undefined' == typeof Reflect || !Reflect.construct) return !1; + if (Reflect.construct.sham) return !1; + if ('function' == typeof Proxy) return !0; + try { + return ( + Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})), !0 + ); + } catch (s) { + return !1; + } + })(); + return function _createSuperInternal() { + var i, + u = _getPrototypeOf(s); + if (o) { + var _ = _getPrototypeOf(this).constructor; + i = Reflect.construct(u, arguments, _); + } else i = u.apply(this, arguments); + return (function _possibleConstructorReturn(s, o) { + if (o && ('object' === _typeof(o) || 'function' == typeof o)) return o; + if (void 0 !== o) + throw new TypeError('Derived constructors may only return object or undefined'); + return _assertThisInitialized(s); + })(this, i); + }; + } + function _assertThisInitialized(s) { + if (void 0 === s) + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + return s; + } + function _getPrototypeOf(s) { + return ( + (_getPrototypeOf = Object.setPrototypeOf + ? Object.getPrototypeOf + : function _getPrototypeOf(s) { + return s.__proto__ || Object.getPrototypeOf(s); + }), + _getPrototypeOf(s) + ); + } + function _defineProperty(s, o, i) { + return ( + o in s + ? Object.defineProperty(s, o, { + value: i, + enumerable: !0, + configurable: !0, + writable: !0 + }) + : (s[o] = i), + s + ); + } + var x = (function (s) { + !(function _inherits(s, o) { + if ('function' != typeof o && null !== o) + throw new TypeError('Super expression must either be null or a function'); + (s.prototype = Object.create(o && o.prototype, { + constructor: { value: s, writable: !0, configurable: !0 } + })), + Object.defineProperty(s, 'prototype', { writable: !1 }), + o && _setPrototypeOf(s, o); + })(CopyToClipboard, s); + var o = _createSuper(CopyToClipboard); + function CopyToClipboard() { + var s; + !(function _classCallCheck(s, o) { + if (!(s instanceof o)) throw new TypeError('Cannot call a class as a function'); + })(this, CopyToClipboard); + for (var i = arguments.length, w = new Array(i), x = 0; x < i; x++) + w[x] = arguments[x]; + return ( + _defineProperty( + _assertThisInitialized((s = o.call.apply(o, [this].concat(w)))), + 'onClick', + function (o) { + var i = s.props, + w = i.text, + x = i.onCopy, + C = i.children, + j = i.options, + L = u.default.Children.only(C), + B = (0, _.default)(w, j); + x && x(w, B), + L && L.props && 'function' == typeof L.props.onClick && L.props.onClick(o); + } + ), + s + ); + } + return ( + (function _createClass(s, o, i) { + return ( + o && _defineProperties(s.prototype, o), + i && _defineProperties(s, i), + Object.defineProperty(s, 'prototype', { writable: !1 }), + s + ); + })(CopyToClipboard, [ + { + key: 'render', + value: function render() { + var s = this.props, + o = (s.text, s.onCopy, s.options, s.children), + i = _objectWithoutProperties(s, w), + _ = u.default.Children.only(o); + return u.default.cloneElement( + _, + _objectSpread(_objectSpread({}, i), {}, { onClick: this.onClick }) + ); + } + } + ]), + CopyToClipboard + ); + })(u.default.PureComponent); + (o.CopyToClipboard = x), + _defineProperty(x, 'defaultProps', { onCopy: void 0, options: void 0 }); + }, + 59399: (s, o, i) => { + 'use strict'; + var u = i(25264).CopyToClipboard; + (u.CopyToClipboard = u), (s.exports = u); + }, + 81214: (s, o, i) => { + 'use strict'; + function _typeof(s) { + return ( + (_typeof = + 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator + ? function (s) { + return typeof s; + } + : function (s) { + return s && + 'function' == typeof Symbol && + s.constructor === Symbol && + s !== Symbol.prototype + ? 'symbol' + : typeof s; + }), + _typeof(s) + ); + } + Object.defineProperty(o, '__esModule', { value: !0 }), (o.DebounceInput = void 0); + var u = _interopRequireDefault(i(96540)), + _ = _interopRequireDefault(i(20181)), + w = [ + 'element', + 'onChange', + 'value', + 'minLength', + 'debounceTimeout', + 'forceNotifyByEnter', + 'forceNotifyOnBlur', + 'onKeyDown', + 'onBlur', + 'inputRef' + ]; + function _interopRequireDefault(s) { + return s && s.__esModule ? s : { default: s }; + } + function _objectWithoutProperties(s, o) { + if (null == s) return {}; + var i, + u, + _ = (function _objectWithoutPropertiesLoose(s, o) { + if (null == s) return {}; + var i, + u, + _ = {}, + w = Object.keys(s); + for (u = 0; u < w.length; u++) (i = w[u]), o.indexOf(i) >= 0 || (_[i] = s[i]); + return _; + })(s, o); + if (Object.getOwnPropertySymbols) { + var w = Object.getOwnPropertySymbols(s); + for (u = 0; u < w.length; u++) + (i = w[u]), + o.indexOf(i) >= 0 || + (Object.prototype.propertyIsEnumerable.call(s, i) && (_[i] = s[i])); + } + return _; + } + function ownKeys(s, o) { + var i = Object.keys(s); + if (Object.getOwnPropertySymbols) { + var u = Object.getOwnPropertySymbols(s); + o && + (u = u.filter(function (o) { + return Object.getOwnPropertyDescriptor(s, o).enumerable; + })), + i.push.apply(i, u); + } + return i; + } + function _objectSpread(s) { + for (var o = 1; o < arguments.length; o++) { + var i = null != arguments[o] ? arguments[o] : {}; + o % 2 + ? ownKeys(Object(i), !0).forEach(function (o) { + _defineProperty(s, o, i[o]); + }) + : Object.getOwnPropertyDescriptors + ? Object.defineProperties(s, Object.getOwnPropertyDescriptors(i)) + : ownKeys(Object(i)).forEach(function (o) { + Object.defineProperty(s, o, Object.getOwnPropertyDescriptor(i, o)); + }); + } + return s; + } + function _defineProperties(s, o) { + for (var i = 0; i < o.length; i++) { + var u = o[i]; + (u.enumerable = u.enumerable || !1), + (u.configurable = !0), + 'value' in u && (u.writable = !0), + Object.defineProperty(s, u.key, u); + } + } + function _setPrototypeOf(s, o) { + return ( + (_setPrototypeOf = + Object.setPrototypeOf || + function _setPrototypeOf(s, o) { + return (s.__proto__ = o), s; + }), + _setPrototypeOf(s, o) + ); + } + function _createSuper(s) { + var o = (function _isNativeReflectConstruct() { + if ('undefined' == typeof Reflect || !Reflect.construct) return !1; + if (Reflect.construct.sham) return !1; + if ('function' == typeof Proxy) return !0; + try { + return ( + Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})), !0 + ); + } catch (s) { + return !1; + } + })(); + return function _createSuperInternal() { + var i, + u = _getPrototypeOf(s); + if (o) { + var _ = _getPrototypeOf(this).constructor; + i = Reflect.construct(u, arguments, _); + } else i = u.apply(this, arguments); + return (function _possibleConstructorReturn(s, o) { + if (o && ('object' === _typeof(o) || 'function' == typeof o)) return o; + if (void 0 !== o) + throw new TypeError('Derived constructors may only return object or undefined'); + return _assertThisInitialized(s); + })(this, i); + }; + } + function _assertThisInitialized(s) { + if (void 0 === s) + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + return s; + } + function _getPrototypeOf(s) { + return ( + (_getPrototypeOf = Object.setPrototypeOf + ? Object.getPrototypeOf + : function _getPrototypeOf(s) { + return s.__proto__ || Object.getPrototypeOf(s); + }), + _getPrototypeOf(s) + ); + } + function _defineProperty(s, o, i) { + return ( + o in s + ? Object.defineProperty(s, o, { + value: i, + enumerable: !0, + configurable: !0, + writable: !0 + }) + : (s[o] = i), + s + ); + } + var x = (function (s) { + !(function _inherits(s, o) { + if ('function' != typeof o && null !== o) + throw new TypeError('Super expression must either be null or a function'); + (s.prototype = Object.create(o && o.prototype, { + constructor: { value: s, writable: !0, configurable: !0 } + })), + Object.defineProperty(s, 'prototype', { writable: !1 }), + o && _setPrototypeOf(s, o); + })(DebounceInput, s); + var o = _createSuper(DebounceInput); + function DebounceInput(s) { + var i; + !(function _classCallCheck(s, o) { + if (!(s instanceof o)) throw new TypeError('Cannot call a class as a function'); + })(this, DebounceInput), + _defineProperty( + _assertThisInitialized((i = o.call(this, s))), + 'onChange', + function (s) { + s.persist(); + var o = i.state.value, + u = i.props.minLength; + i.setState({ value: s.target.value }, function () { + var _ = i.state.value; + _.length >= u + ? i.notify(s) + : o.length > _.length && + i.notify( + _objectSpread( + _objectSpread({}, s), + {}, + { + target: _objectSpread( + _objectSpread({}, s.target), + {}, + { value: '' } + ) + } + ) + ); + }); + } + ), + _defineProperty(_assertThisInitialized(i), 'onKeyDown', function (s) { + 'Enter' === s.key && i.forceNotify(s); + var o = i.props.onKeyDown; + o && (s.persist(), o(s)); + }), + _defineProperty(_assertThisInitialized(i), 'onBlur', function (s) { + i.forceNotify(s); + var o = i.props.onBlur; + o && (s.persist(), o(s)); + }), + _defineProperty(_assertThisInitialized(i), 'createNotifier', function (s) { + if (s < 0) + i.notify = function () { + return null; + }; + else if (0 === s) i.notify = i.doNotify; + else { + var o = (0, _.default)(function (s) { + (i.isDebouncing = !1), i.doNotify(s); + }, s); + (i.notify = function (s) { + (i.isDebouncing = !0), o(s); + }), + (i.flush = function () { + return o.flush(); + }), + (i.cancel = function () { + (i.isDebouncing = !1), o.cancel(); + }); + } + }), + _defineProperty(_assertThisInitialized(i), 'doNotify', function () { + i.props.onChange.apply(void 0, arguments); + }), + _defineProperty(_assertThisInitialized(i), 'forceNotify', function (s) { + var o = i.props.debounceTimeout; + if (i.isDebouncing || !(o > 0)) { + i.cancel && i.cancel(); + var u = i.state.value, + _ = i.props.minLength; + u.length >= _ + ? i.doNotify(s) + : i.doNotify( + _objectSpread( + _objectSpread({}, s), + {}, + { target: _objectSpread(_objectSpread({}, s.target), {}, { value: u }) } + ) + ); + } + }), + (i.isDebouncing = !1), + (i.state = { value: void 0 === s.value || null === s.value ? '' : s.value }); + var u = i.props.debounceTimeout; + return i.createNotifier(u), i; + } + return ( + (function _createClass(s, o, i) { + return ( + o && _defineProperties(s.prototype, o), + i && _defineProperties(s, i), + Object.defineProperty(s, 'prototype', { writable: !1 }), + s + ); + })(DebounceInput, [ + { + key: 'componentDidUpdate', + value: function componentDidUpdate(s) { + if (!this.isDebouncing) { + var o = this.props, + i = o.value, + u = o.debounceTimeout, + _ = s.debounceTimeout, + w = s.value, + x = this.state.value; + void 0 !== i && w !== i && x !== i && this.setState({ value: i }), + u !== _ && this.createNotifier(u); + } + } + }, + { + key: 'componentWillUnmount', + value: function componentWillUnmount() { + this.flush && this.flush(); + } + }, + { + key: 'render', + value: function render() { + var s, + o, + i = this.props, + _ = i.element, + x = + (i.onChange, i.value, i.minLength, i.debounceTimeout, i.forceNotifyByEnter), + C = i.forceNotifyOnBlur, + j = i.onKeyDown, + L = i.onBlur, + B = i.inputRef, + $ = _objectWithoutProperties(i, w), + V = this.state.value; + (s = x ? { onKeyDown: this.onKeyDown } : j ? { onKeyDown: j } : {}), + (o = C ? { onBlur: this.onBlur } : L ? { onBlur: L } : {}); + var U = B ? { ref: B } : {}; + return u.default.createElement( + _, + _objectSpread( + _objectSpread( + _objectSpread( + _objectSpread({}, $), + {}, + { onChange: this.onChange, value: V }, + s + ), + o + ), + U + ) + ); + } + } + ]), + DebounceInput + ); + })(u.default.PureComponent); + (o.DebounceInput = x), + _defineProperty(x, 'defaultProps', { + element: 'input', + type: 'text', + onKeyDown: void 0, + onBlur: void 0, + value: void 0, + minLength: 0, + debounceTimeout: 100, + forceNotifyByEnter: !0, + forceNotifyOnBlur: !0, + inputRef: void 0 + }); + }, + 24677: (s, o, i) => { + 'use strict'; + var u = i(81214).DebounceInput; + (u.DebounceInput = u), (s.exports = u); + }, + 22551: (s, o, i) => { + 'use strict'; + var u = i(96540), + _ = i(69982); + function p(s) { + for ( + var o = 'https://reactjs.org/docs/error-decoder.html?invariant=' + s, i = 1; + i < arguments.length; + i++ + ) + o += '&args[]=' + encodeURIComponent(arguments[i]); + return ( + 'Minified React error #' + + s + + '; visit ' + + o + + ' for the full message or use the non-minified dev environment for full errors and additional helpful warnings.' + ); + } + var w = new Set(), + x = {}; + function fa(s, o) { + ha(s, o), ha(s + 'Capture', o); + } + function ha(s, o) { + for (x[s] = o, s = 0; s < o.length; s++) w.add(o[s]); + } + var C = !( + 'undefined' == typeof window || + void 0 === window.document || + void 0 === window.document.createElement + ), + j = Object.prototype.hasOwnProperty, + L = + /^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/, + B = {}, + $ = {}; + function v(s, o, i, u, _, w, x) { + (this.acceptsBooleans = 2 === o || 3 === o || 4 === o), + (this.attributeName = u), + (this.attributeNamespace = _), + (this.mustUseProperty = i), + (this.propertyName = s), + (this.type = o), + (this.sanitizeURL = w), + (this.removeEmptyString = x); + } + var V = {}; + 'children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style' + .split(' ') + .forEach(function (s) { + V[s] = new v(s, 0, !1, s, null, !1, !1); + }), + [ + ['acceptCharset', 'accept-charset'], + ['className', 'class'], + ['htmlFor', 'for'], + ['httpEquiv', 'http-equiv'] + ].forEach(function (s) { + var o = s[0]; + V[o] = new v(o, 1, !1, s[1], null, !1, !1); + }), + ['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (s) { + V[s] = new v(s, 2, !1, s.toLowerCase(), null, !1, !1); + }), + ['autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha'].forEach( + function (s) { + V[s] = new v(s, 2, !1, s, null, !1, !1); + } + ), + 'allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope' + .split(' ') + .forEach(function (s) { + V[s] = new v(s, 3, !1, s.toLowerCase(), null, !1, !1); + }), + ['checked', 'multiple', 'muted', 'selected'].forEach(function (s) { + V[s] = new v(s, 3, !0, s, null, !1, !1); + }), + ['capture', 'download'].forEach(function (s) { + V[s] = new v(s, 4, !1, s, null, !1, !1); + }), + ['cols', 'rows', 'size', 'span'].forEach(function (s) { + V[s] = new v(s, 6, !1, s, null, !1, !1); + }), + ['rowSpan', 'start'].forEach(function (s) { + V[s] = new v(s, 5, !1, s.toLowerCase(), null, !1, !1); + }); + var U = /[\-:]([a-z])/g; + function sa(s) { + return s[1].toUpperCase(); + } + function ta(s, o, i, u) { + var _ = V.hasOwnProperty(o) ? V[o] : null; + (null !== _ + ? 0 !== _.type + : u || + !(2 < o.length) || + ('o' !== o[0] && 'O' !== o[0]) || + ('n' !== o[1] && 'N' !== o[1])) && + ((function qa(s, o, i, u) { + if ( + null == o || + (function pa(s, o, i, u) { + if (null !== i && 0 === i.type) return !1; + switch (typeof o) { + case 'function': + case 'symbol': + return !0; + case 'boolean': + return ( + !u && + (null !== i + ? !i.acceptsBooleans + : 'data-' !== (s = s.toLowerCase().slice(0, 5)) && 'aria-' !== s) + ); + default: + return !1; + } + })(s, o, i, u) + ) + return !0; + if (u) return !1; + if (null !== i) + switch (i.type) { + case 3: + return !o; + case 4: + return !1 === o; + case 5: + return isNaN(o); + case 6: + return isNaN(o) || 1 > o; + } + return !1; + })(o, i, _, u) && (i = null), + u || null === _ + ? (function oa(s) { + return ( + !!j.call($, s) || + (!j.call(B, s) && (L.test(s) ? ($[s] = !0) : ((B[s] = !0), !1))) + ); + })(o) && (null === i ? s.removeAttribute(o) : s.setAttribute(o, '' + i)) + : _.mustUseProperty + ? (s[_.propertyName] = null === i ? 3 !== _.type && '' : i) + : ((o = _.attributeName), + (u = _.attributeNamespace), + null === i + ? s.removeAttribute(o) + : ((i = 3 === (_ = _.type) || (4 === _ && !0 === i) ? '' : '' + i), + u ? s.setAttributeNS(u, o, i) : s.setAttribute(o, i)))); + } + 'accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height' + .split(' ') + .forEach(function (s) { + var o = s.replace(U, sa); + V[o] = new v(o, 1, !1, s, null, !1, !1); + }), + 'xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type' + .split(' ') + .forEach(function (s) { + var o = s.replace(U, sa); + V[o] = new v(o, 1, !1, s, 'http://www.w3.org/1999/xlink', !1, !1); + }), + ['xml:base', 'xml:lang', 'xml:space'].forEach(function (s) { + var o = s.replace(U, sa); + V[o] = new v(o, 1, !1, s, 'http://www.w3.org/XML/1998/namespace', !1, !1); + }), + ['tabIndex', 'crossOrigin'].forEach(function (s) { + V[s] = new v(s, 1, !1, s.toLowerCase(), null, !1, !1); + }), + (V.xlinkHref = new v( + 'xlinkHref', + 1, + !1, + 'xlink:href', + 'http://www.w3.org/1999/xlink', + !0, + !1 + )), + ['src', 'href', 'action', 'formAction'].forEach(function (s) { + V[s] = new v(s, 1, !1, s.toLowerCase(), null, !0, !0); + }); + var z = u.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, + Y = Symbol.for('react.element'), + Z = Symbol.for('react.portal'), + ee = Symbol.for('react.fragment'), + ie = Symbol.for('react.strict_mode'), + ae = Symbol.for('react.profiler'), + le = Symbol.for('react.provider'), + ce = Symbol.for('react.context'), + pe = Symbol.for('react.forward_ref'), + de = Symbol.for('react.suspense'), + fe = Symbol.for('react.suspense_list'), + ye = Symbol.for('react.memo'), + be = Symbol.for('react.lazy'); + Symbol.for('react.scope'), Symbol.for('react.debug_trace_mode'); + var _e = Symbol.for('react.offscreen'); + Symbol.for('react.legacy_hidden'), + Symbol.for('react.cache'), + Symbol.for('react.tracing_marker'); + var we = Symbol.iterator; + function Ka(s) { + return null === s || 'object' != typeof s + ? null + : 'function' == typeof (s = (we && s[we]) || s['@@iterator']) + ? s + : null; + } + var Se, + xe = Object.assign; + function Ma(s) { + if (void 0 === Se) + try { + throw Error(); + } catch (s) { + var o = s.stack.trim().match(/\n( *(at )?)/); + Se = (o && o[1]) || ''; + } + return '\n' + Se + s; + } + var Pe = !1; + function Oa(s, o) { + if (!s || Pe) return ''; + Pe = !0; + var i = Error.prepareStackTrace; + Error.prepareStackTrace = void 0; + try { + if (o) + if ( + ((o = function () { + throw Error(); + }), + Object.defineProperty(o.prototype, 'props', { + set: function () { + throw Error(); + } + }), + 'object' == typeof Reflect && Reflect.construct) + ) { + try { + Reflect.construct(o, []); + } catch (s) { + var u = s; + } + Reflect.construct(s, [], o); + } else { + try { + o.call(); + } catch (s) { + u = s; + } + s.call(o.prototype); + } + else { + try { + throw Error(); + } catch (s) { + u = s; + } + s(); + } + } catch (o) { + if (o && u && 'string' == typeof o.stack) { + for ( + var _ = o.stack.split('\n'), + w = u.stack.split('\n'), + x = _.length - 1, + C = w.length - 1; + 1 <= x && 0 <= C && _[x] !== w[C]; + + ) + C--; + for (; 1 <= x && 0 <= C; x--, C--) + if (_[x] !== w[C]) { + if (1 !== x || 1 !== C) + do { + if ((x--, 0 > --C || _[x] !== w[C])) { + var j = '\n' + _[x].replace(' at new ', ' at '); + return ( + s.displayName && + j.includes('') && + (j = j.replace('', s.displayName)), + j + ); + } + } while (1 <= x && 0 <= C); + break; + } + } + } finally { + (Pe = !1), (Error.prepareStackTrace = i); + } + return (s = s ? s.displayName || s.name : '') ? Ma(s) : ''; + } + function Pa(s) { + switch (s.tag) { + case 5: + return Ma(s.type); + case 16: + return Ma('Lazy'); + case 13: + return Ma('Suspense'); + case 19: + return Ma('SuspenseList'); + case 0: + case 2: + case 15: + return (s = Oa(s.type, !1)); + case 11: + return (s = Oa(s.type.render, !1)); + case 1: + return (s = Oa(s.type, !0)); + default: + return ''; + } + } + function Qa(s) { + if (null == s) return null; + if ('function' == typeof s) return s.displayName || s.name || null; + if ('string' == typeof s) return s; + switch (s) { + case ee: + return 'Fragment'; + case Z: + return 'Portal'; + case ae: + return 'Profiler'; + case ie: + return 'StrictMode'; + case de: + return 'Suspense'; + case fe: + return 'SuspenseList'; + } + if ('object' == typeof s) + switch (s.$$typeof) { + case ce: + return (s.displayName || 'Context') + '.Consumer'; + case le: + return (s._context.displayName || 'Context') + '.Provider'; + case pe: + var o = s.render; + return ( + (s = s.displayName) || + (s = + '' !== (s = o.displayName || o.name || '') + ? 'ForwardRef(' + s + ')' + : 'ForwardRef'), + s + ); + case ye: + return null !== (o = s.displayName || null) ? o : Qa(s.type) || 'Memo'; + case be: + (o = s._payload), (s = s._init); + try { + return Qa(s(o)); + } catch (s) {} + } + return null; + } + function Ra(s) { + var o = s.type; + switch (s.tag) { + case 24: + return 'Cache'; + case 9: + return (o.displayName || 'Context') + '.Consumer'; + case 10: + return (o._context.displayName || 'Context') + '.Provider'; + case 18: + return 'DehydratedFragment'; + case 11: + return ( + (s = (s = o.render).displayName || s.name || ''), + o.displayName || ('' !== s ? 'ForwardRef(' + s + ')' : 'ForwardRef') + ); + case 7: + return 'Fragment'; + case 5: + return o; + case 4: + return 'Portal'; + case 3: + return 'Root'; + case 6: + return 'Text'; + case 16: + return Qa(o); + case 8: + return o === ie ? 'StrictMode' : 'Mode'; + case 22: + return 'Offscreen'; + case 12: + return 'Profiler'; + case 21: + return 'Scope'; + case 13: + return 'Suspense'; + case 19: + return 'SuspenseList'; + case 25: + return 'TracingMarker'; + case 1: + case 0: + case 17: + case 2: + case 14: + case 15: + if ('function' == typeof o) return o.displayName || o.name || null; + if ('string' == typeof o) return o; + } + return null; + } + function Sa(s) { + switch (typeof s) { + case 'boolean': + case 'number': + case 'string': + case 'undefined': + case 'object': + return s; + default: + return ''; + } + } + function Ta(s) { + var o = s.type; + return ( + (s = s.nodeName) && 'input' === s.toLowerCase() && ('checkbox' === o || 'radio' === o) + ); + } + function Va(s) { + s._valueTracker || + (s._valueTracker = (function Ua(s) { + var o = Ta(s) ? 'checked' : 'value', + i = Object.getOwnPropertyDescriptor(s.constructor.prototype, o), + u = '' + s[o]; + if ( + !s.hasOwnProperty(o) && + void 0 !== i && + 'function' == typeof i.get && + 'function' == typeof i.set + ) { + var _ = i.get, + w = i.set; + return ( + Object.defineProperty(s, o, { + configurable: !0, + get: function () { + return _.call(this); + }, + set: function (s) { + (u = '' + s), w.call(this, s); + } + }), + Object.defineProperty(s, o, { enumerable: i.enumerable }), + { + getValue: function () { + return u; + }, + setValue: function (s) { + u = '' + s; + }, + stopTracking: function () { + (s._valueTracker = null), delete s[o]; + } + } + ); + } + })(s)); + } + function Wa(s) { + if (!s) return !1; + var o = s._valueTracker; + if (!o) return !0; + var i = o.getValue(), + u = ''; + return ( + s && (u = Ta(s) ? (s.checked ? 'true' : 'false') : s.value), + (s = u) !== i && (o.setValue(s), !0) + ); + } + function Xa(s) { + if (void 0 === (s = s || ('undefined' != typeof document ? document : void 0))) + return null; + try { + return s.activeElement || s.body; + } catch (o) { + return s.body; + } + } + function Ya(s, o) { + var i = o.checked; + return xe({}, o, { + defaultChecked: void 0, + defaultValue: void 0, + value: void 0, + checked: null != i ? i : s._wrapperState.initialChecked + }); + } + function Za(s, o) { + var i = null == o.defaultValue ? '' : o.defaultValue, + u = null != o.checked ? o.checked : o.defaultChecked; + (i = Sa(null != o.value ? o.value : i)), + (s._wrapperState = { + initialChecked: u, + initialValue: i, + controlled: + 'checkbox' === o.type || 'radio' === o.type ? null != o.checked : null != o.value + }); + } + function ab(s, o) { + null != (o = o.checked) && ta(s, 'checked', o, !1); + } + function bb(s, o) { + ab(s, o); + var i = Sa(o.value), + u = o.type; + if (null != i) + 'number' === u + ? ((0 === i && '' === s.value) || s.value != i) && (s.value = '' + i) + : s.value !== '' + i && (s.value = '' + i); + else if ('submit' === u || 'reset' === u) return void s.removeAttribute('value'); + o.hasOwnProperty('value') + ? cb(s, o.type, i) + : o.hasOwnProperty('defaultValue') && cb(s, o.type, Sa(o.defaultValue)), + null == o.checked && + null != o.defaultChecked && + (s.defaultChecked = !!o.defaultChecked); + } + function db(s, o, i) { + if (o.hasOwnProperty('value') || o.hasOwnProperty('defaultValue')) { + var u = o.type; + if (!(('submit' !== u && 'reset' !== u) || (void 0 !== o.value && null !== o.value))) + return; + (o = '' + s._wrapperState.initialValue), + i || o === s.value || (s.value = o), + (s.defaultValue = o); + } + '' !== (i = s.name) && (s.name = ''), + (s.defaultChecked = !!s._wrapperState.initialChecked), + '' !== i && (s.name = i); + } + function cb(s, o, i) { + ('number' === o && Xa(s.ownerDocument) === s) || + (null == i + ? (s.defaultValue = '' + s._wrapperState.initialValue) + : s.defaultValue !== '' + i && (s.defaultValue = '' + i)); + } + var Te = Array.isArray; + function fb(s, o, i, u) { + if (((s = s.options), o)) { + o = {}; + for (var _ = 0; _ < i.length; _++) o['$' + i[_]] = !0; + for (i = 0; i < s.length; i++) + (_ = o.hasOwnProperty('$' + s[i].value)), + s[i].selected !== _ && (s[i].selected = _), + _ && u && (s[i].defaultSelected = !0); + } else { + for (i = '' + Sa(i), o = null, _ = 0; _ < s.length; _++) { + if (s[_].value === i) + return (s[_].selected = !0), void (u && (s[_].defaultSelected = !0)); + null !== o || s[_].disabled || (o = s[_]); + } + null !== o && (o.selected = !0); + } + } + function gb(s, o) { + if (null != o.dangerouslySetInnerHTML) throw Error(p(91)); + return xe({}, o, { + value: void 0, + defaultValue: void 0, + children: '' + s._wrapperState.initialValue + }); + } + function hb(s, o) { + var i = o.value; + if (null == i) { + if (((i = o.children), (o = o.defaultValue), null != i)) { + if (null != o) throw Error(p(92)); + if (Te(i)) { + if (1 < i.length) throw Error(p(93)); + i = i[0]; + } + o = i; + } + null == o && (o = ''), (i = o); + } + s._wrapperState = { initialValue: Sa(i) }; + } + function ib(s, o) { + var i = Sa(o.value), + u = Sa(o.defaultValue); + null != i && + ((i = '' + i) !== s.value && (s.value = i), + null == o.defaultValue && s.defaultValue !== i && (s.defaultValue = i)), + null != u && (s.defaultValue = '' + u); + } + function jb(s) { + var o = s.textContent; + o === s._wrapperState.initialValue && '' !== o && null !== o && (s.value = o); + } + function kb(s) { + switch (s) { + case 'svg': + return 'http://www.w3.org/2000/svg'; + case 'math': + return 'http://www.w3.org/1998/Math/MathML'; + default: + return 'http://www.w3.org/1999/xhtml'; + } + } + function lb(s, o) { + return null == s || 'http://www.w3.org/1999/xhtml' === s + ? kb(o) + : 'http://www.w3.org/2000/svg' === s && 'foreignObject' === o + ? 'http://www.w3.org/1999/xhtml' + : s; + } + var Re, + qe, + $e = + ((qe = function (s, o) { + if ('http://www.w3.org/2000/svg' !== s.namespaceURI || 'innerHTML' in s) + s.innerHTML = o; + else { + for ( + (Re = Re || document.createElement('div')).innerHTML = + '' + o.valueOf().toString() + '', + o = Re.firstChild; + s.firstChild; + + ) + s.removeChild(s.firstChild); + for (; o.firstChild; ) s.appendChild(o.firstChild); + } + }), + 'undefined' != typeof MSApp && MSApp.execUnsafeLocalFunction + ? function (s, o, i, u) { + MSApp.execUnsafeLocalFunction(function () { + return qe(s, o); + }); + } + : qe); + function ob(s, o) { + if (o) { + var i = s.firstChild; + if (i && i === s.lastChild && 3 === i.nodeType) return void (i.nodeValue = o); + } + s.textContent = o; + } + var ze = { + animationIterationCount: !0, + aspectRatio: !0, + borderImageOutset: !0, + borderImageSlice: !0, + borderImageWidth: !0, + boxFlex: !0, + boxFlexGroup: !0, + boxOrdinalGroup: !0, + columnCount: !0, + columns: !0, + flex: !0, + flexGrow: !0, + flexPositive: !0, + flexShrink: !0, + flexNegative: !0, + flexOrder: !0, + gridArea: !0, + gridRow: !0, + gridRowEnd: !0, + gridRowSpan: !0, + gridRowStart: !0, + gridColumn: !0, + gridColumnEnd: !0, + gridColumnSpan: !0, + gridColumnStart: !0, + fontWeight: !0, + lineClamp: !0, + lineHeight: !0, + opacity: !0, + order: !0, + orphans: !0, + tabSize: !0, + widows: !0, + zIndex: !0, + zoom: !0, + fillOpacity: !0, + floodOpacity: !0, + stopOpacity: !0, + strokeDasharray: !0, + strokeDashoffset: !0, + strokeMiterlimit: !0, + strokeOpacity: !0, + strokeWidth: !0 + }, + We = ['Webkit', 'ms', 'Moz', 'O']; + function rb(s, o, i) { + return null == o || 'boolean' == typeof o || '' === o + ? '' + : i || 'number' != typeof o || 0 === o || (ze.hasOwnProperty(s) && ze[s]) + ? ('' + o).trim() + : o + 'px'; + } + function sb(s, o) { + for (var i in ((s = s.style), o)) + if (o.hasOwnProperty(i)) { + var u = 0 === i.indexOf('--'), + _ = rb(i, o[i], u); + 'float' === i && (i = 'cssFloat'), u ? s.setProperty(i, _) : (s[i] = _); + } + } + Object.keys(ze).forEach(function (s) { + We.forEach(function (o) { + (o = o + s.charAt(0).toUpperCase() + s.substring(1)), (ze[o] = ze[s]); + }); + }); + var He = xe( + { menuitem: !0 }, + { + area: !0, + base: !0, + br: !0, + col: !0, + embed: !0, + hr: !0, + img: !0, + input: !0, + keygen: !0, + link: !0, + meta: !0, + param: !0, + source: !0, + track: !0, + wbr: !0 + } + ); + function ub(s, o) { + if (o) { + if (He[s] && (null != o.children || null != o.dangerouslySetInnerHTML)) + throw Error(p(137, s)); + if (null != o.dangerouslySetInnerHTML) { + if (null != o.children) throw Error(p(60)); + if ( + 'object' != typeof o.dangerouslySetInnerHTML || + !('__html' in o.dangerouslySetInnerHTML) + ) + throw Error(p(61)); + } + if (null != o.style && 'object' != typeof o.style) throw Error(p(62)); + } + } + function vb(s, o) { + if (-1 === s.indexOf('-')) return 'string' == typeof o.is; + switch (s) { + case 'annotation-xml': + case 'color-profile': + case 'font-face': + case 'font-face-src': + case 'font-face-uri': + case 'font-face-format': + case 'font-face-name': + case 'missing-glyph': + return !1; + default: + return !0; + } + } + var Ye = null; + function xb(s) { + return ( + (s = s.target || s.srcElement || window).correspondingUseElement && + (s = s.correspondingUseElement), + 3 === s.nodeType ? s.parentNode : s + ); + } + var Xe = null, + Qe = null, + et = null; + function Bb(s) { + if ((s = Cb(s))) { + if ('function' != typeof Xe) throw Error(p(280)); + var o = s.stateNode; + o && ((o = Db(o)), Xe(s.stateNode, s.type, o)); + } + } + function Eb(s) { + Qe ? (et ? et.push(s) : (et = [s])) : (Qe = s); + } + function Fb() { + if (Qe) { + var s = Qe, + o = et; + if (((et = Qe = null), Bb(s), o)) for (s = 0; s < o.length; s++) Bb(o[s]); + } + } + function Gb(s, o) { + return s(o); + } + function Hb() {} + var tt = !1; + function Jb(s, o, i) { + if (tt) return s(o, i); + tt = !0; + try { + return Gb(s, o, i); + } finally { + (tt = !1), (null !== Qe || null !== et) && (Hb(), Fb()); + } + } + function Kb(s, o) { + var i = s.stateNode; + if (null === i) return null; + var u = Db(i); + if (null === u) return null; + i = u[o]; + e: switch (o) { + case 'onClick': + case 'onClickCapture': + case 'onDoubleClick': + case 'onDoubleClickCapture': + case 'onMouseDown': + case 'onMouseDownCapture': + case 'onMouseMove': + case 'onMouseMoveCapture': + case 'onMouseUp': + case 'onMouseUpCapture': + case 'onMouseEnter': + (u = !u.disabled) || + (u = !( + 'button' === (s = s.type) || + 'input' === s || + 'select' === s || + 'textarea' === s + )), + (s = !u); + break e; + default: + s = !1; + } + if (s) return null; + if (i && 'function' != typeof i) throw Error(p(231, o, typeof i)); + return i; + } + var rt = !1; + if (C) + try { + var nt = {}; + Object.defineProperty(nt, 'passive', { + get: function () { + rt = !0; + } + }), + window.addEventListener('test', nt, nt), + window.removeEventListener('test', nt, nt); + } catch (qe) { + rt = !1; + } + function Nb(s, o, i, u, _, w, x, C, j) { + var L = Array.prototype.slice.call(arguments, 3); + try { + o.apply(i, L); + } catch (s) { + this.onError(s); + } + } + var st = !1, + ot = null, + it = !1, + at = null, + lt = { + onError: function (s) { + (st = !0), (ot = s); + } + }; + function Tb(s, o, i, u, _, w, x, C, j) { + (st = !1), (ot = null), Nb.apply(lt, arguments); + } + function Vb(s) { + var o = s, + i = s; + if (s.alternate) for (; o.return; ) o = o.return; + else { + s = o; + do { + !!(4098 & (o = s).flags) && (i = o.return), (s = o.return); + } while (s); + } + return 3 === o.tag ? i : null; + } + function Wb(s) { + if (13 === s.tag) { + var o = s.memoizedState; + if ((null === o && null !== (s = s.alternate) && (o = s.memoizedState), null !== o)) + return o.dehydrated; + } + return null; + } + function Xb(s) { + if (Vb(s) !== s) throw Error(p(188)); + } + function Zb(s) { + return null !== + (s = (function Yb(s) { + var o = s.alternate; + if (!o) { + if (null === (o = Vb(s))) throw Error(p(188)); + return o !== s ? null : s; + } + for (var i = s, u = o; ; ) { + var _ = i.return; + if (null === _) break; + var w = _.alternate; + if (null === w) { + if (null !== (u = _.return)) { + i = u; + continue; + } + break; + } + if (_.child === w.child) { + for (w = _.child; w; ) { + if (w === i) return Xb(_), s; + if (w === u) return Xb(_), o; + w = w.sibling; + } + throw Error(p(188)); + } + if (i.return !== u.return) (i = _), (u = w); + else { + for (var x = !1, C = _.child; C; ) { + if (C === i) { + (x = !0), (i = _), (u = w); + break; + } + if (C === u) { + (x = !0), (u = _), (i = w); + break; + } + C = C.sibling; + } + if (!x) { + for (C = w.child; C; ) { + if (C === i) { + (x = !0), (i = w), (u = _); + break; + } + if (C === u) { + (x = !0), (u = w), (i = _); + break; + } + C = C.sibling; + } + if (!x) throw Error(p(189)); + } + } + if (i.alternate !== u) throw Error(p(190)); + } + if (3 !== i.tag) throw Error(p(188)); + return i.stateNode.current === i ? s : o; + })(s)) + ? $b(s) + : null; + } + function $b(s) { + if (5 === s.tag || 6 === s.tag) return s; + for (s = s.child; null !== s; ) { + var o = $b(s); + if (null !== o) return o; + s = s.sibling; + } + return null; + } + var ct = _.unstable_scheduleCallback, + ut = _.unstable_cancelCallback, + pt = _.unstable_shouldYield, + ht = _.unstable_requestPaint, + dt = _.unstable_now, + mt = _.unstable_getCurrentPriorityLevel, + gt = _.unstable_ImmediatePriority, + yt = _.unstable_UserBlockingPriority, + vt = _.unstable_NormalPriority, + bt = _.unstable_LowPriority, + _t = _.unstable_IdlePriority, + Et = null, + wt = null; + var St = Math.clz32 + ? Math.clz32 + : function nc(s) { + return (s >>>= 0), 0 === s ? 32 : (31 - ((xt(s) / kt) | 0)) | 0; + }, + xt = Math.log, + kt = Math.LN2; + var Ct = 64, + Ot = 4194304; + function tc(s) { + switch (s & -s) { + case 1: + return 1; + case 2: + return 2; + case 4: + return 4; + case 8: + return 8; + case 16: + return 16; + case 32: + return 32; + case 64: + case 128: + case 256: + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + return 4194240 & s; + case 4194304: + case 8388608: + case 16777216: + case 33554432: + case 67108864: + return 130023424 & s; + case 134217728: + return 134217728; + case 268435456: + return 268435456; + case 536870912: + return 536870912; + case 1073741824: + return 1073741824; + default: + return s; + } + } + function uc(s, o) { + var i = s.pendingLanes; + if (0 === i) return 0; + var u = 0, + _ = s.suspendedLanes, + w = s.pingedLanes, + x = 268435455 & i; + if (0 !== x) { + var C = x & ~_; + 0 !== C ? (u = tc(C)) : 0 !== (w &= x) && (u = tc(w)); + } else 0 !== (x = i & ~_) ? (u = tc(x)) : 0 !== w && (u = tc(w)); + if (0 === u) return 0; + if ( + 0 !== o && + o !== u && + !(o & _) && + ((_ = u & -u) >= (w = o & -o) || (16 === _ && 4194240 & w)) + ) + return o; + if ((4 & u && (u |= 16 & i), 0 !== (o = s.entangledLanes))) + for (s = s.entanglements, o &= u; 0 < o; ) + (_ = 1 << (i = 31 - St(o))), (u |= s[i]), (o &= ~_); + return u; + } + function vc(s, o) { + switch (s) { + case 1: + case 2: + case 4: + return o + 250; + case 8: + case 16: + case 32: + case 64: + case 128: + case 256: + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + return o + 5e3; + default: + return -1; + } + } + function xc(s) { + return 0 !== (s = -1073741825 & s.pendingLanes) ? s : 1073741824 & s ? 1073741824 : 0; + } + function yc() { + var s = Ct; + return !(4194240 & (Ct <<= 1)) && (Ct = 64), s; + } + function zc(s) { + for (var o = [], i = 0; 31 > i; i++) o.push(s); + return o; + } + function Ac(s, o, i) { + (s.pendingLanes |= o), + 536870912 !== o && ((s.suspendedLanes = 0), (s.pingedLanes = 0)), + ((s = s.eventTimes)[(o = 31 - St(o))] = i); + } + function Cc(s, o) { + var i = (s.entangledLanes |= o); + for (s = s.entanglements; i; ) { + var u = 31 - St(i), + _ = 1 << u; + (_ & o) | (s[u] & o) && (s[u] |= o), (i &= ~_); + } + } + var At = 0; + function Dc(s) { + return 1 < (s &= -s) ? (4 < s ? (268435455 & s ? 16 : 536870912) : 4) : 1; + } + var jt, + It, + Pt, + Mt, + Tt, + Nt = !1, + Rt = [], + Dt = null, + Lt = null, + Bt = null, + Ft = new Map(), + qt = new Map(), + $t = [], + Vt = + 'mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit'.split( + ' ' + ); + function Sc(s, o) { + switch (s) { + case 'focusin': + case 'focusout': + Dt = null; + break; + case 'dragenter': + case 'dragleave': + Lt = null; + break; + case 'mouseover': + case 'mouseout': + Bt = null; + break; + case 'pointerover': + case 'pointerout': + Ft.delete(o.pointerId); + break; + case 'gotpointercapture': + case 'lostpointercapture': + qt.delete(o.pointerId); + } + } + function Tc(s, o, i, u, _, w) { + return null === s || s.nativeEvent !== w + ? ((s = { + blockedOn: o, + domEventName: i, + eventSystemFlags: u, + nativeEvent: w, + targetContainers: [_] + }), + null !== o && null !== (o = Cb(o)) && It(o), + s) + : ((s.eventSystemFlags |= u), + (o = s.targetContainers), + null !== _ && -1 === o.indexOf(_) && o.push(_), + s); + } + function Vc(s) { + var o = Wc(s.target); + if (null !== o) { + var i = Vb(o); + if (null !== i) + if (13 === (o = i.tag)) { + if (null !== (o = Wb(i))) + return ( + (s.blockedOn = o), + void Tt(s.priority, function () { + Pt(i); + }) + ); + } else if (3 === o && i.stateNode.current.memoizedState.isDehydrated) + return void (s.blockedOn = 3 === i.tag ? i.stateNode.containerInfo : null); + } + s.blockedOn = null; + } + function Xc(s) { + if (null !== s.blockedOn) return !1; + for (var o = s.targetContainers; 0 < o.length; ) { + var i = Yc(s.domEventName, s.eventSystemFlags, o[0], s.nativeEvent); + if (null !== i) return null !== (o = Cb(i)) && It(o), (s.blockedOn = i), !1; + var u = new (i = s.nativeEvent).constructor(i.type, i); + (Ye = u), i.target.dispatchEvent(u), (Ye = null), o.shift(); + } + return !0; + } + function Zc(s, o, i) { + Xc(s) && i.delete(o); + } + function $c() { + (Nt = !1), + null !== Dt && Xc(Dt) && (Dt = null), + null !== Lt && Xc(Lt) && (Lt = null), + null !== Bt && Xc(Bt) && (Bt = null), + Ft.forEach(Zc), + qt.forEach(Zc); + } + function ad(s, o) { + s.blockedOn === o && + ((s.blockedOn = null), + Nt || ((Nt = !0), _.unstable_scheduleCallback(_.unstable_NormalPriority, $c))); + } + function bd(s) { + function b(o) { + return ad(o, s); + } + if (0 < Rt.length) { + ad(Rt[0], s); + for (var o = 1; o < Rt.length; o++) { + var i = Rt[o]; + i.blockedOn === s && (i.blockedOn = null); + } + } + for ( + null !== Dt && ad(Dt, s), + null !== Lt && ad(Lt, s), + null !== Bt && ad(Bt, s), + Ft.forEach(b), + qt.forEach(b), + o = 0; + o < $t.length; + o++ + ) + (i = $t[o]).blockedOn === s && (i.blockedOn = null); + for (; 0 < $t.length && null === (o = $t[0]).blockedOn; ) + Vc(o), null === o.blockedOn && $t.shift(); + } + var Ut = z.ReactCurrentBatchConfig, + zt = !0; + function ed(s, o, i, u) { + var _ = At, + w = Ut.transition; + Ut.transition = null; + try { + (At = 1), fd(s, o, i, u); + } finally { + (At = _), (Ut.transition = w); + } + } + function gd(s, o, i, u) { + var _ = At, + w = Ut.transition; + Ut.transition = null; + try { + (At = 4), fd(s, o, i, u); + } finally { + (At = _), (Ut.transition = w); + } + } + function fd(s, o, i, u) { + if (zt) { + var _ = Yc(s, o, i, u); + if (null === _) hd(s, o, u, Wt, i), Sc(s, u); + else if ( + (function Uc(s, o, i, u, _) { + switch (o) { + case 'focusin': + return (Dt = Tc(Dt, s, o, i, u, _)), !0; + case 'dragenter': + return (Lt = Tc(Lt, s, o, i, u, _)), !0; + case 'mouseover': + return (Bt = Tc(Bt, s, o, i, u, _)), !0; + case 'pointerover': + var w = _.pointerId; + return Ft.set(w, Tc(Ft.get(w) || null, s, o, i, u, _)), !0; + case 'gotpointercapture': + return (w = _.pointerId), qt.set(w, Tc(qt.get(w) || null, s, o, i, u, _)), !0; + } + return !1; + })(_, s, o, i, u) + ) + u.stopPropagation(); + else if ((Sc(s, u), 4 & o && -1 < Vt.indexOf(s))) { + for (; null !== _; ) { + var w = Cb(_); + if ( + (null !== w && jt(w), + null === (w = Yc(s, o, i, u)) && hd(s, o, u, Wt, i), + w === _) + ) + break; + _ = w; + } + null !== _ && u.stopPropagation(); + } else hd(s, o, u, null, i); + } + } + var Wt = null; + function Yc(s, o, i, u) { + if (((Wt = null), null !== (s = Wc((s = xb(u)))))) + if (null === (o = Vb(s))) s = null; + else if (13 === (i = o.tag)) { + if (null !== (s = Wb(o))) return s; + s = null; + } else if (3 === i) { + if (o.stateNode.current.memoizedState.isDehydrated) + return 3 === o.tag ? o.stateNode.containerInfo : null; + s = null; + } else o !== s && (s = null); + return (Wt = s), null; + } + function jd(s) { + switch (s) { + case 'cancel': + case 'click': + case 'close': + case 'contextmenu': + case 'copy': + case 'cut': + case 'auxclick': + case 'dblclick': + case 'dragend': + case 'dragstart': + case 'drop': + case 'focusin': + case 'focusout': + case 'input': + case 'invalid': + case 'keydown': + case 'keypress': + case 'keyup': + case 'mousedown': + case 'mouseup': + case 'paste': + case 'pause': + case 'play': + case 'pointercancel': + case 'pointerdown': + case 'pointerup': + case 'ratechange': + case 'reset': + case 'resize': + case 'seeked': + case 'submit': + case 'touchcancel': + case 'touchend': + case 'touchstart': + case 'volumechange': + case 'change': + case 'selectionchange': + case 'textInput': + case 'compositionstart': + case 'compositionend': + case 'compositionupdate': + case 'beforeblur': + case 'afterblur': + case 'beforeinput': + case 'blur': + case 'fullscreenchange': + case 'focus': + case 'hashchange': + case 'popstate': + case 'select': + case 'selectstart': + return 1; + case 'drag': + case 'dragenter': + case 'dragexit': + case 'dragleave': + case 'dragover': + case 'mousemove': + case 'mouseout': + case 'mouseover': + case 'pointermove': + case 'pointerout': + case 'pointerover': + case 'scroll': + case 'toggle': + case 'touchmove': + case 'wheel': + case 'mouseenter': + case 'mouseleave': + case 'pointerenter': + case 'pointerleave': + return 4; + case 'message': + switch (mt()) { + case gt: + return 1; + case yt: + return 4; + case vt: + case bt: + return 16; + case _t: + return 536870912; + default: + return 16; + } + default: + return 16; + } + } + var Kt = null, + Ht = null, + Jt = null; + function nd() { + if (Jt) return Jt; + var s, + o, + i = Ht, + u = i.length, + _ = 'value' in Kt ? Kt.value : Kt.textContent, + w = _.length; + for (s = 0; s < u && i[s] === _[s]; s++); + var x = u - s; + for (o = 1; o <= x && i[u - o] === _[w - o]; o++); + return (Jt = _.slice(s, 1 < o ? 1 - o : void 0)); + } + function od(s) { + var o = s.keyCode; + return ( + 'charCode' in s ? 0 === (s = s.charCode) && 13 === o && (s = 13) : (s = o), + 10 === s && (s = 13), + 32 <= s || 13 === s ? s : 0 + ); + } + function pd() { + return !0; + } + function qd() { + return !1; + } + function rd(s) { + function b(o, i, u, _, w) { + for (var x in ((this._reactName = o), + (this._targetInst = u), + (this.type = i), + (this.nativeEvent = _), + (this.target = w), + (this.currentTarget = null), + s)) + s.hasOwnProperty(x) && ((o = s[x]), (this[x] = o ? o(_) : _[x])); + return ( + (this.isDefaultPrevented = ( + null != _.defaultPrevented ? _.defaultPrevented : !1 === _.returnValue + ) + ? pd + : qd), + (this.isPropagationStopped = qd), + this + ); + } + return ( + xe(b.prototype, { + preventDefault: function () { + this.defaultPrevented = !0; + var s = this.nativeEvent; + s && + (s.preventDefault + ? s.preventDefault() + : 'unknown' != typeof s.returnValue && (s.returnValue = !1), + (this.isDefaultPrevented = pd)); + }, + stopPropagation: function () { + var s = this.nativeEvent; + s && + (s.stopPropagation + ? s.stopPropagation() + : 'unknown' != typeof s.cancelBubble && (s.cancelBubble = !0), + (this.isPropagationStopped = pd)); + }, + persist: function () {}, + isPersistent: pd + }), + b + ); + } + var Gt, + Yt, + Xt, + Zt = { + eventPhase: 0, + bubbles: 0, + cancelable: 0, + timeStamp: function (s) { + return s.timeStamp || Date.now(); + }, + defaultPrevented: 0, + isTrusted: 0 + }, + Qt = rd(Zt), + er = xe({}, Zt, { view: 0, detail: 0 }), + tr = rd(er), + rr = xe({}, er, { + screenX: 0, + screenY: 0, + clientX: 0, + clientY: 0, + pageX: 0, + pageY: 0, + ctrlKey: 0, + shiftKey: 0, + altKey: 0, + metaKey: 0, + getModifierState: zd, + button: 0, + buttons: 0, + relatedTarget: function (s) { + return void 0 === s.relatedTarget + ? s.fromElement === s.srcElement + ? s.toElement + : s.fromElement + : s.relatedTarget; + }, + movementX: function (s) { + return 'movementX' in s + ? s.movementX + : (s !== Xt && + (Xt && 'mousemove' === s.type + ? ((Gt = s.screenX - Xt.screenX), (Yt = s.screenY - Xt.screenY)) + : (Yt = Gt = 0), + (Xt = s)), + Gt); + }, + movementY: function (s) { + return 'movementY' in s ? s.movementY : Yt; + } + }), + nr = rd(rr), + sr = rd(xe({}, rr, { dataTransfer: 0 })), + ir = rd(xe({}, er, { relatedTarget: 0 })), + ar = rd(xe({}, Zt, { animationName: 0, elapsedTime: 0, pseudoElement: 0 })), + lr = xe({}, Zt, { + clipboardData: function (s) { + return 'clipboardData' in s ? s.clipboardData : window.clipboardData; + } + }), + cr = rd(lr), + ur = rd(xe({}, Zt, { data: 0 })), + pr = { + Esc: 'Escape', + Spacebar: ' ', + Left: 'ArrowLeft', + Up: 'ArrowUp', + Right: 'ArrowRight', + Down: 'ArrowDown', + Del: 'Delete', + Win: 'OS', + Menu: 'ContextMenu', + Apps: 'ContextMenu', + Scroll: 'ScrollLock', + MozPrintableKey: 'Unidentified' + }, + dr = { + 8: 'Backspace', + 9: 'Tab', + 12: 'Clear', + 13: 'Enter', + 16: 'Shift', + 17: 'Control', + 18: 'Alt', + 19: 'Pause', + 20: 'CapsLock', + 27: 'Escape', + 32: ' ', + 33: 'PageUp', + 34: 'PageDown', + 35: 'End', + 36: 'Home', + 37: 'ArrowLeft', + 38: 'ArrowUp', + 39: 'ArrowRight', + 40: 'ArrowDown', + 45: 'Insert', + 46: 'Delete', + 112: 'F1', + 113: 'F2', + 114: 'F3', + 115: 'F4', + 116: 'F5', + 117: 'F6', + 118: 'F7', + 119: 'F8', + 120: 'F9', + 121: 'F10', + 122: 'F11', + 123: 'F12', + 144: 'NumLock', + 145: 'ScrollLock', + 224: 'Meta' + }, + fr = { Alt: 'altKey', Control: 'ctrlKey', Meta: 'metaKey', Shift: 'shiftKey' }; + function Pd(s) { + var o = this.nativeEvent; + return o.getModifierState ? o.getModifierState(s) : !!(s = fr[s]) && !!o[s]; + } + function zd() { + return Pd; + } + var mr = xe({}, er, { + key: function (s) { + if (s.key) { + var o = pr[s.key] || s.key; + if ('Unidentified' !== o) return o; + } + return 'keypress' === s.type + ? 13 === (s = od(s)) + ? 'Enter' + : String.fromCharCode(s) + : 'keydown' === s.type || 'keyup' === s.type + ? dr[s.keyCode] || 'Unidentified' + : ''; + }, + code: 0, + location: 0, + ctrlKey: 0, + shiftKey: 0, + altKey: 0, + metaKey: 0, + repeat: 0, + locale: 0, + getModifierState: zd, + charCode: function (s) { + return 'keypress' === s.type ? od(s) : 0; + }, + keyCode: function (s) { + return 'keydown' === s.type || 'keyup' === s.type ? s.keyCode : 0; + }, + which: function (s) { + return 'keypress' === s.type + ? od(s) + : 'keydown' === s.type || 'keyup' === s.type + ? s.keyCode + : 0; + } + }), + gr = rd(mr), + yr = rd( + xe({}, rr, { + pointerId: 0, + width: 0, + height: 0, + pressure: 0, + tangentialPressure: 0, + tiltX: 0, + tiltY: 0, + twist: 0, + pointerType: 0, + isPrimary: 0 + }) + ), + vr = rd( + xe({}, er, { + touches: 0, + targetTouches: 0, + changedTouches: 0, + altKey: 0, + metaKey: 0, + ctrlKey: 0, + shiftKey: 0, + getModifierState: zd + }) + ), + br = rd(xe({}, Zt, { propertyName: 0, elapsedTime: 0, pseudoElement: 0 })), + _r = xe({}, rr, { + deltaX: function (s) { + return 'deltaX' in s ? s.deltaX : 'wheelDeltaX' in s ? -s.wheelDeltaX : 0; + }, + deltaY: function (s) { + return 'deltaY' in s + ? s.deltaY + : 'wheelDeltaY' in s + ? -s.wheelDeltaY + : 'wheelDelta' in s + ? -s.wheelDelta + : 0; + }, + deltaZ: 0, + deltaMode: 0 + }), + Er = rd(_r), + wr = [9, 13, 27, 32], + Sr = C && 'CompositionEvent' in window, + xr = null; + C && 'documentMode' in document && (xr = document.documentMode); + var kr = C && 'TextEvent' in window && !xr, + Cr = C && (!Sr || (xr && 8 < xr && 11 >= xr)), + Or = String.fromCharCode(32), + Ar = !1; + function ge(s, o) { + switch (s) { + case 'keyup': + return -1 !== wr.indexOf(o.keyCode); + case 'keydown': + return 229 !== o.keyCode; + case 'keypress': + case 'mousedown': + case 'focusout': + return !0; + default: + return !1; + } + } + function he(s) { + return 'object' == typeof (s = s.detail) && 'data' in s ? s.data : null; + } + var jr = !1; + var Ir = { + color: !0, + date: !0, + datetime: !0, + 'datetime-local': !0, + email: !0, + month: !0, + number: !0, + password: !0, + range: !0, + search: !0, + tel: !0, + text: !0, + time: !0, + url: !0, + week: !0 + }; + function me(s) { + var o = s && s.nodeName && s.nodeName.toLowerCase(); + return 'input' === o ? !!Ir[s.type] : 'textarea' === o; + } + function ne(s, o, i, u) { + Eb(u), + 0 < (o = oe(o, 'onChange')).length && + ((i = new Qt('onChange', 'change', null, i, u)), + s.push({ event: i, listeners: o })); + } + var Pr = null, + Mr = null; + function re(s) { + se(s, 0); + } + function te(s) { + if (Wa(ue(s))) return s; + } + function ve(s, o) { + if ('change' === s) return o; + } + var Tr = !1; + if (C) { + var Nr; + if (C) { + var Rr = 'oninput' in document; + if (!Rr) { + var Dr = document.createElement('div'); + Dr.setAttribute('oninput', 'return;'), (Rr = 'function' == typeof Dr.oninput); + } + Nr = Rr; + } else Nr = !1; + Tr = Nr && (!document.documentMode || 9 < document.documentMode); + } + function Ae() { + Pr && (Pr.detachEvent('onpropertychange', Be), (Mr = Pr = null)); + } + function Be(s) { + if ('value' === s.propertyName && te(Mr)) { + var o = []; + ne(o, Mr, s, xb(s)), Jb(re, o); + } + } + function Ce(s, o, i) { + 'focusin' === s + ? (Ae(), (Mr = i), (Pr = o).attachEvent('onpropertychange', Be)) + : 'focusout' === s && Ae(); + } + function De(s) { + if ('selectionchange' === s || 'keyup' === s || 'keydown' === s) return te(Mr); + } + function Ee(s, o) { + if ('click' === s) return te(o); + } + function Fe(s, o) { + if ('input' === s || 'change' === s) return te(o); + } + var Lr = + 'function' == typeof Object.is + ? Object.is + : function Ge(s, o) { + return (s === o && (0 !== s || 1 / s == 1 / o)) || (s != s && o != o); + }; + function Ie(s, o) { + if (Lr(s, o)) return !0; + if ('object' != typeof s || null === s || 'object' != typeof o || null === o) return !1; + var i = Object.keys(s), + u = Object.keys(o); + if (i.length !== u.length) return !1; + for (u = 0; u < i.length; u++) { + var _ = i[u]; + if (!j.call(o, _) || !Lr(s[_], o[_])) return !1; + } + return !0; + } + function Je(s) { + for (; s && s.firstChild; ) s = s.firstChild; + return s; + } + function Ke(s, o) { + var i, + u = Je(s); + for (s = 0; u; ) { + if (3 === u.nodeType) { + if (((i = s + u.textContent.length), s <= o && i >= o)) + return { node: u, offset: o - s }; + s = i; + } + e: { + for (; u; ) { + if (u.nextSibling) { + u = u.nextSibling; + break e; + } + u = u.parentNode; + } + u = void 0; + } + u = Je(u); + } + } + function Le(s, o) { + return ( + !(!s || !o) && + (s === o || + ((!s || 3 !== s.nodeType) && + (o && 3 === o.nodeType + ? Le(s, o.parentNode) + : 'contains' in s + ? s.contains(o) + : !!s.compareDocumentPosition && !!(16 & s.compareDocumentPosition(o))))) + ); + } + function Me() { + for (var s = window, o = Xa(); o instanceof s.HTMLIFrameElement; ) { + try { + var i = 'string' == typeof o.contentWindow.location.href; + } catch (s) { + i = !1; + } + if (!i) break; + o = Xa((s = o.contentWindow).document); + } + return o; + } + function Ne(s) { + var o = s && s.nodeName && s.nodeName.toLowerCase(); + return ( + o && + (('input' === o && + ('text' === s.type || + 'search' === s.type || + 'tel' === s.type || + 'url' === s.type || + 'password' === s.type)) || + 'textarea' === o || + 'true' === s.contentEditable) + ); + } + function Oe(s) { + var o = Me(), + i = s.focusedElem, + u = s.selectionRange; + if (o !== i && i && i.ownerDocument && Le(i.ownerDocument.documentElement, i)) { + if (null !== u && Ne(i)) + if (((o = u.start), void 0 === (s = u.end) && (s = o), 'selectionStart' in i)) + (i.selectionStart = o), (i.selectionEnd = Math.min(s, i.value.length)); + else if ( + (s = ((o = i.ownerDocument || document) && o.defaultView) || window).getSelection + ) { + s = s.getSelection(); + var _ = i.textContent.length, + w = Math.min(u.start, _); + (u = void 0 === u.end ? w : Math.min(u.end, _)), + !s.extend && w > u && ((_ = u), (u = w), (w = _)), + (_ = Ke(i, w)); + var x = Ke(i, u); + _ && + x && + (1 !== s.rangeCount || + s.anchorNode !== _.node || + s.anchorOffset !== _.offset || + s.focusNode !== x.node || + s.focusOffset !== x.offset) && + ((o = o.createRange()).setStart(_.node, _.offset), + s.removeAllRanges(), + w > u + ? (s.addRange(o), s.extend(x.node, x.offset)) + : (o.setEnd(x.node, x.offset), s.addRange(o))); + } + for (o = [], s = i; (s = s.parentNode); ) + 1 === s.nodeType && o.push({ element: s, left: s.scrollLeft, top: s.scrollTop }); + for ('function' == typeof i.focus && i.focus(), i = 0; i < o.length; i++) + ((s = o[i]).element.scrollLeft = s.left), (s.element.scrollTop = s.top); + } + } + var Br = C && 'documentMode' in document && 11 >= document.documentMode, + Fr = null, + qr = null, + $r = null, + Vr = !1; + function Ue(s, o, i) { + var u = i.window === i ? i.document : 9 === i.nodeType ? i : i.ownerDocument; + Vr || + null == Fr || + Fr !== Xa(u) || + ('selectionStart' in (u = Fr) && Ne(u) + ? (u = { start: u.selectionStart, end: u.selectionEnd }) + : (u = { + anchorNode: (u = ( + (u.ownerDocument && u.ownerDocument.defaultView) || + window + ).getSelection()).anchorNode, + anchorOffset: u.anchorOffset, + focusNode: u.focusNode, + focusOffset: u.focusOffset + }), + ($r && Ie($r, u)) || + (($r = u), + 0 < (u = oe(qr, 'onSelect')).length && + ((o = new Qt('onSelect', 'select', null, o, i)), + s.push({ event: o, listeners: u }), + (o.target = Fr)))); + } + function Ve(s, o) { + var i = {}; + return ( + (i[s.toLowerCase()] = o.toLowerCase()), + (i['Webkit' + s] = 'webkit' + o), + (i['Moz' + s] = 'moz' + o), + i + ); + } + var Ur = { + animationend: Ve('Animation', 'AnimationEnd'), + animationiteration: Ve('Animation', 'AnimationIteration'), + animationstart: Ve('Animation', 'AnimationStart'), + transitionend: Ve('Transition', 'TransitionEnd') + }, + zr = {}, + Wr = {}; + function Ze(s) { + if (zr[s]) return zr[s]; + if (!Ur[s]) return s; + var o, + i = Ur[s]; + for (o in i) if (i.hasOwnProperty(o) && o in Wr) return (zr[s] = i[o]); + return s; + } + C && + ((Wr = document.createElement('div').style), + 'AnimationEvent' in window || + (delete Ur.animationend.animation, + delete Ur.animationiteration.animation, + delete Ur.animationstart.animation), + 'TransitionEvent' in window || delete Ur.transitionend.transition); + var Kr = Ze('animationend'), + Hr = Ze('animationiteration'), + Jr = Ze('animationstart'), + Gr = Ze('transitionend'), + Yr = new Map(), + Xr = + 'abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel'.split( + ' ' + ); + function ff(s, o) { + Yr.set(s, o), fa(o, [s]); + } + for (var Zr = 0; Zr < Xr.length; Zr++) { + var Qr = Xr[Zr]; + ff(Qr.toLowerCase(), 'on' + (Qr[0].toUpperCase() + Qr.slice(1))); + } + ff(Kr, 'onAnimationEnd'), + ff(Hr, 'onAnimationIteration'), + ff(Jr, 'onAnimationStart'), + ff('dblclick', 'onDoubleClick'), + ff('focusin', 'onFocus'), + ff('focusout', 'onBlur'), + ff(Gr, 'onTransitionEnd'), + ha('onMouseEnter', ['mouseout', 'mouseover']), + ha('onMouseLeave', ['mouseout', 'mouseover']), + ha('onPointerEnter', ['pointerout', 'pointerover']), + ha('onPointerLeave', ['pointerout', 'pointerover']), + fa( + 'onChange', + 'change click focusin focusout input keydown keyup selectionchange'.split(' ') + ), + fa( + 'onSelect', + 'focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange'.split( + ' ' + ) + ), + fa('onBeforeInput', ['compositionend', 'keypress', 'textInput', 'paste']), + fa( + 'onCompositionEnd', + 'compositionend focusout keydown keypress keyup mousedown'.split(' ') + ), + fa( + 'onCompositionStart', + 'compositionstart focusout keydown keypress keyup mousedown'.split(' ') + ), + fa( + 'onCompositionUpdate', + 'compositionupdate focusout keydown keypress keyup mousedown'.split(' ') + ); + var en = + 'abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting'.split( + ' ' + ), + tn = new Set('cancel close invalid load scroll toggle'.split(' ').concat(en)); + function nf(s, o, i) { + var u = s.type || 'unknown-event'; + (s.currentTarget = i), + (function Ub(s, o, i, u, _, w, x, C, j) { + if ((Tb.apply(this, arguments), st)) { + if (!st) throw Error(p(198)); + var L = ot; + (st = !1), (ot = null), it || ((it = !0), (at = L)); + } + })(u, o, void 0, s), + (s.currentTarget = null); + } + function se(s, o) { + o = !!(4 & o); + for (var i = 0; i < s.length; i++) { + var u = s[i], + _ = u.event; + u = u.listeners; + e: { + var w = void 0; + if (o) + for (var x = u.length - 1; 0 <= x; x--) { + var C = u[x], + j = C.instance, + L = C.currentTarget; + if (((C = C.listener), j !== w && _.isPropagationStopped())) break e; + nf(_, C, L), (w = j); + } + else + for (x = 0; x < u.length; x++) { + if ( + ((j = (C = u[x]).instance), + (L = C.currentTarget), + (C = C.listener), + j !== w && _.isPropagationStopped()) + ) + break e; + nf(_, C, L), (w = j); + } + } + } + if (it) throw ((s = at), (it = !1), (at = null), s); + } + function D(s, o) { + var i = o[gn]; + void 0 === i && (i = o[gn] = new Set()); + var u = s + '__bubble'; + i.has(u) || (pf(o, s, 2, !1), i.add(u)); + } + function qf(s, o, i) { + var u = 0; + o && (u |= 4), pf(i, s, u, o); + } + var rn = '_reactListening' + Math.random().toString(36).slice(2); + function sf(s) { + if (!s[rn]) { + (s[rn] = !0), + w.forEach(function (o) { + 'selectionchange' !== o && (tn.has(o) || qf(o, !1, s), qf(o, !0, s)); + }); + var o = 9 === s.nodeType ? s : s.ownerDocument; + null === o || o[rn] || ((o[rn] = !0), qf('selectionchange', !1, o)); + } + } + function pf(s, o, i, u) { + switch (jd(o)) { + case 1: + var _ = ed; + break; + case 4: + _ = gd; + break; + default: + _ = fd; + } + (i = _.bind(null, o, i, s)), + (_ = void 0), + !rt || ('touchstart' !== o && 'touchmove' !== o && 'wheel' !== o) || (_ = !0), + u + ? void 0 !== _ + ? s.addEventListener(o, i, { capture: !0, passive: _ }) + : s.addEventListener(o, i, !0) + : void 0 !== _ + ? s.addEventListener(o, i, { passive: _ }) + : s.addEventListener(o, i, !1); + } + function hd(s, o, i, u, _) { + var w = u; + if (!(1 & o || 2 & o || null === u)) + e: for (;;) { + if (null === u) return; + var x = u.tag; + if (3 === x || 4 === x) { + var C = u.stateNode.containerInfo; + if (C === _ || (8 === C.nodeType && C.parentNode === _)) break; + if (4 === x) + for (x = u.return; null !== x; ) { + var j = x.tag; + if ( + (3 === j || 4 === j) && + ((j = x.stateNode.containerInfo) === _ || + (8 === j.nodeType && j.parentNode === _)) + ) + return; + x = x.return; + } + for (; null !== C; ) { + if (null === (x = Wc(C))) return; + if (5 === (j = x.tag) || 6 === j) { + u = w = x; + continue e; + } + C = C.parentNode; + } + } + u = u.return; + } + Jb(function () { + var u = w, + _ = xb(i), + x = []; + e: { + var C = Yr.get(s); + if (void 0 !== C) { + var j = Qt, + L = s; + switch (s) { + case 'keypress': + if (0 === od(i)) break e; + case 'keydown': + case 'keyup': + j = gr; + break; + case 'focusin': + (L = 'focus'), (j = ir); + break; + case 'focusout': + (L = 'blur'), (j = ir); + break; + case 'beforeblur': + case 'afterblur': + j = ir; + break; + case 'click': + if (2 === i.button) break e; + case 'auxclick': + case 'dblclick': + case 'mousedown': + case 'mousemove': + case 'mouseup': + case 'mouseout': + case 'mouseover': + case 'contextmenu': + j = nr; + break; + case 'drag': + case 'dragend': + case 'dragenter': + case 'dragexit': + case 'dragleave': + case 'dragover': + case 'dragstart': + case 'drop': + j = sr; + break; + case 'touchcancel': + case 'touchend': + case 'touchmove': + case 'touchstart': + j = vr; + break; + case Kr: + case Hr: + case Jr: + j = ar; + break; + case Gr: + j = br; + break; + case 'scroll': + j = tr; + break; + case 'wheel': + j = Er; + break; + case 'copy': + case 'cut': + case 'paste': + j = cr; + break; + case 'gotpointercapture': + case 'lostpointercapture': + case 'pointercancel': + case 'pointerdown': + case 'pointermove': + case 'pointerout': + case 'pointerover': + case 'pointerup': + j = yr; + } + var B = !!(4 & o), + $ = !B && 'scroll' === s, + V = B ? (null !== C ? C + 'Capture' : null) : C; + B = []; + for (var U, z = u; null !== z; ) { + var Y = (U = z).stateNode; + if ( + (5 === U.tag && + null !== Y && + ((U = Y), null !== V && null != (Y = Kb(z, V)) && B.push(tf(z, Y, U))), + $) + ) + break; + z = z.return; + } + 0 < B.length && + ((C = new j(C, L, null, i, _)), x.push({ event: C, listeners: B })); + } + } + if (!(7 & o)) { + if ( + ((j = 'mouseout' === s || 'pointerout' === s), + (!(C = 'mouseover' === s || 'pointerover' === s) || + i === Ye || + !(L = i.relatedTarget || i.fromElement) || + (!Wc(L) && !L[mn])) && + (j || C) && + ((C = + _.window === _ + ? _ + : (C = _.ownerDocument) + ? C.defaultView || C.parentWindow + : window), + j + ? ((j = u), + null !== (L = (L = i.relatedTarget || i.toElement) ? Wc(L) : null) && + (L !== ($ = Vb(L)) || (5 !== L.tag && 6 !== L.tag)) && + (L = null)) + : ((j = null), (L = u)), + j !== L)) + ) { + if ( + ((B = nr), + (Y = 'onMouseLeave'), + (V = 'onMouseEnter'), + (z = 'mouse'), + ('pointerout' !== s && 'pointerover' !== s) || + ((B = yr), (Y = 'onPointerLeave'), (V = 'onPointerEnter'), (z = 'pointer')), + ($ = null == j ? C : ue(j)), + (U = null == L ? C : ue(L)), + ((C = new B(Y, z + 'leave', j, i, _)).target = $), + (C.relatedTarget = U), + (Y = null), + Wc(_) === u && + (((B = new B(V, z + 'enter', L, i, _)).target = U), + (B.relatedTarget = $), + (Y = B)), + ($ = Y), + j && L) + ) + e: { + for (V = L, z = 0, U = B = j; U; U = vf(U)) z++; + for (U = 0, Y = V; Y; Y = vf(Y)) U++; + for (; 0 < z - U; ) (B = vf(B)), z--; + for (; 0 < U - z; ) (V = vf(V)), U--; + for (; z--; ) { + if (B === V || (null !== V && B === V.alternate)) break e; + (B = vf(B)), (V = vf(V)); + } + B = null; + } + else B = null; + null !== j && wf(x, C, j, B, !1), null !== L && null !== $ && wf(x, $, L, B, !0); + } + if ( + 'select' === + (j = (C = u ? ue(u) : window).nodeName && C.nodeName.toLowerCase()) || + ('input' === j && 'file' === C.type) + ) + var Z = ve; + else if (me(C)) + if (Tr) Z = Fe; + else { + Z = De; + var ee = Ce; + } + else + (j = C.nodeName) && + 'input' === j.toLowerCase() && + ('checkbox' === C.type || 'radio' === C.type) && + (Z = Ee); + switch ( + (Z && (Z = Z(s, u)) + ? ne(x, Z, i, _) + : (ee && ee(s, C, u), + 'focusout' === s && + (ee = C._wrapperState) && + ee.controlled && + 'number' === C.type && + cb(C, 'number', C.value)), + (ee = u ? ue(u) : window), + s) + ) { + case 'focusin': + (me(ee) || 'true' === ee.contentEditable) && ((Fr = ee), (qr = u), ($r = null)); + break; + case 'focusout': + $r = qr = Fr = null; + break; + case 'mousedown': + Vr = !0; + break; + case 'contextmenu': + case 'mouseup': + case 'dragend': + (Vr = !1), Ue(x, i, _); + break; + case 'selectionchange': + if (Br) break; + case 'keydown': + case 'keyup': + Ue(x, i, _); + } + var ie; + if (Sr) + e: { + switch (s) { + case 'compositionstart': + var ae = 'onCompositionStart'; + break e; + case 'compositionend': + ae = 'onCompositionEnd'; + break e; + case 'compositionupdate': + ae = 'onCompositionUpdate'; + break e; + } + ae = void 0; + } + else + jr + ? ge(s, i) && (ae = 'onCompositionEnd') + : 'keydown' === s && 229 === i.keyCode && (ae = 'onCompositionStart'); + ae && + (Cr && + 'ko' !== i.locale && + (jr || 'onCompositionStart' !== ae + ? 'onCompositionEnd' === ae && jr && (ie = nd()) + : ((Ht = 'value' in (Kt = _) ? Kt.value : Kt.textContent), (jr = !0))), + 0 < (ee = oe(u, ae)).length && + ((ae = new ur(ae, s, null, i, _)), + x.push({ event: ae, listeners: ee }), + ie ? (ae.data = ie) : null !== (ie = he(i)) && (ae.data = ie))), + (ie = kr + ? (function je(s, o) { + switch (s) { + case 'compositionend': + return he(o); + case 'keypress': + return 32 !== o.which ? null : ((Ar = !0), Or); + case 'textInput': + return (s = o.data) === Or && Ar ? null : s; + default: + return null; + } + })(s, i) + : (function ke(s, o) { + if (jr) + return 'compositionend' === s || (!Sr && ge(s, o)) + ? ((s = nd()), (Jt = Ht = Kt = null), (jr = !1), s) + : null; + switch (s) { + case 'paste': + default: + return null; + case 'keypress': + if (!(o.ctrlKey || o.altKey || o.metaKey) || (o.ctrlKey && o.altKey)) { + if (o.char && 1 < o.char.length) return o.char; + if (o.which) return String.fromCharCode(o.which); + } + return null; + case 'compositionend': + return Cr && 'ko' !== o.locale ? null : o.data; + } + })(s, i)) && + 0 < (u = oe(u, 'onBeforeInput')).length && + ((_ = new ur('onBeforeInput', 'beforeinput', null, i, _)), + x.push({ event: _, listeners: u }), + (_.data = ie)); + } + se(x, o); + }); + } + function tf(s, o, i) { + return { instance: s, listener: o, currentTarget: i }; + } + function oe(s, o) { + for (var i = o + 'Capture', u = []; null !== s; ) { + var _ = s, + w = _.stateNode; + 5 === _.tag && + null !== w && + ((_ = w), + null != (w = Kb(s, i)) && u.unshift(tf(s, w, _)), + null != (w = Kb(s, o)) && u.push(tf(s, w, _))), + (s = s.return); + } + return u; + } + function vf(s) { + if (null === s) return null; + do { + s = s.return; + } while (s && 5 !== s.tag); + return s || null; + } + function wf(s, o, i, u, _) { + for (var w = o._reactName, x = []; null !== i && i !== u; ) { + var C = i, + j = C.alternate, + L = C.stateNode; + if (null !== j && j === u) break; + 5 === C.tag && + null !== L && + ((C = L), + _ + ? null != (j = Kb(i, w)) && x.unshift(tf(i, j, C)) + : _ || (null != (j = Kb(i, w)) && x.push(tf(i, j, C)))), + (i = i.return); + } + 0 !== x.length && s.push({ event: o, listeners: x }); + } + var nn = /\r\n?/g, + sn = /\u0000|\uFFFD/g; + function zf(s) { + return ('string' == typeof s ? s : '' + s).replace(nn, '\n').replace(sn, ''); + } + function Af(s, o, i) { + if (((o = zf(o)), zf(s) !== o && i)) throw Error(p(425)); + } + function Bf() {} + var on = null, + an = null; + function Ef(s, o) { + return ( + 'textarea' === s || + 'noscript' === s || + 'string' == typeof o.children || + 'number' == typeof o.children || + ('object' == typeof o.dangerouslySetInnerHTML && + null !== o.dangerouslySetInnerHTML && + null != o.dangerouslySetInnerHTML.__html) + ); + } + var ln = 'function' == typeof setTimeout ? setTimeout : void 0, + cn = 'function' == typeof clearTimeout ? clearTimeout : void 0, + un = 'function' == typeof Promise ? Promise : void 0, + pn = + 'function' == typeof queueMicrotask + ? queueMicrotask + : void 0 !== un + ? function (s) { + return un.resolve(null).then(s).catch(If); + } + : ln; + function If(s) { + setTimeout(function () { + throw s; + }); + } + function Kf(s, o) { + var i = o, + u = 0; + do { + var _ = i.nextSibling; + if ((s.removeChild(i), _ && 8 === _.nodeType)) + if ('/$' === (i = _.data)) { + if (0 === u) return s.removeChild(_), void bd(o); + u--; + } else ('$' !== i && '$?' !== i && '$!' !== i) || u++; + i = _; + } while (i); + bd(o); + } + function Lf(s) { + for (; null != s; s = s.nextSibling) { + var o = s.nodeType; + if (1 === o || 3 === o) break; + if (8 === o) { + if ('$' === (o = s.data) || '$!' === o || '$?' === o) break; + if ('/$' === o) return null; + } + } + return s; + } + function Mf(s) { + s = s.previousSibling; + for (var o = 0; s; ) { + if (8 === s.nodeType) { + var i = s.data; + if ('$' === i || '$!' === i || '$?' === i) { + if (0 === o) return s; + o--; + } else '/$' === i && o++; + } + s = s.previousSibling; + } + return null; + } + var hn = Math.random().toString(36).slice(2), + dn = '__reactFiber$' + hn, + fn = '__reactProps$' + hn, + mn = '__reactContainer$' + hn, + gn = '__reactEvents$' + hn, + yn = '__reactListeners$' + hn, + vn = '__reactHandles$' + hn; + function Wc(s) { + var o = s[dn]; + if (o) return o; + for (var i = s.parentNode; i; ) { + if ((o = i[mn] || i[dn])) { + if (((i = o.alternate), null !== o.child || (null !== i && null !== i.child))) + for (s = Mf(s); null !== s; ) { + if ((i = s[dn])) return i; + s = Mf(s); + } + return o; + } + i = (s = i).parentNode; + } + return null; + } + function Cb(s) { + return !(s = s[dn] || s[mn]) || + (5 !== s.tag && 6 !== s.tag && 13 !== s.tag && 3 !== s.tag) + ? null + : s; + } + function ue(s) { + if (5 === s.tag || 6 === s.tag) return s.stateNode; + throw Error(p(33)); + } + function Db(s) { + return s[fn] || null; + } + var bn = [], + _n = -1; + function Uf(s) { + return { current: s }; + } + function E(s) { + 0 > _n || ((s.current = bn[_n]), (bn[_n] = null), _n--); + } + function G(s, o) { + _n++, (bn[_n] = s.current), (s.current = o); + } + var En = {}, + wn = Uf(En), + Sn = Uf(!1), + xn = En; + function Yf(s, o) { + var i = s.type.contextTypes; + if (!i) return En; + var u = s.stateNode; + if (u && u.__reactInternalMemoizedUnmaskedChildContext === o) + return u.__reactInternalMemoizedMaskedChildContext; + var _, + w = {}; + for (_ in i) w[_] = o[_]; + return ( + u && + (((s = s.stateNode).__reactInternalMemoizedUnmaskedChildContext = o), + (s.__reactInternalMemoizedMaskedChildContext = w)), + w + ); + } + function Zf(s) { + return null != (s = s.childContextTypes); + } + function $f() { + E(Sn), E(wn); + } + function ag(s, o, i) { + if (wn.current !== En) throw Error(p(168)); + G(wn, o), G(Sn, i); + } + function bg(s, o, i) { + var u = s.stateNode; + if (((o = o.childContextTypes), 'function' != typeof u.getChildContext)) return i; + for (var _ in (u = u.getChildContext())) + if (!(_ in o)) throw Error(p(108, Ra(s) || 'Unknown', _)); + return xe({}, i, u); + } + function cg(s) { + return ( + (s = ((s = s.stateNode) && s.__reactInternalMemoizedMergedChildContext) || En), + (xn = wn.current), + G(wn, s), + G(Sn, Sn.current), + !0 + ); + } + function dg(s, o, i) { + var u = s.stateNode; + if (!u) throw Error(p(169)); + i + ? ((s = bg(s, o, xn)), + (u.__reactInternalMemoizedMergedChildContext = s), + E(Sn), + E(wn), + G(wn, s)) + : E(Sn), + G(Sn, i); + } + var kn = null, + Cn = !1, + On = !1; + function hg(s) { + null === kn ? (kn = [s]) : kn.push(s); + } + function jg() { + if (!On && null !== kn) { + On = !0; + var s = 0, + o = At; + try { + var i = kn; + for (At = 1; s < i.length; s++) { + var u = i[s]; + do { + u = u(!0); + } while (null !== u); + } + (kn = null), (Cn = !1); + } catch (o) { + throw (null !== kn && (kn = kn.slice(s + 1)), ct(gt, jg), o); + } finally { + (At = o), (On = !1); + } + } + return null; + } + var An = [], + jn = 0, + In = null, + Pn = 0, + Mn = [], + Tn = 0, + Nn = null, + Rn = 1, + Dn = ''; + function tg(s, o) { + (An[jn++] = Pn), (An[jn++] = In), (In = s), (Pn = o); + } + function ug(s, o, i) { + (Mn[Tn++] = Rn), (Mn[Tn++] = Dn), (Mn[Tn++] = Nn), (Nn = s); + var u = Rn; + s = Dn; + var _ = 32 - St(u) - 1; + (u &= ~(1 << _)), (i += 1); + var w = 32 - St(o) + _; + if (30 < w) { + var x = _ - (_ % 5); + (w = (u & ((1 << x) - 1)).toString(32)), + (u >>= x), + (_ -= x), + (Rn = (1 << (32 - St(o) + _)) | (i << _) | u), + (Dn = w + s); + } else (Rn = (1 << w) | (i << _) | u), (Dn = s); + } + function vg(s) { + null !== s.return && (tg(s, 1), ug(s, 1, 0)); + } + function wg(s) { + for (; s === In; ) (In = An[--jn]), (An[jn] = null), (Pn = An[--jn]), (An[jn] = null); + for (; s === Nn; ) + (Nn = Mn[--Tn]), + (Mn[Tn] = null), + (Dn = Mn[--Tn]), + (Mn[Tn] = null), + (Rn = Mn[--Tn]), + (Mn[Tn] = null); + } + var Ln = null, + Bn = null, + Fn = !1, + qn = null; + function Ag(s, o) { + var i = Bg(5, null, null, 0); + (i.elementType = 'DELETED'), + (i.stateNode = o), + (i.return = s), + null === (o = s.deletions) ? ((s.deletions = [i]), (s.flags |= 16)) : o.push(i); + } + function Cg(s, o) { + switch (s.tag) { + case 5: + var i = s.type; + return ( + null !== + (o = + 1 !== o.nodeType || i.toLowerCase() !== o.nodeName.toLowerCase() + ? null + : o) && ((s.stateNode = o), (Ln = s), (Bn = Lf(o.firstChild)), !0) + ); + case 6: + return ( + null !== (o = '' === s.pendingProps || 3 !== o.nodeType ? null : o) && + ((s.stateNode = o), (Ln = s), (Bn = null), !0) + ); + case 13: + return ( + null !== (o = 8 !== o.nodeType ? null : o) && + ((i = null !== Nn ? { id: Rn, overflow: Dn } : null), + (s.memoizedState = { dehydrated: o, treeContext: i, retryLane: 1073741824 }), + ((i = Bg(18, null, null, 0)).stateNode = o), + (i.return = s), + (s.child = i), + (Ln = s), + (Bn = null), + !0) + ); + default: + return !1; + } + } + function Dg(s) { + return !(!(1 & s.mode) || 128 & s.flags); + } + function Eg(s) { + if (Fn) { + var o = Bn; + if (o) { + var i = o; + if (!Cg(s, o)) { + if (Dg(s)) throw Error(p(418)); + o = Lf(i.nextSibling); + var u = Ln; + o && Cg(s, o) + ? Ag(u, i) + : ((s.flags = (-4097 & s.flags) | 2), (Fn = !1), (Ln = s)); + } + } else { + if (Dg(s)) throw Error(p(418)); + (s.flags = (-4097 & s.flags) | 2), (Fn = !1), (Ln = s); + } + } + } + function Fg(s) { + for (s = s.return; null !== s && 5 !== s.tag && 3 !== s.tag && 13 !== s.tag; ) + s = s.return; + Ln = s; + } + function Gg(s) { + if (s !== Ln) return !1; + if (!Fn) return Fg(s), (Fn = !0), !1; + var o; + if ( + ((o = 3 !== s.tag) && + !(o = 5 !== s.tag) && + (o = 'head' !== (o = s.type) && 'body' !== o && !Ef(s.type, s.memoizedProps)), + o && (o = Bn)) + ) { + if (Dg(s)) throw (Hg(), Error(p(418))); + for (; o; ) Ag(s, o), (o = Lf(o.nextSibling)); + } + if ((Fg(s), 13 === s.tag)) { + if (!(s = null !== (s = s.memoizedState) ? s.dehydrated : null)) throw Error(p(317)); + e: { + for (s = s.nextSibling, o = 0; s; ) { + if (8 === s.nodeType) { + var i = s.data; + if ('/$' === i) { + if (0 === o) { + Bn = Lf(s.nextSibling); + break e; + } + o--; + } else ('$' !== i && '$!' !== i && '$?' !== i) || o++; + } + s = s.nextSibling; + } + Bn = null; + } + } else Bn = Ln ? Lf(s.stateNode.nextSibling) : null; + return !0; + } + function Hg() { + for (var s = Bn; s; ) s = Lf(s.nextSibling); + } + function Ig() { + (Bn = Ln = null), (Fn = !1); + } + function Jg(s) { + null === qn ? (qn = [s]) : qn.push(s); + } + var $n = z.ReactCurrentBatchConfig; + function Lg(s, o, i) { + if (null !== (s = i.ref) && 'function' != typeof s && 'object' != typeof s) { + if (i._owner) { + if ((i = i._owner)) { + if (1 !== i.tag) throw Error(p(309)); + var u = i.stateNode; + } + if (!u) throw Error(p(147, s)); + var _ = u, + w = '' + s; + return null !== o && + null !== o.ref && + 'function' == typeof o.ref && + o.ref._stringRef === w + ? o.ref + : ((o = function (s) { + var o = _.refs; + null === s ? delete o[w] : (o[w] = s); + }), + (o._stringRef = w), + o); + } + if ('string' != typeof s) throw Error(p(284)); + if (!i._owner) throw Error(p(290, s)); + } + return s; + } + function Mg(s, o) { + throw ( + ((s = Object.prototype.toString.call(o)), + Error( + p( + 31, + '[object Object]' === s + ? 'object with keys {' + Object.keys(o).join(', ') + '}' + : s + ) + )) + ); + } + function Ng(s) { + return (0, s._init)(s._payload); + } + function Og(s) { + function b(o, i) { + if (s) { + var u = o.deletions; + null === u ? ((o.deletions = [i]), (o.flags |= 16)) : u.push(i); + } + } + function c(o, i) { + if (!s) return null; + for (; null !== i; ) b(o, i), (i = i.sibling); + return null; + } + function d(s, o) { + for (s = new Map(); null !== o; ) + null !== o.key ? s.set(o.key, o) : s.set(o.index, o), (o = o.sibling); + return s; + } + function e(s, o) { + return ((s = Pg(s, o)).index = 0), (s.sibling = null), s; + } + function f(o, i, u) { + return ( + (o.index = u), + s + ? null !== (u = o.alternate) + ? (u = u.index) < i + ? ((o.flags |= 2), i) + : u + : ((o.flags |= 2), i) + : ((o.flags |= 1048576), i) + ); + } + function g(o) { + return s && null === o.alternate && (o.flags |= 2), o; + } + function h(s, o, i, u) { + return null === o || 6 !== o.tag + ? (((o = Qg(i, s.mode, u)).return = s), o) + : (((o = e(o, i)).return = s), o); + } + function k(s, o, i, u) { + var _ = i.type; + return _ === ee + ? m(s, o, i.props.children, u, i.key) + : null !== o && + (o.elementType === _ || + ('object' == typeof _ && null !== _ && _.$$typeof === be && Ng(_) === o.type)) + ? (((u = e(o, i.props)).ref = Lg(s, o, i)), (u.return = s), u) + : (((u = Rg(i.type, i.key, i.props, null, s.mode, u)).ref = Lg(s, o, i)), + (u.return = s), + u); + } + function l(s, o, i, u) { + return null === o || + 4 !== o.tag || + o.stateNode.containerInfo !== i.containerInfo || + o.stateNode.implementation !== i.implementation + ? (((o = Sg(i, s.mode, u)).return = s), o) + : (((o = e(o, i.children || [])).return = s), o); + } + function m(s, o, i, u, _) { + return null === o || 7 !== o.tag + ? (((o = Tg(i, s.mode, u, _)).return = s), o) + : (((o = e(o, i)).return = s), o); + } + function q(s, o, i) { + if (('string' == typeof o && '' !== o) || 'number' == typeof o) + return ((o = Qg('' + o, s.mode, i)).return = s), o; + if ('object' == typeof o && null !== o) { + switch (o.$$typeof) { + case Y: + return ( + ((i = Rg(o.type, o.key, o.props, null, s.mode, i)).ref = Lg(s, null, o)), + (i.return = s), + i + ); + case Z: + return ((o = Sg(o, s.mode, i)).return = s), o; + case be: + return q(s, (0, o._init)(o._payload), i); + } + if (Te(o) || Ka(o)) return ((o = Tg(o, s.mode, i, null)).return = s), o; + Mg(s, o); + } + return null; + } + function r(s, o, i, u) { + var _ = null !== o ? o.key : null; + if (('string' == typeof i && '' !== i) || 'number' == typeof i) + return null !== _ ? null : h(s, o, '' + i, u); + if ('object' == typeof i && null !== i) { + switch (i.$$typeof) { + case Y: + return i.key === _ ? k(s, o, i, u) : null; + case Z: + return i.key === _ ? l(s, o, i, u) : null; + case be: + return r(s, o, (_ = i._init)(i._payload), u); + } + if (Te(i) || Ka(i)) return null !== _ ? null : m(s, o, i, u, null); + Mg(s, i); + } + return null; + } + function y(s, o, i, u, _) { + if (('string' == typeof u && '' !== u) || 'number' == typeof u) + return h(o, (s = s.get(i) || null), '' + u, _); + if ('object' == typeof u && null !== u) { + switch (u.$$typeof) { + case Y: + return k(o, (s = s.get(null === u.key ? i : u.key) || null), u, _); + case Z: + return l(o, (s = s.get(null === u.key ? i : u.key) || null), u, _); + case be: + return y(s, o, i, (0, u._init)(u._payload), _); + } + if (Te(u) || Ka(u)) return m(o, (s = s.get(i) || null), u, _, null); + Mg(o, u); + } + return null; + } + function n(o, i, u, _) { + for ( + var w = null, x = null, C = i, j = (i = 0), L = null; + null !== C && j < u.length; + j++ + ) { + C.index > j ? ((L = C), (C = null)) : (L = C.sibling); + var B = r(o, C, u[j], _); + if (null === B) { + null === C && (C = L); + break; + } + s && C && null === B.alternate && b(o, C), + (i = f(B, i, j)), + null === x ? (w = B) : (x.sibling = B), + (x = B), + (C = L); + } + if (j === u.length) return c(o, C), Fn && tg(o, j), w; + if (null === C) { + for (; j < u.length; j++) + null !== (C = q(o, u[j], _)) && + ((i = f(C, i, j)), null === x ? (w = C) : (x.sibling = C), (x = C)); + return Fn && tg(o, j), w; + } + for (C = d(o, C); j < u.length; j++) + null !== (L = y(C, o, j, u[j], _)) && + (s && null !== L.alternate && C.delete(null === L.key ? j : L.key), + (i = f(L, i, j)), + null === x ? (w = L) : (x.sibling = L), + (x = L)); + return ( + s && + C.forEach(function (s) { + return b(o, s); + }), + Fn && tg(o, j), + w + ); + } + function t(o, i, u, _) { + var w = Ka(u); + if ('function' != typeof w) throw Error(p(150)); + if (null == (u = w.call(u))) throw Error(p(151)); + for ( + var x = (w = null), C = i, j = (i = 0), L = null, B = u.next(); + null !== C && !B.done; + j++, B = u.next() + ) { + C.index > j ? ((L = C), (C = null)) : (L = C.sibling); + var $ = r(o, C, B.value, _); + if (null === $) { + null === C && (C = L); + break; + } + s && C && null === $.alternate && b(o, C), + (i = f($, i, j)), + null === x ? (w = $) : (x.sibling = $), + (x = $), + (C = L); + } + if (B.done) return c(o, C), Fn && tg(o, j), w; + if (null === C) { + for (; !B.done; j++, B = u.next()) + null !== (B = q(o, B.value, _)) && + ((i = f(B, i, j)), null === x ? (w = B) : (x.sibling = B), (x = B)); + return Fn && tg(o, j), w; + } + for (C = d(o, C); !B.done; j++, B = u.next()) + null !== (B = y(C, o, j, B.value, _)) && + (s && null !== B.alternate && C.delete(null === B.key ? j : B.key), + (i = f(B, i, j)), + null === x ? (w = B) : (x.sibling = B), + (x = B)); + return ( + s && + C.forEach(function (s) { + return b(o, s); + }), + Fn && tg(o, j), + w + ); + } + return function J(s, o, i, u) { + if ( + ('object' == typeof i && + null !== i && + i.type === ee && + null === i.key && + (i = i.props.children), + 'object' == typeof i && null !== i) + ) { + switch (i.$$typeof) { + case Y: + e: { + for (var _ = i.key, w = o; null !== w; ) { + if (w.key === _) { + if ((_ = i.type) === ee) { + if (7 === w.tag) { + c(s, w.sibling), ((o = e(w, i.props.children)).return = s), (s = o); + break e; + } + } else if ( + w.elementType === _ || + ('object' == typeof _ && + null !== _ && + _.$$typeof === be && + Ng(_) === w.type) + ) { + c(s, w.sibling), + ((o = e(w, i.props)).ref = Lg(s, w, i)), + (o.return = s), + (s = o); + break e; + } + c(s, w); + break; + } + b(s, w), (w = w.sibling); + } + i.type === ee + ? (((o = Tg(i.props.children, s.mode, u, i.key)).return = s), (s = o)) + : (((u = Rg(i.type, i.key, i.props, null, s.mode, u)).ref = Lg(s, o, i)), + (u.return = s), + (s = u)); + } + return g(s); + case Z: + e: { + for (w = i.key; null !== o; ) { + if (o.key === w) { + if ( + 4 === o.tag && + o.stateNode.containerInfo === i.containerInfo && + o.stateNode.implementation === i.implementation + ) { + c(s, o.sibling), ((o = e(o, i.children || [])).return = s), (s = o); + break e; + } + c(s, o); + break; + } + b(s, o), (o = o.sibling); + } + ((o = Sg(i, s.mode, u)).return = s), (s = o); + } + return g(s); + case be: + return J(s, o, (w = i._init)(i._payload), u); + } + if (Te(i)) return n(s, o, i, u); + if (Ka(i)) return t(s, o, i, u); + Mg(s, i); + } + return ('string' == typeof i && '' !== i) || 'number' == typeof i + ? ((i = '' + i), + null !== o && 6 === o.tag + ? (c(s, o.sibling), ((o = e(o, i)).return = s), (s = o)) + : (c(s, o), ((o = Qg(i, s.mode, u)).return = s), (s = o)), + g(s)) + : c(s, o); + }; + } + var Vn = Og(!0), + Un = Og(!1), + zn = Uf(null), + Wn = null, + Kn = null, + Hn = null; + function $g() { + Hn = Kn = Wn = null; + } + function ah(s) { + var o = zn.current; + E(zn), (s._currentValue = o); + } + function bh(s, o, i) { + for (; null !== s; ) { + var u = s.alternate; + if ( + ((s.childLanes & o) !== o + ? ((s.childLanes |= o), null !== u && (u.childLanes |= o)) + : null !== u && (u.childLanes & o) !== o && (u.childLanes |= o), + s === i) + ) + break; + s = s.return; + } + } + function ch(s, o) { + (Wn = s), + (Hn = Kn = null), + null !== (s = s.dependencies) && + null !== s.firstContext && + (!!(s.lanes & o) && (_s = !0), (s.firstContext = null)); + } + function eh(s) { + var o = s._currentValue; + if (Hn !== s) + if (((s = { context: s, memoizedValue: o, next: null }), null === Kn)) { + if (null === Wn) throw Error(p(308)); + (Kn = s), (Wn.dependencies = { lanes: 0, firstContext: s }); + } else Kn = Kn.next = s; + return o; + } + var Jn = null; + function gh(s) { + null === Jn ? (Jn = [s]) : Jn.push(s); + } + function hh(s, o, i, u) { + var _ = o.interleaved; + return ( + null === _ ? ((i.next = i), gh(o)) : ((i.next = _.next), (_.next = i)), + (o.interleaved = i), + ih(s, u) + ); + } + function ih(s, o) { + s.lanes |= o; + var i = s.alternate; + for (null !== i && (i.lanes |= o), i = s, s = s.return; null !== s; ) + (s.childLanes |= o), + null !== (i = s.alternate) && (i.childLanes |= o), + (i = s), + (s = s.return); + return 3 === i.tag ? i.stateNode : null; + } + var Gn = !1; + function kh(s) { + s.updateQueue = { + baseState: s.memoizedState, + firstBaseUpdate: null, + lastBaseUpdate: null, + shared: { pending: null, interleaved: null, lanes: 0 }, + effects: null + }; + } + function lh(s, o) { + (s = s.updateQueue), + o.updateQueue === s && + (o.updateQueue = { + baseState: s.baseState, + firstBaseUpdate: s.firstBaseUpdate, + lastBaseUpdate: s.lastBaseUpdate, + shared: s.shared, + effects: s.effects + }); + } + function mh(s, o) { + return { eventTime: s, lane: o, tag: 0, payload: null, callback: null, next: null }; + } + function nh(s, o, i) { + var u = s.updateQueue; + if (null === u) return null; + if (((u = u.shared), 2 & Bs)) { + var _ = u.pending; + return ( + null === _ ? (o.next = o) : ((o.next = _.next), (_.next = o)), + (u.pending = o), + ih(s, i) + ); + } + return ( + null === (_ = u.interleaved) + ? ((o.next = o), gh(u)) + : ((o.next = _.next), (_.next = o)), + (u.interleaved = o), + ih(s, i) + ); + } + function oh(s, o, i) { + if (null !== (o = o.updateQueue) && ((o = o.shared), 4194240 & i)) { + var u = o.lanes; + (i |= u &= s.pendingLanes), (o.lanes = i), Cc(s, i); + } + } + function ph(s, o) { + var i = s.updateQueue, + u = s.alternate; + if (null !== u && i === (u = u.updateQueue)) { + var _ = null, + w = null; + if (null !== (i = i.firstBaseUpdate)) { + do { + var x = { + eventTime: i.eventTime, + lane: i.lane, + tag: i.tag, + payload: i.payload, + callback: i.callback, + next: null + }; + null === w ? (_ = w = x) : (w = w.next = x), (i = i.next); + } while (null !== i); + null === w ? (_ = w = o) : (w = w.next = o); + } else _ = w = o; + return ( + (i = { + baseState: u.baseState, + firstBaseUpdate: _, + lastBaseUpdate: w, + shared: u.shared, + effects: u.effects + }), + void (s.updateQueue = i) + ); + } + null === (s = i.lastBaseUpdate) ? (i.firstBaseUpdate = o) : (s.next = o), + (i.lastBaseUpdate = o); + } + function qh(s, o, i, u) { + var _ = s.updateQueue; + Gn = !1; + var w = _.firstBaseUpdate, + x = _.lastBaseUpdate, + C = _.shared.pending; + if (null !== C) { + _.shared.pending = null; + var j = C, + L = j.next; + (j.next = null), null === x ? (w = L) : (x.next = L), (x = j); + var B = s.alternate; + null !== B && + (C = (B = B.updateQueue).lastBaseUpdate) !== x && + (null === C ? (B.firstBaseUpdate = L) : (C.next = L), (B.lastBaseUpdate = j)); + } + if (null !== w) { + var $ = _.baseState; + for (x = 0, B = L = j = null, C = w; ; ) { + var V = C.lane, + U = C.eventTime; + if ((u & V) === V) { + null !== B && + (B = B.next = + { + eventTime: U, + lane: 0, + tag: C.tag, + payload: C.payload, + callback: C.callback, + next: null + }); + e: { + var z = s, + Y = C; + switch (((V = o), (U = i), Y.tag)) { + case 1: + if ('function' == typeof (z = Y.payload)) { + $ = z.call(U, $, V); + break e; + } + $ = z; + break e; + case 3: + z.flags = (-65537 & z.flags) | 128; + case 0: + if ( + null == (V = 'function' == typeof (z = Y.payload) ? z.call(U, $, V) : z) + ) + break e; + $ = xe({}, $, V); + break e; + case 2: + Gn = !0; + } + } + null !== C.callback && + 0 !== C.lane && + ((s.flags |= 64), null === (V = _.effects) ? (_.effects = [C]) : V.push(C)); + } else + (U = { + eventTime: U, + lane: V, + tag: C.tag, + payload: C.payload, + callback: C.callback, + next: null + }), + null === B ? ((L = B = U), (j = $)) : (B = B.next = U), + (x |= V); + if (null === (C = C.next)) { + if (null === (C = _.shared.pending)) break; + (C = (V = C).next), + (V.next = null), + (_.lastBaseUpdate = V), + (_.shared.pending = null); + } + } + if ( + (null === B && (j = $), + (_.baseState = j), + (_.firstBaseUpdate = L), + (_.lastBaseUpdate = B), + null !== (o = _.shared.interleaved)) + ) { + _ = o; + do { + (x |= _.lane), (_ = _.next); + } while (_ !== o); + } else null === w && (_.shared.lanes = 0); + (Ks |= x), (s.lanes = x), (s.memoizedState = $); + } + } + function sh(s, o, i) { + if (((s = o.effects), (o.effects = null), null !== s)) + for (o = 0; o < s.length; o++) { + var u = s[o], + _ = u.callback; + if (null !== _) { + if (((u.callback = null), (u = i), 'function' != typeof _)) + throw Error(p(191, _)); + _.call(u); + } + } + } + var Yn = {}, + Xn = Uf(Yn), + Zn = Uf(Yn), + Qn = Uf(Yn); + function xh(s) { + if (s === Yn) throw Error(p(174)); + return s; + } + function yh(s, o) { + switch ((G(Qn, o), G(Zn, s), G(Xn, Yn), (s = o.nodeType))) { + case 9: + case 11: + o = (o = o.documentElement) ? o.namespaceURI : lb(null, ''); + break; + default: + o = lb( + (o = (s = 8 === s ? o.parentNode : o).namespaceURI || null), + (s = s.tagName) + ); + } + E(Xn), G(Xn, o); + } + function zh() { + E(Xn), E(Zn), E(Qn); + } + function Ah(s) { + xh(Qn.current); + var o = xh(Xn.current), + i = lb(o, s.type); + o !== i && (G(Zn, s), G(Xn, i)); + } + function Bh(s) { + Zn.current === s && (E(Xn), E(Zn)); + } + var es = Uf(0); + function Ch(s) { + for (var o = s; null !== o; ) { + if (13 === o.tag) { + var i = o.memoizedState; + if ( + null !== i && + (null === (i = i.dehydrated) || '$?' === i.data || '$!' === i.data) + ) + return o; + } else if (19 === o.tag && void 0 !== o.memoizedProps.revealOrder) { + if (128 & o.flags) return o; + } else if (null !== o.child) { + (o.child.return = o), (o = o.child); + continue; + } + if (o === s) break; + for (; null === o.sibling; ) { + if (null === o.return || o.return === s) return null; + o = o.return; + } + (o.sibling.return = o.return), (o = o.sibling); + } + return null; + } + var ts = []; + function Eh() { + for (var s = 0; s < ts.length; s++) ts[s]._workInProgressVersionPrimary = null; + ts.length = 0; + } + var rs = z.ReactCurrentDispatcher, + ns = z.ReactCurrentBatchConfig, + ss = 0, + os = null, + as = null, + ls = null, + cs = !1, + us = !1, + ps = 0, + hs = 0; + function P() { + throw Error(p(321)); + } + function Mh(s, o) { + if (null === o) return !1; + for (var i = 0; i < o.length && i < s.length; i++) if (!Lr(s[i], o[i])) return !1; + return !0; + } + function Nh(s, o, i, u, _, w) { + if ( + ((ss = w), + (os = o), + (o.memoizedState = null), + (o.updateQueue = null), + (o.lanes = 0), + (rs.current = null === s || null === s.memoizedState ? fs : ms), + (s = i(u, _)), + us) + ) { + w = 0; + do { + if (((us = !1), (ps = 0), 25 <= w)) throw Error(p(301)); + (w += 1), + (ls = as = null), + (o.updateQueue = null), + (rs.current = gs), + (s = i(u, _)); + } while (us); + } + if ( + ((rs.current = ds), + (o = null !== as && null !== as.next), + (ss = 0), + (ls = as = os = null), + (cs = !1), + o) + ) + throw Error(p(300)); + return s; + } + function Sh() { + var s = 0 !== ps; + return (ps = 0), s; + } + function Th() { + var s = { + memoizedState: null, + baseState: null, + baseQueue: null, + queue: null, + next: null + }; + return null === ls ? (os.memoizedState = ls = s) : (ls = ls.next = s), ls; + } + function Uh() { + if (null === as) { + var s = os.alternate; + s = null !== s ? s.memoizedState : null; + } else s = as.next; + var o = null === ls ? os.memoizedState : ls.next; + if (null !== o) (ls = o), (as = s); + else { + if (null === s) throw Error(p(310)); + (s = { + memoizedState: (as = s).memoizedState, + baseState: as.baseState, + baseQueue: as.baseQueue, + queue: as.queue, + next: null + }), + null === ls ? (os.memoizedState = ls = s) : (ls = ls.next = s); + } + return ls; + } + function Vh(s, o) { + return 'function' == typeof o ? o(s) : o; + } + function Wh(s) { + var o = Uh(), + i = o.queue; + if (null === i) throw Error(p(311)); + i.lastRenderedReducer = s; + var u = as, + _ = u.baseQueue, + w = i.pending; + if (null !== w) { + if (null !== _) { + var x = _.next; + (_.next = w.next), (w.next = x); + } + (u.baseQueue = _ = w), (i.pending = null); + } + if (null !== _) { + (w = _.next), (u = u.baseState); + var C = (x = null), + j = null, + L = w; + do { + var B = L.lane; + if ((ss & B) === B) + null !== j && + (j = j.next = + { + lane: 0, + action: L.action, + hasEagerState: L.hasEagerState, + eagerState: L.eagerState, + next: null + }), + (u = L.hasEagerState ? L.eagerState : s(u, L.action)); + else { + var $ = { + lane: B, + action: L.action, + hasEagerState: L.hasEagerState, + eagerState: L.eagerState, + next: null + }; + null === j ? ((C = j = $), (x = u)) : (j = j.next = $), + (os.lanes |= B), + (Ks |= B); + } + L = L.next; + } while (null !== L && L !== w); + null === j ? (x = u) : (j.next = C), + Lr(u, o.memoizedState) || (_s = !0), + (o.memoizedState = u), + (o.baseState = x), + (o.baseQueue = j), + (i.lastRenderedState = u); + } + if (null !== (s = i.interleaved)) { + _ = s; + do { + (w = _.lane), (os.lanes |= w), (Ks |= w), (_ = _.next); + } while (_ !== s); + } else null === _ && (i.lanes = 0); + return [o.memoizedState, i.dispatch]; + } + function Xh(s) { + var o = Uh(), + i = o.queue; + if (null === i) throw Error(p(311)); + i.lastRenderedReducer = s; + var u = i.dispatch, + _ = i.pending, + w = o.memoizedState; + if (null !== _) { + i.pending = null; + var x = (_ = _.next); + do { + (w = s(w, x.action)), (x = x.next); + } while (x !== _); + Lr(w, o.memoizedState) || (_s = !0), + (o.memoizedState = w), + null === o.baseQueue && (o.baseState = w), + (i.lastRenderedState = w); + } + return [w, u]; + } + function Yh() {} + function Zh(s, o) { + var i = os, + u = Uh(), + _ = o(), + w = !Lr(u.memoizedState, _); + if ( + (w && ((u.memoizedState = _), (_s = !0)), + (u = u.queue), + $h(ai.bind(null, i, u, s), [s]), + u.getSnapshot !== o || w || (null !== ls && 1 & ls.memoizedState.tag)) + ) { + if (((i.flags |= 2048), bi(9, ci.bind(null, i, u, _, o), void 0, null), null === Fs)) + throw Error(p(349)); + 30 & ss || di(i, o, _); + } + return _; + } + function di(s, o, i) { + (s.flags |= 16384), + (s = { getSnapshot: o, value: i }), + null === (o = os.updateQueue) + ? ((o = { lastEffect: null, stores: null }), (os.updateQueue = o), (o.stores = [s])) + : null === (i = o.stores) + ? (o.stores = [s]) + : i.push(s); + } + function ci(s, o, i, u) { + (o.value = i), (o.getSnapshot = u), ei(o) && fi(s); + } + function ai(s, o, i) { + return i(function () { + ei(o) && fi(s); + }); + } + function ei(s) { + var o = s.getSnapshot; + s = s.value; + try { + var i = o(); + return !Lr(s, i); + } catch (s) { + return !0; + } + } + function fi(s) { + var o = ih(s, 1); + null !== o && gi(o, s, 1, -1); + } + function hi(s) { + var o = Th(); + return ( + 'function' == typeof s && (s = s()), + (o.memoizedState = o.baseState = s), + (s = { + pending: null, + interleaved: null, + lanes: 0, + dispatch: null, + lastRenderedReducer: Vh, + lastRenderedState: s + }), + (o.queue = s), + (s = s.dispatch = ii.bind(null, os, s)), + [o.memoizedState, s] + ); + } + function bi(s, o, i, u) { + return ( + (s = { tag: s, create: o, destroy: i, deps: u, next: null }), + null === (o = os.updateQueue) + ? ((o = { lastEffect: null, stores: null }), + (os.updateQueue = o), + (o.lastEffect = s.next = s)) + : null === (i = o.lastEffect) + ? (o.lastEffect = s.next = s) + : ((u = i.next), (i.next = s), (s.next = u), (o.lastEffect = s)), + s + ); + } + function ji() { + return Uh().memoizedState; + } + function ki(s, o, i, u) { + var _ = Th(); + (os.flags |= s), (_.memoizedState = bi(1 | o, i, void 0, void 0 === u ? null : u)); + } + function li(s, o, i, u) { + var _ = Uh(); + u = void 0 === u ? null : u; + var w = void 0; + if (null !== as) { + var x = as.memoizedState; + if (((w = x.destroy), null !== u && Mh(u, x.deps))) + return void (_.memoizedState = bi(o, i, w, u)); + } + (os.flags |= s), (_.memoizedState = bi(1 | o, i, w, u)); + } + function mi(s, o) { + return ki(8390656, 8, s, o); + } + function $h(s, o) { + return li(2048, 8, s, o); + } + function ni(s, o) { + return li(4, 2, s, o); + } + function oi(s, o) { + return li(4, 4, s, o); + } + function pi(s, o) { + return 'function' == typeof o + ? ((s = s()), + o(s), + function () { + o(null); + }) + : null != o + ? ((s = s()), + (o.current = s), + function () { + o.current = null; + }) + : void 0; + } + function qi(s, o, i) { + return (i = null != i ? i.concat([s]) : null), li(4, 4, pi.bind(null, o, s), i); + } + function ri() {} + function si(s, o) { + var i = Uh(); + o = void 0 === o ? null : o; + var u = i.memoizedState; + return null !== u && null !== o && Mh(o, u[1]) ? u[0] : ((i.memoizedState = [s, o]), s); + } + function ti(s, o) { + var i = Uh(); + o = void 0 === o ? null : o; + var u = i.memoizedState; + return null !== u && null !== o && Mh(o, u[1]) + ? u[0] + : ((s = s()), (i.memoizedState = [s, o]), s); + } + function ui(s, o, i) { + return 21 & ss + ? (Lr(i, o) || ((i = yc()), (os.lanes |= i), (Ks |= i), (s.baseState = !0)), o) + : (s.baseState && ((s.baseState = !1), (_s = !0)), (s.memoizedState = i)); + } + function vi(s, o) { + var i = At; + (At = 0 !== i && 4 > i ? i : 4), s(!0); + var u = ns.transition; + ns.transition = {}; + try { + s(!1), o(); + } finally { + (At = i), (ns.transition = u); + } + } + function wi() { + return Uh().memoizedState; + } + function xi(s, o, i) { + var u = yi(s); + if ( + ((i = { lane: u, action: i, hasEagerState: !1, eagerState: null, next: null }), zi(s)) + ) + Ai(o, i); + else if (null !== (i = hh(s, o, i, u))) { + gi(i, s, u, R()), Bi(i, o, u); + } + } + function ii(s, o, i) { + var u = yi(s), + _ = { lane: u, action: i, hasEagerState: !1, eagerState: null, next: null }; + if (zi(s)) Ai(o, _); + else { + var w = s.alternate; + if ( + 0 === s.lanes && + (null === w || 0 === w.lanes) && + null !== (w = o.lastRenderedReducer) + ) + try { + var x = o.lastRenderedState, + C = w(x, i); + if (((_.hasEagerState = !0), (_.eagerState = C), Lr(C, x))) { + var j = o.interleaved; + return ( + null === j ? ((_.next = _), gh(o)) : ((_.next = j.next), (j.next = _)), + void (o.interleaved = _) + ); + } + } catch (s) {} + null !== (i = hh(s, o, _, u)) && (gi(i, s, u, (_ = R())), Bi(i, o, u)); + } + } + function zi(s) { + var o = s.alternate; + return s === os || (null !== o && o === os); + } + function Ai(s, o) { + us = cs = !0; + var i = s.pending; + null === i ? (o.next = o) : ((o.next = i.next), (i.next = o)), (s.pending = o); + } + function Bi(s, o, i) { + if (4194240 & i) { + var u = o.lanes; + (i |= u &= s.pendingLanes), (o.lanes = i), Cc(s, i); + } + } + var ds = { + readContext: eh, + useCallback: P, + useContext: P, + useEffect: P, + useImperativeHandle: P, + useInsertionEffect: P, + useLayoutEffect: P, + useMemo: P, + useReducer: P, + useRef: P, + useState: P, + useDebugValue: P, + useDeferredValue: P, + useTransition: P, + useMutableSource: P, + useSyncExternalStore: P, + useId: P, + unstable_isNewReconciler: !1 + }, + fs = { + readContext: eh, + useCallback: function (s, o) { + return (Th().memoizedState = [s, void 0 === o ? null : o]), s; + }, + useContext: eh, + useEffect: mi, + useImperativeHandle: function (s, o, i) { + return ( + (i = null != i ? i.concat([s]) : null), ki(4194308, 4, pi.bind(null, o, s), i) + ); + }, + useLayoutEffect: function (s, o) { + return ki(4194308, 4, s, o); + }, + useInsertionEffect: function (s, o) { + return ki(4, 2, s, o); + }, + useMemo: function (s, o) { + var i = Th(); + return (o = void 0 === o ? null : o), (s = s()), (i.memoizedState = [s, o]), s; + }, + useReducer: function (s, o, i) { + var u = Th(); + return ( + (o = void 0 !== i ? i(o) : o), + (u.memoizedState = u.baseState = o), + (s = { + pending: null, + interleaved: null, + lanes: 0, + dispatch: null, + lastRenderedReducer: s, + lastRenderedState: o + }), + (u.queue = s), + (s = s.dispatch = xi.bind(null, os, s)), + [u.memoizedState, s] + ); + }, + useRef: function (s) { + return (s = { current: s }), (Th().memoizedState = s); + }, + useState: hi, + useDebugValue: ri, + useDeferredValue: function (s) { + return (Th().memoizedState = s); + }, + useTransition: function () { + var s = hi(!1), + o = s[0]; + return (s = vi.bind(null, s[1])), (Th().memoizedState = s), [o, s]; + }, + useMutableSource: function () {}, + useSyncExternalStore: function (s, o, i) { + var u = os, + _ = Th(); + if (Fn) { + if (void 0 === i) throw Error(p(407)); + i = i(); + } else { + if (((i = o()), null === Fs)) throw Error(p(349)); + 30 & ss || di(u, o, i); + } + _.memoizedState = i; + var w = { value: i, getSnapshot: o }; + return ( + (_.queue = w), + mi(ai.bind(null, u, w, s), [s]), + (u.flags |= 2048), + bi(9, ci.bind(null, u, w, i, o), void 0, null), + i + ); + }, + useId: function () { + var s = Th(), + o = Fs.identifierPrefix; + if (Fn) { + var i = Dn; + (o = ':' + o + 'R' + (i = (Rn & ~(1 << (32 - St(Rn) - 1))).toString(32) + i)), + 0 < (i = ps++) && (o += 'H' + i.toString(32)), + (o += ':'); + } else o = ':' + o + 'r' + (i = hs++).toString(32) + ':'; + return (s.memoizedState = o); + }, + unstable_isNewReconciler: !1 + }, + ms = { + readContext: eh, + useCallback: si, + useContext: eh, + useEffect: $h, + useImperativeHandle: qi, + useInsertionEffect: ni, + useLayoutEffect: oi, + useMemo: ti, + useReducer: Wh, + useRef: ji, + useState: function () { + return Wh(Vh); + }, + useDebugValue: ri, + useDeferredValue: function (s) { + return ui(Uh(), as.memoizedState, s); + }, + useTransition: function () { + return [Wh(Vh)[0], Uh().memoizedState]; + }, + useMutableSource: Yh, + useSyncExternalStore: Zh, + useId: wi, + unstable_isNewReconciler: !1 + }, + gs = { + readContext: eh, + useCallback: si, + useContext: eh, + useEffect: $h, + useImperativeHandle: qi, + useInsertionEffect: ni, + useLayoutEffect: oi, + useMemo: ti, + useReducer: Xh, + useRef: ji, + useState: function () { + return Xh(Vh); + }, + useDebugValue: ri, + useDeferredValue: function (s) { + var o = Uh(); + return null === as ? (o.memoizedState = s) : ui(o, as.memoizedState, s); + }, + useTransition: function () { + return [Xh(Vh)[0], Uh().memoizedState]; + }, + useMutableSource: Yh, + useSyncExternalStore: Zh, + useId: wi, + unstable_isNewReconciler: !1 + }; + function Ci(s, o) { + if (s && s.defaultProps) { + for (var i in ((o = xe({}, o)), (s = s.defaultProps))) + void 0 === o[i] && (o[i] = s[i]); + return o; + } + return o; + } + function Di(s, o, i, u) { + (i = null == (i = i(u, (o = s.memoizedState))) ? o : xe({}, o, i)), + (s.memoizedState = i), + 0 === s.lanes && (s.updateQueue.baseState = i); + } + var ys = { + isMounted: function (s) { + return !!(s = s._reactInternals) && Vb(s) === s; + }, + enqueueSetState: function (s, o, i) { + s = s._reactInternals; + var u = R(), + _ = yi(s), + w = mh(u, _); + (w.payload = o), + null != i && (w.callback = i), + null !== (o = nh(s, w, _)) && (gi(o, s, _, u), oh(o, s, _)); + }, + enqueueReplaceState: function (s, o, i) { + s = s._reactInternals; + var u = R(), + _ = yi(s), + w = mh(u, _); + (w.tag = 1), + (w.payload = o), + null != i && (w.callback = i), + null !== (o = nh(s, w, _)) && (gi(o, s, _, u), oh(o, s, _)); + }, + enqueueForceUpdate: function (s, o) { + s = s._reactInternals; + var i = R(), + u = yi(s), + _ = mh(i, u); + (_.tag = 2), + null != o && (_.callback = o), + null !== (o = nh(s, _, u)) && (gi(o, s, u, i), oh(o, s, u)); + } + }; + function Fi(s, o, i, u, _, w, x) { + return 'function' == typeof (s = s.stateNode).shouldComponentUpdate + ? s.shouldComponentUpdate(u, w, x) + : !o.prototype || !o.prototype.isPureReactComponent || !Ie(i, u) || !Ie(_, w); + } + function Gi(s, o, i) { + var u = !1, + _ = En, + w = o.contextType; + return ( + 'object' == typeof w && null !== w + ? (w = eh(w)) + : ((_ = Zf(o) ? xn : wn.current), + (w = (u = null != (u = o.contextTypes)) ? Yf(s, _) : En)), + (o = new o(i, w)), + (s.memoizedState = null !== o.state && void 0 !== o.state ? o.state : null), + (o.updater = ys), + (s.stateNode = o), + (o._reactInternals = s), + u && + (((s = s.stateNode).__reactInternalMemoizedUnmaskedChildContext = _), + (s.__reactInternalMemoizedMaskedChildContext = w)), + o + ); + } + function Hi(s, o, i, u) { + (s = o.state), + 'function' == typeof o.componentWillReceiveProps && o.componentWillReceiveProps(i, u), + 'function' == typeof o.UNSAFE_componentWillReceiveProps && + o.UNSAFE_componentWillReceiveProps(i, u), + o.state !== s && ys.enqueueReplaceState(o, o.state, null); + } + function Ii(s, o, i, u) { + var _ = s.stateNode; + (_.props = i), (_.state = s.memoizedState), (_.refs = {}), kh(s); + var w = o.contextType; + 'object' == typeof w && null !== w + ? (_.context = eh(w)) + : ((w = Zf(o) ? xn : wn.current), (_.context = Yf(s, w))), + (_.state = s.memoizedState), + 'function' == typeof (w = o.getDerivedStateFromProps) && + (Di(s, o, w, i), (_.state = s.memoizedState)), + 'function' == typeof o.getDerivedStateFromProps || + 'function' == typeof _.getSnapshotBeforeUpdate || + ('function' != typeof _.UNSAFE_componentWillMount && + 'function' != typeof _.componentWillMount) || + ((o = _.state), + 'function' == typeof _.componentWillMount && _.componentWillMount(), + 'function' == typeof _.UNSAFE_componentWillMount && _.UNSAFE_componentWillMount(), + o !== _.state && ys.enqueueReplaceState(_, _.state, null), + qh(s, i, _, u), + (_.state = s.memoizedState)), + 'function' == typeof _.componentDidMount && (s.flags |= 4194308); + } + function Ji(s, o) { + try { + var i = '', + u = o; + do { + (i += Pa(u)), (u = u.return); + } while (u); + var _ = i; + } catch (s) { + _ = '\nError generating stack: ' + s.message + '\n' + s.stack; + } + return { value: s, source: o, stack: _, digest: null }; + } + function Ki(s, o, i) { + return { + value: s, + source: null, + stack: null != i ? i : null, + digest: null != o ? o : null + }; + } + function Li(s, o) { + try { + console.error(o.value); + } catch (s) { + setTimeout(function () { + throw s; + }); + } + } + var vs = 'function' == typeof WeakMap ? WeakMap : Map; + function Ni(s, o, i) { + ((i = mh(-1, i)).tag = 3), (i.payload = { element: null }); + var u = o.value; + return ( + (i.callback = function () { + eo || ((eo = !0), (to = u)), Li(0, o); + }), + i + ); + } + function Qi(s, o, i) { + (i = mh(-1, i)).tag = 3; + var u = s.type.getDerivedStateFromError; + if ('function' == typeof u) { + var _ = o.value; + (i.payload = function () { + return u(_); + }), + (i.callback = function () { + Li(0, o); + }); + } + var w = s.stateNode; + return ( + null !== w && + 'function' == typeof w.componentDidCatch && + (i.callback = function () { + Li(0, o), + 'function' != typeof u && (null === ro ? (ro = new Set([this])) : ro.add(this)); + var s = o.stack; + this.componentDidCatch(o.value, { componentStack: null !== s ? s : '' }); + }), + i + ); + } + function Si(s, o, i) { + var u = s.pingCache; + if (null === u) { + u = s.pingCache = new vs(); + var _ = new Set(); + u.set(o, _); + } else void 0 === (_ = u.get(o)) && ((_ = new Set()), u.set(o, _)); + _.has(i) || (_.add(i), (s = Ti.bind(null, s, o, i)), o.then(s, s)); + } + function Ui(s) { + do { + var o; + if ( + ((o = 13 === s.tag) && + (o = null === (o = s.memoizedState) || null !== o.dehydrated), + o) + ) + return s; + s = s.return; + } while (null !== s); + return null; + } + function Vi(s, o, i, u, _) { + return 1 & s.mode + ? ((s.flags |= 65536), (s.lanes = _), s) + : (s === o + ? (s.flags |= 65536) + : ((s.flags |= 128), + (i.flags |= 131072), + (i.flags &= -52805), + 1 === i.tag && + (null === i.alternate + ? (i.tag = 17) + : (((o = mh(-1, 1)).tag = 2), nh(i, o, 1))), + (i.lanes |= 1)), + s); + } + var bs = z.ReactCurrentOwner, + _s = !1; + function Xi(s, o, i, u) { + o.child = null === s ? Un(o, null, i, u) : Vn(o, s.child, i, u); + } + function Yi(s, o, i, u, _) { + i = i.render; + var w = o.ref; + return ( + ch(o, _), + (u = Nh(s, o, i, u, w, _)), + (i = Sh()), + null === s || _s + ? (Fn && i && vg(o), (o.flags |= 1), Xi(s, o, u, _), o.child) + : ((o.updateQueue = s.updateQueue), + (o.flags &= -2053), + (s.lanes &= ~_), + Zi(s, o, _)) + ); + } + function $i(s, o, i, u, _) { + if (null === s) { + var w = i.type; + return 'function' != typeof w || + aj(w) || + void 0 !== w.defaultProps || + null !== i.compare || + void 0 !== i.defaultProps + ? (((s = Rg(i.type, null, u, o, o.mode, _)).ref = o.ref), + (s.return = o), + (o.child = s)) + : ((o.tag = 15), (o.type = w), bj(s, o, w, u, _)); + } + if (((w = s.child), !(s.lanes & _))) { + var x = w.memoizedProps; + if ((i = null !== (i = i.compare) ? i : Ie)(x, u) && s.ref === o.ref) + return Zi(s, o, _); + } + return (o.flags |= 1), ((s = Pg(w, u)).ref = o.ref), (s.return = o), (o.child = s); + } + function bj(s, o, i, u, _) { + if (null !== s) { + var w = s.memoizedProps; + if (Ie(w, u) && s.ref === o.ref) { + if (((_s = !1), (o.pendingProps = u = w), !(s.lanes & _))) + return (o.lanes = s.lanes), Zi(s, o, _); + 131072 & s.flags && (_s = !0); + } + } + return cj(s, o, i, u, _); + } + function dj(s, o, i) { + var u = o.pendingProps, + _ = u.children, + w = null !== s ? s.memoizedState : null; + if ('hidden' === u.mode) + if (1 & o.mode) { + if (!(1073741824 & i)) + return ( + (s = null !== w ? w.baseLanes | i : i), + (o.lanes = o.childLanes = 1073741824), + (o.memoizedState = { baseLanes: s, cachePool: null, transitions: null }), + (o.updateQueue = null), + G(Us, Vs), + (Vs |= s), + null + ); + (o.memoizedState = { baseLanes: 0, cachePool: null, transitions: null }), + (u = null !== w ? w.baseLanes : i), + G(Us, Vs), + (Vs |= u); + } else + (o.memoizedState = { baseLanes: 0, cachePool: null, transitions: null }), + G(Us, Vs), + (Vs |= i); + else + null !== w ? ((u = w.baseLanes | i), (o.memoizedState = null)) : (u = i), + G(Us, Vs), + (Vs |= u); + return Xi(s, o, _, i), o.child; + } + function gj(s, o) { + var i = o.ref; + ((null === s && null !== i) || (null !== s && s.ref !== i)) && + ((o.flags |= 512), (o.flags |= 2097152)); + } + function cj(s, o, i, u, _) { + var w = Zf(i) ? xn : wn.current; + return ( + (w = Yf(o, w)), + ch(o, _), + (i = Nh(s, o, i, u, w, _)), + (u = Sh()), + null === s || _s + ? (Fn && u && vg(o), (o.flags |= 1), Xi(s, o, i, _), o.child) + : ((o.updateQueue = s.updateQueue), + (o.flags &= -2053), + (s.lanes &= ~_), + Zi(s, o, _)) + ); + } + function hj(s, o, i, u, _) { + if (Zf(i)) { + var w = !0; + cg(o); + } else w = !1; + if ((ch(o, _), null === o.stateNode)) ij(s, o), Gi(o, i, u), Ii(o, i, u, _), (u = !0); + else if (null === s) { + var x = o.stateNode, + C = o.memoizedProps; + x.props = C; + var j = x.context, + L = i.contextType; + 'object' == typeof L && null !== L + ? (L = eh(L)) + : (L = Yf(o, (L = Zf(i) ? xn : wn.current))); + var B = i.getDerivedStateFromProps, + $ = 'function' == typeof B || 'function' == typeof x.getSnapshotBeforeUpdate; + $ || + ('function' != typeof x.UNSAFE_componentWillReceiveProps && + 'function' != typeof x.componentWillReceiveProps) || + ((C !== u || j !== L) && Hi(o, x, u, L)), + (Gn = !1); + var V = o.memoizedState; + (x.state = V), + qh(o, u, x, _), + (j = o.memoizedState), + C !== u || V !== j || Sn.current || Gn + ? ('function' == typeof B && (Di(o, i, B, u), (j = o.memoizedState)), + (C = Gn || Fi(o, i, C, u, V, j, L)) + ? ($ || + ('function' != typeof x.UNSAFE_componentWillMount && + 'function' != typeof x.componentWillMount) || + ('function' == typeof x.componentWillMount && x.componentWillMount(), + 'function' == typeof x.UNSAFE_componentWillMount && + x.UNSAFE_componentWillMount()), + 'function' == typeof x.componentDidMount && (o.flags |= 4194308)) + : ('function' == typeof x.componentDidMount && (o.flags |= 4194308), + (o.memoizedProps = u), + (o.memoizedState = j)), + (x.props = u), + (x.state = j), + (x.context = L), + (u = C)) + : ('function' == typeof x.componentDidMount && (o.flags |= 4194308), (u = !1)); + } else { + (x = o.stateNode), + lh(s, o), + (C = o.memoizedProps), + (L = o.type === o.elementType ? C : Ci(o.type, C)), + (x.props = L), + ($ = o.pendingProps), + (V = x.context), + 'object' == typeof (j = i.contextType) && null !== j + ? (j = eh(j)) + : (j = Yf(o, (j = Zf(i) ? xn : wn.current))); + var U = i.getDerivedStateFromProps; + (B = 'function' == typeof U || 'function' == typeof x.getSnapshotBeforeUpdate) || + ('function' != typeof x.UNSAFE_componentWillReceiveProps && + 'function' != typeof x.componentWillReceiveProps) || + ((C !== $ || V !== j) && Hi(o, x, u, j)), + (Gn = !1), + (V = o.memoizedState), + (x.state = V), + qh(o, u, x, _); + var z = o.memoizedState; + C !== $ || V !== z || Sn.current || Gn + ? ('function' == typeof U && (Di(o, i, U, u), (z = o.memoizedState)), + (L = Gn || Fi(o, i, L, u, V, z, j) || !1) + ? (B || + ('function' != typeof x.UNSAFE_componentWillUpdate && + 'function' != typeof x.componentWillUpdate) || + ('function' == typeof x.componentWillUpdate && + x.componentWillUpdate(u, z, j), + 'function' == typeof x.UNSAFE_componentWillUpdate && + x.UNSAFE_componentWillUpdate(u, z, j)), + 'function' == typeof x.componentDidUpdate && (o.flags |= 4), + 'function' == typeof x.getSnapshotBeforeUpdate && (o.flags |= 1024)) + : ('function' != typeof x.componentDidUpdate || + (C === s.memoizedProps && V === s.memoizedState) || + (o.flags |= 4), + 'function' != typeof x.getSnapshotBeforeUpdate || + (C === s.memoizedProps && V === s.memoizedState) || + (o.flags |= 1024), + (o.memoizedProps = u), + (o.memoizedState = z)), + (x.props = u), + (x.state = z), + (x.context = j), + (u = L)) + : ('function' != typeof x.componentDidUpdate || + (C === s.memoizedProps && V === s.memoizedState) || + (o.flags |= 4), + 'function' != typeof x.getSnapshotBeforeUpdate || + (C === s.memoizedProps && V === s.memoizedState) || + (o.flags |= 1024), + (u = !1)); + } + return jj(s, o, i, u, w, _); + } + function jj(s, o, i, u, _, w) { + gj(s, o); + var x = !!(128 & o.flags); + if (!u && !x) return _ && dg(o, i, !1), Zi(s, o, w); + (u = o.stateNode), (bs.current = o); + var C = x && 'function' != typeof i.getDerivedStateFromError ? null : u.render(); + return ( + (o.flags |= 1), + null !== s && x + ? ((o.child = Vn(o, s.child, null, w)), (o.child = Vn(o, null, C, w))) + : Xi(s, o, C, w), + (o.memoizedState = u.state), + _ && dg(o, i, !0), + o.child + ); + } + function kj(s) { + var o = s.stateNode; + o.pendingContext + ? ag(0, o.pendingContext, o.pendingContext !== o.context) + : o.context && ag(0, o.context, !1), + yh(s, o.containerInfo); + } + function lj(s, o, i, u, _) { + return Ig(), Jg(_), (o.flags |= 256), Xi(s, o, i, u), o.child; + } + var Es, + ws, + Ss, + xs, + ks = { dehydrated: null, treeContext: null, retryLane: 0 }; + function nj(s) { + return { baseLanes: s, cachePool: null, transitions: null }; + } + function oj(s, o, i) { + var u, + _ = o.pendingProps, + w = es.current, + x = !1, + C = !!(128 & o.flags); + if ( + ((u = C) || (u = (null === s || null !== s.memoizedState) && !!(2 & w)), + u + ? ((x = !0), (o.flags &= -129)) + : (null !== s && null === s.memoizedState) || (w |= 1), + G(es, 1 & w), + null === s) + ) + return ( + Eg(o), + null !== (s = o.memoizedState) && null !== (s = s.dehydrated) + ? (1 & o.mode + ? '$!' === s.data + ? (o.lanes = 8) + : (o.lanes = 1073741824) + : (o.lanes = 1), + null) + : ((C = _.children), + (s = _.fallback), + x + ? ((_ = o.mode), + (x = o.child), + (C = { mode: 'hidden', children: C }), + 1 & _ || null === x + ? (x = pj(C, _, 0, null)) + : ((x.childLanes = 0), (x.pendingProps = C)), + (s = Tg(s, _, i, null)), + (x.return = o), + (s.return = o), + (x.sibling = s), + (o.child = x), + (o.child.memoizedState = nj(i)), + (o.memoizedState = ks), + s) + : qj(o, C)) + ); + if (null !== (w = s.memoizedState) && null !== (u = w.dehydrated)) + return (function rj(s, o, i, u, _, w, x) { + if (i) + return 256 & o.flags + ? ((o.flags &= -257), sj(s, o, x, (u = Ki(Error(p(422)))))) + : null !== o.memoizedState + ? ((o.child = s.child), (o.flags |= 128), null) + : ((w = u.fallback), + (_ = o.mode), + (u = pj({ mode: 'visible', children: u.children }, _, 0, null)), + ((w = Tg(w, _, x, null)).flags |= 2), + (u.return = o), + (w.return = o), + (u.sibling = w), + (o.child = u), + 1 & o.mode && Vn(o, s.child, null, x), + (o.child.memoizedState = nj(x)), + (o.memoizedState = ks), + w); + if (!(1 & o.mode)) return sj(s, o, x, null); + if ('$!' === _.data) { + if ((u = _.nextSibling && _.nextSibling.dataset)) var C = u.dgst; + return (u = C), sj(s, o, x, (u = Ki((w = Error(p(419))), u, void 0))); + } + if (((C = !!(x & s.childLanes)), _s || C)) { + if (null !== (u = Fs)) { + switch (x & -x) { + case 4: + _ = 2; + break; + case 16: + _ = 8; + break; + case 64: + case 128: + case 256: + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + case 4194304: + case 8388608: + case 16777216: + case 33554432: + case 67108864: + _ = 32; + break; + case 536870912: + _ = 268435456; + break; + default: + _ = 0; + } + 0 !== (_ = _ & (u.suspendedLanes | x) ? 0 : _) && + _ !== w.retryLane && + ((w.retryLane = _), ih(s, _), gi(u, s, _, -1)); + } + return tj(), sj(s, o, x, (u = Ki(Error(p(421))))); + } + return '$?' === _.data + ? ((o.flags |= 128), + (o.child = s.child), + (o = uj.bind(null, s)), + (_._reactRetry = o), + null) + : ((s = w.treeContext), + (Bn = Lf(_.nextSibling)), + (Ln = o), + (Fn = !0), + (qn = null), + null !== s && + ((Mn[Tn++] = Rn), + (Mn[Tn++] = Dn), + (Mn[Tn++] = Nn), + (Rn = s.id), + (Dn = s.overflow), + (Nn = o)), + (o = qj(o, u.children)), + (o.flags |= 4096), + o); + })(s, o, C, _, u, w, i); + if (x) { + (x = _.fallback), (C = o.mode), (u = (w = s.child).sibling); + var j = { mode: 'hidden', children: _.children }; + return ( + 1 & C || o.child === w + ? ((_ = Pg(w, j)).subtreeFlags = 14680064 & w.subtreeFlags) + : (((_ = o.child).childLanes = 0), (_.pendingProps = j), (o.deletions = null)), + null !== u ? (x = Pg(u, x)) : ((x = Tg(x, C, i, null)).flags |= 2), + (x.return = o), + (_.return = o), + (_.sibling = x), + (o.child = _), + (_ = x), + (x = o.child), + (C = + null === (C = s.child.memoizedState) + ? nj(i) + : { baseLanes: C.baseLanes | i, cachePool: null, transitions: C.transitions }), + (x.memoizedState = C), + (x.childLanes = s.childLanes & ~i), + (o.memoizedState = ks), + _ + ); + } + return ( + (s = (x = s.child).sibling), + (_ = Pg(x, { mode: 'visible', children: _.children })), + !(1 & o.mode) && (_.lanes = i), + (_.return = o), + (_.sibling = null), + null !== s && + (null === (i = o.deletions) ? ((o.deletions = [s]), (o.flags |= 16)) : i.push(s)), + (o.child = _), + (o.memoizedState = null), + _ + ); + } + function qj(s, o) { + return ( + ((o = pj({ mode: 'visible', children: o }, s.mode, 0, null)).return = s), + (s.child = o) + ); + } + function sj(s, o, i, u) { + return ( + null !== u && Jg(u), + Vn(o, s.child, null, i), + ((s = qj(o, o.pendingProps.children)).flags |= 2), + (o.memoizedState = null), + s + ); + } + function vj(s, o, i) { + s.lanes |= o; + var u = s.alternate; + null !== u && (u.lanes |= o), bh(s.return, o, i); + } + function wj(s, o, i, u, _) { + var w = s.memoizedState; + null === w + ? (s.memoizedState = { + isBackwards: o, + rendering: null, + renderingStartTime: 0, + last: u, + tail: i, + tailMode: _ + }) + : ((w.isBackwards = o), + (w.rendering = null), + (w.renderingStartTime = 0), + (w.last = u), + (w.tail = i), + (w.tailMode = _)); + } + function xj(s, o, i) { + var u = o.pendingProps, + _ = u.revealOrder, + w = u.tail; + if ((Xi(s, o, u.children, i), 2 & (u = es.current))) + (u = (1 & u) | 2), (o.flags |= 128); + else { + if (null !== s && 128 & s.flags) + e: for (s = o.child; null !== s; ) { + if (13 === s.tag) null !== s.memoizedState && vj(s, i, o); + else if (19 === s.tag) vj(s, i, o); + else if (null !== s.child) { + (s.child.return = s), (s = s.child); + continue; + } + if (s === o) break e; + for (; null === s.sibling; ) { + if (null === s.return || s.return === o) break e; + s = s.return; + } + (s.sibling.return = s.return), (s = s.sibling); + } + u &= 1; + } + if ((G(es, u), 1 & o.mode)) + switch (_) { + case 'forwards': + for (i = o.child, _ = null; null !== i; ) + null !== (s = i.alternate) && null === Ch(s) && (_ = i), (i = i.sibling); + null === (i = _) + ? ((_ = o.child), (o.child = null)) + : ((_ = i.sibling), (i.sibling = null)), + wj(o, !1, _, i, w); + break; + case 'backwards': + for (i = null, _ = o.child, o.child = null; null !== _; ) { + if (null !== (s = _.alternate) && null === Ch(s)) { + o.child = _; + break; + } + (s = _.sibling), (_.sibling = i), (i = _), (_ = s); + } + wj(o, !0, i, null, w); + break; + case 'together': + wj(o, !1, null, null, void 0); + break; + default: + o.memoizedState = null; + } + else o.memoizedState = null; + return o.child; + } + function ij(s, o) { + !(1 & o.mode) && + null !== s && + ((s.alternate = null), (o.alternate = null), (o.flags |= 2)); + } + function Zi(s, o, i) { + if ( + (null !== s && (o.dependencies = s.dependencies), + (Ks |= o.lanes), + !(i & o.childLanes)) + ) + return null; + if (null !== s && o.child !== s.child) throw Error(p(153)); + if (null !== o.child) { + for ( + i = Pg((s = o.child), s.pendingProps), o.child = i, i.return = o; + null !== s.sibling; + + ) + (s = s.sibling), ((i = i.sibling = Pg(s, s.pendingProps)).return = o); + i.sibling = null; + } + return o.child; + } + function Dj(s, o) { + if (!Fn) + switch (s.tailMode) { + case 'hidden': + o = s.tail; + for (var i = null; null !== o; ) null !== o.alternate && (i = o), (o = o.sibling); + null === i ? (s.tail = null) : (i.sibling = null); + break; + case 'collapsed': + i = s.tail; + for (var u = null; null !== i; ) null !== i.alternate && (u = i), (i = i.sibling); + null === u + ? o || null === s.tail + ? (s.tail = null) + : (s.tail.sibling = null) + : (u.sibling = null); + } + } + function S(s) { + var o = null !== s.alternate && s.alternate.child === s.child, + i = 0, + u = 0; + if (o) + for (var _ = s.child; null !== _; ) + (i |= _.lanes | _.childLanes), + (u |= 14680064 & _.subtreeFlags), + (u |= 14680064 & _.flags), + (_.return = s), + (_ = _.sibling); + else + for (_ = s.child; null !== _; ) + (i |= _.lanes | _.childLanes), + (u |= _.subtreeFlags), + (u |= _.flags), + (_.return = s), + (_ = _.sibling); + return (s.subtreeFlags |= u), (s.childLanes = i), o; + } + function Ej(s, o, i) { + var u = o.pendingProps; + switch ((wg(o), o.tag)) { + case 2: + case 16: + case 15: + case 0: + case 11: + case 7: + case 8: + case 12: + case 9: + case 14: + return S(o), null; + case 1: + case 17: + return Zf(o.type) && $f(), S(o), null; + case 3: + return ( + (u = o.stateNode), + zh(), + E(Sn), + E(wn), + Eh(), + u.pendingContext && ((u.context = u.pendingContext), (u.pendingContext = null)), + (null !== s && null !== s.child) || + (Gg(o) + ? (o.flags |= 4) + : null === s || + (s.memoizedState.isDehydrated && !(256 & o.flags)) || + ((o.flags |= 1024), null !== qn && (Fj(qn), (qn = null)))), + ws(s, o), + S(o), + null + ); + case 5: + Bh(o); + var _ = xh(Qn.current); + if (((i = o.type), null !== s && null != o.stateNode)) + Ss(s, o, i, u, _), s.ref !== o.ref && ((o.flags |= 512), (o.flags |= 2097152)); + else { + if (!u) { + if (null === o.stateNode) throw Error(p(166)); + return S(o), null; + } + if (((s = xh(Xn.current)), Gg(o))) { + (u = o.stateNode), (i = o.type); + var w = o.memoizedProps; + switch (((u[dn] = o), (u[fn] = w), (s = !!(1 & o.mode)), i)) { + case 'dialog': + D('cancel', u), D('close', u); + break; + case 'iframe': + case 'object': + case 'embed': + D('load', u); + break; + case 'video': + case 'audio': + for (_ = 0; _ < en.length; _++) D(en[_], u); + break; + case 'source': + D('error', u); + break; + case 'img': + case 'image': + case 'link': + D('error', u), D('load', u); + break; + case 'details': + D('toggle', u); + break; + case 'input': + Za(u, w), D('invalid', u); + break; + case 'select': + (u._wrapperState = { wasMultiple: !!w.multiple }), D('invalid', u); + break; + case 'textarea': + hb(u, w), D('invalid', u); + } + for (var C in (ub(i, w), (_ = null), w)) + if (w.hasOwnProperty(C)) { + var j = w[C]; + 'children' === C + ? 'string' == typeof j + ? u.textContent !== j && + (!0 !== w.suppressHydrationWarning && Af(u.textContent, j, s), + (_ = ['children', j])) + : 'number' == typeof j && + u.textContent !== '' + j && + (!0 !== w.suppressHydrationWarning && Af(u.textContent, j, s), + (_ = ['children', '' + j])) + : x.hasOwnProperty(C) && null != j && 'onScroll' === C && D('scroll', u); + } + switch (i) { + case 'input': + Va(u), db(u, w, !0); + break; + case 'textarea': + Va(u), jb(u); + break; + case 'select': + case 'option': + break; + default: + 'function' == typeof w.onClick && (u.onclick = Bf); + } + (u = _), (o.updateQueue = u), null !== u && (o.flags |= 4); + } else { + (C = 9 === _.nodeType ? _ : _.ownerDocument), + 'http://www.w3.org/1999/xhtml' === s && (s = kb(i)), + 'http://www.w3.org/1999/xhtml' === s + ? 'script' === i + ? (((s = C.createElement('div')).innerHTML = ''), + (s = s.removeChild(s.firstChild))) + : 'string' == typeof u.is + ? (s = C.createElement(i, { is: u.is })) + : ((s = C.createElement(i)), + 'select' === i && + ((C = s), + u.multiple ? (C.multiple = !0) : u.size && (C.size = u.size))) + : (s = C.createElementNS(s, i)), + (s[dn] = o), + (s[fn] = u), + Es(s, o, !1, !1), + (o.stateNode = s); + e: { + switch (((C = vb(i, u)), i)) { + case 'dialog': + D('cancel', s), D('close', s), (_ = u); + break; + case 'iframe': + case 'object': + case 'embed': + D('load', s), (_ = u); + break; + case 'video': + case 'audio': + for (_ = 0; _ < en.length; _++) D(en[_], s); + _ = u; + break; + case 'source': + D('error', s), (_ = u); + break; + case 'img': + case 'image': + case 'link': + D('error', s), D('load', s), (_ = u); + break; + case 'details': + D('toggle', s), (_ = u); + break; + case 'input': + Za(s, u), (_ = Ya(s, u)), D('invalid', s); + break; + case 'option': + default: + _ = u; + break; + case 'select': + (s._wrapperState = { wasMultiple: !!u.multiple }), + (_ = xe({}, u, { value: void 0 })), + D('invalid', s); + break; + case 'textarea': + hb(s, u), (_ = gb(s, u)), D('invalid', s); + } + for (w in (ub(i, _), (j = _))) + if (j.hasOwnProperty(w)) { + var L = j[w]; + 'style' === w + ? sb(s, L) + : 'dangerouslySetInnerHTML' === w + ? null != (L = L ? L.__html : void 0) && $e(s, L) + : 'children' === w + ? 'string' == typeof L + ? ('textarea' !== i || '' !== L) && ob(s, L) + : 'number' == typeof L && ob(s, '' + L) + : 'suppressContentEditableWarning' !== w && + 'suppressHydrationWarning' !== w && + 'autoFocus' !== w && + (x.hasOwnProperty(w) + ? null != L && 'onScroll' === w && D('scroll', s) + : null != L && ta(s, w, L, C)); + } + switch (i) { + case 'input': + Va(s), db(s, u, !1); + break; + case 'textarea': + Va(s), jb(s); + break; + case 'option': + null != u.value && s.setAttribute('value', '' + Sa(u.value)); + break; + case 'select': + (s.multiple = !!u.multiple), + null != (w = u.value) + ? fb(s, !!u.multiple, w, !1) + : null != u.defaultValue && fb(s, !!u.multiple, u.defaultValue, !0); + break; + default: + 'function' == typeof _.onClick && (s.onclick = Bf); + } + switch (i) { + case 'button': + case 'input': + case 'select': + case 'textarea': + u = !!u.autoFocus; + break e; + case 'img': + u = !0; + break e; + default: + u = !1; + } + } + u && (o.flags |= 4); + } + null !== o.ref && ((o.flags |= 512), (o.flags |= 2097152)); + } + return S(o), null; + case 6: + if (s && null != o.stateNode) xs(s, o, s.memoizedProps, u); + else { + if ('string' != typeof u && null === o.stateNode) throw Error(p(166)); + if (((i = xh(Qn.current)), xh(Xn.current), Gg(o))) { + if ( + ((u = o.stateNode), + (i = o.memoizedProps), + (u[dn] = o), + (w = u.nodeValue !== i) && null !== (s = Ln)) + ) + switch (s.tag) { + case 3: + Af(u.nodeValue, i, !!(1 & s.mode)); + break; + case 5: + !0 !== s.memoizedProps.suppressHydrationWarning && + Af(u.nodeValue, i, !!(1 & s.mode)); + } + w && (o.flags |= 4); + } else + ((u = (9 === i.nodeType ? i : i.ownerDocument).createTextNode(u))[dn] = o), + (o.stateNode = u); + } + return S(o), null; + case 13: + if ( + (E(es), + (u = o.memoizedState), + null === s || (null !== s.memoizedState && null !== s.memoizedState.dehydrated)) + ) { + if (Fn && null !== Bn && 1 & o.mode && !(128 & o.flags)) + Hg(), Ig(), (o.flags |= 98560), (w = !1); + else if (((w = Gg(o)), null !== u && null !== u.dehydrated)) { + if (null === s) { + if (!w) throw Error(p(318)); + if (!(w = null !== (w = o.memoizedState) ? w.dehydrated : null)) + throw Error(p(317)); + w[dn] = o; + } else Ig(), !(128 & o.flags) && (o.memoizedState = null), (o.flags |= 4); + S(o), (w = !1); + } else null !== qn && (Fj(qn), (qn = null)), (w = !0); + if (!w) return 65536 & o.flags ? o : null; + } + return 128 & o.flags + ? ((o.lanes = i), o) + : ((u = null !== u) !== (null !== s && null !== s.memoizedState) && + u && + ((o.child.flags |= 8192), + 1 & o.mode && (null === s || 1 & es.current ? 0 === zs && (zs = 3) : tj())), + null !== o.updateQueue && (o.flags |= 4), + S(o), + null); + case 4: + return zh(), ws(s, o), null === s && sf(o.stateNode.containerInfo), S(o), null; + case 10: + return ah(o.type._context), S(o), null; + case 19: + if ((E(es), null === (w = o.memoizedState))) return S(o), null; + if (((u = !!(128 & o.flags)), null === (C = w.rendering))) + if (u) Dj(w, !1); + else { + if (0 !== zs || (null !== s && 128 & s.flags)) + for (s = o.child; null !== s; ) { + if (null !== (C = Ch(s))) { + for ( + o.flags |= 128, + Dj(w, !1), + null !== (u = C.updateQueue) && ((o.updateQueue = u), (o.flags |= 4)), + o.subtreeFlags = 0, + u = i, + i = o.child; + null !== i; + + ) + (s = u), + ((w = i).flags &= 14680066), + null === (C = w.alternate) + ? ((w.childLanes = 0), + (w.lanes = s), + (w.child = null), + (w.subtreeFlags = 0), + (w.memoizedProps = null), + (w.memoizedState = null), + (w.updateQueue = null), + (w.dependencies = null), + (w.stateNode = null)) + : ((w.childLanes = C.childLanes), + (w.lanes = C.lanes), + (w.child = C.child), + (w.subtreeFlags = 0), + (w.deletions = null), + (w.memoizedProps = C.memoizedProps), + (w.memoizedState = C.memoizedState), + (w.updateQueue = C.updateQueue), + (w.type = C.type), + (s = C.dependencies), + (w.dependencies = + null === s + ? null + : { lanes: s.lanes, firstContext: s.firstContext })), + (i = i.sibling); + return G(es, (1 & es.current) | 2), o.child; + } + s = s.sibling; + } + null !== w.tail && + dt() > Zs && + ((o.flags |= 128), (u = !0), Dj(w, !1), (o.lanes = 4194304)); + } + else { + if (!u) + if (null !== (s = Ch(C))) { + if ( + ((o.flags |= 128), + (u = !0), + null !== (i = s.updateQueue) && ((o.updateQueue = i), (o.flags |= 4)), + Dj(w, !0), + null === w.tail && 'hidden' === w.tailMode && !C.alternate && !Fn) + ) + return S(o), null; + } else + 2 * dt() - w.renderingStartTime > Zs && + 1073741824 !== i && + ((o.flags |= 128), (u = !0), Dj(w, !1), (o.lanes = 4194304)); + w.isBackwards + ? ((C.sibling = o.child), (o.child = C)) + : (null !== (i = w.last) ? (i.sibling = C) : (o.child = C), (w.last = C)); + } + return null !== w.tail + ? ((o = w.tail), + (w.rendering = o), + (w.tail = o.sibling), + (w.renderingStartTime = dt()), + (o.sibling = null), + (i = es.current), + G(es, u ? (1 & i) | 2 : 1 & i), + o) + : (S(o), null); + case 22: + case 23: + return ( + Hj(), + (u = null !== o.memoizedState), + null !== s && (null !== s.memoizedState) !== u && (o.flags |= 8192), + u && 1 & o.mode + ? !!(1073741824 & Vs) && (S(o), 6 & o.subtreeFlags && (o.flags |= 8192)) + : S(o), + null + ); + case 24: + case 25: + return null; + } + throw Error(p(156, o.tag)); + } + function Ij(s, o) { + switch ((wg(o), o.tag)) { + case 1: + return ( + Zf(o.type) && $f(), + 65536 & (s = o.flags) ? ((o.flags = (-65537 & s) | 128), o) : null + ); + case 3: + return ( + zh(), + E(Sn), + E(wn), + Eh(), + 65536 & (s = o.flags) && !(128 & s) ? ((o.flags = (-65537 & s) | 128), o) : null + ); + case 5: + return Bh(o), null; + case 13: + if ((E(es), null !== (s = o.memoizedState) && null !== s.dehydrated)) { + if (null === o.alternate) throw Error(p(340)); + Ig(); + } + return 65536 & (s = o.flags) ? ((o.flags = (-65537 & s) | 128), o) : null; + case 19: + return E(es), null; + case 4: + return zh(), null; + case 10: + return ah(o.type._context), null; + case 22: + case 23: + return Hj(), null; + default: + return null; + } + } + (Es = function (s, o) { + for (var i = o.child; null !== i; ) { + if (5 === i.tag || 6 === i.tag) s.appendChild(i.stateNode); + else if (4 !== i.tag && null !== i.child) { + (i.child.return = i), (i = i.child); + continue; + } + if (i === o) break; + for (; null === i.sibling; ) { + if (null === i.return || i.return === o) return; + i = i.return; + } + (i.sibling.return = i.return), (i = i.sibling); + } + }), + (ws = function () {}), + (Ss = function (s, o, i, u) { + var _ = s.memoizedProps; + if (_ !== u) { + (s = o.stateNode), xh(Xn.current); + var w, + C = null; + switch (i) { + case 'input': + (_ = Ya(s, _)), (u = Ya(s, u)), (C = []); + break; + case 'select': + (_ = xe({}, _, { value: void 0 })), + (u = xe({}, u, { value: void 0 })), + (C = []); + break; + case 'textarea': + (_ = gb(s, _)), (u = gb(s, u)), (C = []); + break; + default: + 'function' != typeof _.onClick && + 'function' == typeof u.onClick && + (s.onclick = Bf); + } + for (B in (ub(i, u), (i = null), _)) + if (!u.hasOwnProperty(B) && _.hasOwnProperty(B) && null != _[B]) + if ('style' === B) { + var j = _[B]; + for (w in j) j.hasOwnProperty(w) && (i || (i = {}), (i[w] = '')); + } else + 'dangerouslySetInnerHTML' !== B && + 'children' !== B && + 'suppressContentEditableWarning' !== B && + 'suppressHydrationWarning' !== B && + 'autoFocus' !== B && + (x.hasOwnProperty(B) ? C || (C = []) : (C = C || []).push(B, null)); + for (B in u) { + var L = u[B]; + if ( + ((j = null != _ ? _[B] : void 0), + u.hasOwnProperty(B) && L !== j && (null != L || null != j)) + ) + if ('style' === B) + if (j) { + for (w in j) + !j.hasOwnProperty(w) || + (L && L.hasOwnProperty(w)) || + (i || (i = {}), (i[w] = '')); + for (w in L) + L.hasOwnProperty(w) && j[w] !== L[w] && (i || (i = {}), (i[w] = L[w])); + } else i || (C || (C = []), C.push(B, i)), (i = L); + else + 'dangerouslySetInnerHTML' === B + ? ((L = L ? L.__html : void 0), + (j = j ? j.__html : void 0), + null != L && j !== L && (C = C || []).push(B, L)) + : 'children' === B + ? ('string' != typeof L && 'number' != typeof L) || + (C = C || []).push(B, '' + L) + : 'suppressContentEditableWarning' !== B && + 'suppressHydrationWarning' !== B && + (x.hasOwnProperty(B) + ? (null != L && 'onScroll' === B && D('scroll', s), + C || j === L || (C = [])) + : (C = C || []).push(B, L)); + } + i && (C = C || []).push('style', i); + var B = C; + (o.updateQueue = B) && (o.flags |= 4); + } + }), + (xs = function (s, o, i, u) { + i !== u && (o.flags |= 4); + }); + var Cs = !1, + Os = !1, + As = 'function' == typeof WeakSet ? WeakSet : Set, + js = null; + function Lj(s, o) { + var i = s.ref; + if (null !== i) + if ('function' == typeof i) + try { + i(null); + } catch (i) { + W(s, o, i); + } + else i.current = null; + } + function Mj(s, o, i) { + try { + i(); + } catch (i) { + W(s, o, i); + } + } + var Is = !1; + function Pj(s, o, i) { + var u = o.updateQueue; + if (null !== (u = null !== u ? u.lastEffect : null)) { + var _ = (u = u.next); + do { + if ((_.tag & s) === s) { + var w = _.destroy; + (_.destroy = void 0), void 0 !== w && Mj(o, i, w); + } + _ = _.next; + } while (_ !== u); + } + } + function Qj(s, o) { + if (null !== (o = null !== (o = o.updateQueue) ? o.lastEffect : null)) { + var i = (o = o.next); + do { + if ((i.tag & s) === s) { + var u = i.create; + i.destroy = u(); + } + i = i.next; + } while (i !== o); + } + } + function Rj(s) { + var o = s.ref; + if (null !== o) { + var i = s.stateNode; + s.tag, (s = i), 'function' == typeof o ? o(s) : (o.current = s); + } + } + function Sj(s) { + var o = s.alternate; + null !== o && ((s.alternate = null), Sj(o)), + (s.child = null), + (s.deletions = null), + (s.sibling = null), + 5 === s.tag && + null !== (o = s.stateNode) && + (delete o[dn], delete o[fn], delete o[gn], delete o[yn], delete o[vn]), + (s.stateNode = null), + (s.return = null), + (s.dependencies = null), + (s.memoizedProps = null), + (s.memoizedState = null), + (s.pendingProps = null), + (s.stateNode = null), + (s.updateQueue = null); + } + function Tj(s) { + return 5 === s.tag || 3 === s.tag || 4 === s.tag; + } + function Uj(s) { + e: for (;;) { + for (; null === s.sibling; ) { + if (null === s.return || Tj(s.return)) return null; + s = s.return; + } + for ( + s.sibling.return = s.return, s = s.sibling; + 5 !== s.tag && 6 !== s.tag && 18 !== s.tag; + + ) { + if (2 & s.flags) continue e; + if (null === s.child || 4 === s.tag) continue e; + (s.child.return = s), (s = s.child); + } + if (!(2 & s.flags)) return s.stateNode; + } + } + function Vj(s, o, i) { + var u = s.tag; + if (5 === u || 6 === u) + (s = s.stateNode), + o + ? 8 === i.nodeType + ? i.parentNode.insertBefore(s, o) + : i.insertBefore(s, o) + : (8 === i.nodeType + ? (o = i.parentNode).insertBefore(s, i) + : (o = i).appendChild(s), + null != (i = i._reactRootContainer) || null !== o.onclick || (o.onclick = Bf)); + else if (4 !== u && null !== (s = s.child)) + for (Vj(s, o, i), s = s.sibling; null !== s; ) Vj(s, o, i), (s = s.sibling); + } + function Wj(s, o, i) { + var u = s.tag; + if (5 === u || 6 === u) (s = s.stateNode), o ? i.insertBefore(s, o) : i.appendChild(s); + else if (4 !== u && null !== (s = s.child)) + for (Wj(s, o, i), s = s.sibling; null !== s; ) Wj(s, o, i), (s = s.sibling); + } + var Ps = null, + Ms = !1; + function Yj(s, o, i) { + for (i = i.child; null !== i; ) Zj(s, o, i), (i = i.sibling); + } + function Zj(s, o, i) { + if (wt && 'function' == typeof wt.onCommitFiberUnmount) + try { + wt.onCommitFiberUnmount(Et, i); + } catch (s) {} + switch (i.tag) { + case 5: + Os || Lj(i, o); + case 6: + var u = Ps, + _ = Ms; + (Ps = null), + Yj(s, o, i), + (Ms = _), + null !== (Ps = u) && + (Ms + ? ((s = Ps), + (i = i.stateNode), + 8 === s.nodeType ? s.parentNode.removeChild(i) : s.removeChild(i)) + : Ps.removeChild(i.stateNode)); + break; + case 18: + null !== Ps && + (Ms + ? ((s = Ps), + (i = i.stateNode), + 8 === s.nodeType ? Kf(s.parentNode, i) : 1 === s.nodeType && Kf(s, i), + bd(s)) + : Kf(Ps, i.stateNode)); + break; + case 4: + (u = Ps), + (_ = Ms), + (Ps = i.stateNode.containerInfo), + (Ms = !0), + Yj(s, o, i), + (Ps = u), + (Ms = _); + break; + case 0: + case 11: + case 14: + case 15: + if (!Os && null !== (u = i.updateQueue) && null !== (u = u.lastEffect)) { + _ = u = u.next; + do { + var w = _, + x = w.destroy; + (w = w.tag), void 0 !== x && (2 & w || 4 & w) && Mj(i, o, x), (_ = _.next); + } while (_ !== u); + } + Yj(s, o, i); + break; + case 1: + if (!Os && (Lj(i, o), 'function' == typeof (u = i.stateNode).componentWillUnmount)) + try { + (u.props = i.memoizedProps), + (u.state = i.memoizedState), + u.componentWillUnmount(); + } catch (s) { + W(i, o, s); + } + Yj(s, o, i); + break; + case 21: + Yj(s, o, i); + break; + case 22: + 1 & i.mode + ? ((Os = (u = Os) || null !== i.memoizedState), Yj(s, o, i), (Os = u)) + : Yj(s, o, i); + break; + default: + Yj(s, o, i); + } + } + function ak(s) { + var o = s.updateQueue; + if (null !== o) { + s.updateQueue = null; + var i = s.stateNode; + null === i && (i = s.stateNode = new As()), + o.forEach(function (o) { + var u = bk.bind(null, s, o); + i.has(o) || (i.add(o), o.then(u, u)); + }); + } + } + function ck(s, o) { + var i = o.deletions; + if (null !== i) + for (var u = 0; u < i.length; u++) { + var _ = i[u]; + try { + var w = s, + x = o, + C = x; + e: for (; null !== C; ) { + switch (C.tag) { + case 5: + (Ps = C.stateNode), (Ms = !1); + break e; + case 3: + case 4: + (Ps = C.stateNode.containerInfo), (Ms = !0); + break e; + } + C = C.return; + } + if (null === Ps) throw Error(p(160)); + Zj(w, x, _), (Ps = null), (Ms = !1); + var j = _.alternate; + null !== j && (j.return = null), (_.return = null); + } catch (s) { + W(_, o, s); + } + } + if (12854 & o.subtreeFlags) for (o = o.child; null !== o; ) dk(o, s), (o = o.sibling); + } + function dk(s, o) { + var i = s.alternate, + u = s.flags; + switch (s.tag) { + case 0: + case 11: + case 14: + case 15: + if ((ck(o, s), ek(s), 4 & u)) { + try { + Pj(3, s, s.return), Qj(3, s); + } catch (o) { + W(s, s.return, o); + } + try { + Pj(5, s, s.return); + } catch (o) { + W(s, s.return, o); + } + } + break; + case 1: + ck(o, s), ek(s), 512 & u && null !== i && Lj(i, i.return); + break; + case 5: + if ((ck(o, s), ek(s), 512 & u && null !== i && Lj(i, i.return), 32 & s.flags)) { + var _ = s.stateNode; + try { + ob(_, ''); + } catch (o) { + W(s, s.return, o); + } + } + if (4 & u && null != (_ = s.stateNode)) { + var w = s.memoizedProps, + x = null !== i ? i.memoizedProps : w, + C = s.type, + j = s.updateQueue; + if (((s.updateQueue = null), null !== j)) + try { + 'input' === C && 'radio' === w.type && null != w.name && ab(_, w), vb(C, x); + var L = vb(C, w); + for (x = 0; x < j.length; x += 2) { + var B = j[x], + $ = j[x + 1]; + 'style' === B + ? sb(_, $) + : 'dangerouslySetInnerHTML' === B + ? $e(_, $) + : 'children' === B + ? ob(_, $) + : ta(_, B, $, L); + } + switch (C) { + case 'input': + bb(_, w); + break; + case 'textarea': + ib(_, w); + break; + case 'select': + var V = _._wrapperState.wasMultiple; + _._wrapperState.wasMultiple = !!w.multiple; + var U = w.value; + null != U + ? fb(_, !!w.multiple, U, !1) + : V !== !!w.multiple && + (null != w.defaultValue + ? fb(_, !!w.multiple, w.defaultValue, !0) + : fb(_, !!w.multiple, w.multiple ? [] : '', !1)); + } + _[fn] = w; + } catch (o) { + W(s, s.return, o); + } + } + break; + case 6: + if ((ck(o, s), ek(s), 4 & u)) { + if (null === s.stateNode) throw Error(p(162)); + (_ = s.stateNode), (w = s.memoizedProps); + try { + _.nodeValue = w; + } catch (o) { + W(s, s.return, o); + } + } + break; + case 3: + if ((ck(o, s), ek(s), 4 & u && null !== i && i.memoizedState.isDehydrated)) + try { + bd(o.containerInfo); + } catch (o) { + W(s, s.return, o); + } + break; + case 4: + default: + ck(o, s), ek(s); + break; + case 13: + ck(o, s), + ek(s), + 8192 & (_ = s.child).flags && + ((w = null !== _.memoizedState), + (_.stateNode.isHidden = w), + !w || + (null !== _.alternate && null !== _.alternate.memoizedState) || + (Xs = dt())), + 4 & u && ak(s); + break; + case 22: + if ( + ((B = null !== i && null !== i.memoizedState), + 1 & s.mode ? ((Os = (L = Os) || B), ck(o, s), (Os = L)) : ck(o, s), + ek(s), + 8192 & u) + ) { + if ( + ((L = null !== s.memoizedState), (s.stateNode.isHidden = L) && !B && 1 & s.mode) + ) + for (js = s, B = s.child; null !== B; ) { + for ($ = js = B; null !== js; ) { + switch (((U = (V = js).child), V.tag)) { + case 0: + case 11: + case 14: + case 15: + Pj(4, V, V.return); + break; + case 1: + Lj(V, V.return); + var z = V.stateNode; + if ('function' == typeof z.componentWillUnmount) { + (u = V), (i = V.return); + try { + (o = u), + (z.props = o.memoizedProps), + (z.state = o.memoizedState), + z.componentWillUnmount(); + } catch (s) { + W(u, i, s); + } + } + break; + case 5: + Lj(V, V.return); + break; + case 22: + if (null !== V.memoizedState) { + gk($); + continue; + } + } + null !== U ? ((U.return = V), (js = U)) : gk($); + } + B = B.sibling; + } + e: for (B = null, $ = s; ; ) { + if (5 === $.tag) { + if (null === B) { + B = $; + try { + (_ = $.stateNode), + L + ? 'function' == typeof (w = _.style).setProperty + ? w.setProperty('display', 'none', 'important') + : (w.display = 'none') + : ((C = $.stateNode), + (x = + null != (j = $.memoizedProps.style) && j.hasOwnProperty('display') + ? j.display + : null), + (C.style.display = rb('display', x))); + } catch (o) { + W(s, s.return, o); + } + } + } else if (6 === $.tag) { + if (null === B) + try { + $.stateNode.nodeValue = L ? '' : $.memoizedProps; + } catch (o) { + W(s, s.return, o); + } + } else if ( + ((22 !== $.tag && 23 !== $.tag) || null === $.memoizedState || $ === s) && + null !== $.child + ) { + ($.child.return = $), ($ = $.child); + continue; + } + if ($ === s) break e; + for (; null === $.sibling; ) { + if (null === $.return || $.return === s) break e; + B === $ && (B = null), ($ = $.return); + } + B === $ && (B = null), ($.sibling.return = $.return), ($ = $.sibling); + } + } + break; + case 19: + ck(o, s), ek(s), 4 & u && ak(s); + case 21: + } + } + function ek(s) { + var o = s.flags; + if (2 & o) { + try { + e: { + for (var i = s.return; null !== i; ) { + if (Tj(i)) { + var u = i; + break e; + } + i = i.return; + } + throw Error(p(160)); + } + switch (u.tag) { + case 5: + var _ = u.stateNode; + 32 & u.flags && (ob(_, ''), (u.flags &= -33)), Wj(s, Uj(s), _); + break; + case 3: + case 4: + var w = u.stateNode.containerInfo; + Vj(s, Uj(s), w); + break; + default: + throw Error(p(161)); + } + } catch (o) { + W(s, s.return, o); + } + s.flags &= -3; + } + 4096 & o && (s.flags &= -4097); + } + function hk(s, o, i) { + (js = s), ik(s, o, i); + } + function ik(s, o, i) { + for (var u = !!(1 & s.mode); null !== js; ) { + var _ = js, + w = _.child; + if (22 === _.tag && u) { + var x = null !== _.memoizedState || Cs; + if (!x) { + var C = _.alternate, + j = (null !== C && null !== C.memoizedState) || Os; + C = Cs; + var L = Os; + if (((Cs = x), (Os = j) && !L)) + for (js = _; null !== js; ) + (j = (x = js).child), + 22 === x.tag && null !== x.memoizedState + ? jk(_) + : null !== j + ? ((j.return = x), (js = j)) + : jk(_); + for (; null !== w; ) (js = w), ik(w, o, i), (w = w.sibling); + (js = _), (Cs = C), (Os = L); + } + kk(s); + } else 8772 & _.subtreeFlags && null !== w ? ((w.return = _), (js = w)) : kk(s); + } + } + function kk(s) { + for (; null !== js; ) { + var o = js; + if (8772 & o.flags) { + var i = o.alternate; + try { + if (8772 & o.flags) + switch (o.tag) { + case 0: + case 11: + case 15: + Os || Qj(5, o); + break; + case 1: + var u = o.stateNode; + if (4 & o.flags && !Os) + if (null === i) u.componentDidMount(); + else { + var _ = + o.elementType === o.type + ? i.memoizedProps + : Ci(o.type, i.memoizedProps); + u.componentDidUpdate( + _, + i.memoizedState, + u.__reactInternalSnapshotBeforeUpdate + ); + } + var w = o.updateQueue; + null !== w && sh(o, w, u); + break; + case 3: + var x = o.updateQueue; + if (null !== x) { + if (((i = null), null !== o.child)) + switch (o.child.tag) { + case 5: + case 1: + i = o.child.stateNode; + } + sh(o, x, i); + } + break; + case 5: + var C = o.stateNode; + if (null === i && 4 & o.flags) { + i = C; + var j = o.memoizedProps; + switch (o.type) { + case 'button': + case 'input': + case 'select': + case 'textarea': + j.autoFocus && i.focus(); + break; + case 'img': + j.src && (i.src = j.src); + } + } + break; + case 6: + case 4: + case 12: + case 19: + case 17: + case 21: + case 22: + case 23: + case 25: + break; + case 13: + if (null === o.memoizedState) { + var L = o.alternate; + if (null !== L) { + var B = L.memoizedState; + if (null !== B) { + var $ = B.dehydrated; + null !== $ && bd($); + } + } + } + break; + default: + throw Error(p(163)); + } + Os || (512 & o.flags && Rj(o)); + } catch (s) { + W(o, o.return, s); + } + } + if (o === s) { + js = null; + break; + } + if (null !== (i = o.sibling)) { + (i.return = o.return), (js = i); + break; + } + js = o.return; + } + } + function gk(s) { + for (; null !== js; ) { + var o = js; + if (o === s) { + js = null; + break; + } + var i = o.sibling; + if (null !== i) { + (i.return = o.return), (js = i); + break; + } + js = o.return; + } + } + function jk(s) { + for (; null !== js; ) { + var o = js; + try { + switch (o.tag) { + case 0: + case 11: + case 15: + var i = o.return; + try { + Qj(4, o); + } catch (s) { + W(o, i, s); + } + break; + case 1: + var u = o.stateNode; + if ('function' == typeof u.componentDidMount) { + var _ = o.return; + try { + u.componentDidMount(); + } catch (s) { + W(o, _, s); + } + } + var w = o.return; + try { + Rj(o); + } catch (s) { + W(o, w, s); + } + break; + case 5: + var x = o.return; + try { + Rj(o); + } catch (s) { + W(o, x, s); + } + } + } catch (s) { + W(o, o.return, s); + } + if (o === s) { + js = null; + break; + } + var C = o.sibling; + if (null !== C) { + (C.return = o.return), (js = C); + break; + } + js = o.return; + } + } + var Ts, + Ns = Math.ceil, + Rs = z.ReactCurrentDispatcher, + Ds = z.ReactCurrentOwner, + Ls = z.ReactCurrentBatchConfig, + Bs = 0, + Fs = null, + qs = null, + $s = 0, + Vs = 0, + Us = Uf(0), + zs = 0, + Ws = null, + Ks = 0, + Hs = 0, + Js = 0, + Gs = null, + Ys = null, + Xs = 0, + Zs = 1 / 0, + Qs = null, + eo = !1, + to = null, + ro = null, + no = !1, + so = null, + oo = 0, + io = 0, + ao = null, + lo = -1, + co = 0; + function R() { + return 6 & Bs ? dt() : -1 !== lo ? lo : (lo = dt()); + } + function yi(s) { + return 1 & s.mode + ? 2 & Bs && 0 !== $s + ? $s & -$s + : null !== $n.transition + ? (0 === co && (co = yc()), co) + : 0 !== (s = At) + ? s + : (s = void 0 === (s = window.event) ? 16 : jd(s.type)) + : 1; + } + function gi(s, o, i, u) { + if (50 < io) throw ((io = 0), (ao = null), Error(p(185))); + Ac(s, i, u), + (2 & Bs && s === Fs) || + (s === Fs && (!(2 & Bs) && (Hs |= i), 4 === zs && Ck(s, $s)), + Dk(s, u), + 1 === i && 0 === Bs && !(1 & o.mode) && ((Zs = dt() + 500), Cn && jg())); + } + function Dk(s, o) { + var i = s.callbackNode; + !(function wc(s, o) { + for ( + var i = s.suspendedLanes, + u = s.pingedLanes, + _ = s.expirationTimes, + w = s.pendingLanes; + 0 < w; + + ) { + var x = 31 - St(w), + C = 1 << x, + j = _[x]; + -1 === j + ? (C & i && !(C & u)) || (_[x] = vc(C, o)) + : j <= o && (s.expiredLanes |= C), + (w &= ~C); + } + })(s, o); + var u = uc(s, s === Fs ? $s : 0); + if (0 === u) null !== i && ut(i), (s.callbackNode = null), (s.callbackPriority = 0); + else if (((o = u & -u), s.callbackPriority !== o)) { + if ((null != i && ut(i), 1 === o)) + 0 === s.tag + ? (function ig(s) { + (Cn = !0), hg(s); + })(Ek.bind(null, s)) + : hg(Ek.bind(null, s)), + pn(function () { + !(6 & Bs) && jg(); + }), + (i = null); + else { + switch (Dc(u)) { + case 1: + i = gt; + break; + case 4: + i = yt; + break; + case 16: + default: + i = vt; + break; + case 536870912: + i = _t; + } + i = Fk(i, Gk.bind(null, s)); + } + (s.callbackPriority = o), (s.callbackNode = i); + } + } + function Gk(s, o) { + if (((lo = -1), (co = 0), 6 & Bs)) throw Error(p(327)); + var i = s.callbackNode; + if (Hk() && s.callbackNode !== i) return null; + var u = uc(s, s === Fs ? $s : 0); + if (0 === u) return null; + if (30 & u || u & s.expiredLanes || o) o = Ik(s, u); + else { + o = u; + var _ = Bs; + Bs |= 2; + var w = Jk(); + for ((Fs === s && $s === o) || ((Qs = null), (Zs = dt() + 500), Kk(s, o)); ; ) + try { + Lk(); + break; + } catch (o) { + Mk(s, o); + } + $g(), + (Rs.current = w), + (Bs = _), + null !== qs ? (o = 0) : ((Fs = null), ($s = 0), (o = zs)); + } + if (0 !== o) { + if ((2 === o && 0 !== (_ = xc(s)) && ((u = _), (o = Nk(s, _))), 1 === o)) + throw ((i = Ws), Kk(s, 0), Ck(s, u), Dk(s, dt()), i); + if (6 === o) Ck(s, u); + else { + if ( + ((_ = s.current.alternate), + !( + 30 & u || + (function Ok(s) { + for (var o = s; ; ) { + if (16384 & o.flags) { + var i = o.updateQueue; + if (null !== i && null !== (i = i.stores)) + for (var u = 0; u < i.length; u++) { + var _ = i[u], + w = _.getSnapshot; + _ = _.value; + try { + if (!Lr(w(), _)) return !1; + } catch (s) { + return !1; + } + } + } + if (((i = o.child), 16384 & o.subtreeFlags && null !== i)) + (i.return = o), (o = i); + else { + if (o === s) break; + for (; null === o.sibling; ) { + if (null === o.return || o.return === s) return !0; + o = o.return; + } + (o.sibling.return = o.return), (o = o.sibling); + } + } + return !0; + })(_) || + ((o = Ik(s, u)), + 2 === o && ((w = xc(s)), 0 !== w && ((u = w), (o = Nk(s, w)))), + 1 !== o) + )) + ) + throw ((i = Ws), Kk(s, 0), Ck(s, u), Dk(s, dt()), i); + switch (((s.finishedWork = _), (s.finishedLanes = u), o)) { + case 0: + case 1: + throw Error(p(345)); + case 2: + case 5: + Pk(s, Ys, Qs); + break; + case 3: + if ((Ck(s, u), (130023424 & u) === u && 10 < (o = Xs + 500 - dt()))) { + if (0 !== uc(s, 0)) break; + if (((_ = s.suspendedLanes) & u) !== u) { + R(), (s.pingedLanes |= s.suspendedLanes & _); + break; + } + s.timeoutHandle = ln(Pk.bind(null, s, Ys, Qs), o); + break; + } + Pk(s, Ys, Qs); + break; + case 4: + if ((Ck(s, u), (4194240 & u) === u)) break; + for (o = s.eventTimes, _ = -1; 0 < u; ) { + var x = 31 - St(u); + (w = 1 << x), (x = o[x]) > _ && (_ = x), (u &= ~w); + } + if ( + ((u = _), + 10 < + (u = + (120 > (u = dt() - u) + ? 120 + : 480 > u + ? 480 + : 1080 > u + ? 1080 + : 1920 > u + ? 1920 + : 3e3 > u + ? 3e3 + : 4320 > u + ? 4320 + : 1960 * Ns(u / 1960)) - u)) + ) { + s.timeoutHandle = ln(Pk.bind(null, s, Ys, Qs), u); + break; + } + Pk(s, Ys, Qs); + break; + default: + throw Error(p(329)); + } + } + } + return Dk(s, dt()), s.callbackNode === i ? Gk.bind(null, s) : null; + } + function Nk(s, o) { + var i = Gs; + return ( + s.current.memoizedState.isDehydrated && (Kk(s, o).flags |= 256), + 2 !== (s = Ik(s, o)) && ((o = Ys), (Ys = i), null !== o && Fj(o)), + s + ); + } + function Fj(s) { + null === Ys ? (Ys = s) : Ys.push.apply(Ys, s); + } + function Ck(s, o) { + for ( + o &= ~Js, o &= ~Hs, s.suspendedLanes |= o, s.pingedLanes &= ~o, s = s.expirationTimes; + 0 < o; + + ) { + var i = 31 - St(o), + u = 1 << i; + (s[i] = -1), (o &= ~u); + } + } + function Ek(s) { + if (6 & Bs) throw Error(p(327)); + Hk(); + var o = uc(s, 0); + if (!(1 & o)) return Dk(s, dt()), null; + var i = Ik(s, o); + if (0 !== s.tag && 2 === i) { + var u = xc(s); + 0 !== u && ((o = u), (i = Nk(s, u))); + } + if (1 === i) throw ((i = Ws), Kk(s, 0), Ck(s, o), Dk(s, dt()), i); + if (6 === i) throw Error(p(345)); + return ( + (s.finishedWork = s.current.alternate), + (s.finishedLanes = o), + Pk(s, Ys, Qs), + Dk(s, dt()), + null + ); + } + function Qk(s, o) { + var i = Bs; + Bs |= 1; + try { + return s(o); + } finally { + 0 === (Bs = i) && ((Zs = dt() + 500), Cn && jg()); + } + } + function Rk(s) { + null !== so && 0 === so.tag && !(6 & Bs) && Hk(); + var o = Bs; + Bs |= 1; + var i = Ls.transition, + u = At; + try { + if (((Ls.transition = null), (At = 1), s)) return s(); + } finally { + (At = u), (Ls.transition = i), !(6 & (Bs = o)) && jg(); + } + } + function Hj() { + (Vs = Us.current), E(Us); + } + function Kk(s, o) { + (s.finishedWork = null), (s.finishedLanes = 0); + var i = s.timeoutHandle; + if ((-1 !== i && ((s.timeoutHandle = -1), cn(i)), null !== qs)) + for (i = qs.return; null !== i; ) { + var u = i; + switch ((wg(u), u.tag)) { + case 1: + null != (u = u.type.childContextTypes) && $f(); + break; + case 3: + zh(), E(Sn), E(wn), Eh(); + break; + case 5: + Bh(u); + break; + case 4: + zh(); + break; + case 13: + case 19: + E(es); + break; + case 10: + ah(u.type._context); + break; + case 22: + case 23: + Hj(); + } + i = i.return; + } + if ( + ((Fs = s), + (qs = s = Pg(s.current, null)), + ($s = Vs = o), + (zs = 0), + (Ws = null), + (Js = Hs = Ks = 0), + (Ys = Gs = null), + null !== Jn) + ) { + for (o = 0; o < Jn.length; o++) + if (null !== (u = (i = Jn[o]).interleaved)) { + i.interleaved = null; + var _ = u.next, + w = i.pending; + if (null !== w) { + var x = w.next; + (w.next = _), (u.next = x); + } + i.pending = u; + } + Jn = null; + } + return s; + } + function Mk(s, o) { + for (;;) { + var i = qs; + try { + if (($g(), (rs.current = ds), cs)) { + for (var u = os.memoizedState; null !== u; ) { + var _ = u.queue; + null !== _ && (_.pending = null), (u = u.next); + } + cs = !1; + } + if ( + ((ss = 0), + (ls = as = os = null), + (us = !1), + (ps = 0), + (Ds.current = null), + null === i || null === i.return) + ) { + (zs = 1), (Ws = o), (qs = null); + break; + } + e: { + var w = s, + x = i.return, + C = i, + j = o; + if ( + ((o = $s), + (C.flags |= 32768), + null !== j && 'object' == typeof j && 'function' == typeof j.then) + ) { + var L = j, + B = C, + $ = B.tag; + if (!(1 & B.mode || (0 !== $ && 11 !== $ && 15 !== $))) { + var V = B.alternate; + V + ? ((B.updateQueue = V.updateQueue), + (B.memoizedState = V.memoizedState), + (B.lanes = V.lanes)) + : ((B.updateQueue = null), (B.memoizedState = null)); + } + var U = Ui(x); + if (null !== U) { + (U.flags &= -257), Vi(U, x, C, 0, o), 1 & U.mode && Si(w, L, o), (j = L); + var z = (o = U).updateQueue; + if (null === z) { + var Y = new Set(); + Y.add(j), (o.updateQueue = Y); + } else z.add(j); + break e; + } + if (!(1 & o)) { + Si(w, L, o), tj(); + break e; + } + j = Error(p(426)); + } else if (Fn && 1 & C.mode) { + var Z = Ui(x); + if (null !== Z) { + !(65536 & Z.flags) && (Z.flags |= 256), Vi(Z, x, C, 0, o), Jg(Ji(j, C)); + break e; + } + } + (w = j = Ji(j, C)), + 4 !== zs && (zs = 2), + null === Gs ? (Gs = [w]) : Gs.push(w), + (w = x); + do { + switch (w.tag) { + case 3: + (w.flags |= 65536), (o &= -o), (w.lanes |= o), ph(w, Ni(0, j, o)); + break e; + case 1: + C = j; + var ee = w.type, + ie = w.stateNode; + if ( + !( + 128 & w.flags || + ('function' != typeof ee.getDerivedStateFromError && + (null === ie || + 'function' != typeof ie.componentDidCatch || + (null !== ro && ro.has(ie)))) + ) + ) { + (w.flags |= 65536), (o &= -o), (w.lanes |= o), ph(w, Qi(w, C, o)); + break e; + } + } + w = w.return; + } while (null !== w); + } + Sk(i); + } catch (s) { + (o = s), qs === i && null !== i && (qs = i = i.return); + continue; + } + break; + } + } + function Jk() { + var s = Rs.current; + return (Rs.current = ds), null === s ? ds : s; + } + function tj() { + (0 !== zs && 3 !== zs && 2 !== zs) || (zs = 4), + null === Fs || (!(268435455 & Ks) && !(268435455 & Hs)) || Ck(Fs, $s); + } + function Ik(s, o) { + var i = Bs; + Bs |= 2; + var u = Jk(); + for ((Fs === s && $s === o) || ((Qs = null), Kk(s, o)); ; ) + try { + Tk(); + break; + } catch (o) { + Mk(s, o); + } + if (($g(), (Bs = i), (Rs.current = u), null !== qs)) throw Error(p(261)); + return (Fs = null), ($s = 0), zs; + } + function Tk() { + for (; null !== qs; ) Uk(qs); + } + function Lk() { + for (; null !== qs && !pt(); ) Uk(qs); + } + function Uk(s) { + var o = Ts(s.alternate, s, Vs); + (s.memoizedProps = s.pendingProps), null === o ? Sk(s) : (qs = o), (Ds.current = null); + } + function Sk(s) { + var o = s; + do { + var i = o.alternate; + if (((s = o.return), 32768 & o.flags)) { + if (null !== (i = Ij(i, o))) return (i.flags &= 32767), void (qs = i); + if (null === s) return (zs = 6), void (qs = null); + (s.flags |= 32768), (s.subtreeFlags = 0), (s.deletions = null); + } else if (null !== (i = Ej(i, o, Vs))) return void (qs = i); + if (null !== (o = o.sibling)) return void (qs = o); + qs = o = s; + } while (null !== o); + 0 === zs && (zs = 5); + } + function Pk(s, o, i) { + var u = At, + _ = Ls.transition; + try { + (Ls.transition = null), + (At = 1), + (function Wk(s, o, i, u) { + do { + Hk(); + } while (null !== so); + if (6 & Bs) throw Error(p(327)); + i = s.finishedWork; + var _ = s.finishedLanes; + if (null === i) return null; + if (((s.finishedWork = null), (s.finishedLanes = 0), i === s.current)) + throw Error(p(177)); + (s.callbackNode = null), (s.callbackPriority = 0); + var w = i.lanes | i.childLanes; + if ( + ((function Bc(s, o) { + var i = s.pendingLanes & ~o; + (s.pendingLanes = o), + (s.suspendedLanes = 0), + (s.pingedLanes = 0), + (s.expiredLanes &= o), + (s.mutableReadLanes &= o), + (s.entangledLanes &= o), + (o = s.entanglements); + var u = s.eventTimes; + for (s = s.expirationTimes; 0 < i; ) { + var _ = 31 - St(i), + w = 1 << _; + (o[_] = 0), (u[_] = -1), (s[_] = -1), (i &= ~w); + } + })(s, w), + s === Fs && ((qs = Fs = null), ($s = 0)), + (!(2064 & i.subtreeFlags) && !(2064 & i.flags)) || + no || + ((no = !0), + Fk(vt, function () { + return Hk(), null; + })), + (w = !!(15990 & i.flags)), + !!(15990 & i.subtreeFlags) || w) + ) { + (w = Ls.transition), (Ls.transition = null); + var x = At; + At = 1; + var C = Bs; + (Bs |= 4), + (Ds.current = null), + (function Oj(s, o) { + if (((on = zt), Ne((s = Me())))) { + if ('selectionStart' in s) + var i = { start: s.selectionStart, end: s.selectionEnd }; + else + e: { + var u = + (i = ((i = s.ownerDocument) && i.defaultView) || window) + .getSelection && i.getSelection(); + if (u && 0 !== u.rangeCount) { + i = u.anchorNode; + var _ = u.anchorOffset, + w = u.focusNode; + u = u.focusOffset; + try { + i.nodeType, w.nodeType; + } catch (s) { + i = null; + break e; + } + var x = 0, + C = -1, + j = -1, + L = 0, + B = 0, + $ = s, + V = null; + t: for (;;) { + for ( + var U; + $ !== i || (0 !== _ && 3 !== $.nodeType) || (C = x + _), + $ !== w || (0 !== u && 3 !== $.nodeType) || (j = x + u), + 3 === $.nodeType && (x += $.nodeValue.length), + null !== (U = $.firstChild); + + ) + (V = $), ($ = U); + for (;;) { + if ($ === s) break t; + if ( + (V === i && ++L === _ && (C = x), + V === w && ++B === u && (j = x), + null !== (U = $.nextSibling)) + ) + break; + V = ($ = V).parentNode; + } + $ = U; + } + i = -1 === C || -1 === j ? null : { start: C, end: j }; + } else i = null; + } + i = i || { start: 0, end: 0 }; + } else i = null; + for ( + an = { focusedElem: s, selectionRange: i }, zt = !1, js = o; + null !== js; + + ) + if (((s = (o = js).child), 1028 & o.subtreeFlags && null !== s)) + (s.return = o), (js = s); + else + for (; null !== js; ) { + o = js; + try { + var z = o.alternate; + if (1024 & o.flags) + switch (o.tag) { + case 0: + case 11: + case 15: + case 5: + case 6: + case 4: + case 17: + break; + case 1: + if (null !== z) { + var Y = z.memoizedProps, + Z = z.memoizedState, + ee = o.stateNode, + ie = ee.getSnapshotBeforeUpdate( + o.elementType === o.type ? Y : Ci(o.type, Y), + Z + ); + ee.__reactInternalSnapshotBeforeUpdate = ie; + } + break; + case 3: + var ae = o.stateNode.containerInfo; + 1 === ae.nodeType + ? (ae.textContent = '') + : 9 === ae.nodeType && + ae.documentElement && + ae.removeChild(ae.documentElement); + break; + default: + throw Error(p(163)); + } + } catch (s) { + W(o, o.return, s); + } + if (null !== (s = o.sibling)) { + (s.return = o.return), (js = s); + break; + } + js = o.return; + } + return (z = Is), (Is = !1), z; + })(s, i), + dk(i, s), + Oe(an), + (zt = !!on), + (an = on = null), + (s.current = i), + hk(i, s, _), + ht(), + (Bs = C), + (At = x), + (Ls.transition = w); + } else s.current = i; + if ( + (no && ((no = !1), (so = s), (oo = _)), + (w = s.pendingLanes), + 0 === w && (ro = null), + (function mc(s) { + if (wt && 'function' == typeof wt.onCommitFiberRoot) + try { + wt.onCommitFiberRoot(Et, s, void 0, !(128 & ~s.current.flags)); + } catch (s) {} + })(i.stateNode), + Dk(s, dt()), + null !== o) + ) + for (u = s.onRecoverableError, i = 0; i < o.length; i++) + (_ = o[i]), u(_.value, { componentStack: _.stack, digest: _.digest }); + if (eo) throw ((eo = !1), (s = to), (to = null), s); + return ( + !!(1 & oo) && 0 !== s.tag && Hk(), + (w = s.pendingLanes), + 1 & w ? (s === ao ? io++ : ((io = 0), (ao = s))) : (io = 0), + jg(), + null + ); + })(s, o, i, u); + } finally { + (Ls.transition = _), (At = u); + } + return null; + } + function Hk() { + if (null !== so) { + var s = Dc(oo), + o = Ls.transition, + i = At; + try { + if (((Ls.transition = null), (At = 16 > s ? 16 : s), null === so)) var u = !1; + else { + if (((s = so), (so = null), (oo = 0), 6 & Bs)) throw Error(p(331)); + var _ = Bs; + for (Bs |= 4, js = s.current; null !== js; ) { + var w = js, + x = w.child; + if (16 & js.flags) { + var C = w.deletions; + if (null !== C) { + for (var j = 0; j < C.length; j++) { + var L = C[j]; + for (js = L; null !== js; ) { + var B = js; + switch (B.tag) { + case 0: + case 11: + case 15: + Pj(8, B, w); + } + var $ = B.child; + if (null !== $) ($.return = B), (js = $); + else + for (; null !== js; ) { + var V = (B = js).sibling, + U = B.return; + if ((Sj(B), B === L)) { + js = null; + break; + } + if (null !== V) { + (V.return = U), (js = V); + break; + } + js = U; + } + } + } + var z = w.alternate; + if (null !== z) { + var Y = z.child; + if (null !== Y) { + z.child = null; + do { + var Z = Y.sibling; + (Y.sibling = null), (Y = Z); + } while (null !== Y); + } + } + js = w; + } + } + if (2064 & w.subtreeFlags && null !== x) (x.return = w), (js = x); + else + e: for (; null !== js; ) { + if (2048 & (w = js).flags) + switch (w.tag) { + case 0: + case 11: + case 15: + Pj(9, w, w.return); + } + var ee = w.sibling; + if (null !== ee) { + (ee.return = w.return), (js = ee); + break e; + } + js = w.return; + } + } + var ie = s.current; + for (js = ie; null !== js; ) { + var ae = (x = js).child; + if (2064 & x.subtreeFlags && null !== ae) (ae.return = x), (js = ae); + else + e: for (x = ie; null !== js; ) { + if (2048 & (C = js).flags) + try { + switch (C.tag) { + case 0: + case 11: + case 15: + Qj(9, C); + } + } catch (s) { + W(C, C.return, s); + } + if (C === x) { + js = null; + break e; + } + var le = C.sibling; + if (null !== le) { + (le.return = C.return), (js = le); + break e; + } + js = C.return; + } + } + if (((Bs = _), jg(), wt && 'function' == typeof wt.onPostCommitFiberRoot)) + try { + wt.onPostCommitFiberRoot(Et, s); + } catch (s) {} + u = !0; + } + return u; + } finally { + (At = i), (Ls.transition = o); + } + } + return !1; + } + function Xk(s, o, i) { + (s = nh(s, (o = Ni(0, (o = Ji(i, o)), 1)), 1)), + (o = R()), + null !== s && (Ac(s, 1, o), Dk(s, o)); + } + function W(s, o, i) { + if (3 === s.tag) Xk(s, s, i); + else + for (; null !== o; ) { + if (3 === o.tag) { + Xk(o, s, i); + break; + } + if (1 === o.tag) { + var u = o.stateNode; + if ( + 'function' == typeof o.type.getDerivedStateFromError || + ('function' == typeof u.componentDidCatch && (null === ro || !ro.has(u))) + ) { + (o = nh(o, (s = Qi(o, (s = Ji(i, s)), 1)), 1)), + (s = R()), + null !== o && (Ac(o, 1, s), Dk(o, s)); + break; + } + } + o = o.return; + } + } + function Ti(s, o, i) { + var u = s.pingCache; + null !== u && u.delete(o), + (o = R()), + (s.pingedLanes |= s.suspendedLanes & i), + Fs === s && + ($s & i) === i && + (4 === zs || (3 === zs && (130023424 & $s) === $s && 500 > dt() - Xs) + ? Kk(s, 0) + : (Js |= i)), + Dk(s, o); + } + function Yk(s, o) { + 0 === o && + (1 & s.mode ? ((o = Ot), !(130023424 & (Ot <<= 1)) && (Ot = 4194304)) : (o = 1)); + var i = R(); + null !== (s = ih(s, o)) && (Ac(s, o, i), Dk(s, i)); + } + function uj(s) { + var o = s.memoizedState, + i = 0; + null !== o && (i = o.retryLane), Yk(s, i); + } + function bk(s, o) { + var i = 0; + switch (s.tag) { + case 13: + var u = s.stateNode, + _ = s.memoizedState; + null !== _ && (i = _.retryLane); + break; + case 19: + u = s.stateNode; + break; + default: + throw Error(p(314)); + } + null !== u && u.delete(o), Yk(s, i); + } + function Fk(s, o) { + return ct(s, o); + } + function $k(s, o, i, u) { + (this.tag = s), + (this.key = i), + (this.sibling = + this.child = + this.return = + this.stateNode = + this.type = + this.elementType = + null), + (this.index = 0), + (this.ref = null), + (this.pendingProps = o), + (this.dependencies = + this.memoizedState = + this.updateQueue = + this.memoizedProps = + null), + (this.mode = u), + (this.subtreeFlags = this.flags = 0), + (this.deletions = null), + (this.childLanes = this.lanes = 0), + (this.alternate = null); + } + function Bg(s, o, i, u) { + return new $k(s, o, i, u); + } + function aj(s) { + return !(!(s = s.prototype) || !s.isReactComponent); + } + function Pg(s, o) { + var i = s.alternate; + return ( + null === i + ? (((i = Bg(s.tag, o, s.key, s.mode)).elementType = s.elementType), + (i.type = s.type), + (i.stateNode = s.stateNode), + (i.alternate = s), + (s.alternate = i)) + : ((i.pendingProps = o), + (i.type = s.type), + (i.flags = 0), + (i.subtreeFlags = 0), + (i.deletions = null)), + (i.flags = 14680064 & s.flags), + (i.childLanes = s.childLanes), + (i.lanes = s.lanes), + (i.child = s.child), + (i.memoizedProps = s.memoizedProps), + (i.memoizedState = s.memoizedState), + (i.updateQueue = s.updateQueue), + (o = s.dependencies), + (i.dependencies = + null === o ? null : { lanes: o.lanes, firstContext: o.firstContext }), + (i.sibling = s.sibling), + (i.index = s.index), + (i.ref = s.ref), + i + ); + } + function Rg(s, o, i, u, _, w) { + var x = 2; + if (((u = s), 'function' == typeof s)) aj(s) && (x = 1); + else if ('string' == typeof s) x = 5; + else + e: switch (s) { + case ee: + return Tg(i.children, _, w, o); + case ie: + (x = 8), (_ |= 8); + break; + case ae: + return ((s = Bg(12, i, o, 2 | _)).elementType = ae), (s.lanes = w), s; + case de: + return ((s = Bg(13, i, o, _)).elementType = de), (s.lanes = w), s; + case fe: + return ((s = Bg(19, i, o, _)).elementType = fe), (s.lanes = w), s; + case _e: + return pj(i, _, w, o); + default: + if ('object' == typeof s && null !== s) + switch (s.$$typeof) { + case le: + x = 10; + break e; + case ce: + x = 9; + break e; + case pe: + x = 11; + break e; + case ye: + x = 14; + break e; + case be: + (x = 16), (u = null); + break e; + } + throw Error(p(130, null == s ? s : typeof s, '')); + } + return ((o = Bg(x, i, o, _)).elementType = s), (o.type = u), (o.lanes = w), o; + } + function Tg(s, o, i, u) { + return ((s = Bg(7, s, u, o)).lanes = i), s; + } + function pj(s, o, i, u) { + return ( + ((s = Bg(22, s, u, o)).elementType = _e), + (s.lanes = i), + (s.stateNode = { isHidden: !1 }), + s + ); + } + function Qg(s, o, i) { + return ((s = Bg(6, s, null, o)).lanes = i), s; + } + function Sg(s, o, i) { + return ( + ((o = Bg(4, null !== s.children ? s.children : [], s.key, o)).lanes = i), + (o.stateNode = { + containerInfo: s.containerInfo, + pendingChildren: null, + implementation: s.implementation + }), + o + ); + } + function al(s, o, i, u, _) { + (this.tag = o), + (this.containerInfo = s), + (this.finishedWork = this.pingCache = this.current = this.pendingChildren = null), + (this.timeoutHandle = -1), + (this.callbackNode = this.pendingContext = this.context = null), + (this.callbackPriority = 0), + (this.eventTimes = zc(0)), + (this.expirationTimes = zc(-1)), + (this.entangledLanes = + this.finishedLanes = + this.mutableReadLanes = + this.expiredLanes = + this.pingedLanes = + this.suspendedLanes = + this.pendingLanes = + 0), + (this.entanglements = zc(0)), + (this.identifierPrefix = u), + (this.onRecoverableError = _), + (this.mutableSourceEagerHydrationData = null); + } + function bl(s, o, i, u, _, w, x, C, j) { + return ( + (s = new al(s, o, i, C, j)), + 1 === o ? ((o = 1), !0 === w && (o |= 8)) : (o = 0), + (w = Bg(3, null, null, o)), + (s.current = w), + (w.stateNode = s), + (w.memoizedState = { + element: u, + isDehydrated: i, + cache: null, + transitions: null, + pendingSuspenseBoundaries: null + }), + kh(w), + s + ); + } + function dl(s) { + if (!s) return En; + e: { + if (Vb((s = s._reactInternals)) !== s || 1 !== s.tag) throw Error(p(170)); + var o = s; + do { + switch (o.tag) { + case 3: + o = o.stateNode.context; + break e; + case 1: + if (Zf(o.type)) { + o = o.stateNode.__reactInternalMemoizedMergedChildContext; + break e; + } + } + o = o.return; + } while (null !== o); + throw Error(p(171)); + } + if (1 === s.tag) { + var i = s.type; + if (Zf(i)) return bg(s, i, o); + } + return o; + } + function el(s, o, i, u, _, w, x, C, j) { + return ( + ((s = bl(i, u, !0, s, 0, w, 0, C, j)).context = dl(null)), + (i = s.current), + ((w = mh((u = R()), (_ = yi(i)))).callback = null != o ? o : null), + nh(i, w, _), + (s.current.lanes = _), + Ac(s, _, u), + Dk(s, u), + s + ); + } + function fl(s, o, i, u) { + var _ = o.current, + w = R(), + x = yi(_); + return ( + (i = dl(i)), + null === o.context ? (o.context = i) : (o.pendingContext = i), + ((o = mh(w, x)).payload = { element: s }), + null !== (u = void 0 === u ? null : u) && (o.callback = u), + null !== (s = nh(_, o, x)) && (gi(s, _, x, w), oh(s, _, x)), + x + ); + } + function gl(s) { + return (s = s.current).child ? (s.child.tag, s.child.stateNode) : null; + } + function hl(s, o) { + if (null !== (s = s.memoizedState) && null !== s.dehydrated) { + var i = s.retryLane; + s.retryLane = 0 !== i && i < o ? i : o; + } + } + function il(s, o) { + hl(s, o), (s = s.alternate) && hl(s, o); + } + Ts = function (s, o, i) { + if (null !== s) + if (s.memoizedProps !== o.pendingProps || Sn.current) _s = !0; + else { + if (!(s.lanes & i || 128 & o.flags)) + return ( + (_s = !1), + (function yj(s, o, i) { + switch (o.tag) { + case 3: + kj(o), Ig(); + break; + case 5: + Ah(o); + break; + case 1: + Zf(o.type) && cg(o); + break; + case 4: + yh(o, o.stateNode.containerInfo); + break; + case 10: + var u = o.type._context, + _ = o.memoizedProps.value; + G(zn, u._currentValue), (u._currentValue = _); + break; + case 13: + if (null !== (u = o.memoizedState)) + return null !== u.dehydrated + ? (G(es, 1 & es.current), (o.flags |= 128), null) + : i & o.child.childLanes + ? oj(s, o, i) + : (G(es, 1 & es.current), + null !== (s = Zi(s, o, i)) ? s.sibling : null); + G(es, 1 & es.current); + break; + case 19: + if (((u = !!(i & o.childLanes)), 128 & s.flags)) { + if (u) return xj(s, o, i); + o.flags |= 128; + } + if ( + (null !== (_ = o.memoizedState) && + ((_.rendering = null), (_.tail = null), (_.lastEffect = null)), + G(es, es.current), + u) + ) + break; + return null; + case 22: + case 23: + return (o.lanes = 0), dj(s, o, i); + } + return Zi(s, o, i); + })(s, o, i) + ); + _s = !!(131072 & s.flags); + } + else (_s = !1), Fn && 1048576 & o.flags && ug(o, Pn, o.index); + switch (((o.lanes = 0), o.tag)) { + case 2: + var u = o.type; + ij(s, o), (s = o.pendingProps); + var _ = Yf(o, wn.current); + ch(o, i), (_ = Nh(null, o, u, s, _, i)); + var w = Sh(); + return ( + (o.flags |= 1), + 'object' == typeof _ && + null !== _ && + 'function' == typeof _.render && + void 0 === _.$$typeof + ? ((o.tag = 1), + (o.memoizedState = null), + (o.updateQueue = null), + Zf(u) ? ((w = !0), cg(o)) : (w = !1), + (o.memoizedState = null !== _.state && void 0 !== _.state ? _.state : null), + kh(o), + (_.updater = ys), + (o.stateNode = _), + (_._reactInternals = o), + Ii(o, u, s, i), + (o = jj(null, o, u, !0, w, i))) + : ((o.tag = 0), Fn && w && vg(o), Xi(null, o, _, i), (o = o.child)), + o + ); + case 16: + u = o.elementType; + e: { + switch ( + (ij(s, o), + (s = o.pendingProps), + (u = (_ = u._init)(u._payload)), + (o.type = u), + (_ = o.tag = + (function Zk(s) { + if ('function' == typeof s) return aj(s) ? 1 : 0; + if (null != s) { + if ((s = s.$$typeof) === pe) return 11; + if (s === ye) return 14; + } + return 2; + })(u)), + (s = Ci(u, s)), + _) + ) { + case 0: + o = cj(null, o, u, s, i); + break e; + case 1: + o = hj(null, o, u, s, i); + break e; + case 11: + o = Yi(null, o, u, s, i); + break e; + case 14: + o = $i(null, o, u, Ci(u.type, s), i); + break e; + } + throw Error(p(306, u, '')); + } + return o; + case 0: + return ( + (u = o.type), + (_ = o.pendingProps), + cj(s, o, u, (_ = o.elementType === u ? _ : Ci(u, _)), i) + ); + case 1: + return ( + (u = o.type), + (_ = o.pendingProps), + hj(s, o, u, (_ = o.elementType === u ? _ : Ci(u, _)), i) + ); + case 3: + e: { + if ((kj(o), null === s)) throw Error(p(387)); + (u = o.pendingProps), + (_ = (w = o.memoizedState).element), + lh(s, o), + qh(o, u, null, i); + var x = o.memoizedState; + if (((u = x.element), w.isDehydrated)) { + if ( + ((w = { + element: u, + isDehydrated: !1, + cache: x.cache, + pendingSuspenseBoundaries: x.pendingSuspenseBoundaries, + transitions: x.transitions + }), + (o.updateQueue.baseState = w), + (o.memoizedState = w), + 256 & o.flags) + ) { + o = lj(s, o, u, i, (_ = Ji(Error(p(423)), o))); + break e; + } + if (u !== _) { + o = lj(s, o, u, i, (_ = Ji(Error(p(424)), o))); + break e; + } + for ( + Bn = Lf(o.stateNode.containerInfo.firstChild), + Ln = o, + Fn = !0, + qn = null, + i = Un(o, null, u, i), + o.child = i; + i; + + ) + (i.flags = (-3 & i.flags) | 4096), (i = i.sibling); + } else { + if ((Ig(), u === _)) { + o = Zi(s, o, i); + break e; + } + Xi(s, o, u, i); + } + o = o.child; + } + return o; + case 5: + return ( + Ah(o), + null === s && Eg(o), + (u = o.type), + (_ = o.pendingProps), + (w = null !== s ? s.memoizedProps : null), + (x = _.children), + Ef(u, _) ? (x = null) : null !== w && Ef(u, w) && (o.flags |= 32), + gj(s, o), + Xi(s, o, x, i), + o.child + ); + case 6: + return null === s && Eg(o), null; + case 13: + return oj(s, o, i); + case 4: + return ( + yh(o, o.stateNode.containerInfo), + (u = o.pendingProps), + null === s ? (o.child = Vn(o, null, u, i)) : Xi(s, o, u, i), + o.child + ); + case 11: + return ( + (u = o.type), + (_ = o.pendingProps), + Yi(s, o, u, (_ = o.elementType === u ? _ : Ci(u, _)), i) + ); + case 7: + return Xi(s, o, o.pendingProps, i), o.child; + case 8: + case 12: + return Xi(s, o, o.pendingProps.children, i), o.child; + case 10: + e: { + if ( + ((u = o.type._context), + (_ = o.pendingProps), + (w = o.memoizedProps), + (x = _.value), + G(zn, u._currentValue), + (u._currentValue = x), + null !== w) + ) + if (Lr(w.value, x)) { + if (w.children === _.children && !Sn.current) { + o = Zi(s, o, i); + break e; + } + } else + for (null !== (w = o.child) && (w.return = o); null !== w; ) { + var C = w.dependencies; + if (null !== C) { + x = w.child; + for (var j = C.firstContext; null !== j; ) { + if (j.context === u) { + if (1 === w.tag) { + (j = mh(-1, i & -i)).tag = 2; + var L = w.updateQueue; + if (null !== L) { + var B = (L = L.shared).pending; + null === B ? (j.next = j) : ((j.next = B.next), (B.next = j)), + (L.pending = j); + } + } + (w.lanes |= i), + null !== (j = w.alternate) && (j.lanes |= i), + bh(w.return, i, o), + (C.lanes |= i); + break; + } + j = j.next; + } + } else if (10 === w.tag) x = w.type === o.type ? null : w.child; + else if (18 === w.tag) { + if (null === (x = w.return)) throw Error(p(341)); + (x.lanes |= i), + null !== (C = x.alternate) && (C.lanes |= i), + bh(x, i, o), + (x = w.sibling); + } else x = w.child; + if (null !== x) x.return = w; + else + for (x = w; null !== x; ) { + if (x === o) { + x = null; + break; + } + if (null !== (w = x.sibling)) { + (w.return = x.return), (x = w); + break; + } + x = x.return; + } + w = x; + } + Xi(s, o, _.children, i), (o = o.child); + } + return o; + case 9: + return ( + (_ = o.type), + (u = o.pendingProps.children), + ch(o, i), + (u = u((_ = eh(_)))), + (o.flags |= 1), + Xi(s, o, u, i), + o.child + ); + case 14: + return (_ = Ci((u = o.type), o.pendingProps)), $i(s, o, u, (_ = Ci(u.type, _)), i); + case 15: + return bj(s, o, o.type, o.pendingProps, i); + case 17: + return ( + (u = o.type), + (_ = o.pendingProps), + (_ = o.elementType === u ? _ : Ci(u, _)), + ij(s, o), + (o.tag = 1), + Zf(u) ? ((s = !0), cg(o)) : (s = !1), + ch(o, i), + Gi(o, u, _), + Ii(o, u, _, i), + jj(null, o, u, !0, s, i) + ); + case 19: + return xj(s, o, i); + case 22: + return dj(s, o, i); + } + throw Error(p(156, o.tag)); + }; + var uo = + 'function' == typeof reportError + ? reportError + : function (s) { + console.error(s); + }; + function ll(s) { + this._internalRoot = s; + } + function ml(s) { + this._internalRoot = s; + } + function nl(s) { + return !(!s || (1 !== s.nodeType && 9 !== s.nodeType && 11 !== s.nodeType)); + } + function ol(s) { + return !( + !s || + (1 !== s.nodeType && + 9 !== s.nodeType && + 11 !== s.nodeType && + (8 !== s.nodeType || ' react-mount-point-unstable ' !== s.nodeValue)) + ); + } + function pl() {} + function rl(s, o, i, u, _) { + var w = i._reactRootContainer; + if (w) { + var x = w; + if ('function' == typeof _) { + var C = _; + _ = function () { + var s = gl(x); + C.call(s); + }; + } + fl(o, x, s, _); + } else + x = (function ql(s, o, i, u, _) { + if (_) { + if ('function' == typeof u) { + var w = u; + u = function () { + var s = gl(x); + w.call(s); + }; + } + var x = el(o, u, s, 0, null, !1, 0, '', pl); + return ( + (s._reactRootContainer = x), + (s[mn] = x.current), + sf(8 === s.nodeType ? s.parentNode : s), + Rk(), + x + ); + } + for (; (_ = s.lastChild); ) s.removeChild(_); + if ('function' == typeof u) { + var C = u; + u = function () { + var s = gl(j); + C.call(s); + }; + } + var j = bl(s, 0, !1, null, 0, !1, 0, '', pl); + return ( + (s._reactRootContainer = j), + (s[mn] = j.current), + sf(8 === s.nodeType ? s.parentNode : s), + Rk(function () { + fl(o, j, i, u); + }), + j + ); + })(i, o, s, _, u); + return gl(x); + } + (ml.prototype.render = ll.prototype.render = + function (s) { + var o = this._internalRoot; + if (null === o) throw Error(p(409)); + fl(s, o, null, null); + }), + (ml.prototype.unmount = ll.prototype.unmount = + function () { + var s = this._internalRoot; + if (null !== s) { + this._internalRoot = null; + var o = s.containerInfo; + Rk(function () { + fl(null, s, null, null); + }), + (o[mn] = null); + } + }), + (ml.prototype.unstable_scheduleHydration = function (s) { + if (s) { + var o = Mt(); + s = { blockedOn: null, target: s, priority: o }; + for (var i = 0; i < $t.length && 0 !== o && o < $t[i].priority; i++); + $t.splice(i, 0, s), 0 === i && Vc(s); + } + }), + (jt = function (s) { + switch (s.tag) { + case 3: + var o = s.stateNode; + if (o.current.memoizedState.isDehydrated) { + var i = tc(o.pendingLanes); + 0 !== i && (Cc(o, 1 | i), Dk(o, dt()), !(6 & Bs) && ((Zs = dt() + 500), jg())); + } + break; + case 13: + Rk(function () { + var o = ih(s, 1); + if (null !== o) { + var i = R(); + gi(o, s, 1, i); + } + }), + il(s, 1); + } + }), + (It = function (s) { + if (13 === s.tag) { + var o = ih(s, 134217728); + if (null !== o) gi(o, s, 134217728, R()); + il(s, 134217728); + } + }), + (Pt = function (s) { + if (13 === s.tag) { + var o = yi(s), + i = ih(s, o); + if (null !== i) gi(i, s, o, R()); + il(s, o); + } + }), + (Mt = function () { + return At; + }), + (Tt = function (s, o) { + var i = At; + try { + return (At = s), o(); + } finally { + At = i; + } + }), + (Xe = function (s, o, i) { + switch (o) { + case 'input': + if ((bb(s, i), (o = i.name), 'radio' === i.type && null != o)) { + for (i = s; i.parentNode; ) i = i.parentNode; + for ( + i = i.querySelectorAll( + 'input[name=' + JSON.stringify('' + o) + '][type="radio"]' + ), + o = 0; + o < i.length; + o++ + ) { + var u = i[o]; + if (u !== s && u.form === s.form) { + var _ = Db(u); + if (!_) throw Error(p(90)); + Wa(u), bb(u, _); + } + } + } + break; + case 'textarea': + ib(s, i); + break; + case 'select': + null != (o = i.value) && fb(s, !!i.multiple, o, !1); + } + }), + (Gb = Qk), + (Hb = Rk); + var po = { usingClientEntryPoint: !1, Events: [Cb, ue, Db, Eb, Fb, Qk] }, + ho = { + findFiberByHostInstance: Wc, + bundleType: 0, + version: '18.3.1', + rendererPackageName: 'react-dom' + }, + fo = { + bundleType: ho.bundleType, + version: ho.version, + rendererPackageName: ho.rendererPackageName, + rendererConfig: ho.rendererConfig, + overrideHookState: null, + overrideHookStateDeletePath: null, + overrideHookStateRenamePath: null, + overrideProps: null, + overridePropsDeletePath: null, + overridePropsRenamePath: null, + setErrorHandler: null, + setSuspenseHandler: null, + scheduleUpdate: null, + currentDispatcherRef: z.ReactCurrentDispatcher, + findHostInstanceByFiber: function (s) { + return null === (s = Zb(s)) ? null : s.stateNode; + }, + findFiberByHostInstance: + ho.findFiberByHostInstance || + function jl() { + return null; + }, + findHostInstancesForRefresh: null, + scheduleRefresh: null, + scheduleRoot: null, + setRefreshHandler: null, + getCurrentFiber: null, + reconcilerVersion: '18.3.1-next-f1338f8080-20240426' + }; + if ('undefined' != typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { + var mo = __REACT_DEVTOOLS_GLOBAL_HOOK__; + if (!mo.isDisabled && mo.supportsFiber) + try { + (Et = mo.inject(fo)), (wt = mo); + } catch (qe) {} + } + (o.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = po), + (o.createPortal = function (s, o) { + var i = 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null; + if (!nl(o)) throw Error(p(200)); + return (function cl(s, o, i) { + var u = 3 < arguments.length && void 0 !== arguments[3] ? arguments[3] : null; + return { + $$typeof: Z, + key: null == u ? null : '' + u, + children: s, + containerInfo: o, + implementation: i + }; + })(s, o, null, i); + }), + (o.createRoot = function (s, o) { + if (!nl(s)) throw Error(p(299)); + var i = !1, + u = '', + _ = uo; + return ( + null != o && + (!0 === o.unstable_strictMode && (i = !0), + void 0 !== o.identifierPrefix && (u = o.identifierPrefix), + void 0 !== o.onRecoverableError && (_ = o.onRecoverableError)), + (o = bl(s, 1, !1, null, 0, i, 0, u, _)), + (s[mn] = o.current), + sf(8 === s.nodeType ? s.parentNode : s), + new ll(o) + ); + }), + (o.findDOMNode = function (s) { + if (null == s) return null; + if (1 === s.nodeType) return s; + var o = s._reactInternals; + if (void 0 === o) { + if ('function' == typeof s.render) throw Error(p(188)); + throw ((s = Object.keys(s).join(',')), Error(p(268, s))); + } + return (s = null === (s = Zb(o)) ? null : s.stateNode); + }), + (o.flushSync = function (s) { + return Rk(s); + }), + (o.hydrate = function (s, o, i) { + if (!ol(o)) throw Error(p(200)); + return rl(null, s, o, !0, i); + }), + (o.hydrateRoot = function (s, o, i) { + if (!nl(s)) throw Error(p(405)); + var u = (null != i && i.hydratedSources) || null, + _ = !1, + w = '', + x = uo; + if ( + (null != i && + (!0 === i.unstable_strictMode && (_ = !0), + void 0 !== i.identifierPrefix && (w = i.identifierPrefix), + void 0 !== i.onRecoverableError && (x = i.onRecoverableError)), + (o = el(o, null, s, 1, null != i ? i : null, _, 0, w, x)), + (s[mn] = o.current), + sf(s), + u) + ) + for (s = 0; s < u.length; s++) + (_ = (_ = (i = u[s])._getVersion)(i._source)), + null == o.mutableSourceEagerHydrationData + ? (o.mutableSourceEagerHydrationData = [i, _]) + : o.mutableSourceEagerHydrationData.push(i, _); + return new ml(o); + }), + (o.render = function (s, o, i) { + if (!ol(o)) throw Error(p(200)); + return rl(null, s, o, !1, i); + }), + (o.unmountComponentAtNode = function (s) { + if (!ol(s)) throw Error(p(40)); + return ( + !!s._reactRootContainer && + (Rk(function () { + rl(null, null, s, !1, function () { + (s._reactRootContainer = null), (s[mn] = null); + }); + }), + !0) + ); + }), + (o.unstable_batchedUpdates = Qk), + (o.unstable_renderSubtreeIntoContainer = function (s, o, i, u) { + if (!ol(i)) throw Error(p(200)); + if (null == s || void 0 === s._reactInternals) throw Error(p(38)); + return rl(s, o, i, !1, u); + }), + (o.version = '18.3.1-next-f1338f8080-20240426'); + }, + 40961: (s, o, i) => { + 'use strict'; + !(function checkDCE() { + if ( + 'undefined' != typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && + 'function' == typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE + ) + try { + __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(checkDCE); + } catch (s) { + console.error(s); + } + })(), + (s.exports = i(22551)); + }, + 2209: (s, o, i) => { + 'use strict'; + var u, + _ = i(9404), + w = function productionTypeChecker() { + invariant(!1, 'ImmutablePropTypes type checking code is stripped in production.'); + }; + w.isRequired = w; + var x = function getProductionTypeChecker() { + return w; + }; + function getPropType(s) { + var o = typeof s; + return Array.isArray(s) + ? 'array' + : s instanceof RegExp + ? 'object' + : s instanceof _.Iterable + ? 'Immutable.' + s.toSource().split(' ')[0] + : o; + } + function createChainableTypeChecker(s) { + function checkType(o, i, u, _, w, x) { + for (var C = arguments.length, j = Array(C > 6 ? C - 6 : 0), L = 6; L < C; L++) + j[L - 6] = arguments[L]; + return ( + (x = x || u), + (_ = _ || '<>'), + null != i[u] + ? s.apply(void 0, [i, u, _, w, x].concat(j)) + : o + ? new Error('Required ' + w + ' `' + x + '` was not specified in `' + _ + '`.') + : void 0 + ); + } + var o = checkType.bind(null, !1); + return (o.isRequired = checkType.bind(null, !0)), o; + } + function createIterableSubclassTypeChecker(s, o) { + return (function createImmutableTypeChecker(s, o) { + return createChainableTypeChecker(function validate(i, u, _, w, x) { + var C = i[u]; + if (!o(C)) { + var j = getPropType(C); + return new Error( + 'Invalid ' + + w + + ' `' + + x + + '` of type `' + + j + + '` supplied to `' + + _ + + '`, expected `' + + s + + '`.' + ); + } + return null; + }); + })('Iterable.' + s, function (s) { + return _.Iterable.isIterable(s) && o(s); + }); + } + ((u = { + listOf: x, + mapOf: x, + orderedMapOf: x, + setOf: x, + orderedSetOf: x, + stackOf: x, + iterableOf: x, + recordOf: x, + shape: x, + contains: x, + mapContains: x, + orderedMapContains: x, + list: w, + map: w, + orderedMap: w, + set: w, + orderedSet: w, + stack: w, + seq: w, + record: w, + iterable: w + }).iterable.indexed = createIterableSubclassTypeChecker('Indexed', _.Iterable.isIndexed)), + (u.iterable.keyed = createIterableSubclassTypeChecker('Keyed', _.Iterable.isKeyed)), + (s.exports = u); + }, + 15287: (s, o) => { + 'use strict'; + var i = Symbol.for('react.element'), + u = Symbol.for('react.portal'), + _ = Symbol.for('react.fragment'), + w = Symbol.for('react.strict_mode'), + x = Symbol.for('react.profiler'), + C = Symbol.for('react.provider'), + j = Symbol.for('react.context'), + L = Symbol.for('react.forward_ref'), + B = Symbol.for('react.suspense'), + $ = Symbol.for('react.memo'), + V = Symbol.for('react.lazy'), + U = Symbol.iterator; + var z = { + isMounted: function () { + return !1; + }, + enqueueForceUpdate: function () {}, + enqueueReplaceState: function () {}, + enqueueSetState: function () {} + }, + Y = Object.assign, + Z = {}; + function E(s, o, i) { + (this.props = s), (this.context = o), (this.refs = Z), (this.updater = i || z); + } + function F() {} + function G(s, o, i) { + (this.props = s), (this.context = o), (this.refs = Z), (this.updater = i || z); + } + (E.prototype.isReactComponent = {}), + (E.prototype.setState = function (s, o) { + if ('object' != typeof s && 'function' != typeof s && null != s) + throw Error( + 'setState(...): takes an object of state variables to update or a function which returns an object of state variables.' + ); + this.updater.enqueueSetState(this, s, o, 'setState'); + }), + (E.prototype.forceUpdate = function (s) { + this.updater.enqueueForceUpdate(this, s, 'forceUpdate'); + }), + (F.prototype = E.prototype); + var ee = (G.prototype = new F()); + (ee.constructor = G), Y(ee, E.prototype), (ee.isPureReactComponent = !0); + var ie = Array.isArray, + ae = Object.prototype.hasOwnProperty, + le = { current: null }, + ce = { key: !0, ref: !0, __self: !0, __source: !0 }; + function M(s, o, u) { + var _, + w = {}, + x = null, + C = null; + if (null != o) + for (_ in (void 0 !== o.ref && (C = o.ref), void 0 !== o.key && (x = '' + o.key), o)) + ae.call(o, _) && !ce.hasOwnProperty(_) && (w[_] = o[_]); + var j = arguments.length - 2; + if (1 === j) w.children = u; + else if (1 < j) { + for (var L = Array(j), B = 0; B < j; B++) L[B] = arguments[B + 2]; + w.children = L; + } + if (s && s.defaultProps) + for (_ in (j = s.defaultProps)) void 0 === w[_] && (w[_] = j[_]); + return { $$typeof: i, type: s, key: x, ref: C, props: w, _owner: le.current }; + } + function O(s) { + return 'object' == typeof s && null !== s && s.$$typeof === i; + } + var pe = /\/+/g; + function Q(s, o) { + return 'object' == typeof s && null !== s && null != s.key + ? (function escape(s) { + var o = { '=': '=0', ':': '=2' }; + return ( + '$' + + s.replace(/[=:]/g, function (s) { + return o[s]; + }) + ); + })('' + s.key) + : o.toString(36); + } + function R(s, o, _, w, x) { + var C = typeof s; + ('undefined' !== C && 'boolean' !== C) || (s = null); + var j = !1; + if (null === s) j = !0; + else + switch (C) { + case 'string': + case 'number': + j = !0; + break; + case 'object': + switch (s.$$typeof) { + case i: + case u: + j = !0; + } + } + if (j) + return ( + (x = x((j = s))), + (s = '' === w ? '.' + Q(j, 0) : w), + ie(x) + ? ((_ = ''), + null != s && (_ = s.replace(pe, '$&/') + '/'), + R(x, o, _, '', function (s) { + return s; + })) + : null != x && + (O(x) && + (x = (function N(s, o) { + return { + $$typeof: i, + type: s.type, + key: o, + ref: s.ref, + props: s.props, + _owner: s._owner + }; + })( + x, + _ + + (!x.key || (j && j.key === x.key) + ? '' + : ('' + x.key).replace(pe, '$&/') + '/') + + s + )), + o.push(x)), + 1 + ); + if (((j = 0), (w = '' === w ? '.' : w + ':'), ie(s))) + for (var L = 0; L < s.length; L++) { + var B = w + Q((C = s[L]), L); + j += R(C, o, _, B, x); + } + else if ( + ((B = (function A(s) { + return null === s || 'object' != typeof s + ? null + : 'function' == typeof (s = (U && s[U]) || s['@@iterator']) + ? s + : null; + })(s)), + 'function' == typeof B) + ) + for (s = B.call(s), L = 0; !(C = s.next()).done; ) + j += R((C = C.value), o, _, (B = w + Q(C, L++)), x); + else if ('object' === C) + throw ( + ((o = String(s)), + Error( + 'Objects are not valid as a React child (found: ' + + ('[object Object]' === o + ? 'object with keys {' + Object.keys(s).join(', ') + '}' + : o) + + '). If you meant to render a collection of children, use an array instead.' + )) + ); + return j; + } + function S(s, o, i) { + if (null == s) return s; + var u = [], + _ = 0; + return ( + R(s, u, '', '', function (s) { + return o.call(i, s, _++); + }), + u + ); + } + function T(s) { + if (-1 === s._status) { + var o = s._result; + (o = o()).then( + function (o) { + (0 !== s._status && -1 !== s._status) || ((s._status = 1), (s._result = o)); + }, + function (o) { + (0 !== s._status && -1 !== s._status) || ((s._status = 2), (s._result = o)); + } + ), + -1 === s._status && ((s._status = 0), (s._result = o)); + } + if (1 === s._status) return s._result.default; + throw s._result; + } + var de = { current: null }, + fe = { transition: null }, + ye = { ReactCurrentDispatcher: de, ReactCurrentBatchConfig: fe, ReactCurrentOwner: le }; + function X() { + throw Error('act(...) is not supported in production builds of React.'); + } + (o.Children = { + map: S, + forEach: function (s, o, i) { + S( + s, + function () { + o.apply(this, arguments); + }, + i + ); + }, + count: function (s) { + var o = 0; + return ( + S(s, function () { + o++; + }), + o + ); + }, + toArray: function (s) { + return ( + S(s, function (s) { + return s; + }) || [] + ); + }, + only: function (s) { + if (!O(s)) + throw Error( + 'React.Children.only expected to receive a single React element child.' + ); + return s; + } + }), + (o.Component = E), + (o.Fragment = _), + (o.Profiler = x), + (o.PureComponent = G), + (o.StrictMode = w), + (o.Suspense = B), + (o.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = ye), + (o.act = X), + (o.cloneElement = function (s, o, u) { + if (null == s) + throw Error( + 'React.cloneElement(...): The argument must be a React element, but you passed ' + + s + + '.' + ); + var _ = Y({}, s.props), + w = s.key, + x = s.ref, + C = s._owner; + if (null != o) { + if ( + (void 0 !== o.ref && ((x = o.ref), (C = le.current)), + void 0 !== o.key && (w = '' + o.key), + s.type && s.type.defaultProps) + ) + var j = s.type.defaultProps; + for (L in o) + ae.call(o, L) && + !ce.hasOwnProperty(L) && + (_[L] = void 0 === o[L] && void 0 !== j ? j[L] : o[L]); + } + var L = arguments.length - 2; + if (1 === L) _.children = u; + else if (1 < L) { + j = Array(L); + for (var B = 0; B < L; B++) j[B] = arguments[B + 2]; + _.children = j; + } + return { $$typeof: i, type: s.type, key: w, ref: x, props: _, _owner: C }; + }), + (o.createContext = function (s) { + return ( + ((s = { + $$typeof: j, + _currentValue: s, + _currentValue2: s, + _threadCount: 0, + Provider: null, + Consumer: null, + _defaultValue: null, + _globalName: null + }).Provider = { $$typeof: C, _context: s }), + (s.Consumer = s) + ); + }), + (o.createElement = M), + (o.createFactory = function (s) { + var o = M.bind(null, s); + return (o.type = s), o; + }), + (o.createRef = function () { + return { current: null }; + }), + (o.forwardRef = function (s) { + return { $$typeof: L, render: s }; + }), + (o.isValidElement = O), + (o.lazy = function (s) { + return { $$typeof: V, _payload: { _status: -1, _result: s }, _init: T }; + }), + (o.memo = function (s, o) { + return { $$typeof: $, type: s, compare: void 0 === o ? null : o }; + }), + (o.startTransition = function (s) { + var o = fe.transition; + fe.transition = {}; + try { + s(); + } finally { + fe.transition = o; + } + }), + (o.unstable_act = X), + (o.useCallback = function (s, o) { + return de.current.useCallback(s, o); + }), + (o.useContext = function (s) { + return de.current.useContext(s); + }), + (o.useDebugValue = function () {}), + (o.useDeferredValue = function (s) { + return de.current.useDeferredValue(s); + }), + (o.useEffect = function (s, o) { + return de.current.useEffect(s, o); + }), + (o.useId = function () { + return de.current.useId(); + }), + (o.useImperativeHandle = function (s, o, i) { + return de.current.useImperativeHandle(s, o, i); + }), + (o.useInsertionEffect = function (s, o) { + return de.current.useInsertionEffect(s, o); + }), + (o.useLayoutEffect = function (s, o) { + return de.current.useLayoutEffect(s, o); + }), + (o.useMemo = function (s, o) { + return de.current.useMemo(s, o); + }), + (o.useReducer = function (s, o, i) { + return de.current.useReducer(s, o, i); + }), + (o.useRef = function (s) { + return de.current.useRef(s); + }), + (o.useState = function (s) { + return de.current.useState(s); + }), + (o.useSyncExternalStore = function (s, o, i) { + return de.current.useSyncExternalStore(s, o, i); + }), + (o.useTransition = function () { + return de.current.useTransition(); + }), + (o.version = '18.3.1'); + }, + 96540: (s, o, i) => { + 'use strict'; + s.exports = i(15287); + }, + 86048: (s) => { + 'use strict'; + var o = {}; + function createErrorType(s, i, u) { + u || (u = Error); + var _ = (function (s) { + function NodeError(o, u, _) { + return ( + s.call( + this, + (function getMessage(s, o, u) { + return 'string' == typeof i ? i : i(s, o, u); + })(o, u, _) + ) || this + ); + } + return ( + (function _inheritsLoose(s, o) { + (s.prototype = Object.create(o.prototype)), + (s.prototype.constructor = s), + (s.__proto__ = o); + })(NodeError, s), + NodeError + ); + })(u); + (_.prototype.name = u.name), (_.prototype.code = s), (o[s] = _); + } + function oneOf(s, o) { + if (Array.isArray(s)) { + var i = s.length; + return ( + (s = s.map(function (s) { + return String(s); + })), + i > 2 + ? 'one of '.concat(o, ' ').concat(s.slice(0, i - 1).join(', '), ', or ') + + s[i - 1] + : 2 === i + ? 'one of '.concat(o, ' ').concat(s[0], ' or ').concat(s[1]) + : 'of '.concat(o, ' ').concat(s[0]) + ); + } + return 'of '.concat(o, ' ').concat(String(s)); + } + createErrorType( + 'ERR_INVALID_OPT_VALUE', + function (s, o) { + return 'The value "' + o + '" is invalid for option "' + s + '"'; + }, + TypeError + ), + createErrorType( + 'ERR_INVALID_ARG_TYPE', + function (s, o, i) { + var u, _; + if ( + ('string' == typeof o && + (function startsWith(s, o, i) { + return s.substr(!i || i < 0 ? 0 : +i, o.length) === o; + })(o, 'not ') + ? ((u = 'must not be'), (o = o.replace(/^not /, ''))) + : (u = 'must be'), + (function endsWith(s, o, i) { + return ( + (void 0 === i || i > s.length) && (i = s.length), + s.substring(i - o.length, i) === o + ); + })(s, ' argument')) + ) + _ = 'The '.concat(s, ' ').concat(u, ' ').concat(oneOf(o, 'type')); + else { + var w = (function includes(s, o, i) { + return ( + 'number' != typeof i && (i = 0), + !(i + o.length > s.length) && -1 !== s.indexOf(o, i) + ); + })(s, '.') + ? 'property' + : 'argument'; + _ = 'The "' + .concat(s, '" ') + .concat(w, ' ') + .concat(u, ' ') + .concat(oneOf(o, 'type')); + } + return (_ += '. Received type '.concat(typeof i)); + }, + TypeError + ), + createErrorType('ERR_STREAM_PUSH_AFTER_EOF', 'stream.push() after EOF'), + createErrorType('ERR_METHOD_NOT_IMPLEMENTED', function (s) { + return 'The ' + s + ' method is not implemented'; + }), + createErrorType('ERR_STREAM_PREMATURE_CLOSE', 'Premature close'), + createErrorType('ERR_STREAM_DESTROYED', function (s) { + return 'Cannot call ' + s + ' after a stream was destroyed'; + }), + createErrorType('ERR_MULTIPLE_CALLBACK', 'Callback called multiple times'), + createErrorType('ERR_STREAM_CANNOT_PIPE', 'Cannot pipe, not readable'), + createErrorType('ERR_STREAM_WRITE_AFTER_END', 'write after end'), + createErrorType( + 'ERR_STREAM_NULL_VALUES', + 'May not write null values to stream', + TypeError + ), + createErrorType( + 'ERR_UNKNOWN_ENCODING', + function (s) { + return 'Unknown encoding: ' + s; + }, + TypeError + ), + createErrorType( + 'ERR_STREAM_UNSHIFT_AFTER_END_EVENT', + 'stream.unshift() after end event' + ), + (s.exports.F = o); + }, + 25382: (s, o, i) => { + 'use strict'; + var u = i(65606), + _ = + Object.keys || + function (s) { + var o = []; + for (var i in s) o.push(i); + return o; + }; + s.exports = Duplex; + var w = i(45412), + x = i(16708); + i(56698)(Duplex, w); + for (var C = _(x.prototype), j = 0; j < C.length; j++) { + var L = C[j]; + Duplex.prototype[L] || (Duplex.prototype[L] = x.prototype[L]); + } + function Duplex(s) { + if (!(this instanceof Duplex)) return new Duplex(s); + w.call(this, s), + x.call(this, s), + (this.allowHalfOpen = !0), + s && + (!1 === s.readable && (this.readable = !1), + !1 === s.writable && (this.writable = !1), + !1 === s.allowHalfOpen && ((this.allowHalfOpen = !1), this.once('end', onend))); + } + function onend() { + this._writableState.ended || u.nextTick(onEndNT, this); + } + function onEndNT(s) { + s.end(); + } + Object.defineProperty(Duplex.prototype, 'writableHighWaterMark', { + enumerable: !1, + get: function get() { + return this._writableState.highWaterMark; + } + }), + Object.defineProperty(Duplex.prototype, 'writableBuffer', { + enumerable: !1, + get: function get() { + return this._writableState && this._writableState.getBuffer(); + } + }), + Object.defineProperty(Duplex.prototype, 'writableLength', { + enumerable: !1, + get: function get() { + return this._writableState.length; + } + }), + Object.defineProperty(Duplex.prototype, 'destroyed', { + enumerable: !1, + get: function get() { + return ( + void 0 !== this._readableState && + void 0 !== this._writableState && + this._readableState.destroyed && + this._writableState.destroyed + ); + }, + set: function set(s) { + void 0 !== this._readableState && + void 0 !== this._writableState && + ((this._readableState.destroyed = s), (this._writableState.destroyed = s)); + } + }); + }, + 63600: (s, o, i) => { + 'use strict'; + s.exports = PassThrough; + var u = i(74610); + function PassThrough(s) { + if (!(this instanceof PassThrough)) return new PassThrough(s); + u.call(this, s); + } + i(56698)(PassThrough, u), + (PassThrough.prototype._transform = function (s, o, i) { + i(null, s); + }); + }, + 45412: (s, o, i) => { + 'use strict'; + var u, + _ = i(65606); + (s.exports = Readable), (Readable.ReadableState = ReadableState); + i(37007).EventEmitter; + var w = function EElistenerCount(s, o) { + return s.listeners(o).length; + }, + x = i(40345), + C = i(48287).Buffer, + j = + (void 0 !== i.g + ? i.g + : 'undefined' != typeof window + ? window + : 'undefined' != typeof self + ? self + : {} + ).Uint8Array || function () {}; + var L, + B = i(79838); + L = B && B.debuglog ? B.debuglog('stream') : function debug() {}; + var $, + V, + U, + z = i(80345), + Y = i(75896), + Z = i(65291).getHighWaterMark, + ee = i(86048).F, + ie = ee.ERR_INVALID_ARG_TYPE, + ae = ee.ERR_STREAM_PUSH_AFTER_EOF, + le = ee.ERR_METHOD_NOT_IMPLEMENTED, + ce = ee.ERR_STREAM_UNSHIFT_AFTER_END_EVENT; + i(56698)(Readable, x); + var pe = Y.errorOrDestroy, + de = ['error', 'close', 'destroy', 'pause', 'resume']; + function ReadableState(s, o, _) { + (u = u || i(25382)), + (s = s || {}), + 'boolean' != typeof _ && (_ = o instanceof u), + (this.objectMode = !!s.objectMode), + _ && (this.objectMode = this.objectMode || !!s.readableObjectMode), + (this.highWaterMark = Z(this, s, 'readableHighWaterMark', _)), + (this.buffer = new z()), + (this.length = 0), + (this.pipes = null), + (this.pipesCount = 0), + (this.flowing = null), + (this.ended = !1), + (this.endEmitted = !1), + (this.reading = !1), + (this.sync = !0), + (this.needReadable = !1), + (this.emittedReadable = !1), + (this.readableListening = !1), + (this.resumeScheduled = !1), + (this.paused = !0), + (this.emitClose = !1 !== s.emitClose), + (this.autoDestroy = !!s.autoDestroy), + (this.destroyed = !1), + (this.defaultEncoding = s.defaultEncoding || 'utf8'), + (this.awaitDrain = 0), + (this.readingMore = !1), + (this.decoder = null), + (this.encoding = null), + s.encoding && + ($ || ($ = i(83141).I), + (this.decoder = new $(s.encoding)), + (this.encoding = s.encoding)); + } + function Readable(s) { + if (((u = u || i(25382)), !(this instanceof Readable))) return new Readable(s); + var o = this instanceof u; + (this._readableState = new ReadableState(s, this, o)), + (this.readable = !0), + s && + ('function' == typeof s.read && (this._read = s.read), + 'function' == typeof s.destroy && (this._destroy = s.destroy)), + x.call(this); + } + function readableAddChunk(s, o, i, u, _) { + L('readableAddChunk', o); + var w, + x = s._readableState; + if (null === o) + (x.reading = !1), + (function onEofChunk(s, o) { + if ((L('onEofChunk'), o.ended)) return; + if (o.decoder) { + var i = o.decoder.end(); + i && i.length && (o.buffer.push(i), (o.length += o.objectMode ? 1 : i.length)); + } + (o.ended = !0), + o.sync + ? emitReadable(s) + : ((o.needReadable = !1), + o.emittedReadable || ((o.emittedReadable = !0), emitReadable_(s))); + })(s, x); + else if ( + (_ || + (w = (function chunkInvalid(s, o) { + var i; + (function _isUint8Array(s) { + return C.isBuffer(s) || s instanceof j; + })(o) || + 'string' == typeof o || + void 0 === o || + s.objectMode || + (i = new ie('chunk', ['string', 'Buffer', 'Uint8Array'], o)); + return i; + })(x, o)), + w) + ) + pe(s, w); + else if (x.objectMode || (o && o.length > 0)) + if ( + ('string' == typeof o || + x.objectMode || + Object.getPrototypeOf(o) === C.prototype || + (o = (function _uint8ArrayToBuffer(s) { + return C.from(s); + })(o)), + u) + ) + x.endEmitted ? pe(s, new ce()) : addChunk(s, x, o, !0); + else if (x.ended) pe(s, new ae()); + else { + if (x.destroyed) return !1; + (x.reading = !1), + x.decoder && !i + ? ((o = x.decoder.write(o)), + x.objectMode || 0 !== o.length ? addChunk(s, x, o, !1) : maybeReadMore(s, x)) + : addChunk(s, x, o, !1); + } + else u || ((x.reading = !1), maybeReadMore(s, x)); + return !x.ended && (x.length < x.highWaterMark || 0 === x.length); + } + function addChunk(s, o, i, u) { + o.flowing && 0 === o.length && !o.sync + ? ((o.awaitDrain = 0), s.emit('data', i)) + : ((o.length += o.objectMode ? 1 : i.length), + u ? o.buffer.unshift(i) : o.buffer.push(i), + o.needReadable && emitReadable(s)), + maybeReadMore(s, o); + } + Object.defineProperty(Readable.prototype, 'destroyed', { + enumerable: !1, + get: function get() { + return void 0 !== this._readableState && this._readableState.destroyed; + }, + set: function set(s) { + this._readableState && (this._readableState.destroyed = s); + } + }), + (Readable.prototype.destroy = Y.destroy), + (Readable.prototype._undestroy = Y.undestroy), + (Readable.prototype._destroy = function (s, o) { + o(s); + }), + (Readable.prototype.push = function (s, o) { + var i, + u = this._readableState; + return ( + u.objectMode + ? (i = !0) + : 'string' == typeof s && + ((o = o || u.defaultEncoding) !== u.encoding && ((s = C.from(s, o)), (o = '')), + (i = !0)), + readableAddChunk(this, s, o, !1, i) + ); + }), + (Readable.prototype.unshift = function (s) { + return readableAddChunk(this, s, null, !0, !1); + }), + (Readable.prototype.isPaused = function () { + return !1 === this._readableState.flowing; + }), + (Readable.prototype.setEncoding = function (s) { + $ || ($ = i(83141).I); + var o = new $(s); + (this._readableState.decoder = o), + (this._readableState.encoding = this._readableState.decoder.encoding); + for (var u = this._readableState.buffer.head, _ = ''; null !== u; ) + (_ += o.write(u.data)), (u = u.next); + return ( + this._readableState.buffer.clear(), + '' !== _ && this._readableState.buffer.push(_), + (this._readableState.length = _.length), + this + ); + }); + var fe = 1073741824; + function howMuchToRead(s, o) { + return s <= 0 || (0 === o.length && o.ended) + ? 0 + : o.objectMode + ? 1 + : s != s + ? o.flowing && o.length + ? o.buffer.head.data.length + : o.length + : (s > o.highWaterMark && + (o.highWaterMark = (function computeNewHighWaterMark(s) { + return ( + s >= fe + ? (s = fe) + : (s--, + (s |= s >>> 1), + (s |= s >>> 2), + (s |= s >>> 4), + (s |= s >>> 8), + (s |= s >>> 16), + s++), + s + ); + })(s)), + s <= o.length ? s : o.ended ? o.length : ((o.needReadable = !0), 0)); + } + function emitReadable(s) { + var o = s._readableState; + L('emitReadable', o.needReadable, o.emittedReadable), + (o.needReadable = !1), + o.emittedReadable || + (L('emitReadable', o.flowing), + (o.emittedReadable = !0), + _.nextTick(emitReadable_, s)); + } + function emitReadable_(s) { + var o = s._readableState; + L('emitReadable_', o.destroyed, o.length, o.ended), + o.destroyed || + (!o.length && !o.ended) || + (s.emit('readable'), (o.emittedReadable = !1)), + (o.needReadable = !o.flowing && !o.ended && o.length <= o.highWaterMark), + flow(s); + } + function maybeReadMore(s, o) { + o.readingMore || ((o.readingMore = !0), _.nextTick(maybeReadMore_, s, o)); + } + function maybeReadMore_(s, o) { + for ( + ; + !o.reading && + !o.ended && + (o.length < o.highWaterMark || (o.flowing && 0 === o.length)); + + ) { + var i = o.length; + if ((L('maybeReadMore read 0'), s.read(0), i === o.length)) break; + } + o.readingMore = !1; + } + function updateReadableListening(s) { + var o = s._readableState; + (o.readableListening = s.listenerCount('readable') > 0), + o.resumeScheduled && !o.paused + ? (o.flowing = !0) + : s.listenerCount('data') > 0 && s.resume(); + } + function nReadingNextTick(s) { + L('readable nexttick read 0'), s.read(0); + } + function resume_(s, o) { + L('resume', o.reading), + o.reading || s.read(0), + (o.resumeScheduled = !1), + s.emit('resume'), + flow(s), + o.flowing && !o.reading && s.read(0); + } + function flow(s) { + var o = s._readableState; + for (L('flow', o.flowing); o.flowing && null !== s.read(); ); + } + function fromList(s, o) { + return 0 === o.length + ? null + : (o.objectMode + ? (i = o.buffer.shift()) + : !s || s >= o.length + ? ((i = o.decoder + ? o.buffer.join('') + : 1 === o.buffer.length + ? o.buffer.first() + : o.buffer.concat(o.length)), + o.buffer.clear()) + : (i = o.buffer.consume(s, o.decoder)), + i); + var i; + } + function endReadable(s) { + var o = s._readableState; + L('endReadable', o.endEmitted), + o.endEmitted || ((o.ended = !0), _.nextTick(endReadableNT, o, s)); + } + function endReadableNT(s, o) { + if ( + (L('endReadableNT', s.endEmitted, s.length), + !s.endEmitted && + 0 === s.length && + ((s.endEmitted = !0), (o.readable = !1), o.emit('end'), s.autoDestroy)) + ) { + var i = o._writableState; + (!i || (i.autoDestroy && i.finished)) && o.destroy(); + } + } + function indexOf(s, o) { + for (var i = 0, u = s.length; i < u; i++) if (s[i] === o) return i; + return -1; + } + (Readable.prototype.read = function (s) { + L('read', s), (s = parseInt(s, 10)); + var o = this._readableState, + i = s; + if ( + (0 !== s && (o.emittedReadable = !1), + 0 === s && + o.needReadable && + ((0 !== o.highWaterMark ? o.length >= o.highWaterMark : o.length > 0) || o.ended)) + ) + return ( + L('read: emitReadable', o.length, o.ended), + 0 === o.length && o.ended ? endReadable(this) : emitReadable(this), + null + ); + if (0 === (s = howMuchToRead(s, o)) && o.ended) + return 0 === o.length && endReadable(this), null; + var u, + _ = o.needReadable; + return ( + L('need readable', _), + (0 === o.length || o.length - s < o.highWaterMark) && + L('length less than watermark', (_ = !0)), + o.ended || o.reading + ? L('reading or ended', (_ = !1)) + : _ && + (L('do read'), + (o.reading = !0), + (o.sync = !0), + 0 === o.length && (o.needReadable = !0), + this._read(o.highWaterMark), + (o.sync = !1), + o.reading || (s = howMuchToRead(i, o))), + null === (u = s > 0 ? fromList(s, o) : null) + ? ((o.needReadable = o.length <= o.highWaterMark), (s = 0)) + : ((o.length -= s), (o.awaitDrain = 0)), + 0 === o.length && + (o.ended || (o.needReadable = !0), i !== s && o.ended && endReadable(this)), + null !== u && this.emit('data', u), + u + ); + }), + (Readable.prototype._read = function (s) { + pe(this, new le('_read()')); + }), + (Readable.prototype.pipe = function (s, o) { + var i = this, + u = this._readableState; + switch (u.pipesCount) { + case 0: + u.pipes = s; + break; + case 1: + u.pipes = [u.pipes, s]; + break; + default: + u.pipes.push(s); + } + (u.pipesCount += 1), L('pipe count=%d opts=%j', u.pipesCount, o); + var x = (!o || !1 !== o.end) && s !== _.stdout && s !== _.stderr ? onend : unpipe; + function onunpipe(o, _) { + L('onunpipe'), + o === i && + _ && + !1 === _.hasUnpiped && + ((_.hasUnpiped = !0), + (function cleanup() { + L('cleanup'), + s.removeListener('close', onclose), + s.removeListener('finish', onfinish), + s.removeListener('drain', C), + s.removeListener('error', onerror), + s.removeListener('unpipe', onunpipe), + i.removeListener('end', onend), + i.removeListener('end', unpipe), + i.removeListener('data', ondata), + (j = !0), + !u.awaitDrain || (s._writableState && !s._writableState.needDrain) || C(); + })()); + } + function onend() { + L('onend'), s.end(); + } + u.endEmitted ? _.nextTick(x) : i.once('end', x), s.on('unpipe', onunpipe); + var C = (function pipeOnDrain(s) { + return function pipeOnDrainFunctionResult() { + var o = s._readableState; + L('pipeOnDrain', o.awaitDrain), + o.awaitDrain && o.awaitDrain--, + 0 === o.awaitDrain && w(s, 'data') && ((o.flowing = !0), flow(s)); + }; + })(i); + s.on('drain', C); + var j = !1; + function ondata(o) { + L('ondata'); + var _ = s.write(o); + L('dest.write', _), + !1 === _ && + (((1 === u.pipesCount && u.pipes === s) || + (u.pipesCount > 1 && -1 !== indexOf(u.pipes, s))) && + !j && + (L('false write response, pause', u.awaitDrain), u.awaitDrain++), + i.pause()); + } + function onerror(o) { + L('onerror', o), + unpipe(), + s.removeListener('error', onerror), + 0 === w(s, 'error') && pe(s, o); + } + function onclose() { + s.removeListener('finish', onfinish), unpipe(); + } + function onfinish() { + L('onfinish'), s.removeListener('close', onclose), unpipe(); + } + function unpipe() { + L('unpipe'), i.unpipe(s); + } + return ( + i.on('data', ondata), + (function prependListener(s, o, i) { + if ('function' == typeof s.prependListener) return s.prependListener(o, i); + s._events && s._events[o] + ? Array.isArray(s._events[o]) + ? s._events[o].unshift(i) + : (s._events[o] = [i, s._events[o]]) + : s.on(o, i); + })(s, 'error', onerror), + s.once('close', onclose), + s.once('finish', onfinish), + s.emit('pipe', i), + u.flowing || (L('pipe resume'), i.resume()), + s + ); + }), + (Readable.prototype.unpipe = function (s) { + var o = this._readableState, + i = { hasUnpiped: !1 }; + if (0 === o.pipesCount) return this; + if (1 === o.pipesCount) + return ( + (s && s !== o.pipes) || + (s || (s = o.pipes), + (o.pipes = null), + (o.pipesCount = 0), + (o.flowing = !1), + s && s.emit('unpipe', this, i)), + this + ); + if (!s) { + var u = o.pipes, + _ = o.pipesCount; + (o.pipes = null), (o.pipesCount = 0), (o.flowing = !1); + for (var w = 0; w < _; w++) u[w].emit('unpipe', this, { hasUnpiped: !1 }); + return this; + } + var x = indexOf(o.pipes, s); + return ( + -1 === x || + (o.pipes.splice(x, 1), + (o.pipesCount -= 1), + 1 === o.pipesCount && (o.pipes = o.pipes[0]), + s.emit('unpipe', this, i)), + this + ); + }), + (Readable.prototype.on = function (s, o) { + var i = x.prototype.on.call(this, s, o), + u = this._readableState; + return ( + 'data' === s + ? ((u.readableListening = this.listenerCount('readable') > 0), + !1 !== u.flowing && this.resume()) + : 'readable' === s && + (u.endEmitted || + u.readableListening || + ((u.readableListening = u.needReadable = !0), + (u.flowing = !1), + (u.emittedReadable = !1), + L('on readable', u.length, u.reading), + u.length + ? emitReadable(this) + : u.reading || _.nextTick(nReadingNextTick, this))), + i + ); + }), + (Readable.prototype.addListener = Readable.prototype.on), + (Readable.prototype.removeListener = function (s, o) { + var i = x.prototype.removeListener.call(this, s, o); + return 'readable' === s && _.nextTick(updateReadableListening, this), i; + }), + (Readable.prototype.removeAllListeners = function (s) { + var o = x.prototype.removeAllListeners.apply(this, arguments); + return ( + ('readable' !== s && void 0 !== s) || _.nextTick(updateReadableListening, this), o + ); + }), + (Readable.prototype.resume = function () { + var s = this._readableState; + return ( + s.flowing || + (L('resume'), + (s.flowing = !s.readableListening), + (function resume(s, o) { + o.resumeScheduled || ((o.resumeScheduled = !0), _.nextTick(resume_, s, o)); + })(this, s)), + (s.paused = !1), + this + ); + }), + (Readable.prototype.pause = function () { + return ( + L('call pause flowing=%j', this._readableState.flowing), + !1 !== this._readableState.flowing && + (L('pause'), (this._readableState.flowing = !1), this.emit('pause')), + (this._readableState.paused = !0), + this + ); + }), + (Readable.prototype.wrap = function (s) { + var o = this, + i = this._readableState, + u = !1; + for (var _ in (s.on('end', function () { + if ((L('wrapped end'), i.decoder && !i.ended)) { + var s = i.decoder.end(); + s && s.length && o.push(s); + } + o.push(null); + }), + s.on('data', function (_) { + (L('wrapped data'), + i.decoder && (_ = i.decoder.write(_)), + i.objectMode && null == _) || + ((i.objectMode || (_ && _.length)) && (o.push(_) || ((u = !0), s.pause()))); + }), + s)) + void 0 === this[_] && + 'function' == typeof s[_] && + (this[_] = (function methodWrap(o) { + return function methodWrapReturnFunction() { + return s[o].apply(s, arguments); + }; + })(_)); + for (var w = 0; w < de.length; w++) s.on(de[w], this.emit.bind(this, de[w])); + return ( + (this._read = function (o) { + L('wrapped _read', o), u && ((u = !1), s.resume()); + }), + this + ); + }), + 'function' == typeof Symbol && + (Readable.prototype[Symbol.asyncIterator] = function () { + return void 0 === V && (V = i(2955)), V(this); + }), + Object.defineProperty(Readable.prototype, 'readableHighWaterMark', { + enumerable: !1, + get: function get() { + return this._readableState.highWaterMark; + } + }), + Object.defineProperty(Readable.prototype, 'readableBuffer', { + enumerable: !1, + get: function get() { + return this._readableState && this._readableState.buffer; + } + }), + Object.defineProperty(Readable.prototype, 'readableFlowing', { + enumerable: !1, + get: function get() { + return this._readableState.flowing; + }, + set: function set(s) { + this._readableState && (this._readableState.flowing = s); + } + }), + (Readable._fromList = fromList), + Object.defineProperty(Readable.prototype, 'readableLength', { + enumerable: !1, + get: function get() { + return this._readableState.length; + } + }), + 'function' == typeof Symbol && + (Readable.from = function (s, o) { + return void 0 === U && (U = i(55157)), U(Readable, s, o); + }); + }, + 74610: (s, o, i) => { + 'use strict'; + s.exports = Transform; + var u = i(86048).F, + _ = u.ERR_METHOD_NOT_IMPLEMENTED, + w = u.ERR_MULTIPLE_CALLBACK, + x = u.ERR_TRANSFORM_ALREADY_TRANSFORMING, + C = u.ERR_TRANSFORM_WITH_LENGTH_0, + j = i(25382); + function afterTransform(s, o) { + var i = this._transformState; + i.transforming = !1; + var u = i.writecb; + if (null === u) return this.emit('error', new w()); + (i.writechunk = null), (i.writecb = null), null != o && this.push(o), u(s); + var _ = this._readableState; + (_.reading = !1), + (_.needReadable || _.length < _.highWaterMark) && this._read(_.highWaterMark); + } + function Transform(s) { + if (!(this instanceof Transform)) return new Transform(s); + j.call(this, s), + (this._transformState = { + afterTransform: afterTransform.bind(this), + needTransform: !1, + transforming: !1, + writecb: null, + writechunk: null, + writeencoding: null + }), + (this._readableState.needReadable = !0), + (this._readableState.sync = !1), + s && + ('function' == typeof s.transform && (this._transform = s.transform), + 'function' == typeof s.flush && (this._flush = s.flush)), + this.on('prefinish', prefinish); + } + function prefinish() { + var s = this; + 'function' != typeof this._flush || this._readableState.destroyed + ? done(this, null, null) + : this._flush(function (o, i) { + done(s, o, i); + }); + } + function done(s, o, i) { + if (o) return s.emit('error', o); + if ((null != i && s.push(i), s._writableState.length)) throw new C(); + if (s._transformState.transforming) throw new x(); + return s.push(null); + } + i(56698)(Transform, j), + (Transform.prototype.push = function (s, o) { + return (this._transformState.needTransform = !1), j.prototype.push.call(this, s, o); + }), + (Transform.prototype._transform = function (s, o, i) { + i(new _('_transform()')); + }), + (Transform.prototype._write = function (s, o, i) { + var u = this._transformState; + if (((u.writecb = i), (u.writechunk = s), (u.writeencoding = o), !u.transforming)) { + var _ = this._readableState; + (u.needTransform || _.needReadable || _.length < _.highWaterMark) && + this._read(_.highWaterMark); + } + }), + (Transform.prototype._read = function (s) { + var o = this._transformState; + null === o.writechunk || o.transforming + ? (o.needTransform = !0) + : ((o.transforming = !0), + this._transform(o.writechunk, o.writeencoding, o.afterTransform)); + }), + (Transform.prototype._destroy = function (s, o) { + j.prototype._destroy.call(this, s, function (s) { + o(s); + }); + }); + }, + 16708: (s, o, i) => { + 'use strict'; + var u, + _ = i(65606); + function CorkedRequest(s) { + var o = this; + (this.next = null), + (this.entry = null), + (this.finish = function () { + !(function onCorkedFinish(s, o, i) { + var u = s.entry; + s.entry = null; + for (; u; ) { + var _ = u.callback; + o.pendingcb--, _(i), (u = u.next); + } + o.corkedRequestsFree.next = s; + })(o, s); + }); + } + (s.exports = Writable), (Writable.WritableState = WritableState); + var w = { deprecate: i(94643) }, + x = i(40345), + C = i(48287).Buffer, + j = + (void 0 !== i.g + ? i.g + : 'undefined' != typeof window + ? window + : 'undefined' != typeof self + ? self + : {} + ).Uint8Array || function () {}; + var L, + B = i(75896), + $ = i(65291).getHighWaterMark, + V = i(86048).F, + U = V.ERR_INVALID_ARG_TYPE, + z = V.ERR_METHOD_NOT_IMPLEMENTED, + Y = V.ERR_MULTIPLE_CALLBACK, + Z = V.ERR_STREAM_CANNOT_PIPE, + ee = V.ERR_STREAM_DESTROYED, + ie = V.ERR_STREAM_NULL_VALUES, + ae = V.ERR_STREAM_WRITE_AFTER_END, + le = V.ERR_UNKNOWN_ENCODING, + ce = B.errorOrDestroy; + function nop() {} + function WritableState(s, o, w) { + (u = u || i(25382)), + (s = s || {}), + 'boolean' != typeof w && (w = o instanceof u), + (this.objectMode = !!s.objectMode), + w && (this.objectMode = this.objectMode || !!s.writableObjectMode), + (this.highWaterMark = $(this, s, 'writableHighWaterMark', w)), + (this.finalCalled = !1), + (this.needDrain = !1), + (this.ending = !1), + (this.ended = !1), + (this.finished = !1), + (this.destroyed = !1); + var x = !1 === s.decodeStrings; + (this.decodeStrings = !x), + (this.defaultEncoding = s.defaultEncoding || 'utf8'), + (this.length = 0), + (this.writing = !1), + (this.corked = 0), + (this.sync = !0), + (this.bufferProcessing = !1), + (this.onwrite = function (s) { + !(function onwrite(s, o) { + var i = s._writableState, + u = i.sync, + w = i.writecb; + if ('function' != typeof w) throw new Y(); + if ( + ((function onwriteStateUpdate(s) { + (s.writing = !1), + (s.writecb = null), + (s.length -= s.writelen), + (s.writelen = 0); + })(i), + o) + ) + !(function onwriteError(s, o, i, u, w) { + --o.pendingcb, + i + ? (_.nextTick(w, u), + _.nextTick(finishMaybe, s, o), + (s._writableState.errorEmitted = !0), + ce(s, u)) + : (w(u), + (s._writableState.errorEmitted = !0), + ce(s, u), + finishMaybe(s, o)); + })(s, i, u, o, w); + else { + var x = needFinish(i) || s.destroyed; + x || i.corked || i.bufferProcessing || !i.bufferedRequest || clearBuffer(s, i), + u ? _.nextTick(afterWrite, s, i, x, w) : afterWrite(s, i, x, w); + } + })(o, s); + }), + (this.writecb = null), + (this.writelen = 0), + (this.bufferedRequest = null), + (this.lastBufferedRequest = null), + (this.pendingcb = 0), + (this.prefinished = !1), + (this.errorEmitted = !1), + (this.emitClose = !1 !== s.emitClose), + (this.autoDestroy = !!s.autoDestroy), + (this.bufferedRequestCount = 0), + (this.corkedRequestsFree = new CorkedRequest(this)); + } + function Writable(s) { + var o = this instanceof (u = u || i(25382)); + if (!o && !L.call(Writable, this)) return new Writable(s); + (this._writableState = new WritableState(s, this, o)), + (this.writable = !0), + s && + ('function' == typeof s.write && (this._write = s.write), + 'function' == typeof s.writev && (this._writev = s.writev), + 'function' == typeof s.destroy && (this._destroy = s.destroy), + 'function' == typeof s.final && (this._final = s.final)), + x.call(this); + } + function doWrite(s, o, i, u, _, w, x) { + (o.writelen = u), + (o.writecb = x), + (o.writing = !0), + (o.sync = !0), + o.destroyed + ? o.onwrite(new ee('write')) + : i + ? s._writev(_, o.onwrite) + : s._write(_, w, o.onwrite), + (o.sync = !1); + } + function afterWrite(s, o, i, u) { + i || + (function onwriteDrain(s, o) { + 0 === o.length && o.needDrain && ((o.needDrain = !1), s.emit('drain')); + })(s, o), + o.pendingcb--, + u(), + finishMaybe(s, o); + } + function clearBuffer(s, o) { + o.bufferProcessing = !0; + var i = o.bufferedRequest; + if (s._writev && i && i.next) { + var u = o.bufferedRequestCount, + _ = new Array(u), + w = o.corkedRequestsFree; + w.entry = i; + for (var x = 0, C = !0; i; ) (_[x] = i), i.isBuf || (C = !1), (i = i.next), (x += 1); + (_.allBuffers = C), + doWrite(s, o, !0, o.length, _, '', w.finish), + o.pendingcb++, + (o.lastBufferedRequest = null), + w.next + ? ((o.corkedRequestsFree = w.next), (w.next = null)) + : (o.corkedRequestsFree = new CorkedRequest(o)), + (o.bufferedRequestCount = 0); + } else { + for (; i; ) { + var j = i.chunk, + L = i.encoding, + B = i.callback; + if ( + (doWrite(s, o, !1, o.objectMode ? 1 : j.length, j, L, B), + (i = i.next), + o.bufferedRequestCount--, + o.writing) + ) + break; + } + null === i && (o.lastBufferedRequest = null); + } + (o.bufferedRequest = i), (o.bufferProcessing = !1); + } + function needFinish(s) { + return ( + s.ending && 0 === s.length && null === s.bufferedRequest && !s.finished && !s.writing + ); + } + function callFinal(s, o) { + s._final(function (i) { + o.pendingcb--, + i && ce(s, i), + (o.prefinished = !0), + s.emit('prefinish'), + finishMaybe(s, o); + }); + } + function finishMaybe(s, o) { + var i = needFinish(o); + if ( + i && + ((function prefinish(s, o) { + o.prefinished || + o.finalCalled || + ('function' != typeof s._final || o.destroyed + ? ((o.prefinished = !0), s.emit('prefinish')) + : (o.pendingcb++, (o.finalCalled = !0), _.nextTick(callFinal, s, o))); + })(s, o), + 0 === o.pendingcb && ((o.finished = !0), s.emit('finish'), o.autoDestroy)) + ) { + var u = s._readableState; + (!u || (u.autoDestroy && u.endEmitted)) && s.destroy(); + } + return i; + } + i(56698)(Writable, x), + (WritableState.prototype.getBuffer = function getBuffer() { + for (var s = this.bufferedRequest, o = []; s; ) o.push(s), (s = s.next); + return o; + }), + (function () { + try { + Object.defineProperty(WritableState.prototype, 'buffer', { + get: w.deprecate( + function writableStateBufferGetter() { + return this.getBuffer(); + }, + '_writableState.buffer is deprecated. Use _writableState.getBuffer instead.', + 'DEP0003' + ) + }); + } catch (s) {} + })(), + 'function' == typeof Symbol && + Symbol.hasInstance && + 'function' == typeof Function.prototype[Symbol.hasInstance] + ? ((L = Function.prototype[Symbol.hasInstance]), + Object.defineProperty(Writable, Symbol.hasInstance, { + value: function value(s) { + return ( + !!L.call(this, s) || + (this === Writable && s && s._writableState instanceof WritableState) + ); + } + })) + : (L = function realHasInstance(s) { + return s instanceof this; + }), + (Writable.prototype.pipe = function () { + ce(this, new Z()); + }), + (Writable.prototype.write = function (s, o, i) { + var u = this._writableState, + w = !1, + x = + !u.objectMode && + (function _isUint8Array(s) { + return C.isBuffer(s) || s instanceof j; + })(s); + return ( + x && + !C.isBuffer(s) && + (s = (function _uint8ArrayToBuffer(s) { + return C.from(s); + })(s)), + 'function' == typeof o && ((i = o), (o = null)), + x ? (o = 'buffer') : o || (o = u.defaultEncoding), + 'function' != typeof i && (i = nop), + u.ending + ? (function writeAfterEnd(s, o) { + var i = new ae(); + ce(s, i), _.nextTick(o, i); + })(this, i) + : (x || + (function validChunk(s, o, i, u) { + var w; + return ( + null === i + ? (w = new ie()) + : 'string' == typeof i || + o.objectMode || + (w = new U('chunk', ['string', 'Buffer'], i)), + !w || (ce(s, w), _.nextTick(u, w), !1) + ); + })(this, u, s, i)) && + (u.pendingcb++, + (w = (function writeOrBuffer(s, o, i, u, _, w) { + if (!i) { + var x = (function decodeChunk(s, o, i) { + s.objectMode || + !1 === s.decodeStrings || + 'string' != typeof o || + (o = C.from(o, i)); + return o; + })(o, u, _); + u !== x && ((i = !0), (_ = 'buffer'), (u = x)); + } + var j = o.objectMode ? 1 : u.length; + o.length += j; + var L = o.length < o.highWaterMark; + L || (o.needDrain = !0); + if (o.writing || o.corked) { + var B = o.lastBufferedRequest; + (o.lastBufferedRequest = { + chunk: u, + encoding: _, + isBuf: i, + callback: w, + next: null + }), + B + ? (B.next = o.lastBufferedRequest) + : (o.bufferedRequest = o.lastBufferedRequest), + (o.bufferedRequestCount += 1); + } else doWrite(s, o, !1, j, u, _, w); + return L; + })(this, u, x, s, o, i))), + w + ); + }), + (Writable.prototype.cork = function () { + this._writableState.corked++; + }), + (Writable.prototype.uncork = function () { + var s = this._writableState; + s.corked && + (s.corked--, + s.writing || + s.corked || + s.bufferProcessing || + !s.bufferedRequest || + clearBuffer(this, s)); + }), + (Writable.prototype.setDefaultEncoding = function setDefaultEncoding(s) { + if ( + ('string' == typeof s && (s = s.toLowerCase()), + !( + [ + 'hex', + 'utf8', + 'utf-8', + 'ascii', + 'binary', + 'base64', + 'ucs2', + 'ucs-2', + 'utf16le', + 'utf-16le', + 'raw' + ].indexOf((s + '').toLowerCase()) > -1 + )) + ) + throw new le(s); + return (this._writableState.defaultEncoding = s), this; + }), + Object.defineProperty(Writable.prototype, 'writableBuffer', { + enumerable: !1, + get: function get() { + return this._writableState && this._writableState.getBuffer(); + } + }), + Object.defineProperty(Writable.prototype, 'writableHighWaterMark', { + enumerable: !1, + get: function get() { + return this._writableState.highWaterMark; + } + }), + (Writable.prototype._write = function (s, o, i) { + i(new z('_write()')); + }), + (Writable.prototype._writev = null), + (Writable.prototype.end = function (s, o, i) { + var u = this._writableState; + return ( + 'function' == typeof s + ? ((i = s), (s = null), (o = null)) + : 'function' == typeof o && ((i = o), (o = null)), + null != s && this.write(s, o), + u.corked && ((u.corked = 1), this.uncork()), + u.ending || + (function endWritable(s, o, i) { + (o.ending = !0), + finishMaybe(s, o), + i && (o.finished ? _.nextTick(i) : s.once('finish', i)); + (o.ended = !0), (s.writable = !1); + })(this, u, i), + this + ); + }), + Object.defineProperty(Writable.prototype, 'writableLength', { + enumerable: !1, + get: function get() { + return this._writableState.length; + } + }), + Object.defineProperty(Writable.prototype, 'destroyed', { + enumerable: !1, + get: function get() { + return void 0 !== this._writableState && this._writableState.destroyed; + }, + set: function set(s) { + this._writableState && (this._writableState.destroyed = s); + } + }), + (Writable.prototype.destroy = B.destroy), + (Writable.prototype._undestroy = B.undestroy), + (Writable.prototype._destroy = function (s, o) { + o(s); + }); + }, + 2955: (s, o, i) => { + 'use strict'; + var u, + _ = i(65606); + function _defineProperty(s, o, i) { + return ( + (o = (function _toPropertyKey(s) { + var o = (function _toPrimitive(s, o) { + if ('object' != typeof s || null === s) return s; + var i = s[Symbol.toPrimitive]; + if (void 0 !== i) { + var u = i.call(s, o || 'default'); + if ('object' != typeof u) return u; + throw new TypeError('@@toPrimitive must return a primitive value.'); + } + return ('string' === o ? String : Number)(s); + })(s, 'string'); + return 'symbol' == typeof o ? o : String(o); + })(o)) in s + ? Object.defineProperty(s, o, { + value: i, + enumerable: !0, + configurable: !0, + writable: !0 + }) + : (s[o] = i), + s + ); + } + var w = i(86238), + x = Symbol('lastResolve'), + C = Symbol('lastReject'), + j = Symbol('error'), + L = Symbol('ended'), + B = Symbol('lastPromise'), + $ = Symbol('handlePromise'), + V = Symbol('stream'); + function createIterResult(s, o) { + return { value: s, done: o }; + } + function readAndResolve(s) { + var o = s[x]; + if (null !== o) { + var i = s[V].read(); + null !== i && + ((s[B] = null), (s[x] = null), (s[C] = null), o(createIterResult(i, !1))); + } + } + function onReadable(s) { + _.nextTick(readAndResolve, s); + } + var U = Object.getPrototypeOf(function () {}), + z = Object.setPrototypeOf( + (_defineProperty( + (u = { + get stream() { + return this[V]; + }, + next: function next() { + var s = this, + o = this[j]; + if (null !== o) return Promise.reject(o); + if (this[L]) return Promise.resolve(createIterResult(void 0, !0)); + if (this[V].destroyed) + return new Promise(function (o, i) { + _.nextTick(function () { + s[j] ? i(s[j]) : o(createIterResult(void 0, !0)); + }); + }); + var i, + u = this[B]; + if (u) + i = new Promise( + (function wrapForNext(s, o) { + return function (i, u) { + s.then(function () { + o[L] ? i(createIterResult(void 0, !0)) : o[$](i, u); + }, u); + }; + })(u, this) + ); + else { + var w = this[V].read(); + if (null !== w) return Promise.resolve(createIterResult(w, !1)); + i = new Promise(this[$]); + } + return (this[B] = i), i; + } + }), + Symbol.asyncIterator, + function () { + return this; + } + ), + _defineProperty(u, 'return', function _return() { + var s = this; + return new Promise(function (o, i) { + s[V].destroy(null, function (s) { + s ? i(s) : o(createIterResult(void 0, !0)); + }); + }); + }), + u), + U + ); + s.exports = function createReadableStreamAsyncIterator(s) { + var o, + i = Object.create( + z, + (_defineProperty((o = {}), V, { value: s, writable: !0 }), + _defineProperty(o, x, { value: null, writable: !0 }), + _defineProperty(o, C, { value: null, writable: !0 }), + _defineProperty(o, j, { value: null, writable: !0 }), + _defineProperty(o, L, { value: s._readableState.endEmitted, writable: !0 }), + _defineProperty(o, $, { + value: function value(s, o) { + var u = i[V].read(); + u + ? ((i[B] = null), (i[x] = null), (i[C] = null), s(createIterResult(u, !1))) + : ((i[x] = s), (i[C] = o)); + }, + writable: !0 + }), + o) + ); + return ( + (i[B] = null), + w(s, function (s) { + if (s && 'ERR_STREAM_PREMATURE_CLOSE' !== s.code) { + var o = i[C]; + return ( + null !== o && ((i[B] = null), (i[x] = null), (i[C] = null), o(s)), + void (i[j] = s) + ); + } + var u = i[x]; + null !== u && + ((i[B] = null), (i[x] = null), (i[C] = null), u(createIterResult(void 0, !0))), + (i[L] = !0); + }), + s.on('readable', onReadable.bind(null, i)), + i + ); + }; + }, + 80345: (s, o, i) => { + 'use strict'; + function ownKeys(s, o) { + var i = Object.keys(s); + if (Object.getOwnPropertySymbols) { + var u = Object.getOwnPropertySymbols(s); + o && + (u = u.filter(function (o) { + return Object.getOwnPropertyDescriptor(s, o).enumerable; + })), + i.push.apply(i, u); + } + return i; + } + function _objectSpread(s) { + for (var o = 1; o < arguments.length; o++) { + var i = null != arguments[o] ? arguments[o] : {}; + o % 2 + ? ownKeys(Object(i), !0).forEach(function (o) { + _defineProperty(s, o, i[o]); + }) + : Object.getOwnPropertyDescriptors + ? Object.defineProperties(s, Object.getOwnPropertyDescriptors(i)) + : ownKeys(Object(i)).forEach(function (o) { + Object.defineProperty(s, o, Object.getOwnPropertyDescriptor(i, o)); + }); + } + return s; + } + function _defineProperty(s, o, i) { + return ( + (o = _toPropertyKey(o)) in s + ? Object.defineProperty(s, o, { + value: i, + enumerable: !0, + configurable: !0, + writable: !0 + }) + : (s[o] = i), + s + ); + } + function _defineProperties(s, o) { + for (var i = 0; i < o.length; i++) { + var u = o[i]; + (u.enumerable = u.enumerable || !1), + (u.configurable = !0), + 'value' in u && (u.writable = !0), + Object.defineProperty(s, _toPropertyKey(u.key), u); + } + } + function _toPropertyKey(s) { + var o = (function _toPrimitive(s, o) { + if ('object' != typeof s || null === s) return s; + var i = s[Symbol.toPrimitive]; + if (void 0 !== i) { + var u = i.call(s, o || 'default'); + if ('object' != typeof u) return u; + throw new TypeError('@@toPrimitive must return a primitive value.'); + } + return ('string' === o ? String : Number)(s); + })(s, 'string'); + return 'symbol' == typeof o ? o : String(o); + } + var u = i(48287).Buffer, + _ = i(15340).inspect, + w = (_ && _.custom) || 'inspect'; + s.exports = (function () { + function BufferList() { + !(function _classCallCheck(s, o) { + if (!(s instanceof o)) throw new TypeError('Cannot call a class as a function'); + })(this, BufferList), + (this.head = null), + (this.tail = null), + (this.length = 0); + } + return ( + (function _createClass(s, o, i) { + return ( + o && _defineProperties(s.prototype, o), + i && _defineProperties(s, i), + Object.defineProperty(s, 'prototype', { writable: !1 }), + s + ); + })(BufferList, [ + { + key: 'push', + value: function push(s) { + var o = { data: s, next: null }; + this.length > 0 ? (this.tail.next = o) : (this.head = o), + (this.tail = o), + ++this.length; + } + }, + { + key: 'unshift', + value: function unshift(s) { + var o = { data: s, next: this.head }; + 0 === this.length && (this.tail = o), (this.head = o), ++this.length; + } + }, + { + key: 'shift', + value: function shift() { + if (0 !== this.length) { + var s = this.head.data; + return ( + 1 === this.length + ? (this.head = this.tail = null) + : (this.head = this.head.next), + --this.length, + s + ); + } + } + }, + { + key: 'clear', + value: function clear() { + (this.head = this.tail = null), (this.length = 0); + } + }, + { + key: 'join', + value: function join(s) { + if (0 === this.length) return ''; + for (var o = this.head, i = '' + o.data; (o = o.next); ) i += s + o.data; + return i; + } + }, + { + key: 'concat', + value: function concat(s) { + if (0 === this.length) return u.alloc(0); + for (var o, i, _, w = u.allocUnsafe(s >>> 0), x = this.head, C = 0; x; ) + (o = x.data), + (i = w), + (_ = C), + u.prototype.copy.call(o, i, _), + (C += x.data.length), + (x = x.next); + return w; + } + }, + { + key: 'consume', + value: function consume(s, o) { + var i; + return ( + s < this.head.data.length + ? ((i = this.head.data.slice(0, s)), + (this.head.data = this.head.data.slice(s))) + : (i = + s === this.head.data.length + ? this.shift() + : o + ? this._getString(s) + : this._getBuffer(s)), + i + ); + } + }, + { + key: 'first', + value: function first() { + return this.head.data; + } + }, + { + key: '_getString', + value: function _getString(s) { + var o = this.head, + i = 1, + u = o.data; + for (s -= u.length; (o = o.next); ) { + var _ = o.data, + w = s > _.length ? _.length : s; + if ((w === _.length ? (u += _) : (u += _.slice(0, s)), 0 === (s -= w))) { + w === _.length + ? (++i, o.next ? (this.head = o.next) : (this.head = this.tail = null)) + : ((this.head = o), (o.data = _.slice(w))); + break; + } + ++i; + } + return (this.length -= i), u; + } + }, + { + key: '_getBuffer', + value: function _getBuffer(s) { + var o = u.allocUnsafe(s), + i = this.head, + _ = 1; + for (i.data.copy(o), s -= i.data.length; (i = i.next); ) { + var w = i.data, + x = s > w.length ? w.length : s; + if ((w.copy(o, o.length - s, 0, x), 0 === (s -= x))) { + x === w.length + ? (++_, i.next ? (this.head = i.next) : (this.head = this.tail = null)) + : ((this.head = i), (i.data = w.slice(x))); + break; + } + ++_; + } + return (this.length -= _), o; + } + }, + { + key: w, + value: function value(s, o) { + return _( + this, + _objectSpread(_objectSpread({}, o), {}, { depth: 0, customInspect: !1 }) + ); + } + } + ]), + BufferList + ); + })(); + }, + 75896: (s, o, i) => { + 'use strict'; + var u = i(65606); + function emitErrorAndCloseNT(s, o) { + emitErrorNT(s, o), emitCloseNT(s); + } + function emitCloseNT(s) { + (s._writableState && !s._writableState.emitClose) || + (s._readableState && !s._readableState.emitClose) || + s.emit('close'); + } + function emitErrorNT(s, o) { + s.emit('error', o); + } + s.exports = { + destroy: function destroy(s, o) { + var i = this, + _ = this._readableState && this._readableState.destroyed, + w = this._writableState && this._writableState.destroyed; + return _ || w + ? (o + ? o(s) + : s && + (this._writableState + ? this._writableState.errorEmitted || + ((this._writableState.errorEmitted = !0), + u.nextTick(emitErrorNT, this, s)) + : u.nextTick(emitErrorNT, this, s)), + this) + : (this._readableState && (this._readableState.destroyed = !0), + this._writableState && (this._writableState.destroyed = !0), + this._destroy(s || null, function (s) { + !o && s + ? i._writableState + ? i._writableState.errorEmitted + ? u.nextTick(emitCloseNT, i) + : ((i._writableState.errorEmitted = !0), + u.nextTick(emitErrorAndCloseNT, i, s)) + : u.nextTick(emitErrorAndCloseNT, i, s) + : o + ? (u.nextTick(emitCloseNT, i), o(s)) + : u.nextTick(emitCloseNT, i); + }), + this); + }, + undestroy: function undestroy() { + this._readableState && + ((this._readableState.destroyed = !1), + (this._readableState.reading = !1), + (this._readableState.ended = !1), + (this._readableState.endEmitted = !1)), + this._writableState && + ((this._writableState.destroyed = !1), + (this._writableState.ended = !1), + (this._writableState.ending = !1), + (this._writableState.finalCalled = !1), + (this._writableState.prefinished = !1), + (this._writableState.finished = !1), + (this._writableState.errorEmitted = !1)); + }, + errorOrDestroy: function errorOrDestroy(s, o) { + var i = s._readableState, + u = s._writableState; + (i && i.autoDestroy) || (u && u.autoDestroy) ? s.destroy(o) : s.emit('error', o); + } + }; + }, + 86238: (s, o, i) => { + 'use strict'; + var u = i(86048).F.ERR_STREAM_PREMATURE_CLOSE; + function noop() {} + s.exports = function eos(s, o, i) { + if ('function' == typeof o) return eos(s, null, o); + o || (o = {}), + (i = (function once(s) { + var o = !1; + return function () { + if (!o) { + o = !0; + for (var i = arguments.length, u = new Array(i), _ = 0; _ < i; _++) + u[_] = arguments[_]; + s.apply(this, u); + } + }; + })(i || noop)); + var _ = o.readable || (!1 !== o.readable && s.readable), + w = o.writable || (!1 !== o.writable && s.writable), + x = function onlegacyfinish() { + s.writable || j(); + }, + C = s._writableState && s._writableState.finished, + j = function onfinish() { + (w = !1), (C = !0), _ || i.call(s); + }, + L = s._readableState && s._readableState.endEmitted, + B = function onend() { + (_ = !1), (L = !0), w || i.call(s); + }, + $ = function onerror(o) { + i.call(s, o); + }, + V = function onclose() { + var o; + return _ && !L + ? ((s._readableState && s._readableState.ended) || (o = new u()), i.call(s, o)) + : w && !C + ? ((s._writableState && s._writableState.ended) || (o = new u()), i.call(s, o)) + : void 0; + }, + U = function onrequest() { + s.req.on('finish', j); + }; + return ( + !(function isRequest(s) { + return s.setHeader && 'function' == typeof s.abort; + })(s) + ? w && !s._writableState && (s.on('end', x), s.on('close', x)) + : (s.on('complete', j), s.on('abort', V), s.req ? U() : s.on('request', U)), + s.on('end', B), + s.on('finish', j), + !1 !== o.error && s.on('error', $), + s.on('close', V), + function () { + s.removeListener('complete', j), + s.removeListener('abort', V), + s.removeListener('request', U), + s.req && s.req.removeListener('finish', j), + s.removeListener('end', x), + s.removeListener('close', x), + s.removeListener('finish', j), + s.removeListener('end', B), + s.removeListener('error', $), + s.removeListener('close', V); + } + ); + }; + }, + 55157: (s) => { + s.exports = function () { + throw new Error('Readable.from is not available in the browser'); + }; + }, + 57758: (s, o, i) => { + 'use strict'; + var u; + var _ = i(86048).F, + w = _.ERR_MISSING_ARGS, + x = _.ERR_STREAM_DESTROYED; + function noop(s) { + if (s) throw s; + } + function call(s) { + s(); + } + function pipe(s, o) { + return s.pipe(o); + } + s.exports = function pipeline() { + for (var s = arguments.length, o = new Array(s), _ = 0; _ < s; _++) o[_] = arguments[_]; + var C, + j = (function popCallback(s) { + return s.length ? ('function' != typeof s[s.length - 1] ? noop : s.pop()) : noop; + })(o); + if ((Array.isArray(o[0]) && (o = o[0]), o.length < 2)) throw new w('streams'); + var L = o.map(function (s, _) { + var w = _ < o.length - 1; + return (function destroyer(s, o, _, w) { + w = (function once(s) { + var o = !1; + return function () { + o || ((o = !0), s.apply(void 0, arguments)); + }; + })(w); + var C = !1; + s.on('close', function () { + C = !0; + }), + void 0 === u && (u = i(86238)), + u(s, { readable: o, writable: _ }, function (s) { + if (s) return w(s); + (C = !0), w(); + }); + var j = !1; + return function (o) { + if (!C && !j) + return ( + (j = !0), + (function isRequest(s) { + return s.setHeader && 'function' == typeof s.abort; + })(s) + ? s.abort() + : 'function' == typeof s.destroy + ? s.destroy() + : void w(o || new x('pipe')) + ); + }; + })(s, w, _ > 0, function (s) { + C || (C = s), s && L.forEach(call), w || (L.forEach(call), j(C)); + }); + }); + return o.reduce(pipe); + }; + }, + 65291: (s, o, i) => { + 'use strict'; + var u = i(86048).F.ERR_INVALID_OPT_VALUE; + s.exports = { + getHighWaterMark: function getHighWaterMark(s, o, i, _) { + var w = (function highWaterMarkFrom(s, o, i) { + return null != s.highWaterMark ? s.highWaterMark : o ? s[i] : null; + })(o, _, i); + if (null != w) { + if (!isFinite(w) || Math.floor(w) !== w || w < 0) + throw new u(_ ? i : 'highWaterMark', w); + return Math.floor(w); + } + return s.objectMode ? 16 : 16384; + } + }; + }, + 40345: (s, o, i) => { + s.exports = i(37007).EventEmitter; + }, + 84977: (s, o, i) => { + 'use strict'; + Object.defineProperty(o, '__esModule', { value: !0 }); + var u = (function _interopRequireDefault(s) { + return s && s.__esModule ? s : { default: s }; + })(i(9404)), + _ = i(55674); + (o.default = function (s) { + var o = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : u.default.Map, + i = Object.keys(s); + return function () { + var u = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : o(), + w = arguments[1]; + return u.withMutations(function (o) { + i.forEach(function (i) { + var u = (0, s[i])(o.get(i), w); + (0, _.validateNextState)(u, i, w), o.set(i, u); + }); + }); + }; + }), + (s.exports = o.default); + }, + 89593: (s, o, i) => { + 'use strict'; + o.H = void 0; + var u = (function _interopRequireDefault(s) { + return s && s.__esModule ? s : { default: s }; + })(i(84977)); + o.H = u.default; + }, + 48590: (s, o) => { + 'use strict'; + Object.defineProperty(o, '__esModule', { value: !0 }), + (o.default = function (s) { + return s && '@@redux/INIT' === s.type + ? 'initialState argument passed to createStore' + : 'previous state received by the reducer'; + }), + (s.exports = o.default); + }, + 82261: (s, o, i) => { + 'use strict'; + Object.defineProperty(o, '__esModule', { value: !0 }); + var u = _interopRequireDefault(i(9404)), + _ = _interopRequireDefault(i(48590)); + function _interopRequireDefault(s) { + return s && s.__esModule ? s : { default: s }; + } + (o.default = function (s, o, i) { + var w = Object.keys(o); + if (!w.length) + return 'Store does not have a valid reducer. Make sure the argument passed to combineReducers is an object whose values are reducers.'; + var x = (0, _.default)(i); + if ( + u.default.isImmutable ? !u.default.isImmutable(s) : !u.default.Iterable.isIterable(s) + ) + return ( + 'The ' + + x + + ' is of unexpected type. Expected argument to be an instance of Immutable.Collection or Immutable.Record with the following properties: "' + + w.join('", "') + + '".' + ); + var C = s + .toSeq() + .keySeq() + .toArray() + .filter(function (s) { + return !o.hasOwnProperty(s); + }); + return C.length > 0 + ? 'Unexpected ' + + (1 === C.length ? 'property' : 'properties') + + ' "' + + C.join('", "') + + '" found in ' + + x + + '. Expected to find one of the known reducer property names instead: "' + + w.join('", "') + + '". Unexpected properties will be ignored.' + : null; + }), + (s.exports = o.default); + }, + 55674: (s, o, i) => { + 'use strict'; + Object.defineProperty(o, '__esModule', { value: !0 }), + (o.validateNextState = + o.getUnexpectedInvocationParameterMessage = + o.getStateName = + void 0); + var u = _interopRequireDefault(i(48590)), + _ = _interopRequireDefault(i(82261)), + w = _interopRequireDefault(i(27374)); + function _interopRequireDefault(s) { + return s && s.__esModule ? s : { default: s }; + } + (o.getStateName = u.default), + (o.getUnexpectedInvocationParameterMessage = _.default), + (o.validateNextState = w.default); + }, + 27374: (s, o) => { + 'use strict'; + Object.defineProperty(o, '__esModule', { value: !0 }), + (o.default = function (s, o, i) { + if (void 0 === s) + throw new Error( + 'Reducer "' + + o + + '" returned undefined when handling "' + + i.type + + '" action. To ignore an action, you must explicitly return the previous state.' + ); + }), + (s.exports = o.default); + }, + 75208: (s) => { + 'use strict'; + var o, + i = ''; + s.exports = function repeat(s, u) { + if ('string' != typeof s) throw new TypeError('expected a string'); + if (1 === u) return s; + if (2 === u) return s + s; + var _ = s.length * u; + if (o !== s || void 0 === o) (o = s), (i = ''); + else if (i.length >= _) return i.substr(0, _); + for (; _ > i.length && u > 1; ) 1 & u && (i += s), (u >>= 1), (s += s); + return (i = (i += s).substr(0, _)); + }; + }, + 92063: (s) => { + 'use strict'; + s.exports = function required(s, o) { + if (((o = o.split(':')[0]), !(s = +s))) return !1; + switch (o) { + case 'http': + case 'ws': + return 80 !== s; + case 'https': + case 'wss': + return 443 !== s; + case 'ftp': + return 21 !== s; + case 'gopher': + return 70 !== s; + case 'file': + return !1; + } + return 0 !== s; + }; + }, + 27096: (s, o, i) => { + const u = i(87586), + _ = i(6205), + w = i(10023), + x = i(8048); + (s.exports = (s) => { + var o, + i, + C = 0, + j = { type: _.ROOT, stack: [] }, + L = j, + B = j.stack, + $ = [], + repeatErr = (o) => { + u.error(s, 'Nothing to repeat at column ' + (o - 1)); + }, + V = u.strToChars(s); + for (o = V.length; C < o; ) + switch ((i = V[C++])) { + case '\\': + switch ((i = V[C++])) { + case 'b': + B.push(x.wordBoundary()); + break; + case 'B': + B.push(x.nonWordBoundary()); + break; + case 'w': + B.push(w.words()); + break; + case 'W': + B.push(w.notWords()); + break; + case 'd': + B.push(w.ints()); + break; + case 'D': + B.push(w.notInts()); + break; + case 's': + B.push(w.whitespace()); + break; + case 'S': + B.push(w.notWhitespace()); + break; + default: + /\d/.test(i) + ? B.push({ type: _.REFERENCE, value: parseInt(i, 10) }) + : B.push({ type: _.CHAR, value: i.charCodeAt(0) }); + } + break; + case '^': + B.push(x.begin()); + break; + case '$': + B.push(x.end()); + break; + case '[': + var U; + '^' === V[C] ? ((U = !0), C++) : (U = !1); + var z = u.tokenizeClass(V.slice(C), s); + (C += z[1]), B.push({ type: _.SET, set: z[0], not: U }); + break; + case '.': + B.push(w.anyChar()); + break; + case '(': + var Y = { type: _.GROUP, stack: [], remember: !0 }; + '?' === (i = V[C]) && + ((i = V[C + 1]), + (C += 2), + '=' === i + ? (Y.followedBy = !0) + : '!' === i + ? (Y.notFollowedBy = !0) + : ':' !== i && + u.error( + s, + `Invalid group, character '${i}' after '?' at column ` + (C - 1) + ), + (Y.remember = !1)), + B.push(Y), + $.push(L), + (L = Y), + (B = Y.stack); + break; + case ')': + 0 === $.length && u.error(s, 'Unmatched ) at column ' + (C - 1)), + (B = (L = $.pop()).options ? L.options[L.options.length - 1] : L.stack); + break; + case '|': + L.options || ((L.options = [L.stack]), delete L.stack); + var Z = []; + L.options.push(Z), (B = Z); + break; + case '{': + var ee, + ie, + ae = /^(\d+)(,(\d+)?)?\}/.exec(V.slice(C)); + null !== ae + ? (0 === B.length && repeatErr(C), + (ee = parseInt(ae[1], 10)), + (ie = ae[2] ? (ae[3] ? parseInt(ae[3], 10) : 1 / 0) : ee), + (C += ae[0].length), + B.push({ type: _.REPETITION, min: ee, max: ie, value: B.pop() })) + : B.push({ type: _.CHAR, value: 123 }); + break; + case '?': + 0 === B.length && repeatErr(C), + B.push({ type: _.REPETITION, min: 0, max: 1, value: B.pop() }); + break; + case '+': + 0 === B.length && repeatErr(C), + B.push({ type: _.REPETITION, min: 1, max: 1 / 0, value: B.pop() }); + break; + case '*': + 0 === B.length && repeatErr(C), + B.push({ type: _.REPETITION, min: 0, max: 1 / 0, value: B.pop() }); + break; + default: + B.push({ type: _.CHAR, value: i.charCodeAt(0) }); + } + return 0 !== $.length && u.error(s, 'Unterminated group'), j; + }), + (s.exports.types = _); + }, + 8048: (s, o, i) => { + const u = i(6205); + (o.wordBoundary = () => ({ type: u.POSITION, value: 'b' })), + (o.nonWordBoundary = () => ({ type: u.POSITION, value: 'B' })), + (o.begin = () => ({ type: u.POSITION, value: '^' })), + (o.end = () => ({ type: u.POSITION, value: '$' })); + }, + 10023: (s, o, i) => { + const u = i(6205), + INTS = () => [{ type: u.RANGE, from: 48, to: 57 }], + WORDS = () => + [ + { type: u.CHAR, value: 95 }, + { type: u.RANGE, from: 97, to: 122 }, + { type: u.RANGE, from: 65, to: 90 } + ].concat(INTS()), + WHITESPACE = () => [ + { type: u.CHAR, value: 9 }, + { type: u.CHAR, value: 10 }, + { type: u.CHAR, value: 11 }, + { type: u.CHAR, value: 12 }, + { type: u.CHAR, value: 13 }, + { type: u.CHAR, value: 32 }, + { type: u.CHAR, value: 160 }, + { type: u.CHAR, value: 5760 }, + { type: u.RANGE, from: 8192, to: 8202 }, + { type: u.CHAR, value: 8232 }, + { type: u.CHAR, value: 8233 }, + { type: u.CHAR, value: 8239 }, + { type: u.CHAR, value: 8287 }, + { type: u.CHAR, value: 12288 }, + { type: u.CHAR, value: 65279 } + ]; + (o.words = () => ({ type: u.SET, set: WORDS(), not: !1 })), + (o.notWords = () => ({ type: u.SET, set: WORDS(), not: !0 })), + (o.ints = () => ({ type: u.SET, set: INTS(), not: !1 })), + (o.notInts = () => ({ type: u.SET, set: INTS(), not: !0 })), + (o.whitespace = () => ({ type: u.SET, set: WHITESPACE(), not: !1 })), + (o.notWhitespace = () => ({ type: u.SET, set: WHITESPACE(), not: !0 })), + (o.anyChar = () => ({ + type: u.SET, + set: [ + { type: u.CHAR, value: 10 }, + { type: u.CHAR, value: 13 }, + { type: u.CHAR, value: 8232 }, + { type: u.CHAR, value: 8233 } + ], + not: !0 + })); + }, + 6205: (s) => { + s.exports = { + ROOT: 0, + GROUP: 1, + POSITION: 2, + SET: 3, + RANGE: 4, + REPETITION: 5, + REFERENCE: 6, + CHAR: 7 + }; + }, + 87586: (s, o, i) => { + const u = i(6205), + _ = i(10023), + w = { 0: 0, t: 9, n: 10, v: 11, f: 12, r: 13 }; + (o.strToChars = function (s) { + return (s = s.replace( + /(\[\\b\])|(\\)?\\(?:u([A-F0-9]{4})|x([A-F0-9]{2})|(0?[0-7]{2})|c([@A-Z[\\\]^?])|([0tnvfr]))/g, + function (s, o, i, u, _, x, C, j) { + if (i) return s; + var L = o + ? 8 + : u + ? parseInt(u, 16) + : _ + ? parseInt(_, 16) + : x + ? parseInt(x, 8) + : C + ? '@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^ ?'.indexOf(C) + : w[j], + B = String.fromCharCode(L); + return /[[\]{}^$.|?*+()]/.test(B) && (B = '\\' + B), B; + } + )); + }), + (o.tokenizeClass = (s, i) => { + for ( + var w, + x, + C = [], + j = + /\\(?:(w)|(d)|(s)|(W)|(D)|(S))|((?:(?:\\)(.)|([^\]\\]))-(?:\\)?([^\]]))|(\])|(?:\\)?([^])/g; + null != (w = j.exec(s)); + + ) + if (w[1]) C.push(_.words()); + else if (w[2]) C.push(_.ints()); + else if (w[3]) C.push(_.whitespace()); + else if (w[4]) C.push(_.notWords()); + else if (w[5]) C.push(_.notInts()); + else if (w[6]) C.push(_.notWhitespace()); + else if (w[7]) + C.push({ + type: u.RANGE, + from: (w[8] || w[9]).charCodeAt(0), + to: w[10].charCodeAt(0) + }); + else { + if (!(x = w[12])) return [C, j.lastIndex]; + C.push({ type: u.CHAR, value: x.charCodeAt(0) }); + } + o.error(i, 'Unterminated character class'); + }), + (o.error = (s, o) => { + throw new SyntaxError('Invalid regular expression: /' + s + '/: ' + o); + }); + }, + 92861: (s, o, i) => { + var u = i(48287), + _ = u.Buffer; + function copyProps(s, o) { + for (var i in s) o[i] = s[i]; + } + function SafeBuffer(s, o, i) { + return _(s, o, i); + } + _.from && _.alloc && _.allocUnsafe && _.allocUnsafeSlow + ? (s.exports = u) + : (copyProps(u, o), (o.Buffer = SafeBuffer)), + (SafeBuffer.prototype = Object.create(_.prototype)), + copyProps(_, SafeBuffer), + (SafeBuffer.from = function (s, o, i) { + if ('number' == typeof s) throw new TypeError('Argument must not be a number'); + return _(s, o, i); + }), + (SafeBuffer.alloc = function (s, o, i) { + if ('number' != typeof s) throw new TypeError('Argument must be a number'); + var u = _(s); + return ( + void 0 !== o ? ('string' == typeof i ? u.fill(o, i) : u.fill(o)) : u.fill(0), u + ); + }), + (SafeBuffer.allocUnsafe = function (s) { + if ('number' != typeof s) throw new TypeError('Argument must be a number'); + return _(s); + }), + (SafeBuffer.allocUnsafeSlow = function (s) { + if ('number' != typeof s) throw new TypeError('Argument must be a number'); + return u.SlowBuffer(s); + }); + }, + 29844: (s, o) => { + 'use strict'; + function f(s, o) { + var i = s.length; + s.push(o); + e: for (; 0 < i; ) { + var u = (i - 1) >>> 1, + _ = s[u]; + if (!(0 < g(_, o))) break e; + (s[u] = o), (s[i] = _), (i = u); + } + } + function h(s) { + return 0 === s.length ? null : s[0]; + } + function k(s) { + if (0 === s.length) return null; + var o = s[0], + i = s.pop(); + if (i !== o) { + s[0] = i; + e: for (var u = 0, _ = s.length, w = _ >>> 1; u < w; ) { + var x = 2 * (u + 1) - 1, + C = s[x], + j = x + 1, + L = s[j]; + if (0 > g(C, i)) + j < _ && 0 > g(L, C) + ? ((s[u] = L), (s[j] = i), (u = j)) + : ((s[u] = C), (s[x] = i), (u = x)); + else { + if (!(j < _ && 0 > g(L, i))) break e; + (s[u] = L), (s[j] = i), (u = j); + } + } + } + return o; + } + function g(s, o) { + var i = s.sortIndex - o.sortIndex; + return 0 !== i ? i : s.id - o.id; + } + if ('object' == typeof performance && 'function' == typeof performance.now) { + var i = performance; + o.unstable_now = function () { + return i.now(); + }; + } else { + var u = Date, + _ = u.now(); + o.unstable_now = function () { + return u.now() - _; + }; + } + var w = [], + x = [], + C = 1, + j = null, + L = 3, + B = !1, + $ = !1, + V = !1, + U = 'function' == typeof setTimeout ? setTimeout : null, + z = 'function' == typeof clearTimeout ? clearTimeout : null, + Y = 'undefined' != typeof setImmediate ? setImmediate : null; + function G(s) { + for (var o = h(x); null !== o; ) { + if (null === o.callback) k(x); + else { + if (!(o.startTime <= s)) break; + k(x), (o.sortIndex = o.expirationTime), f(w, o); + } + o = h(x); + } + } + function H(s) { + if (((V = !1), G(s), !$)) + if (null !== h(w)) ($ = !0), I(J); + else { + var o = h(x); + null !== o && K(H, o.startTime - s); + } + } + function J(s, i) { + ($ = !1), V && ((V = !1), z(ae), (ae = -1)), (B = !0); + var u = L; + try { + for (G(i), j = h(w); null !== j && (!(j.expirationTime > i) || (s && !M())); ) { + var _ = j.callback; + if ('function' == typeof _) { + (j.callback = null), (L = j.priorityLevel); + var C = _(j.expirationTime <= i); + (i = o.unstable_now()), + 'function' == typeof C ? (j.callback = C) : j === h(w) && k(w), + G(i); + } else k(w); + j = h(w); + } + if (null !== j) var U = !0; + else { + var Y = h(x); + null !== Y && K(H, Y.startTime - i), (U = !1); + } + return U; + } finally { + (j = null), (L = u), (B = !1); + } + } + 'undefined' != typeof navigator && + void 0 !== navigator.scheduling && + void 0 !== navigator.scheduling.isInputPending && + navigator.scheduling.isInputPending.bind(navigator.scheduling); + var Z, + ee = !1, + ie = null, + ae = -1, + le = 5, + ce = -1; + function M() { + return !(o.unstable_now() - ce < le); + } + function R() { + if (null !== ie) { + var s = o.unstable_now(); + ce = s; + var i = !0; + try { + i = ie(!0, s); + } finally { + i ? Z() : ((ee = !1), (ie = null)); + } + } else ee = !1; + } + if ('function' == typeof Y) + Z = function () { + Y(R); + }; + else if ('undefined' != typeof MessageChannel) { + var pe = new MessageChannel(), + de = pe.port2; + (pe.port1.onmessage = R), + (Z = function () { + de.postMessage(null); + }); + } else + Z = function () { + U(R, 0); + }; + function I(s) { + (ie = s), ee || ((ee = !0), Z()); + } + function K(s, i) { + ae = U(function () { + s(o.unstable_now()); + }, i); + } + (o.unstable_IdlePriority = 5), + (o.unstable_ImmediatePriority = 1), + (o.unstable_LowPriority = 4), + (o.unstable_NormalPriority = 3), + (o.unstable_Profiling = null), + (o.unstable_UserBlockingPriority = 2), + (o.unstable_cancelCallback = function (s) { + s.callback = null; + }), + (o.unstable_continueExecution = function () { + $ || B || (($ = !0), I(J)); + }), + (o.unstable_forceFrameRate = function (s) { + 0 > s || 125 < s + ? console.error( + 'forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported' + ) + : (le = 0 < s ? Math.floor(1e3 / s) : 5); + }), + (o.unstable_getCurrentPriorityLevel = function () { + return L; + }), + (o.unstable_getFirstCallbackNode = function () { + return h(w); + }), + (o.unstable_next = function (s) { + switch (L) { + case 1: + case 2: + case 3: + var o = 3; + break; + default: + o = L; + } + var i = L; + L = o; + try { + return s(); + } finally { + L = i; + } + }), + (o.unstable_pauseExecution = function () {}), + (o.unstable_requestPaint = function () {}), + (o.unstable_runWithPriority = function (s, o) { + switch (s) { + case 1: + case 2: + case 3: + case 4: + case 5: + break; + default: + s = 3; + } + var i = L; + L = s; + try { + return o(); + } finally { + L = i; + } + }), + (o.unstable_scheduleCallback = function (s, i, u) { + var _ = o.unstable_now(); + switch ( + ('object' == typeof u && null !== u + ? (u = 'number' == typeof (u = u.delay) && 0 < u ? _ + u : _) + : (u = _), + s) + ) { + case 1: + var j = -1; + break; + case 2: + j = 250; + break; + case 5: + j = 1073741823; + break; + case 4: + j = 1e4; + break; + default: + j = 5e3; + } + return ( + (s = { + id: C++, + callback: i, + priorityLevel: s, + startTime: u, + expirationTime: (j = u + j), + sortIndex: -1 + }), + u > _ + ? ((s.sortIndex = u), + f(x, s), + null === h(w) && s === h(x) && (V ? (z(ae), (ae = -1)) : (V = !0), K(H, u - _))) + : ((s.sortIndex = j), f(w, s), $ || B || (($ = !0), I(J))), + s + ); + }), + (o.unstable_shouldYield = M), + (o.unstable_wrapCallback = function (s) { + var o = L; + return function () { + var i = L; + L = o; + try { + return s.apply(this, arguments); + } finally { + L = i; + } + }; + }); + }, + 69982: (s, o, i) => { + 'use strict'; + s.exports = i(29844); + }, + 20334: (s, o, i) => { + 'use strict'; + var u = i(48287).Buffer; + class NonError extends Error { + constructor(s) { + super(NonError._prepareSuperMessage(s)), + Object.defineProperty(this, 'name', { + value: 'NonError', + configurable: !0, + writable: !0 + }), + Error.captureStackTrace && Error.captureStackTrace(this, NonError); + } + static _prepareSuperMessage(s) { + try { + return JSON.stringify(s); + } catch { + return String(s); + } + } + } + const _ = [ + { property: 'name', enumerable: !1 }, + { property: 'message', enumerable: !1 }, + { property: 'stack', enumerable: !1 }, + { property: 'code', enumerable: !0 } + ], + w = Symbol('.toJSON called'), + destroyCircular = ({ + from: s, + seen: o, + to_: i, + forceEnumerable: x, + maxDepth: C, + depth: j + }) => { + const L = i || (Array.isArray(s) ? [] : {}); + if ((o.push(s), j >= C)) return L; + if ('function' == typeof s.toJSON && !0 !== s[w]) + return ((s) => { + s[w] = !0; + const o = s.toJSON(); + return delete s[w], o; + })(s); + for (const [i, _] of Object.entries(s)) + 'function' == typeof u && u.isBuffer(_) + ? (L[i] = '[object Buffer]') + : 'function' != typeof _ && + (_ && 'object' == typeof _ + ? o.includes(s[i]) + ? (L[i] = '[Circular]') + : (j++, + (L[i] = destroyCircular({ + from: s[i], + seen: o.slice(), + forceEnumerable: x, + maxDepth: C, + depth: j + }))) + : (L[i] = _)); + for (const { property: o, enumerable: i } of _) + 'string' == typeof s[o] && + Object.defineProperty(L, o, { + value: s[o], + enumerable: !!x || i, + configurable: !0, + writable: !0 + }); + return L; + }; + s.exports = { + serializeError: (s, o = {}) => { + const { maxDepth: i = Number.POSITIVE_INFINITY } = o; + return 'object' == typeof s && null !== s + ? destroyCircular({ from: s, seen: [], forceEnumerable: !0, maxDepth: i, depth: 0 }) + : 'function' == typeof s + ? `[Function: ${s.name || 'anonymous'}]` + : s; + }, + deserializeError: (s, o = {}) => { + const { maxDepth: i = Number.POSITIVE_INFINITY } = o; + if (s instanceof Error) return s; + if ('object' == typeof s && null !== s && !Array.isArray(s)) { + const o = new Error(); + return destroyCircular({ from: s, seen: [], to_: o, maxDepth: i, depth: 0 }), o; + } + return new NonError(s); + } + }; + }, + 90392: (s, o, i) => { + var u = i(92861).Buffer; + function Hash(s, o) { + (this._block = u.alloc(s)), + (this._finalSize = o), + (this._blockSize = s), + (this._len = 0); + } + (Hash.prototype.update = function (s, o) { + 'string' == typeof s && ((o = o || 'utf8'), (s = u.from(s, o))); + for ( + var i = this._block, _ = this._blockSize, w = s.length, x = this._len, C = 0; + C < w; + + ) { + for (var j = x % _, L = Math.min(w - C, _ - j), B = 0; B < L; B++) + i[j + B] = s[C + B]; + (C += L), (x += L) % _ == 0 && this._update(i); + } + return (this._len += w), this; + }), + (Hash.prototype.digest = function (s) { + var o = this._len % this._blockSize; + (this._block[o] = 128), + this._block.fill(0, o + 1), + o >= this._finalSize && (this._update(this._block), this._block.fill(0)); + var i = 8 * this._len; + if (i <= 4294967295) this._block.writeUInt32BE(i, this._blockSize - 4); + else { + var u = (4294967295 & i) >>> 0, + _ = (i - u) / 4294967296; + this._block.writeUInt32BE(_, this._blockSize - 8), + this._block.writeUInt32BE(u, this._blockSize - 4); + } + this._update(this._block); + var w = this._hash(); + return s ? w.toString(s) : w; + }), + (Hash.prototype._update = function () { + throw new Error('_update must be implemented by subclass'); + }), + (s.exports = Hash); + }, + 62802: (s, o, i) => { + var u = (s.exports = function SHA(s) { + s = s.toLowerCase(); + var o = u[s]; + if (!o) throw new Error(s + ' is not supported (we accept pull requests)'); + return new o(); + }); + (u.sha = i(27816)), + (u.sha1 = i(63737)), + (u.sha224 = i(26710)), + (u.sha256 = i(24107)), + (u.sha384 = i(32827)), + (u.sha512 = i(82890)); + }, + 27816: (s, o, i) => { + var u = i(56698), + _ = i(90392), + w = i(92861).Buffer, + x = [1518500249, 1859775393, -1894007588, -899497514], + C = new Array(80); + function Sha() { + this.init(), (this._w = C), _.call(this, 64, 56); + } + function rotl30(s) { + return (s << 30) | (s >>> 2); + } + function ft(s, o, i, u) { + return 0 === s ? (o & i) | (~o & u) : 2 === s ? (o & i) | (o & u) | (i & u) : o ^ i ^ u; + } + u(Sha, _), + (Sha.prototype.init = function () { + return ( + (this._a = 1732584193), + (this._b = 4023233417), + (this._c = 2562383102), + (this._d = 271733878), + (this._e = 3285377520), + this + ); + }), + (Sha.prototype._update = function (s) { + for ( + var o, + i = this._w, + u = 0 | this._a, + _ = 0 | this._b, + w = 0 | this._c, + C = 0 | this._d, + j = 0 | this._e, + L = 0; + L < 16; + ++L + ) + i[L] = s.readInt32BE(4 * L); + for (; L < 80; ++L) i[L] = i[L - 3] ^ i[L - 8] ^ i[L - 14] ^ i[L - 16]; + for (var B = 0; B < 80; ++B) { + var $ = ~~(B / 20), + V = 0 | ((((o = u) << 5) | (o >>> 27)) + ft($, _, w, C) + j + i[B] + x[$]); + (j = C), (C = w), (w = rotl30(_)), (_ = u), (u = V); + } + (this._a = (u + this._a) | 0), + (this._b = (_ + this._b) | 0), + (this._c = (w + this._c) | 0), + (this._d = (C + this._d) | 0), + (this._e = (j + this._e) | 0); + }), + (Sha.prototype._hash = function () { + var s = w.allocUnsafe(20); + return ( + s.writeInt32BE(0 | this._a, 0), + s.writeInt32BE(0 | this._b, 4), + s.writeInt32BE(0 | this._c, 8), + s.writeInt32BE(0 | this._d, 12), + s.writeInt32BE(0 | this._e, 16), + s + ); + }), + (s.exports = Sha); + }, + 63737: (s, o, i) => { + var u = i(56698), + _ = i(90392), + w = i(92861).Buffer, + x = [1518500249, 1859775393, -1894007588, -899497514], + C = new Array(80); + function Sha1() { + this.init(), (this._w = C), _.call(this, 64, 56); + } + function rotl5(s) { + return (s << 5) | (s >>> 27); + } + function rotl30(s) { + return (s << 30) | (s >>> 2); + } + function ft(s, o, i, u) { + return 0 === s ? (o & i) | (~o & u) : 2 === s ? (o & i) | (o & u) | (i & u) : o ^ i ^ u; + } + u(Sha1, _), + (Sha1.prototype.init = function () { + return ( + (this._a = 1732584193), + (this._b = 4023233417), + (this._c = 2562383102), + (this._d = 271733878), + (this._e = 3285377520), + this + ); + }), + (Sha1.prototype._update = function (s) { + for ( + var o, + i = this._w, + u = 0 | this._a, + _ = 0 | this._b, + w = 0 | this._c, + C = 0 | this._d, + j = 0 | this._e, + L = 0; + L < 16; + ++L + ) + i[L] = s.readInt32BE(4 * L); + for (; L < 80; ++L) + i[L] = ((o = i[L - 3] ^ i[L - 8] ^ i[L - 14] ^ i[L - 16]) << 1) | (o >>> 31); + for (var B = 0; B < 80; ++B) { + var $ = ~~(B / 20), + V = (rotl5(u) + ft($, _, w, C) + j + i[B] + x[$]) | 0; + (j = C), (C = w), (w = rotl30(_)), (_ = u), (u = V); + } + (this._a = (u + this._a) | 0), + (this._b = (_ + this._b) | 0), + (this._c = (w + this._c) | 0), + (this._d = (C + this._d) | 0), + (this._e = (j + this._e) | 0); + }), + (Sha1.prototype._hash = function () { + var s = w.allocUnsafe(20); + return ( + s.writeInt32BE(0 | this._a, 0), + s.writeInt32BE(0 | this._b, 4), + s.writeInt32BE(0 | this._c, 8), + s.writeInt32BE(0 | this._d, 12), + s.writeInt32BE(0 | this._e, 16), + s + ); + }), + (s.exports = Sha1); + }, + 26710: (s, o, i) => { + var u = i(56698), + _ = i(24107), + w = i(90392), + x = i(92861).Buffer, + C = new Array(64); + function Sha224() { + this.init(), (this._w = C), w.call(this, 64, 56); + } + u(Sha224, _), + (Sha224.prototype.init = function () { + return ( + (this._a = 3238371032), + (this._b = 914150663), + (this._c = 812702999), + (this._d = 4144912697), + (this._e = 4290775857), + (this._f = 1750603025), + (this._g = 1694076839), + (this._h = 3204075428), + this + ); + }), + (Sha224.prototype._hash = function () { + var s = x.allocUnsafe(28); + return ( + s.writeInt32BE(this._a, 0), + s.writeInt32BE(this._b, 4), + s.writeInt32BE(this._c, 8), + s.writeInt32BE(this._d, 12), + s.writeInt32BE(this._e, 16), + s.writeInt32BE(this._f, 20), + s.writeInt32BE(this._g, 24), + s + ); + }), + (s.exports = Sha224); + }, + 24107: (s, o, i) => { + var u = i(56698), + _ = i(90392), + w = i(92861).Buffer, + x = [ + 1116352408, 1899447441, 3049323471, 3921009573, 961987163, 1508970993, 2453635748, + 2870763221, 3624381080, 310598401, 607225278, 1426881987, 1925078388, 2162078206, + 2614888103, 3248222580, 3835390401, 4022224774, 264347078, 604807628, 770255983, + 1249150122, 1555081692, 1996064986, 2554220882, 2821834349, 2952996808, 3210313671, + 3336571891, 3584528711, 113926993, 338241895, 666307205, 773529912, 1294757372, + 1396182291, 1695183700, 1986661051, 2177026350, 2456956037, 2730485921, 2820302411, + 3259730800, 3345764771, 3516065817, 3600352804, 4094571909, 275423344, 430227734, + 506948616, 659060556, 883997877, 958139571, 1322822218, 1537002063, 1747873779, + 1955562222, 2024104815, 2227730452, 2361852424, 2428436474, 2756734187, 3204031479, + 3329325298 + ], + C = new Array(64); + function Sha256() { + this.init(), (this._w = C), _.call(this, 64, 56); + } + function ch(s, o, i) { + return i ^ (s & (o ^ i)); + } + function maj(s, o, i) { + return (s & o) | (i & (s | o)); + } + function sigma0(s) { + return ((s >>> 2) | (s << 30)) ^ ((s >>> 13) | (s << 19)) ^ ((s >>> 22) | (s << 10)); + } + function sigma1(s) { + return ((s >>> 6) | (s << 26)) ^ ((s >>> 11) | (s << 21)) ^ ((s >>> 25) | (s << 7)); + } + function gamma0(s) { + return ((s >>> 7) | (s << 25)) ^ ((s >>> 18) | (s << 14)) ^ (s >>> 3); + } + u(Sha256, _), + (Sha256.prototype.init = function () { + return ( + (this._a = 1779033703), + (this._b = 3144134277), + (this._c = 1013904242), + (this._d = 2773480762), + (this._e = 1359893119), + (this._f = 2600822924), + (this._g = 528734635), + (this._h = 1541459225), + this + ); + }), + (Sha256.prototype._update = function (s) { + for ( + var o, + i = this._w, + u = 0 | this._a, + _ = 0 | this._b, + w = 0 | this._c, + C = 0 | this._d, + j = 0 | this._e, + L = 0 | this._f, + B = 0 | this._g, + $ = 0 | this._h, + V = 0; + V < 16; + ++V + ) + i[V] = s.readInt32BE(4 * V); + for (; V < 64; ++V) + i[V] = + 0 | + (((((o = i[V - 2]) >>> 17) | (o << 15)) ^ ((o >>> 19) | (o << 13)) ^ (o >>> 10)) + + i[V - 7] + + gamma0(i[V - 15]) + + i[V - 16]); + for (var U = 0; U < 64; ++U) { + var z = ($ + sigma1(j) + ch(j, L, B) + x[U] + i[U]) | 0, + Y = (sigma0(u) + maj(u, _, w)) | 0; + ($ = B), + (B = L), + (L = j), + (j = (C + z) | 0), + (C = w), + (w = _), + (_ = u), + (u = (z + Y) | 0); + } + (this._a = (u + this._a) | 0), + (this._b = (_ + this._b) | 0), + (this._c = (w + this._c) | 0), + (this._d = (C + this._d) | 0), + (this._e = (j + this._e) | 0), + (this._f = (L + this._f) | 0), + (this._g = (B + this._g) | 0), + (this._h = ($ + this._h) | 0); + }), + (Sha256.prototype._hash = function () { + var s = w.allocUnsafe(32); + return ( + s.writeInt32BE(this._a, 0), + s.writeInt32BE(this._b, 4), + s.writeInt32BE(this._c, 8), + s.writeInt32BE(this._d, 12), + s.writeInt32BE(this._e, 16), + s.writeInt32BE(this._f, 20), + s.writeInt32BE(this._g, 24), + s.writeInt32BE(this._h, 28), + s + ); + }), + (s.exports = Sha256); + }, + 32827: (s, o, i) => { + var u = i(56698), + _ = i(82890), + w = i(90392), + x = i(92861).Buffer, + C = new Array(160); + function Sha384() { + this.init(), (this._w = C), w.call(this, 128, 112); + } + u(Sha384, _), + (Sha384.prototype.init = function () { + return ( + (this._ah = 3418070365), + (this._bh = 1654270250), + (this._ch = 2438529370), + (this._dh = 355462360), + (this._eh = 1731405415), + (this._fh = 2394180231), + (this._gh = 3675008525), + (this._hh = 1203062813), + (this._al = 3238371032), + (this._bl = 914150663), + (this._cl = 812702999), + (this._dl = 4144912697), + (this._el = 4290775857), + (this._fl = 1750603025), + (this._gl = 1694076839), + (this._hl = 3204075428), + this + ); + }), + (Sha384.prototype._hash = function () { + var s = x.allocUnsafe(48); + function writeInt64BE(o, i, u) { + s.writeInt32BE(o, u), s.writeInt32BE(i, u + 4); + } + return ( + writeInt64BE(this._ah, this._al, 0), + writeInt64BE(this._bh, this._bl, 8), + writeInt64BE(this._ch, this._cl, 16), + writeInt64BE(this._dh, this._dl, 24), + writeInt64BE(this._eh, this._el, 32), + writeInt64BE(this._fh, this._fl, 40), + s + ); + }), + (s.exports = Sha384); + }, + 82890: (s, o, i) => { + var u = i(56698), + _ = i(90392), + w = i(92861).Buffer, + x = [ + 1116352408, 3609767458, 1899447441, 602891725, 3049323471, 3964484399, 3921009573, + 2173295548, 961987163, 4081628472, 1508970993, 3053834265, 2453635748, 2937671579, + 2870763221, 3664609560, 3624381080, 2734883394, 310598401, 1164996542, 607225278, + 1323610764, 1426881987, 3590304994, 1925078388, 4068182383, 2162078206, 991336113, + 2614888103, 633803317, 3248222580, 3479774868, 3835390401, 2666613458, 4022224774, + 944711139, 264347078, 2341262773, 604807628, 2007800933, 770255983, 1495990901, + 1249150122, 1856431235, 1555081692, 3175218132, 1996064986, 2198950837, 2554220882, + 3999719339, 2821834349, 766784016, 2952996808, 2566594879, 3210313671, 3203337956, + 3336571891, 1034457026, 3584528711, 2466948901, 113926993, 3758326383, 338241895, + 168717936, 666307205, 1188179964, 773529912, 1546045734, 1294757372, 1522805485, + 1396182291, 2643833823, 1695183700, 2343527390, 1986661051, 1014477480, 2177026350, + 1206759142, 2456956037, 344077627, 2730485921, 1290863460, 2820302411, 3158454273, + 3259730800, 3505952657, 3345764771, 106217008, 3516065817, 3606008344, 3600352804, + 1432725776, 4094571909, 1467031594, 275423344, 851169720, 430227734, 3100823752, + 506948616, 1363258195, 659060556, 3750685593, 883997877, 3785050280, 958139571, + 3318307427, 1322822218, 3812723403, 1537002063, 2003034995, 1747873779, 3602036899, + 1955562222, 1575990012, 2024104815, 1125592928, 2227730452, 2716904306, 2361852424, + 442776044, 2428436474, 593698344, 2756734187, 3733110249, 3204031479, 2999351573, + 3329325298, 3815920427, 3391569614, 3928383900, 3515267271, 566280711, 3940187606, + 3454069534, 4118630271, 4000239992, 116418474, 1914138554, 174292421, 2731055270, + 289380356, 3203993006, 460393269, 320620315, 685471733, 587496836, 852142971, + 1086792851, 1017036298, 365543100, 1126000580, 2618297676, 1288033470, 3409855158, + 1501505948, 4234509866, 1607167915, 987167468, 1816402316, 1246189591 + ], + C = new Array(160); + function Sha512() { + this.init(), (this._w = C), _.call(this, 128, 112); + } + function Ch(s, o, i) { + return i ^ (s & (o ^ i)); + } + function maj(s, o, i) { + return (s & o) | (i & (s | o)); + } + function sigma0(s, o) { + return ((s >>> 28) | (o << 4)) ^ ((o >>> 2) | (s << 30)) ^ ((o >>> 7) | (s << 25)); + } + function sigma1(s, o) { + return ((s >>> 14) | (o << 18)) ^ ((s >>> 18) | (o << 14)) ^ ((o >>> 9) | (s << 23)); + } + function Gamma0(s, o) { + return ((s >>> 1) | (o << 31)) ^ ((s >>> 8) | (o << 24)) ^ (s >>> 7); + } + function Gamma0l(s, o) { + return ((s >>> 1) | (o << 31)) ^ ((s >>> 8) | (o << 24)) ^ ((s >>> 7) | (o << 25)); + } + function Gamma1(s, o) { + return ((s >>> 19) | (o << 13)) ^ ((o >>> 29) | (s << 3)) ^ (s >>> 6); + } + function Gamma1l(s, o) { + return ((s >>> 19) | (o << 13)) ^ ((o >>> 29) | (s << 3)) ^ ((s >>> 6) | (o << 26)); + } + function getCarry(s, o) { + return s >>> 0 < o >>> 0 ? 1 : 0; + } + u(Sha512, _), + (Sha512.prototype.init = function () { + return ( + (this._ah = 1779033703), + (this._bh = 3144134277), + (this._ch = 1013904242), + (this._dh = 2773480762), + (this._eh = 1359893119), + (this._fh = 2600822924), + (this._gh = 528734635), + (this._hh = 1541459225), + (this._al = 4089235720), + (this._bl = 2227873595), + (this._cl = 4271175723), + (this._dl = 1595750129), + (this._el = 2917565137), + (this._fl = 725511199), + (this._gl = 4215389547), + (this._hl = 327033209), + this + ); + }), + (Sha512.prototype._update = function (s) { + for ( + var o = this._w, + i = 0 | this._ah, + u = 0 | this._bh, + _ = 0 | this._ch, + w = 0 | this._dh, + C = 0 | this._eh, + j = 0 | this._fh, + L = 0 | this._gh, + B = 0 | this._hh, + $ = 0 | this._al, + V = 0 | this._bl, + U = 0 | this._cl, + z = 0 | this._dl, + Y = 0 | this._el, + Z = 0 | this._fl, + ee = 0 | this._gl, + ie = 0 | this._hl, + ae = 0; + ae < 32; + ae += 2 + ) + (o[ae] = s.readInt32BE(4 * ae)), (o[ae + 1] = s.readInt32BE(4 * ae + 4)); + for (; ae < 160; ae += 2) { + var le = o[ae - 30], + ce = o[ae - 30 + 1], + pe = Gamma0(le, ce), + de = Gamma0l(ce, le), + fe = Gamma1((le = o[ae - 4]), (ce = o[ae - 4 + 1])), + ye = Gamma1l(ce, le), + be = o[ae - 14], + _e = o[ae - 14 + 1], + we = o[ae - 32], + Se = o[ae - 32 + 1], + xe = (de + _e) | 0, + Pe = (pe + be + getCarry(xe, de)) | 0; + (Pe = + ((Pe = (Pe + fe + getCarry((xe = (xe + ye) | 0), ye)) | 0) + + we + + getCarry((xe = (xe + Se) | 0), Se)) | + 0), + (o[ae] = Pe), + (o[ae + 1] = xe); + } + for (var Te = 0; Te < 160; Te += 2) { + (Pe = o[Te]), (xe = o[Te + 1]); + var Re = maj(i, u, _), + qe = maj($, V, U), + $e = sigma0(i, $), + ze = sigma0($, i), + We = sigma1(C, Y), + He = sigma1(Y, C), + Ye = x[Te], + Xe = x[Te + 1], + Qe = Ch(C, j, L), + et = Ch(Y, Z, ee), + tt = (ie + He) | 0, + rt = (B + We + getCarry(tt, ie)) | 0; + rt = + ((rt = + ((rt = (rt + Qe + getCarry((tt = (tt + et) | 0), et)) | 0) + + Ye + + getCarry((tt = (tt + Xe) | 0), Xe)) | + 0) + + Pe + + getCarry((tt = (tt + xe) | 0), xe)) | + 0; + var nt = (ze + qe) | 0, + st = ($e + Re + getCarry(nt, ze)) | 0; + (B = L), + (ie = ee), + (L = j), + (ee = Z), + (j = C), + (Z = Y), + (C = (w + rt + getCarry((Y = (z + tt) | 0), z)) | 0), + (w = _), + (z = U), + (_ = u), + (U = V), + (u = i), + (V = $), + (i = (rt + st + getCarry(($ = (tt + nt) | 0), tt)) | 0); + } + (this._al = (this._al + $) | 0), + (this._bl = (this._bl + V) | 0), + (this._cl = (this._cl + U) | 0), + (this._dl = (this._dl + z) | 0), + (this._el = (this._el + Y) | 0), + (this._fl = (this._fl + Z) | 0), + (this._gl = (this._gl + ee) | 0), + (this._hl = (this._hl + ie) | 0), + (this._ah = (this._ah + i + getCarry(this._al, $)) | 0), + (this._bh = (this._bh + u + getCarry(this._bl, V)) | 0), + (this._ch = (this._ch + _ + getCarry(this._cl, U)) | 0), + (this._dh = (this._dh + w + getCarry(this._dl, z)) | 0), + (this._eh = (this._eh + C + getCarry(this._el, Y)) | 0), + (this._fh = (this._fh + j + getCarry(this._fl, Z)) | 0), + (this._gh = (this._gh + L + getCarry(this._gl, ee)) | 0), + (this._hh = (this._hh + B + getCarry(this._hl, ie)) | 0); + }), + (Sha512.prototype._hash = function () { + var s = w.allocUnsafe(64); + function writeInt64BE(o, i, u) { + s.writeInt32BE(o, u), s.writeInt32BE(i, u + 4); + } + return ( + writeInt64BE(this._ah, this._al, 0), + writeInt64BE(this._bh, this._bl, 8), + writeInt64BE(this._ch, this._cl, 16), + writeInt64BE(this._dh, this._dl, 24), + writeInt64BE(this._eh, this._el, 32), + writeInt64BE(this._fh, this._fl, 40), + writeInt64BE(this._gh, this._gl, 48), + writeInt64BE(this._hh, this._hl, 56), + s + ); + }), + (s.exports = Sha512); + }, + 8068: (s) => { + 'use strict'; + var o = (() => { + var s = Object.defineProperty, + o = Object.getOwnPropertyDescriptor, + i = Object.getOwnPropertyNames, + u = Object.getOwnPropertySymbols, + _ = Object.prototype.hasOwnProperty, + w = Object.prototype.propertyIsEnumerable, + __defNormalProp = (o, i, u) => + i in o + ? s(o, i, { enumerable: !0, configurable: !0, writable: !0, value: u }) + : (o[i] = u), + __spreadValues = (s, o) => { + for (var i in o || (o = {})) _.call(o, i) && __defNormalProp(s, i, o[i]); + if (u) for (var i of u(o)) w.call(o, i) && __defNormalProp(s, i, o[i]); + return s; + }, + __publicField = (s, o, i) => ( + __defNormalProp(s, 'symbol' != typeof o ? o + '' : o, i), i + ), + x = {}; + ((o, i) => { + for (var u in i) s(o, u, { get: i[u], enumerable: !0 }); + })(x, { DEFAULT_OPTIONS: () => j, DEFAULT_UUID_LENGTH: () => C, default: () => $ }); + var C = 6, + j = { dictionary: 'alphanum', shuffle: !0, debug: !1, length: C, counter: 0 }, + L = class _ShortUniqueId { + constructor(s = {}) { + __publicField(this, 'counter'), + __publicField(this, 'debug'), + __publicField(this, 'dict'), + __publicField(this, 'version'), + __publicField(this, 'dictIndex', 0), + __publicField(this, 'dictRange', []), + __publicField(this, 'lowerBound', 0), + __publicField(this, 'upperBound', 0), + __publicField(this, 'dictLength', 0), + __publicField(this, 'uuidLength'), + __publicField(this, '_digit_first_ascii', 48), + __publicField(this, '_digit_last_ascii', 58), + __publicField(this, '_alpha_lower_first_ascii', 97), + __publicField(this, '_alpha_lower_last_ascii', 123), + __publicField(this, '_hex_last_ascii', 103), + __publicField(this, '_alpha_upper_first_ascii', 65), + __publicField(this, '_alpha_upper_last_ascii', 91), + __publicField(this, '_number_dict_ranges', { + digits: [this._digit_first_ascii, this._digit_last_ascii] + }), + __publicField(this, '_alpha_dict_ranges', { + lowerCase: [this._alpha_lower_first_ascii, this._alpha_lower_last_ascii], + upperCase: [this._alpha_upper_first_ascii, this._alpha_upper_last_ascii] + }), + __publicField(this, '_alpha_lower_dict_ranges', { + lowerCase: [this._alpha_lower_first_ascii, this._alpha_lower_last_ascii] + }), + __publicField(this, '_alpha_upper_dict_ranges', { + upperCase: [this._alpha_upper_first_ascii, this._alpha_upper_last_ascii] + }), + __publicField(this, '_alphanum_dict_ranges', { + digits: [this._digit_first_ascii, this._digit_last_ascii], + lowerCase: [this._alpha_lower_first_ascii, this._alpha_lower_last_ascii], + upperCase: [this._alpha_upper_first_ascii, this._alpha_upper_last_ascii] + }), + __publicField(this, '_alphanum_lower_dict_ranges', { + digits: [this._digit_first_ascii, this._digit_last_ascii], + lowerCase: [this._alpha_lower_first_ascii, this._alpha_lower_last_ascii] + }), + __publicField(this, '_alphanum_upper_dict_ranges', { + digits: [this._digit_first_ascii, this._digit_last_ascii], + upperCase: [this._alpha_upper_first_ascii, this._alpha_upper_last_ascii] + }), + __publicField(this, '_hex_dict_ranges', { + decDigits: [this._digit_first_ascii, this._digit_last_ascii], + alphaDigits: [this._alpha_lower_first_ascii, this._hex_last_ascii] + }), + __publicField(this, '_dict_ranges', { + _number_dict_ranges: this._number_dict_ranges, + _alpha_dict_ranges: this._alpha_dict_ranges, + _alpha_lower_dict_ranges: this._alpha_lower_dict_ranges, + _alpha_upper_dict_ranges: this._alpha_upper_dict_ranges, + _alphanum_dict_ranges: this._alphanum_dict_ranges, + _alphanum_lower_dict_ranges: this._alphanum_lower_dict_ranges, + _alphanum_upper_dict_ranges: this._alphanum_upper_dict_ranges, + _hex_dict_ranges: this._hex_dict_ranges + }), + __publicField(this, 'log', (...s) => { + const o = [...s]; + if ( + ((o[0] = `[short-unique-id] ${s[0]}`), + !0 === this.debug && 'undefined' != typeof console && null !== console) + ) + return console.log(...o); + }), + __publicField(this, '_normalizeDictionary', (s, o) => { + let i; + if (s && Array.isArray(s) && s.length > 1) i = s; + else { + let o; + (i = []), (this.dictIndex = o = 0); + const u = `_${s}_dict_ranges`, + _ = this._dict_ranges[u]; + Object.keys(_).forEach((s) => { + const u = s; + for ( + this.dictRange = _[u], + this.lowerBound = this.dictRange[0], + this.upperBound = this.dictRange[1], + this.dictIndex = o = this.lowerBound; + this.lowerBound <= this.upperBound + ? o < this.upperBound + : o > this.upperBound; + this.dictIndex = + this.lowerBound <= this.upperBound ? (o += 1) : (o -= 1) + ) + i.push(String.fromCharCode(this.dictIndex)); + }); + } + if (o) { + const s = 0.5; + i = i.sort(() => Math.random() - s); + } + return i; + }), + __publicField(this, 'setDictionary', (s, o) => { + (this.dict = this._normalizeDictionary(s, o)), + (this.dictLength = this.dict.length), + this.setCounter(0); + }), + __publicField(this, 'seq', () => this.sequentialUUID()), + __publicField(this, 'sequentialUUID', () => { + let s, + o, + i = ''; + s = this.counter; + do { + (o = s % this.dictLength), + (s = Math.trunc(s / this.dictLength)), + (i += this.dict[o]); + } while (0 !== s); + return (this.counter += 1), i; + }), + __publicField(this, 'rnd', (s = this.uuidLength || C) => this.randomUUID(s)), + __publicField(this, 'randomUUID', (s = this.uuidLength || C) => { + let o, i, u; + if (null == s || s < 1) throw new Error('Invalid UUID Length Provided'); + for (o = '', u = 0; u < s; u += 1) + (i = + parseInt((Math.random() * this.dictLength).toFixed(0), 10) % + this.dictLength), + (o += this.dict[i]); + return o; + }), + __publicField(this, 'fmt', (s, o) => this.formattedUUID(s, o)), + __publicField(this, 'formattedUUID', (s, o) => { + const i = { $r: this.randomUUID, $s: this.sequentialUUID, $t: this.stamp }; + return s.replace(/\$[rs]\d{0,}|\$t0|\$t[1-9]\d{1,}/g, (s) => { + const u = s.slice(0, 2), + _ = parseInt(s.slice(2), 10); + return '$s' === u + ? i[u]().padStart(_, '0') + : '$t' === u && o + ? i[u](_, o) + : i[u](_); + }); + }), + __publicField(this, 'availableUUIDs', (s = this.uuidLength) => + parseFloat(Math.pow([...new Set(this.dict)].length, s).toFixed(0)) + ), + __publicField( + this, + 'approxMaxBeforeCollision', + (s = this.availableUUIDs(this.uuidLength)) => + parseFloat(Math.sqrt((Math.PI / 2) * s).toFixed(20)) + ), + __publicField( + this, + 'collisionProbability', + (s = this.availableUUIDs(this.uuidLength), o = this.uuidLength) => + parseFloat( + (this.approxMaxBeforeCollision(s) / this.availableUUIDs(o)).toFixed(20) + ) + ), + __publicField( + this, + 'uniqueness', + (s = this.availableUUIDs(this.uuidLength)) => { + const o = parseFloat( + (1 - this.approxMaxBeforeCollision(s) / s).toFixed(20) + ); + return o > 1 ? 1 : o < 0 ? 0 : o; + } + ), + __publicField(this, 'getVersion', () => this.version), + __publicField(this, 'stamp', (s, o) => { + const i = Math.floor(+(o || new Date()) / 1e3).toString(16); + if ('number' == typeof s && 0 === s) return i; + if ('number' != typeof s || s < 10) + throw new Error( + [ + 'Param finalLength must be a number greater than or equal to 10,', + 'or 0 if you want the raw hexadecimal timestamp' + ].join('\n') + ); + const u = s - 9, + _ = Math.round(Math.random() * (u > 15 ? 15 : u)), + w = this.randomUUID(u); + return `${w.substring(0, _)}${i}${w.substring(_)}${_.toString(16)}`; + }), + __publicField(this, 'parseStamp', (s, o) => { + if (o && !/t0|t[1-9]\d{1,}/.test(o)) + throw new Error( + 'Cannot extract date from a formated UUID with no timestamp in the format' + ); + const i = o + ? o + .replace(/\$[rs]\d{0,}|\$t0|\$t[1-9]\d{1,}/g, (s) => { + const o = { + $r: (s) => [...Array(s)].map(() => 'r').join(''), + $s: (s) => [...Array(s)].map(() => 's').join(''), + $t: (s) => [...Array(s)].map(() => 't').join('') + }, + i = s.slice(0, 2), + u = parseInt(s.slice(2), 10); + return o[i](u); + }) + .replace(/^(.*?)(t{8,})(.*)$/g, (o, i, u) => + s.substring(i.length, i.length + u.length) + ) + : s; + if (8 === i.length) return new Date(1e3 * parseInt(i, 16)); + if (i.length < 10) throw new Error('Stamp length invalid'); + const u = parseInt(i.substring(i.length - 1), 16); + return new Date(1e3 * parseInt(i.substring(u, u + 8), 16)); + }), + __publicField(this, 'setCounter', (s) => { + this.counter = s; + }), + __publicField(this, 'validate', (s, o) => { + const i = o ? this._normalizeDictionary(o) : this.dict; + return s.split('').every((s) => i.includes(s)); + }); + const o = __spreadValues(__spreadValues({}, j), s); + (this.counter = 0), (this.debug = !1), (this.dict = []), (this.version = '5.2.0'); + const { dictionary: i, shuffle: u, length: _, counter: w } = o; + return ( + (this.uuidLength = _), + this.setDictionary(i, u), + this.setCounter(w), + (this.debug = o.debug), + this.log(this.dict), + this.log( + `Generator instantiated with Dictionary Size ${this.dictLength} and counter set to ${this.counter}` + ), + (this.log = this.log.bind(this)), + (this.setDictionary = this.setDictionary.bind(this)), + (this.setCounter = this.setCounter.bind(this)), + (this.seq = this.seq.bind(this)), + (this.sequentialUUID = this.sequentialUUID.bind(this)), + (this.rnd = this.rnd.bind(this)), + (this.randomUUID = this.randomUUID.bind(this)), + (this.fmt = this.fmt.bind(this)), + (this.formattedUUID = this.formattedUUID.bind(this)), + (this.availableUUIDs = this.availableUUIDs.bind(this)), + (this.approxMaxBeforeCollision = this.approxMaxBeforeCollision.bind(this)), + (this.collisionProbability = this.collisionProbability.bind(this)), + (this.uniqueness = this.uniqueness.bind(this)), + (this.getVersion = this.getVersion.bind(this)), + (this.stamp = this.stamp.bind(this)), + (this.parseStamp = this.parseStamp.bind(this)), + this + ); + } + }; + __publicField(L, 'default', L); + var B, + $ = L; + return ( + (B = x), + ((u, w, x, C) => { + if ((w && 'object' == typeof w) || 'function' == typeof w) + for (let j of i(w)) + _.call(u, j) || + j === x || + s(u, j, { get: () => w[j], enumerable: !(C = o(w, j)) || C.enumerable }); + return u; + })(s({}, '__esModule', { value: !0 }), B) + ); + })(); + (s.exports = o.default), 'undefined' != typeof window && (o = o.default); + }, + 88310: (s, o, i) => { + s.exports = Stream; + var u = i(37007).EventEmitter; + function Stream() { + u.call(this); + } + i(56698)(Stream, u), + (Stream.Readable = i(45412)), + (Stream.Writable = i(16708)), + (Stream.Duplex = i(25382)), + (Stream.Transform = i(74610)), + (Stream.PassThrough = i(63600)), + (Stream.finished = i(86238)), + (Stream.pipeline = i(57758)), + (Stream.Stream = Stream), + (Stream.prototype.pipe = function (s, o) { + var i = this; + function ondata(o) { + s.writable && !1 === s.write(o) && i.pause && i.pause(); + } + function ondrain() { + i.readable && i.resume && i.resume(); + } + i.on('data', ondata), + s.on('drain', ondrain), + s._isStdio || (o && !1 === o.end) || (i.on('end', onend), i.on('close', onclose)); + var _ = !1; + function onend() { + _ || ((_ = !0), s.end()); + } + function onclose() { + _ || ((_ = !0), 'function' == typeof s.destroy && s.destroy()); + } + function onerror(s) { + if ((cleanup(), 0 === u.listenerCount(this, 'error'))) throw s; + } + function cleanup() { + i.removeListener('data', ondata), + s.removeListener('drain', ondrain), + i.removeListener('end', onend), + i.removeListener('close', onclose), + i.removeListener('error', onerror), + s.removeListener('error', onerror), + i.removeListener('end', cleanup), + i.removeListener('close', cleanup), + s.removeListener('close', cleanup); + } + return ( + i.on('error', onerror), + s.on('error', onerror), + i.on('end', cleanup), + i.on('close', cleanup), + s.on('close', cleanup), + s.emit('pipe', i), + s + ); + }); + }, + 83141: (s, o, i) => { + 'use strict'; + var u = i(92861).Buffer, + _ = + u.isEncoding || + function (s) { + switch ((s = '' + s) && s.toLowerCase()) { + case 'hex': + case 'utf8': + case 'utf-8': + case 'ascii': + case 'binary': + case 'base64': + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + case 'raw': + return !0; + default: + return !1; + } + }; + function StringDecoder(s) { + var o; + switch ( + ((this.encoding = (function normalizeEncoding(s) { + var o = (function _normalizeEncoding(s) { + if (!s) return 'utf8'; + for (var o; ; ) + switch (s) { + case 'utf8': + case 'utf-8': + return 'utf8'; + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return 'utf16le'; + case 'latin1': + case 'binary': + return 'latin1'; + case 'base64': + case 'ascii': + case 'hex': + return s; + default: + if (o) return; + (s = ('' + s).toLowerCase()), (o = !0); + } + })(s); + if ('string' != typeof o && (u.isEncoding === _ || !_(s))) + throw new Error('Unknown encoding: ' + s); + return o || s; + })(s)), + this.encoding) + ) { + case 'utf16le': + (this.text = utf16Text), (this.end = utf16End), (o = 4); + break; + case 'utf8': + (this.fillLast = utf8FillLast), (o = 4); + break; + case 'base64': + (this.text = base64Text), (this.end = base64End), (o = 3); + break; + default: + return (this.write = simpleWrite), void (this.end = simpleEnd); + } + (this.lastNeed = 0), (this.lastTotal = 0), (this.lastChar = u.allocUnsafe(o)); + } + function utf8CheckByte(s) { + return s <= 127 + ? 0 + : s >> 5 == 6 + ? 2 + : s >> 4 == 14 + ? 3 + : s >> 3 == 30 + ? 4 + : s >> 6 == 2 + ? -1 + : -2; + } + function utf8FillLast(s) { + var o = this.lastTotal - this.lastNeed, + i = (function utf8CheckExtraBytes(s, o, i) { + if (128 != (192 & o[0])) return (s.lastNeed = 0), '�'; + if (s.lastNeed > 1 && o.length > 1) { + if (128 != (192 & o[1])) return (s.lastNeed = 1), '�'; + if (s.lastNeed > 2 && o.length > 2 && 128 != (192 & o[2])) + return (s.lastNeed = 2), '�'; + } + })(this, s); + return void 0 !== i + ? i + : this.lastNeed <= s.length + ? (s.copy(this.lastChar, o, 0, this.lastNeed), + this.lastChar.toString(this.encoding, 0, this.lastTotal)) + : (s.copy(this.lastChar, o, 0, s.length), void (this.lastNeed -= s.length)); + } + function utf16Text(s, o) { + if ((s.length - o) % 2 == 0) { + var i = s.toString('utf16le', o); + if (i) { + var u = i.charCodeAt(i.length - 1); + if (u >= 55296 && u <= 56319) + return ( + (this.lastNeed = 2), + (this.lastTotal = 4), + (this.lastChar[0] = s[s.length - 2]), + (this.lastChar[1] = s[s.length - 1]), + i.slice(0, -1) + ); + } + return i; + } + return ( + (this.lastNeed = 1), + (this.lastTotal = 2), + (this.lastChar[0] = s[s.length - 1]), + s.toString('utf16le', o, s.length - 1) + ); + } + function utf16End(s) { + var o = s && s.length ? this.write(s) : ''; + if (this.lastNeed) { + var i = this.lastTotal - this.lastNeed; + return o + this.lastChar.toString('utf16le', 0, i); + } + return o; + } + function base64Text(s, o) { + var i = (s.length - o) % 3; + return 0 === i + ? s.toString('base64', o) + : ((this.lastNeed = 3 - i), + (this.lastTotal = 3), + 1 === i + ? (this.lastChar[0] = s[s.length - 1]) + : ((this.lastChar[0] = s[s.length - 2]), (this.lastChar[1] = s[s.length - 1])), + s.toString('base64', o, s.length - i)); + } + function base64End(s) { + var o = s && s.length ? this.write(s) : ''; + return this.lastNeed ? o + this.lastChar.toString('base64', 0, 3 - this.lastNeed) : o; + } + function simpleWrite(s) { + return s.toString(this.encoding); + } + function simpleEnd(s) { + return s && s.length ? this.write(s) : ''; + } + (o.I = StringDecoder), + (StringDecoder.prototype.write = function (s) { + if (0 === s.length) return ''; + var o, i; + if (this.lastNeed) { + if (void 0 === (o = this.fillLast(s))) return ''; + (i = this.lastNeed), (this.lastNeed = 0); + } else i = 0; + return i < s.length ? (o ? o + this.text(s, i) : this.text(s, i)) : o || ''; + }), + (StringDecoder.prototype.end = function utf8End(s) { + var o = s && s.length ? this.write(s) : ''; + return this.lastNeed ? o + '�' : o; + }), + (StringDecoder.prototype.text = function utf8Text(s, o) { + var i = (function utf8CheckIncomplete(s, o, i) { + var u = o.length - 1; + if (u < i) return 0; + var _ = utf8CheckByte(o[u]); + if (_ >= 0) return _ > 0 && (s.lastNeed = _ - 1), _; + if (--u < i || -2 === _) return 0; + if (((_ = utf8CheckByte(o[u])), _ >= 0)) return _ > 0 && (s.lastNeed = _ - 2), _; + if (--u < i || -2 === _) return 0; + if (((_ = utf8CheckByte(o[u])), _ >= 0)) + return _ > 0 && (2 === _ ? (_ = 0) : (s.lastNeed = _ - 3)), _; + return 0; + })(this, s, o); + if (!this.lastNeed) return s.toString('utf8', o); + this.lastTotal = i; + var u = s.length - (i - this.lastNeed); + return s.copy(this.lastChar, 0, u), s.toString('utf8', o, u); + }), + (StringDecoder.prototype.fillLast = function (s) { + if (this.lastNeed <= s.length) + return ( + s.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, this.lastNeed), + this.lastChar.toString(this.encoding, 0, this.lastTotal) + ); + s.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, s.length), + (this.lastNeed -= s.length); + }); + }, + 69883: (s, o) => { + 'use strict'; + (o.parse = function parse(s, o) { + if ('string' != typeof s) throw new TypeError('argument str must be a string'); + var i = {}, + _ = s.length; + if (_ < 2) return i; + var w = (o && o.decode) || decode, + x = 0, + C = 0, + j = 0; + do { + if (-1 === (C = s.indexOf('=', x))) break; + if (-1 === (j = s.indexOf(';', x))) j = _; + else if (C > j) { + x = s.lastIndexOf(';', C - 1) + 1; + continue; + } + var L = startIndex(s, x, C), + B = endIndex(s, C, L), + $ = s.slice(L, B); + if (!u.call(i, $)) { + var V = startIndex(s, C + 1, j), + U = endIndex(s, j, V); + 34 === s.charCodeAt(V) && 34 === s.charCodeAt(U - 1) && (V++, U--); + var z = s.slice(V, U); + i[$] = tryDecode(z, w); + } + x = j + 1; + } while (x < _); + return i; + }), + (o.serialize = function serialize(s, o, u) { + var j = (u && u.encode) || encodeURIComponent; + if ('function' != typeof j) throw new TypeError('option encode is invalid'); + if (!_.test(s)) throw new TypeError('argument name is invalid'); + var L = j(o); + if (!w.test(L)) throw new TypeError('argument val is invalid'); + var B = s + '=' + L; + if (!u) return B; + if (null != u.maxAge) { + var $ = Math.floor(u.maxAge); + if (!isFinite($)) throw new TypeError('option maxAge is invalid'); + B += '; Max-Age=' + $; + } + if (u.domain) { + if (!x.test(u.domain)) throw new TypeError('option domain is invalid'); + B += '; Domain=' + u.domain; + } + if (u.path) { + if (!C.test(u.path)) throw new TypeError('option path is invalid'); + B += '; Path=' + u.path; + } + if (u.expires) { + var V = u.expires; + if ( + !(function isDate(s) { + return '[object Date]' === i.call(s); + })(V) || + isNaN(V.valueOf()) + ) + throw new TypeError('option expires is invalid'); + B += '; Expires=' + V.toUTCString(); + } + u.httpOnly && (B += '; HttpOnly'); + u.secure && (B += '; Secure'); + u.partitioned && (B += '; Partitioned'); + if (u.priority) { + switch ('string' == typeof u.priority ? u.priority.toLowerCase() : u.priority) { + case 'low': + B += '; Priority=Low'; + break; + case 'medium': + B += '; Priority=Medium'; + break; + case 'high': + B += '; Priority=High'; + break; + default: + throw new TypeError('option priority is invalid'); + } + } + if (u.sameSite) { + switch ('string' == typeof u.sameSite ? u.sameSite.toLowerCase() : u.sameSite) { + case !0: + B += '; SameSite=Strict'; + break; + case 'lax': + B += '; SameSite=Lax'; + break; + case 'strict': + B += '; SameSite=Strict'; + break; + case 'none': + B += '; SameSite=None'; + break; + default: + throw new TypeError('option sameSite is invalid'); + } + } + return B; + }); + var i = Object.prototype.toString, + u = Object.prototype.hasOwnProperty, + _ = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/, + w = /^("?)[\u0021\u0023-\u002B\u002D-\u003A\u003C-\u005B\u005D-\u007E]*\1$/, + x = + /^([.]?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)([.][a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i, + C = /^[\u0020-\u003A\u003D-\u007E]*$/; + function startIndex(s, o, i) { + do { + var u = s.charCodeAt(o); + if (32 !== u && 9 !== u) return o; + } while (++o < i); + return i; + } + function endIndex(s, o, i) { + for (; o > i; ) { + var u = s.charCodeAt(--o); + if (32 !== u && 9 !== u) return o + 1; + } + return i; + } + function decode(s) { + return -1 !== s.indexOf('%') ? decodeURIComponent(s) : s; + } + function tryDecode(s, o) { + try { + return o(s); + } catch (o) { + return s; + } + } + }, + 16426: (s) => { + s.exports = function () { + var s = document.getSelection(); + if (!s.rangeCount) return function () {}; + for (var o = document.activeElement, i = [], u = 0; u < s.rangeCount; u++) + i.push(s.getRangeAt(u)); + switch (o.tagName.toUpperCase()) { + case 'INPUT': + case 'TEXTAREA': + o.blur(); + break; + default: + o = null; + } + return ( + s.removeAllRanges(), + function () { + 'Caret' === s.type && s.removeAllRanges(), + s.rangeCount || + i.forEach(function (o) { + s.addRange(o); + }), + o && o.focus(); + } + ); + }; + }, + 61160: (s, o, i) => { + 'use strict'; + var u = i(92063), + _ = i(73992), + w = /^[\x00-\x20\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]+/, + x = /[\n\r\t]/g, + C = /^[A-Za-z][A-Za-z0-9+-.]*:\/\//, + j = /:\d+$/, + L = /^([a-z][a-z0-9.+-]*:)?(\/\/)?([\\/]+)?([\S\s]*)/i, + B = /^[a-zA-Z]:/; + function trimLeft(s) { + return (s || '').toString().replace(w, ''); + } + var $ = [ + ['#', 'hash'], + ['?', 'query'], + function sanitize(s, o) { + return isSpecial(o.protocol) ? s.replace(/\\/g, '/') : s; + }, + ['/', 'pathname'], + ['@', 'auth', 1], + [NaN, 'host', void 0, 1, 1], + [/:(\d*)$/, 'port', void 0, 1], + [NaN, 'hostname', void 0, 1, 1] + ], + V = { hash: 1, query: 1 }; + function lolcation(s) { + var o, + u = + ('undefined' != typeof window + ? window + : void 0 !== i.g + ? i.g + : 'undefined' != typeof self + ? self + : {} + ).location || {}, + _ = {}, + w = typeof (s = s || u); + if ('blob:' === s.protocol) _ = new Url(unescape(s.pathname), {}); + else if ('string' === w) for (o in ((_ = new Url(s, {})), V)) delete _[o]; + else if ('object' === w) { + for (o in s) o in V || (_[o] = s[o]); + void 0 === _.slashes && (_.slashes = C.test(s.href)); + } + return _; + } + function isSpecial(s) { + return ( + 'file:' === s || + 'ftp:' === s || + 'http:' === s || + 'https:' === s || + 'ws:' === s || + 'wss:' === s + ); + } + function extractProtocol(s, o) { + (s = (s = trimLeft(s)).replace(x, '')), (o = o || {}); + var i, + u = L.exec(s), + _ = u[1] ? u[1].toLowerCase() : '', + w = !!u[2], + C = !!u[3], + j = 0; + return ( + w + ? C + ? ((i = u[2] + u[3] + u[4]), (j = u[2].length + u[3].length)) + : ((i = u[2] + u[4]), (j = u[2].length)) + : C + ? ((i = u[3] + u[4]), (j = u[3].length)) + : (i = u[4]), + 'file:' === _ + ? j >= 2 && (i = i.slice(2)) + : isSpecial(_) + ? (i = u[4]) + : _ + ? w && (i = i.slice(2)) + : j >= 2 && isSpecial(o.protocol) && (i = u[4]), + { protocol: _, slashes: w || isSpecial(_), slashesCount: j, rest: i } + ); + } + function Url(s, o, i) { + if (((s = (s = trimLeft(s)).replace(x, '')), !(this instanceof Url))) + return new Url(s, o, i); + var w, + C, + j, + L, + V, + U, + z = $.slice(), + Y = typeof o, + Z = this, + ee = 0; + for ( + 'object' !== Y && 'string' !== Y && ((i = o), (o = null)), + i && 'function' != typeof i && (i = _.parse), + w = !(C = extractProtocol(s || '', (o = lolcation(o)))).protocol && !C.slashes, + Z.slashes = C.slashes || (w && o.slashes), + Z.protocol = C.protocol || o.protocol || '', + s = C.rest, + (('file:' === C.protocol && (2 !== C.slashesCount || B.test(s))) || + (!C.slashes && (C.protocol || C.slashesCount < 2 || !isSpecial(Z.protocol)))) && + (z[3] = [/(.*)/, 'pathname']); + ee < z.length; + ee++ + ) + 'function' != typeof (L = z[ee]) + ? ((j = L[0]), + (U = L[1]), + j != j + ? (Z[U] = s) + : 'string' == typeof j + ? ~(V = '@' === j ? s.lastIndexOf(j) : s.indexOf(j)) && + ('number' == typeof L[2] + ? ((Z[U] = s.slice(0, V)), (s = s.slice(V + L[2]))) + : ((Z[U] = s.slice(V)), (s = s.slice(0, V)))) + : (V = j.exec(s)) && ((Z[U] = V[1]), (s = s.slice(0, V.index))), + (Z[U] = Z[U] || (w && L[3] && o[U]) || ''), + L[4] && (Z[U] = Z[U].toLowerCase())) + : (s = L(s, Z)); + i && (Z.query = i(Z.query)), + w && + o.slashes && + '/' !== Z.pathname.charAt(0) && + ('' !== Z.pathname || '' !== o.pathname) && + (Z.pathname = (function resolve(s, o) { + if ('' === s) return o; + for ( + var i = (o || '/').split('/').slice(0, -1).concat(s.split('/')), + u = i.length, + _ = i[u - 1], + w = !1, + x = 0; + u--; + + ) + '.' === i[u] + ? i.splice(u, 1) + : '..' === i[u] + ? (i.splice(u, 1), x++) + : x && (0 === u && (w = !0), i.splice(u, 1), x--); + return w && i.unshift(''), ('.' !== _ && '..' !== _) || i.push(''), i.join('/'); + })(Z.pathname, o.pathname)), + '/' !== Z.pathname.charAt(0) && + isSpecial(Z.protocol) && + (Z.pathname = '/' + Z.pathname), + u(Z.port, Z.protocol) || ((Z.host = Z.hostname), (Z.port = '')), + (Z.username = Z.password = ''), + Z.auth && + (~(V = Z.auth.indexOf(':')) + ? ((Z.username = Z.auth.slice(0, V)), + (Z.username = encodeURIComponent(decodeURIComponent(Z.username))), + (Z.password = Z.auth.slice(V + 1)), + (Z.password = encodeURIComponent(decodeURIComponent(Z.password)))) + : (Z.username = encodeURIComponent(decodeURIComponent(Z.auth))), + (Z.auth = Z.password ? Z.username + ':' + Z.password : Z.username)), + (Z.origin = + 'file:' !== Z.protocol && isSpecial(Z.protocol) && Z.host + ? Z.protocol + '//' + Z.host + : 'null'), + (Z.href = Z.toString()); + } + (Url.prototype = { + set: function set(s, o, i) { + var w = this; + switch (s) { + case 'query': + 'string' == typeof o && o.length && (o = (i || _.parse)(o)), (w[s] = o); + break; + case 'port': + (w[s] = o), + u(o, w.protocol) + ? o && (w.host = w.hostname + ':' + o) + : ((w.host = w.hostname), (w[s] = '')); + break; + case 'hostname': + (w[s] = o), w.port && (o += ':' + w.port), (w.host = o); + break; + case 'host': + (w[s] = o), + j.test(o) + ? ((o = o.split(':')), (w.port = o.pop()), (w.hostname = o.join(':'))) + : ((w.hostname = o), (w.port = '')); + break; + case 'protocol': + (w.protocol = o.toLowerCase()), (w.slashes = !i); + break; + case 'pathname': + case 'hash': + if (o) { + var x = 'pathname' === s ? '/' : '#'; + w[s] = o.charAt(0) !== x ? x + o : o; + } else w[s] = o; + break; + case 'username': + case 'password': + w[s] = encodeURIComponent(o); + break; + case 'auth': + var C = o.indexOf(':'); + ~C + ? ((w.username = o.slice(0, C)), + (w.username = encodeURIComponent(decodeURIComponent(w.username))), + (w.password = o.slice(C + 1)), + (w.password = encodeURIComponent(decodeURIComponent(w.password)))) + : (w.username = encodeURIComponent(decodeURIComponent(o))); + } + for (var L = 0; L < $.length; L++) { + var B = $[L]; + B[4] && (w[B[1]] = w[B[1]].toLowerCase()); + } + return ( + (w.auth = w.password ? w.username + ':' + w.password : w.username), + (w.origin = + 'file:' !== w.protocol && isSpecial(w.protocol) && w.host + ? w.protocol + '//' + w.host + : 'null'), + (w.href = w.toString()), + w + ); + }, + toString: function toString(s) { + (s && 'function' == typeof s) || (s = _.stringify); + var o, + i = this, + u = i.host, + w = i.protocol; + w && ':' !== w.charAt(w.length - 1) && (w += ':'); + var x = w + ((i.protocol && i.slashes) || isSpecial(i.protocol) ? '//' : ''); + return ( + i.username + ? ((x += i.username), i.password && (x += ':' + i.password), (x += '@')) + : i.password + ? ((x += ':' + i.password), (x += '@')) + : 'file:' !== i.protocol && + isSpecial(i.protocol) && + !u && + '/' !== i.pathname && + (x += '@'), + (':' === u[u.length - 1] || (j.test(i.hostname) && !i.port)) && (u += ':'), + (x += u + i.pathname), + (o = 'object' == typeof i.query ? s(i.query) : i.query) && + (x += '?' !== o.charAt(0) ? '?' + o : o), + i.hash && (x += i.hash), + x + ); + } + }), + (Url.extractProtocol = extractProtocol), + (Url.location = lolcation), + (Url.trimLeft = trimLeft), + (Url.qs = _), + (s.exports = Url); + }, + 77154: (s, o, i) => { + 'use strict'; + var u = i(96540); + var _ = + 'function' == typeof Object.is + ? Object.is + : function n(s, o) { + return (s === o && (0 !== s || 1 / s == 1 / o)) || (s != s && o != o); + }, + w = u.useSyncExternalStore, + x = u.useRef, + C = u.useEffect, + j = u.useMemo, + L = u.useDebugValue; + o.useSyncExternalStoreWithSelector = function (s, o, i, u, B) { + var $ = x(null); + if (null === $.current) { + var V = { hasValue: !1, value: null }; + $.current = V; + } else V = $.current; + $ = j( + function () { + function a(o) { + if (!x) { + if (((x = !0), (s = o), (o = u(o)), void 0 !== B && V.hasValue)) { + var i = V.value; + if (B(i, o)) return (w = i); + } + return (w = o); + } + if (((i = w), _(s, o))) return i; + var C = u(o); + return void 0 !== B && B(i, C) ? i : ((s = o), (w = C)); + } + var s, + w, + x = !1, + C = void 0 === i ? null : i; + return [ + function () { + return a(o()); + }, + null === C + ? void 0 + : function () { + return a(C()); + } + ]; + }, + [o, i, u, B] + ); + var U = w(s, $[0], $[1]); + return ( + C( + function () { + (V.hasValue = !0), (V.value = U); + }, + [U] + ), + L(U), + U + ); + }; + }, + 78418: (s, o, i) => { + 'use strict'; + s.exports = i(77154); + }, + 94643: (s, o, i) => { + function config(s) { + try { + if (!i.g.localStorage) return !1; + } catch (s) { + return !1; + } + var o = i.g.localStorage[s]; + return null != o && 'true' === String(o).toLowerCase(); + } + s.exports = function deprecate(s, o) { + if (config('noDeprecation')) return s; + var i = !1; + return function deprecated() { + if (!i) { + if (config('throwDeprecation')) throw new Error(o); + config('traceDeprecation') ? console.trace(o) : console.warn(o), (i = !0); + } + return s.apply(this, arguments); + }; + }; + }, + 26657: (s, o, i) => { + 'use strict'; + var u = i(75208), + _ = function isClosingTag(s) { + return /<\/+[^>]+>/.test(s); + }, + w = function isSelfClosingTag(s) { + return /<[^>]+\/>/.test(s); + }; + function getType(s) { + return _(s) + ? 'ClosingTag' + : (function isOpeningTag(s) { + return ( + (function isTag(s) { + return /<[^>!]+>/.test(s); + })(s) && + !_(s) && + !w(s) + ); + })(s) + ? 'OpeningTag' + : w(s) + ? 'SelfClosingTag' + : 'Text'; + } + s.exports = function (s) { + var o = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, + i = o.indentor, + _ = o.textNodesOnSameLine, + w = 0, + x = []; + i = i || ' '; + var C = (function lexer(s) { + return (function splitOnTags(s) { + return s.split(/(<\/?[^>]+>)/g).filter(function (s) { + return '' !== s.trim(); + }); + })(s).map(function (s) { + return { value: s, type: getType(s) }; + }); + })(s).map(function (s, o, C) { + var j = s.value, + L = s.type; + 'ClosingTag' === L && w--; + var B = u(i, w), + $ = B + j; + if (('OpeningTag' === L && w++, _)) { + var V = C[o - 1], + U = C[o - 2]; + 'ClosingTag' === L && + 'Text' === V.type && + 'OpeningTag' === U.type && + (($ = '' + B + U.value + V.value + j), x.push(o - 2, o - 1)); + } + return $; + }); + return ( + x.forEach(function (s) { + return (C[s] = null); + }), + C.filter(function (s) { + return !!s; + }).join('\n') + ); + }; + }, + 31499: (s) => { + var o = { '&': '&', '"': '"', "'": ''', '<': '<', '>': '>' }; + s.exports = function escapeForXML(s) { + return s && s.replace + ? s.replace(/([&"<>'])/g, function (s, i) { + return o[i]; + }) + : s; + }; + }, + 19123: (s, o, i) => { + var u = i(65606), + _ = i(31499), + w = i(88310).Stream; + function resolve(s, o, i) { + var u, + w = (function create_indent(s, o) { + return new Array(o || 0).join(s || ''); + })(o, (i = i || 0)), + x = s; + if ('object' == typeof s && (x = s[(u = Object.keys(s)[0])]) && x._elem) + return ( + (x._elem.name = u), + (x._elem.icount = i), + (x._elem.indent = o), + (x._elem.indents = w), + (x._elem.interrupt = x), + x._elem + ); + var C, + j = [], + L = []; + function get_attributes(s) { + Object.keys(s).forEach(function (o) { + j.push( + (function attribute(s, o) { + return s + '="' + _(o) + '"'; + })(o, s[o]) + ); + }); + } + switch (typeof x) { + case 'object': + if (null === x) break; + x._attr && get_attributes(x._attr), + x._cdata && + L.push(('/g, ']]]]>') + ']]>'), + x.forEach && + ((C = !1), + L.push(''), + x.forEach(function (s) { + 'object' == typeof s + ? '_attr' == Object.keys(s)[0] + ? get_attributes(s._attr) + : L.push(resolve(s, o, i + 1)) + : (L.pop(), (C = !0), L.push(_(s))); + }), + C || L.push('')); + break; + default: + L.push(_(x)); + } + return { + name: u, + interrupt: !1, + attributes: j, + content: L, + icount: i, + indents: w, + indent: o + }; + } + function format(s, o, i) { + if ('object' != typeof o) return s(!1, o); + var u = o.interrupt ? 1 : o.content.length; + function proceed() { + for (; o.content.length; ) { + var _ = o.content.shift(); + if (void 0 !== _) { + if (interrupt(_)) return; + format(s, _); + } + } + s( + !1, + (u > 1 ? o.indents : '') + + (o.name ? '' : '') + + (o.indent && !i ? '\n' : '') + ), + i && i(); + } + function interrupt(o) { + return ( + !!o.interrupt && + ((o.interrupt.append = s), + (o.interrupt.end = proceed), + (o.interrupt = !1), + s(!0), + !0) + ); + } + if ( + (s( + !1, + o.indents + + (o.name ? '<' + o.name : '') + + (o.attributes.length ? ' ' + o.attributes.join(' ') : '') + + (u ? (o.name ? '>' : '') : o.name ? '/>' : '') + + (o.indent && u > 1 ? '\n' : '') + ), + !u) + ) + return s(!1, o.indent ? '\n' : ''); + interrupt(o) || proceed(); + } + (s.exports = function xml(s, o) { + 'object' != typeof o && (o = { indent: o }); + var i = o.stream ? new w() : null, + _ = '', + x = !1, + C = o.indent ? (!0 === o.indent ? ' ' : o.indent) : '', + j = !0; + function delay(s) { + j ? u.nextTick(s) : s(); + } + function append(s, o) { + if ((void 0 !== o && (_ += o), s && !x && ((i = i || new w()), (x = !0)), s && x)) { + var u = _; + delay(function () { + i.emit('data', u); + }), + (_ = ''); + } + } + function add(s, o) { + format(append, resolve(s, C, C ? 1 : 0), o); + } + function end() { + if (i) { + var s = _; + delay(function () { + i.emit('data', s), i.emit('end'), (i.readable = !1), i.emit('close'); + }); + } + } + return ( + delay(function () { + j = !1; + }), + o.declaration && + (function addXmlDeclaration(s) { + var o = { version: '1.0', encoding: s.encoding || 'UTF-8' }; + s.standalone && (o.standalone = s.standalone), + add({ '?xml': { _attr: o } }), + (_ = _.replace('/>', '?>')); + })(o.declaration), + s && s.forEach + ? s.forEach(function (o, i) { + var u; + i + 1 === s.length && (u = end), add(o, u); + }) + : add(s, end), + i ? ((i.readable = !0), i) : _ + ); + }), + (s.exports.element = s.exports.Element = + function element() { + var s = { + _elem: resolve(Array.prototype.slice.call(arguments)), + push: function (s) { + if (!this.append) throw new Error('not assigned to a parent!'); + var o = this, + i = this._elem.indent; + format( + this.append, + resolve(s, i, this._elem.icount + (i ? 1 : 0)), + function () { + o.append(!0); + } + ); + }, + close: function (s) { + void 0 !== s && this.push(s), this.end && this.end(); + } + }; + return s; + }); + }, + 86215: function (s, o) { + var i, u, _; + (u = []), + (i = (function () { + 'use strict'; + var isNativeSmoothScrollEnabledOn = function (s) { + return ( + s && + 'getComputedStyle' in window && + 'smooth' === window.getComputedStyle(s)['scroll-behavior'] + ); + }; + if ('undefined' == typeof window || !('document' in window)) return {}; + var makeScroller = function (s, o, i) { + var u; + (o = o || 999), i || 0 === i || (i = 9); + var setScrollTimeoutId = function (s) { + u = s; + }, + stopScroll = function () { + clearTimeout(u), setScrollTimeoutId(0); + }, + getTopWithEdgeOffset = function (o) { + return Math.max(0, s.getTopOf(o) - i); + }, + scrollToY = function (i, u, _) { + if ( + (stopScroll(), + 0 === u || (u && u < 0) || isNativeSmoothScrollEnabledOn(s.body)) + ) + s.toY(i), _ && _(); + else { + var w = s.getY(), + x = Math.max(0, i) - w, + C = new Date().getTime(); + (u = u || Math.min(Math.abs(x), o)), + (function loopScroll() { + setScrollTimeoutId( + setTimeout(function () { + var o = Math.min(1, (new Date().getTime() - C) / u), + i = Math.max( + 0, + Math.floor(w + x * (o < 0.5 ? 2 * o * o : o * (4 - 2 * o) - 1)) + ); + s.toY(i), + o < 1 && s.getHeight() + i < s.body.scrollHeight + ? loopScroll() + : (setTimeout(stopScroll, 99), _ && _()); + }, 9) + ); + })(); + } + }, + scrollToElem = function (s, o, i) { + scrollToY(getTopWithEdgeOffset(s), o, i); + }, + scrollIntoView = function (o, u, _) { + var w = o.getBoundingClientRect().height, + x = s.getTopOf(o) + w, + C = s.getHeight(), + j = s.getY(), + L = j + C; + getTopWithEdgeOffset(o) < j || w + i > C + ? scrollToElem(o, u, _) + : x + i > L + ? scrollToY(x - C + i, u, _) + : _ && _(); + }, + scrollToCenterOf = function (o, i, u, _) { + scrollToY( + Math.max( + 0, + s.getTopOf(o) - + s.getHeight() / 2 + + (u || o.getBoundingClientRect().height / 2) + ), + i, + _ + ); + }; + return { + setup: function (s, u) { + return ( + (0 === s || s) && (o = s), + (0 === u || u) && (i = u), + { defaultDuration: o, edgeOffset: i } + ); + }, + to: scrollToElem, + toY: scrollToY, + intoView: scrollIntoView, + center: scrollToCenterOf, + stop: stopScroll, + moving: function () { + return !!u; + }, + getY: s.getY, + getTopOf: s.getTopOf + }; + }, + s = document.documentElement, + getDocY = function () { + return window.scrollY || s.scrollTop; + }, + o = makeScroller({ + body: document.scrollingElement || document.body, + toY: function (s) { + window.scrollTo(0, s); + }, + getY: getDocY, + getHeight: function () { + return window.innerHeight || s.clientHeight; + }, + getTopOf: function (o) { + return o.getBoundingClientRect().top + getDocY() - s.offsetTop; + } + }); + if ( + ((o.createScroller = function (o, i, u) { + return makeScroller( + { + body: o, + toY: function (s) { + o.scrollTop = s; + }, + getY: function () { + return o.scrollTop; + }, + getHeight: function () { + return Math.min(o.clientHeight, window.innerHeight || s.clientHeight); + }, + getTopOf: function (s) { + return s.offsetTop; + } + }, + i, + u + ); + }), + 'addEventListener' in window && + !window.noZensmooth && + !isNativeSmoothScrollEnabledOn(document.body)) + ) { + var i = 'history' in window && 'pushState' in history, + u = i && 'scrollRestoration' in history; + u && (history.scrollRestoration = 'auto'), + window.addEventListener( + 'load', + function () { + u && + (setTimeout(function () { + history.scrollRestoration = 'manual'; + }, 9), + window.addEventListener( + 'popstate', + function (s) { + s.state && 'zenscrollY' in s.state && o.toY(s.state.zenscrollY); + }, + !1 + )), + window.location.hash && + setTimeout(function () { + var s = o.setup().edgeOffset; + if (s) { + var i = document.getElementById(window.location.href.split('#')[1]); + if (i) { + var u = Math.max(0, o.getTopOf(i) - s), + _ = o.getY() - u; + 0 <= _ && _ < 9 && window.scrollTo(0, u); + } + } + }, 9); + }, + !1 + ); + var _ = new RegExp('(^|\\s)noZensmooth(\\s|$)'); + window.addEventListener( + 'click', + function (s) { + for (var w = s.target; w && 'A' !== w.tagName; ) w = w.parentNode; + if ( + !(!w || 1 !== s.which || s.shiftKey || s.metaKey || s.ctrlKey || s.altKey) + ) { + if (u) { + var x = + history.state && 'object' == typeof history.state ? history.state : {}; + x.zenscrollY = o.getY(); + try { + history.replaceState(x, ''); + } catch (s) {} + } + var C = w.getAttribute('href') || ''; + if (0 === C.indexOf('#') && !_.test(w.className)) { + var j = 0, + L = document.getElementById(C.substring(1)); + if ('#' !== C) { + if (!L) return; + j = o.getTopOf(L); + } + s.preventDefault(); + var onDone = function () { + window.location = C; + }, + B = o.setup().edgeOffset; + B && + ((j = Math.max(0, j - B)), + i && + (onDone = function () { + history.pushState({}, '', C); + })), + o.toY(j, null, onDone); + } + } + }, + !1 + ); + } + return o; + })()), + void 0 === (_ = 'function' == typeof i ? i.apply(o, u) : i) || (s.exports = _); + }, + 15340: () => {}, + 79838: () => {}, + 48675: (s, o, i) => { + s.exports = i(20850); + }, + 7666: (s, o, i) => { + var u = i(84851), + _ = i(953); + function _extends() { + var o; + return ( + (s.exports = _extends = + u + ? _((o = u)).call(o) + : function (s) { + for (var o = 1; o < arguments.length; o++) { + var i = arguments[o]; + for (var u in i) ({}).hasOwnProperty.call(i, u) && (s[u] = i[u]); + } + return s; + }), + (s.exports.__esModule = !0), + (s.exports.default = s.exports), + _extends.apply(null, arguments) + ); + } + (s.exports = _extends), (s.exports.__esModule = !0), (s.exports.default = s.exports); + }, + 46942: (s, o) => { + var i; + !(function () { + 'use strict'; + var u = {}.hasOwnProperty; + function classNames() { + for (var s = '', o = 0; o < arguments.length; o++) { + var i = arguments[o]; + i && (s = appendClass(s, parseValue(i))); + } + return s; + } + function parseValue(s) { + if ('string' == typeof s || 'number' == typeof s) return s; + if ('object' != typeof s) return ''; + if (Array.isArray(s)) return classNames.apply(null, s); + if ( + s.toString !== Object.prototype.toString && + !s.toString.toString().includes('[native code]') + ) + return s.toString(); + var o = ''; + for (var i in s) u.call(s, i) && s[i] && (o = appendClass(o, i)); + return o; + } + function appendClass(s, o) { + return o ? (s ? s + ' ' + o : s + o) : s; + } + s.exports + ? ((classNames.default = classNames), (s.exports = classNames)) + : void 0 === + (i = function () { + return classNames; + }.apply(o, [])) || (s.exports = i); + })(); + }, + 68623: (s, o, i) => { + 'use strict'; + var u = i(694); + s.exports = u; + }, + 93700: (s, o, i) => { + 'use strict'; + var u = i(19709); + s.exports = u; + }, + 462: (s, o, i) => { + 'use strict'; + var u = i(40975); + s.exports = u; + }, + 37257: (s, o, i) => { + 'use strict'; + i(96605), i(64502), i(36371), i(99363), i(7057); + var u = i(92046); + s.exports = u.AggregateError; + }, + 32567: (s, o, i) => { + 'use strict'; + i(79307); + var u = i(61747); + s.exports = u('Function', 'bind'); + }, + 23034: (s, o, i) => { + 'use strict'; + var u = i(88280), + _ = i(32567), + w = Function.prototype; + s.exports = function (s) { + var o = s.bind; + return s === w || (u(w, s) && o === w.bind) ? _ : o; + }; + }, + 9748: (s, o, i) => { + 'use strict'; + i(71340); + var u = i(92046); + s.exports = u.Object.assign; + }, + 20850: (s, o, i) => { + 'use strict'; + s.exports = i(46076); + }, + 953: (s, o, i) => { + 'use strict'; + s.exports = i(53375); + }, + 84851: (s, o, i) => { + 'use strict'; + s.exports = i(85401); + }, + 46076: (s, o, i) => { + 'use strict'; + i(91599); + var u = i(68623); + s.exports = u; + }, + 53375: (s, o, i) => { + 'use strict'; + var u = i(93700); + s.exports = u; + }, + 85401: (s, o, i) => { + 'use strict'; + var u = i(462); + s.exports = u; + }, + 82159: (s, o, i) => { + 'use strict'; + var u = i(62250), + _ = i(4640), + w = TypeError; + s.exports = function (s) { + if (u(s)) return s; + throw new w(_(s) + ' is not a function'); + }; + }, + 10043: (s, o, i) => { + 'use strict'; + var u = i(54018), + _ = String, + w = TypeError; + s.exports = function (s) { + if (u(s)) return s; + throw new w("Can't set " + _(s) + ' as a prototype'); + }; + }, + 42156: (s) => { + 'use strict'; + s.exports = function () {}; + }, + 36624: (s, o, i) => { + 'use strict'; + var u = i(46285), + _ = String, + w = TypeError; + s.exports = function (s) { + if (u(s)) return s; + throw new w(_(s) + ' is not an object'); + }; + }, + 74436: (s, o, i) => { + 'use strict'; + var u = i(4993), + _ = i(34849), + w = i(20575), + createMethod = function (s) { + return function (o, i, x) { + var C = u(o), + j = w(C); + if (0 === j) return !s && -1; + var L, + B = _(x, j); + if (s && i != i) { + for (; j > B; ) if ((L = C[B++]) != L) return !0; + } else for (; j > B; B++) if ((s || B in C) && C[B] === i) return s || B || 0; + return !s && -1; + }; + }; + s.exports = { includes: createMethod(!0), indexOf: createMethod(!1) }; + }, + 93427: (s, o, i) => { + 'use strict'; + var u = i(1907); + s.exports = u([].slice); + }, + 45807: (s, o, i) => { + 'use strict'; + var u = i(1907), + _ = u({}.toString), + w = u(''.slice); + s.exports = function (s) { + return w(_(s), 8, -1); + }; + }, + 73948: (s, o, i) => { + 'use strict'; + var u = i(52623), + _ = i(62250), + w = i(45807), + x = i(76264)('toStringTag'), + C = Object, + j = + 'Arguments' === + w( + (function () { + return arguments; + })() + ); + s.exports = u + ? w + : function (s) { + var o, i, u; + return void 0 === s + ? 'Undefined' + : null === s + ? 'Null' + : 'string' == + typeof (i = (function (s, o) { + try { + return s[o]; + } catch (s) {} + })((o = C(s)), x)) + ? i + : j + ? w(o) + : 'Object' === (u = w(o)) && _(o.callee) + ? 'Arguments' + : u; + }; + }, + 19595: (s, o, i) => { + 'use strict'; + var u = i(49724), + _ = i(11042), + w = i(13846), + x = i(74284); + s.exports = function (s, o, i) { + for (var C = _(o), j = x.f, L = w.f, B = 0; B < C.length; B++) { + var $ = C[B]; + u(s, $) || (i && u(i, $)) || j(s, $, L(o, $)); + } + }; + }, + 57382: (s, o, i) => { + 'use strict'; + var u = i(98828); + s.exports = !u(function () { + function F() {} + return (F.prototype.constructor = null), Object.getPrototypeOf(new F()) !== F.prototype; + }); + }, + 59550: (s) => { + 'use strict'; + s.exports = function (s, o) { + return { value: s, done: o }; + }; + }, + 61626: (s, o, i) => { + 'use strict'; + var u = i(39447), + _ = i(74284), + w = i(75817); + s.exports = u + ? function (s, o, i) { + return _.f(s, o, w(1, i)); + } + : function (s, o, i) { + return (s[o] = i), s; + }; + }, + 75817: (s) => { + 'use strict'; + s.exports = function (s, o) { + return { enumerable: !(1 & s), configurable: !(2 & s), writable: !(4 & s), value: o }; + }; + }, + 68055: (s, o, i) => { + 'use strict'; + var u = i(61626); + s.exports = function (s, o, i, _) { + return _ && _.enumerable ? (s[o] = i) : u(s, o, i), s; + }; + }, + 2532: (s, o, i) => { + 'use strict'; + var u = i(45951), + _ = Object.defineProperty; + s.exports = function (s, o) { + try { + _(u, s, { value: o, configurable: !0, writable: !0 }); + } catch (i) { + u[s] = o; + } + return o; + }; + }, + 39447: (s, o, i) => { + 'use strict'; + var u = i(98828); + s.exports = !u(function () { + return ( + 7 !== + Object.defineProperty({}, 1, { + get: function () { + return 7; + } + })[1] + ); + }); + }, + 49552: (s, o, i) => { + 'use strict'; + var u = i(45951), + _ = i(46285), + w = u.document, + x = _(w) && _(w.createElement); + s.exports = function (s) { + return x ? w.createElement(s) : {}; + }; + }, + 19287: (s) => { + 'use strict'; + s.exports = { + CSSRuleList: 0, + CSSStyleDeclaration: 0, + CSSValueList: 0, + ClientRectList: 0, + DOMRectList: 0, + DOMStringList: 0, + DOMTokenList: 1, + DataTransferItemList: 0, + FileList: 0, + HTMLAllCollection: 0, + HTMLCollection: 0, + HTMLFormElement: 0, + HTMLSelectElement: 0, + MediaList: 0, + MimeTypeArray: 0, + NamedNodeMap: 0, + NodeList: 1, + PaintRequestList: 0, + Plugin: 0, + PluginArray: 0, + SVGLengthList: 0, + SVGNumberList: 0, + SVGPathSegList: 0, + SVGPointList: 0, + SVGStringList: 0, + SVGTransformList: 0, + SourceBufferList: 0, + StyleSheetList: 0, + TextTrackCueList: 0, + TextTrackList: 0, + TouchList: 0 + }; + }, + 80376: (s) => { + 'use strict'; + s.exports = [ + 'constructor', + 'hasOwnProperty', + 'isPrototypeOf', + 'propertyIsEnumerable', + 'toLocaleString', + 'toString', + 'valueOf' + ]; + }, + 96794: (s, o, i) => { + 'use strict'; + var u = i(45951).navigator, + _ = u && u.userAgent; + s.exports = _ ? String(_) : ''; + }, + 20798: (s, o, i) => { + 'use strict'; + var u, + _, + w = i(45951), + x = i(96794), + C = w.process, + j = w.Deno, + L = (C && C.versions) || (j && j.version), + B = L && L.v8; + B && (_ = (u = B.split('.'))[0] > 0 && u[0] < 4 ? 1 : +(u[0] + u[1])), + !_ && + x && + (!(u = x.match(/Edge\/(\d+)/)) || u[1] >= 74) && + (u = x.match(/Chrome\/(\d+)/)) && + (_ = +u[1]), + (s.exports = _); + }, + 85762: (s, o, i) => { + 'use strict'; + var u = i(1907), + _ = Error, + w = u(''.replace), + x = String(new _('zxcasd').stack), + C = /\n\s*at [^:]*:[^\n]*/, + j = C.test(x); + s.exports = function (s, o) { + if (j && 'string' == typeof s && !_.prepareStackTrace) for (; o--; ) s = w(s, C, ''); + return s; + }; + }, + 85884: (s, o, i) => { + 'use strict'; + var u = i(61626), + _ = i(85762), + w = i(23888), + x = Error.captureStackTrace; + s.exports = function (s, o, i, C) { + w && (x ? x(s, o) : u(s, 'stack', _(i, C))); + }; + }, + 23888: (s, o, i) => { + 'use strict'; + var u = i(98828), + _ = i(75817); + s.exports = !u(function () { + var s = new Error('a'); + return !('stack' in s) || (Object.defineProperty(s, 'stack', _(1, 7)), 7 !== s.stack); + }); + }, + 11091: (s, o, i) => { + 'use strict'; + var u = i(45951), + _ = i(76024), + w = i(92361), + x = i(62250), + C = i(13846).f, + j = i(7463), + L = i(92046), + B = i(28311), + $ = i(61626), + V = i(49724); + i(36128); + var wrapConstructor = function (s) { + var Wrapper = function (o, i, u) { + if (this instanceof Wrapper) { + switch (arguments.length) { + case 0: + return new s(); + case 1: + return new s(o); + case 2: + return new s(o, i); + } + return new s(o, i, u); + } + return _(s, this, arguments); + }; + return (Wrapper.prototype = s.prototype), Wrapper; + }; + s.exports = function (s, o) { + var i, + _, + U, + z, + Y, + Z, + ee, + ie, + ae, + le = s.target, + ce = s.global, + pe = s.stat, + de = s.proto, + fe = ce ? u : pe ? u[le] : u[le] && u[le].prototype, + ye = ce ? L : L[le] || $(L, le, {})[le], + be = ye.prototype; + for (z in o) + (_ = !(i = j(ce ? z : le + (pe ? '.' : '#') + z, s.forced)) && fe && V(fe, z)), + (Z = ye[z]), + _ && (ee = s.dontCallGetSet ? (ae = C(fe, z)) && ae.value : fe[z]), + (Y = _ && ee ? ee : o[z]), + (i || de || typeof Z != typeof Y) && + ((ie = + s.bind && _ + ? B(Y, u) + : s.wrap && _ + ? wrapConstructor(Y) + : de && x(Y) + ? w(Y) + : Y), + (s.sham || (Y && Y.sham) || (Z && Z.sham)) && $(ie, 'sham', !0), + $(ye, z, ie), + de && + (V(L, (U = le + 'Prototype')) || $(L, U, {}), + $(L[U], z, Y), + s.real && be && (i || !be[z]) && $(be, z, Y))); + }; + }, + 98828: (s) => { + 'use strict'; + s.exports = function (s) { + try { + return !!s(); + } catch (s) { + return !0; + } + }; + }, + 76024: (s, o, i) => { + 'use strict'; + var u = i(41505), + _ = Function.prototype, + w = _.apply, + x = _.call; + s.exports = + ('object' == typeof Reflect && Reflect.apply) || + (u + ? x.bind(w) + : function () { + return x.apply(w, arguments); + }); + }, + 28311: (s, o, i) => { + 'use strict'; + var u = i(92361), + _ = i(82159), + w = i(41505), + x = u(u.bind); + s.exports = function (s, o) { + return ( + _(s), + void 0 === o + ? s + : w + ? x(s, o) + : function () { + return s.apply(o, arguments); + } + ); + }; + }, + 41505: (s, o, i) => { + 'use strict'; + var u = i(98828); + s.exports = !u(function () { + var s = function () {}.bind(); + return 'function' != typeof s || s.hasOwnProperty('prototype'); + }); + }, + 44673: (s, o, i) => { + 'use strict'; + var u = i(1907), + _ = i(82159), + w = i(46285), + x = i(49724), + C = i(93427), + j = i(41505), + L = Function, + B = u([].concat), + $ = u([].join), + V = {}; + s.exports = j + ? L.bind + : function bind(s) { + var o = _(this), + i = o.prototype, + u = C(arguments, 1), + j = function bound() { + var i = B(u, C(arguments)); + return this instanceof j + ? (function (s, o, i) { + if (!x(V, o)) { + for (var u = [], _ = 0; _ < o; _++) u[_] = 'a[' + _ + ']'; + V[o] = L('C,a', 'return new C(' + $(u, ',') + ')'); + } + return V[o](s, i); + })(o, i.length, i) + : o.apply(s, i); + }; + return w(i) && (j.prototype = i), j; + }; + }, + 13930: (s, o, i) => { + 'use strict'; + var u = i(41505), + _ = Function.prototype.call; + s.exports = u + ? _.bind(_) + : function () { + return _.apply(_, arguments); + }; + }, + 36833: (s, o, i) => { + 'use strict'; + var u = i(39447), + _ = i(49724), + w = Function.prototype, + x = u && Object.getOwnPropertyDescriptor, + C = _(w, 'name'), + j = C && 'something' === function something() {}.name, + L = C && (!u || (u && x(w, 'name').configurable)); + s.exports = { EXISTS: C, PROPER: j, CONFIGURABLE: L }; + }, + 51871: (s, o, i) => { + 'use strict'; + var u = i(1907), + _ = i(82159); + s.exports = function (s, o, i) { + try { + return u(_(Object.getOwnPropertyDescriptor(s, o)[i])); + } catch (s) {} + }; + }, + 92361: (s, o, i) => { + 'use strict'; + var u = i(45807), + _ = i(1907); + s.exports = function (s) { + if ('Function' === u(s)) return _(s); + }; + }, + 1907: (s, o, i) => { + 'use strict'; + var u = i(41505), + _ = Function.prototype, + w = _.call, + x = u && _.bind.bind(w, w); + s.exports = u + ? x + : function (s) { + return function () { + return w.apply(s, arguments); + }; + }; + }, + 61747: (s, o, i) => { + 'use strict'; + var u = i(45951), + _ = i(92046); + s.exports = function (s, o) { + var i = _[s + 'Prototype'], + w = i && i[o]; + if (w) return w; + var x = u[s], + C = x && x.prototype; + return C && C[o]; + }; + }, + 85582: (s, o, i) => { + 'use strict'; + var u = i(92046), + _ = i(45951), + w = i(62250), + aFunction = function (s) { + return w(s) ? s : void 0; + }; + s.exports = function (s, o) { + return arguments.length < 2 + ? aFunction(u[s]) || aFunction(_[s]) + : (u[s] && u[s][o]) || (_[s] && _[s][o]); + }; + }, + 73448: (s, o, i) => { + 'use strict'; + var u = i(73948), + _ = i(29367), + w = i(87136), + x = i(93742), + C = i(76264)('iterator'); + s.exports = function (s) { + if (!w(s)) return _(s, C) || _(s, '@@iterator') || x[u(s)]; + }; + }, + 10300: (s, o, i) => { + 'use strict'; + var u = i(13930), + _ = i(82159), + w = i(36624), + x = i(4640), + C = i(73448), + j = TypeError; + s.exports = function (s, o) { + var i = arguments.length < 2 ? C(s) : o; + if (_(i)) return w(u(i, s)); + throw new j(x(s) + ' is not iterable'); + }; + }, + 29367: (s, o, i) => { + 'use strict'; + var u = i(82159), + _ = i(87136); + s.exports = function (s, o) { + var i = s[o]; + return _(i) ? void 0 : u(i); + }; + }, + 45951: function (s, o, i) { + 'use strict'; + var check = function (s) { + return s && s.Math === Math && s; + }; + s.exports = + check('object' == typeof globalThis && globalThis) || + check('object' == typeof window && window) || + check('object' == typeof self && self) || + check('object' == typeof i.g && i.g) || + check('object' == typeof this && this) || + (function () { + return this; + })() || + Function('return this')(); + }, + 49724: (s, o, i) => { + 'use strict'; + var u = i(1907), + _ = i(39298), + w = u({}.hasOwnProperty); + s.exports = + Object.hasOwn || + function hasOwn(s, o) { + return w(_(s), o); + }; + }, + 38530: (s) => { + 'use strict'; + s.exports = {}; + }, + 62416: (s, o, i) => { + 'use strict'; + var u = i(85582); + s.exports = u('document', 'documentElement'); + }, + 73648: (s, o, i) => { + 'use strict'; + var u = i(39447), + _ = i(98828), + w = i(49552); + s.exports = + !u && + !_(function () { + return ( + 7 !== + Object.defineProperty(w('div'), 'a', { + get: function () { + return 7; + } + }).a + ); + }); + }, + 16946: (s, o, i) => { + 'use strict'; + var u = i(1907), + _ = i(98828), + w = i(45807), + x = Object, + C = u(''.split); + s.exports = _(function () { + return !x('z').propertyIsEnumerable(0); + }) + ? function (s) { + return 'String' === w(s) ? C(s, '') : x(s); + } + : x; + }, + 34084: (s, o, i) => { + 'use strict'; + var u = i(62250), + _ = i(46285), + w = i(79192); + s.exports = function (s, o, i) { + var x, C; + return ( + w && + u((x = o.constructor)) && + x !== i && + _((C = x.prototype)) && + C !== i.prototype && + w(s, C), + s + ); + }; + }, + 39259: (s, o, i) => { + 'use strict'; + var u = i(46285), + _ = i(61626); + s.exports = function (s, o) { + u(o) && 'cause' in o && _(s, 'cause', o.cause); + }; + }, + 64932: (s, o, i) => { + 'use strict'; + var u, + _, + w, + x = i(40551), + C = i(45951), + j = i(46285), + L = i(61626), + B = i(49724), + $ = i(36128), + V = i(92522), + U = i(38530), + z = 'Object already initialized', + Y = C.TypeError, + Z = C.WeakMap; + if (x || $.state) { + var ee = $.state || ($.state = new Z()); + (ee.get = ee.get), + (ee.has = ee.has), + (ee.set = ee.set), + (u = function (s, o) { + if (ee.has(s)) throw new Y(z); + return (o.facade = s), ee.set(s, o), o; + }), + (_ = function (s) { + return ee.get(s) || {}; + }), + (w = function (s) { + return ee.has(s); + }); + } else { + var ie = V('state'); + (U[ie] = !0), + (u = function (s, o) { + if (B(s, ie)) throw new Y(z); + return (o.facade = s), L(s, ie, o), o; + }), + (_ = function (s) { + return B(s, ie) ? s[ie] : {}; + }), + (w = function (s) { + return B(s, ie); + }); + } + s.exports = { + set: u, + get: _, + has: w, + enforce: function (s) { + return w(s) ? _(s) : u(s, {}); + }, + getterFor: function (s) { + return function (o) { + var i; + if (!j(o) || (i = _(o)).type !== s) + throw new Y('Incompatible receiver, ' + s + ' required'); + return i; + }; + } + }; + }, + 37812: (s, o, i) => { + 'use strict'; + var u = i(76264), + _ = i(93742), + w = u('iterator'), + x = Array.prototype; + s.exports = function (s) { + return void 0 !== s && (_.Array === s || x[w] === s); + }; + }, + 62250: (s) => { + 'use strict'; + var o = 'object' == typeof document && document.all; + s.exports = + void 0 === o && void 0 !== o + ? function (s) { + return 'function' == typeof s || s === o; + } + : function (s) { + return 'function' == typeof s; + }; + }, + 7463: (s, o, i) => { + 'use strict'; + var u = i(98828), + _ = i(62250), + w = /#|\.prototype\./, + isForced = function (s, o) { + var i = C[x(s)]; + return i === L || (i !== j && (_(o) ? u(o) : !!o)); + }, + x = (isForced.normalize = function (s) { + return String(s).replace(w, '.').toLowerCase(); + }), + C = (isForced.data = {}), + j = (isForced.NATIVE = 'N'), + L = (isForced.POLYFILL = 'P'); + s.exports = isForced; + }, + 87136: (s) => { + 'use strict'; + s.exports = function (s) { + return null == s; + }; + }, + 46285: (s, o, i) => { + 'use strict'; + var u = i(62250); + s.exports = function (s) { + return 'object' == typeof s ? null !== s : u(s); + }; + }, + 54018: (s, o, i) => { + 'use strict'; + var u = i(46285); + s.exports = function (s) { + return u(s) || null === s; + }; + }, + 7376: (s) => { + 'use strict'; + s.exports = !0; + }, + 25594: (s, o, i) => { + 'use strict'; + var u = i(85582), + _ = i(62250), + w = i(88280), + x = i(51175), + C = Object; + s.exports = x + ? function (s) { + return 'symbol' == typeof s; + } + : function (s) { + var o = u('Symbol'); + return _(o) && w(o.prototype, C(s)); + }; + }, + 24823: (s, o, i) => { + 'use strict'; + var u = i(28311), + _ = i(13930), + w = i(36624), + x = i(4640), + C = i(37812), + j = i(20575), + L = i(88280), + B = i(10300), + $ = i(73448), + V = i(40154), + U = TypeError, + Result = function (s, o) { + (this.stopped = s), (this.result = o); + }, + z = Result.prototype; + s.exports = function (s, o, i) { + var Y, + Z, + ee, + ie, + ae, + le, + ce, + pe = i && i.that, + de = !(!i || !i.AS_ENTRIES), + fe = !(!i || !i.IS_RECORD), + ye = !(!i || !i.IS_ITERATOR), + be = !(!i || !i.INTERRUPTED), + _e = u(o, pe), + stop = function (s) { + return Y && V(Y, 'normal', s), new Result(!0, s); + }, + callFn = function (s) { + return de + ? (w(s), be ? _e(s[0], s[1], stop) : _e(s[0], s[1])) + : be + ? _e(s, stop) + : _e(s); + }; + if (fe) Y = s.iterator; + else if (ye) Y = s; + else { + if (!(Z = $(s))) throw new U(x(s) + ' is not iterable'); + if (C(Z)) { + for (ee = 0, ie = j(s); ie > ee; ee++) + if ((ae = callFn(s[ee])) && L(z, ae)) return ae; + return new Result(!1); + } + Y = B(s, Z); + } + for (le = fe ? s.next : Y.next; !(ce = _(le, Y)).done; ) { + try { + ae = callFn(ce.value); + } catch (s) { + V(Y, 'throw', s); + } + if ('object' == typeof ae && ae && L(z, ae)) return ae; + } + return new Result(!1); + }; + }, + 40154: (s, o, i) => { + 'use strict'; + var u = i(13930), + _ = i(36624), + w = i(29367); + s.exports = function (s, o, i) { + var x, C; + _(s); + try { + if (!(x = w(s, 'return'))) { + if ('throw' === o) throw i; + return i; + } + x = u(x, s); + } catch (s) { + (C = !0), (x = s); + } + if ('throw' === o) throw i; + if (C) throw x; + return _(x), i; + }; + }, + 47181: (s, o, i) => { + 'use strict'; + var u = i(95116).IteratorPrototype, + _ = i(58075), + w = i(75817), + x = i(14840), + C = i(93742), + returnThis = function () { + return this; + }; + s.exports = function (s, o, i, j) { + var L = o + ' Iterator'; + return ( + (s.prototype = _(u, { next: w(+!j, i) })), x(s, L, !1, !0), (C[L] = returnThis), s + ); + }; + }, + 60183: (s, o, i) => { + 'use strict'; + var u = i(11091), + _ = i(13930), + w = i(7376), + x = i(36833), + C = i(62250), + j = i(47181), + L = i(15972), + B = i(79192), + $ = i(14840), + V = i(61626), + U = i(68055), + z = i(76264), + Y = i(93742), + Z = i(95116), + ee = x.PROPER, + ie = x.CONFIGURABLE, + ae = Z.IteratorPrototype, + le = Z.BUGGY_SAFARI_ITERATORS, + ce = z('iterator'), + pe = 'keys', + de = 'values', + fe = 'entries', + returnThis = function () { + return this; + }; + s.exports = function (s, o, i, x, z, Z, ye) { + j(i, o, x); + var be, + _e, + we, + getIterationMethod = function (s) { + if (s === z && Re) return Re; + if (!le && s && s in Pe) return Pe[s]; + switch (s) { + case pe: + return function keys() { + return new i(this, s); + }; + case de: + return function values() { + return new i(this, s); + }; + case fe: + return function entries() { + return new i(this, s); + }; + } + return function () { + return new i(this); + }; + }, + Se = o + ' Iterator', + xe = !1, + Pe = s.prototype, + Te = Pe[ce] || Pe['@@iterator'] || (z && Pe[z]), + Re = (!le && Te) || getIterationMethod(z), + qe = ('Array' === o && Pe.entries) || Te; + if ( + (qe && + (be = L(qe.call(new s()))) !== Object.prototype && + be.next && + (w || L(be) === ae || (B ? B(be, ae) : C(be[ce]) || U(be, ce, returnThis)), + $(be, Se, !0, !0), + w && (Y[Se] = returnThis)), + ee && + z === de && + Te && + Te.name !== de && + (!w && ie + ? V(Pe, 'name', de) + : ((xe = !0), + (Re = function values() { + return _(Te, this); + }))), + z) + ) + if ( + ((_e = { + values: getIterationMethod(de), + keys: Z ? Re : getIterationMethod(pe), + entries: getIterationMethod(fe) + }), + ye) + ) + for (we in _e) (le || xe || !(we in Pe)) && U(Pe, we, _e[we]); + else u({ target: o, proto: !0, forced: le || xe }, _e); + return (w && !ye) || Pe[ce] === Re || U(Pe, ce, Re, { name: z }), (Y[o] = Re), _e; + }; + }, + 95116: (s, o, i) => { + 'use strict'; + var u, + _, + w, + x = i(98828), + C = i(62250), + j = i(46285), + L = i(58075), + B = i(15972), + $ = i(68055), + V = i(76264), + U = i(7376), + z = V('iterator'), + Y = !1; + [].keys && + ('next' in (w = [].keys()) ? (_ = B(B(w))) !== Object.prototype && (u = _) : (Y = !0)), + !j(u) || + x(function () { + var s = {}; + return u[z].call(s) !== s; + }) + ? (u = {}) + : U && (u = L(u)), + C(u[z]) || + $(u, z, function () { + return this; + }), + (s.exports = { IteratorPrototype: u, BUGGY_SAFARI_ITERATORS: Y }); + }, + 93742: (s) => { + 'use strict'; + s.exports = {}; + }, + 20575: (s, o, i) => { + 'use strict'; + var u = i(3121); + s.exports = function (s) { + return u(s.length); + }; + }, + 41176: (s) => { + 'use strict'; + var o = Math.ceil, + i = Math.floor; + s.exports = + Math.trunc || + function trunc(s) { + var u = +s; + return (u > 0 ? i : o)(u); + }; + }, + 32096: (s, o, i) => { + 'use strict'; + var u = i(90160); + s.exports = function (s, o) { + return void 0 === s ? (arguments.length < 2 ? '' : o) : u(s); + }; + }, + 29538: (s, o, i) => { + 'use strict'; + var u = i(39447), + _ = i(1907), + w = i(13930), + x = i(98828), + C = i(2875), + j = i(87170), + L = i(22574), + B = i(39298), + $ = i(16946), + V = Object.assign, + U = Object.defineProperty, + z = _([].concat); + s.exports = + !V || + x(function () { + if ( + u && + 1 !== + V( + { b: 1 }, + V( + U({}, 'a', { + enumerable: !0, + get: function () { + U(this, 'b', { value: 3, enumerable: !1 }); + } + }), + { b: 2 } + ) + ).b + ) + return !0; + var s = {}, + o = {}, + i = Symbol('assign detection'), + _ = 'abcdefghijklmnopqrst'; + return ( + (s[i] = 7), + _.split('').forEach(function (s) { + o[s] = s; + }), + 7 !== V({}, s)[i] || C(V({}, o)).join('') !== _ + ); + }) + ? function assign(s, o) { + for (var i = B(s), _ = arguments.length, x = 1, V = j.f, U = L.f; _ > x; ) + for ( + var Y, + Z = $(arguments[x++]), + ee = V ? z(C(Z), V(Z)) : C(Z), + ie = ee.length, + ae = 0; + ie > ae; + + ) + (Y = ee[ae++]), (u && !w(U, Z, Y)) || (i[Y] = Z[Y]); + return i; + } + : V; + }, + 58075: (s, o, i) => { + 'use strict'; + var u, + _ = i(36624), + w = i(42220), + x = i(80376), + C = i(38530), + j = i(62416), + L = i(49552), + B = i(92522), + $ = 'prototype', + V = 'script', + U = B('IE_PROTO'), + EmptyConstructor = function () {}, + scriptTag = function (s) { + return '<' + V + '>' + s + ''; + }, + NullProtoObjectViaActiveX = function (s) { + s.write(scriptTag('')), s.close(); + var o = s.parentWindow.Object; + return (s = null), o; + }, + NullProtoObject = function () { + try { + u = new ActiveXObject('htmlfile'); + } catch (s) {} + var s, o, i; + NullProtoObject = + 'undefined' != typeof document + ? document.domain && u + ? NullProtoObjectViaActiveX(u) + : ((o = L('iframe')), + (i = 'java' + V + ':'), + (o.style.display = 'none'), + j.appendChild(o), + (o.src = String(i)), + (s = o.contentWindow.document).open(), + s.write(scriptTag('document.F=Object')), + s.close(), + s.F) + : NullProtoObjectViaActiveX(u); + for (var _ = x.length; _--; ) delete NullProtoObject[$][x[_]]; + return NullProtoObject(); + }; + (C[U] = !0), + (s.exports = + Object.create || + function create(s, o) { + var i; + return ( + null !== s + ? ((EmptyConstructor[$] = _(s)), + (i = new EmptyConstructor()), + (EmptyConstructor[$] = null), + (i[U] = s)) + : (i = NullProtoObject()), + void 0 === o ? i : w.f(i, o) + ); + }); + }, + 42220: (s, o, i) => { + 'use strict'; + var u = i(39447), + _ = i(58661), + w = i(74284), + x = i(36624), + C = i(4993), + j = i(2875); + o.f = + u && !_ + ? Object.defineProperties + : function defineProperties(s, o) { + x(s); + for (var i, u = C(o), _ = j(o), L = _.length, B = 0; L > B; ) + w.f(s, (i = _[B++]), u[i]); + return s; + }; + }, + 74284: (s, o, i) => { + 'use strict'; + var u = i(39447), + _ = i(73648), + w = i(58661), + x = i(36624), + C = i(70470), + j = TypeError, + L = Object.defineProperty, + B = Object.getOwnPropertyDescriptor, + $ = 'enumerable', + V = 'configurable', + U = 'writable'; + o.f = u + ? w + ? function defineProperty(s, o, i) { + if ( + (x(s), + (o = C(o)), + x(i), + 'function' == typeof s && 'prototype' === o && 'value' in i && U in i && !i[U]) + ) { + var u = B(s, o); + u && + u[U] && + ((s[o] = i.value), + (i = { + configurable: V in i ? i[V] : u[V], + enumerable: $ in i ? i[$] : u[$], + writable: !1 + })); + } + return L(s, o, i); + } + : L + : function defineProperty(s, o, i) { + if ((x(s), (o = C(o)), x(i), _)) + try { + return L(s, o, i); + } catch (s) {} + if ('get' in i || 'set' in i) throw new j('Accessors not supported'); + return 'value' in i && (s[o] = i.value), s; + }; + }, + 13846: (s, o, i) => { + 'use strict'; + var u = i(39447), + _ = i(13930), + w = i(22574), + x = i(75817), + C = i(4993), + j = i(70470), + L = i(49724), + B = i(73648), + $ = Object.getOwnPropertyDescriptor; + o.f = u + ? $ + : function getOwnPropertyDescriptor(s, o) { + if (((s = C(s)), (o = j(o)), B)) + try { + return $(s, o); + } catch (s) {} + if (L(s, o)) return x(!_(w.f, s, o), s[o]); + }; + }, + 24443: (s, o, i) => { + 'use strict'; + var u = i(23045), + _ = i(80376).concat('length', 'prototype'); + o.f = + Object.getOwnPropertyNames || + function getOwnPropertyNames(s) { + return u(s, _); + }; + }, + 87170: (s, o) => { + 'use strict'; + o.f = Object.getOwnPropertySymbols; + }, + 15972: (s, o, i) => { + 'use strict'; + var u = i(49724), + _ = i(62250), + w = i(39298), + x = i(92522), + C = i(57382), + j = x('IE_PROTO'), + L = Object, + B = L.prototype; + s.exports = C + ? L.getPrototypeOf + : function (s) { + var o = w(s); + if (u(o, j)) return o[j]; + var i = o.constructor; + return _(i) && o instanceof i ? i.prototype : o instanceof L ? B : null; + }; + }, + 88280: (s, o, i) => { + 'use strict'; + var u = i(1907); + s.exports = u({}.isPrototypeOf); + }, + 23045: (s, o, i) => { + 'use strict'; + var u = i(1907), + _ = i(49724), + w = i(4993), + x = i(74436).indexOf, + C = i(38530), + j = u([].push); + s.exports = function (s, o) { + var i, + u = w(s), + L = 0, + B = []; + for (i in u) !_(C, i) && _(u, i) && j(B, i); + for (; o.length > L; ) _(u, (i = o[L++])) && (~x(B, i) || j(B, i)); + return B; + }; + }, + 2875: (s, o, i) => { + 'use strict'; + var u = i(23045), + _ = i(80376); + s.exports = + Object.keys || + function keys(s) { + return u(s, _); + }; + }, + 22574: (s, o) => { + 'use strict'; + var i = {}.propertyIsEnumerable, + u = Object.getOwnPropertyDescriptor, + _ = u && !i.call({ 1: 2 }, 1); + o.f = _ + ? function propertyIsEnumerable(s) { + var o = u(this, s); + return !!o && o.enumerable; + } + : i; + }, + 79192: (s, o, i) => { + 'use strict'; + var u = i(51871), + _ = i(46285), + w = i(74239), + x = i(10043); + s.exports = + Object.setPrototypeOf || + ('__proto__' in {} + ? (function () { + var s, + o = !1, + i = {}; + try { + (s = u(Object.prototype, '__proto__', 'set'))(i, []), (o = i instanceof Array); + } catch (s) {} + return function setPrototypeOf(i, u) { + return w(i), x(u), _(i) ? (o ? s(i, u) : (i.__proto__ = u), i) : i; + }; + })() + : void 0); + }, + 54878: (s, o, i) => { + 'use strict'; + var u = i(52623), + _ = i(73948); + s.exports = u + ? {}.toString + : function toString() { + return '[object ' + _(this) + ']'; + }; + }, + 60581: (s, o, i) => { + 'use strict'; + var u = i(13930), + _ = i(62250), + w = i(46285), + x = TypeError; + s.exports = function (s, o) { + var i, C; + if ('string' === o && _((i = s.toString)) && !w((C = u(i, s)))) return C; + if (_((i = s.valueOf)) && !w((C = u(i, s)))) return C; + if ('string' !== o && _((i = s.toString)) && !w((C = u(i, s)))) return C; + throw new x("Can't convert object to primitive value"); + }; + }, + 11042: (s, o, i) => { + 'use strict'; + var u = i(85582), + _ = i(1907), + w = i(24443), + x = i(87170), + C = i(36624), + j = _([].concat); + s.exports = + u('Reflect', 'ownKeys') || + function ownKeys(s) { + var o = w.f(C(s)), + i = x.f; + return i ? j(o, i(s)) : o; + }; + }, + 92046: (s) => { + 'use strict'; + s.exports = {}; + }, + 54829: (s, o, i) => { + 'use strict'; + var u = i(74284).f; + s.exports = function (s, o, i) { + i in s || + u(s, i, { + configurable: !0, + get: function () { + return o[i]; + }, + set: function (s) { + o[i] = s; + } + }); + }; + }, + 74239: (s, o, i) => { + 'use strict'; + var u = i(87136), + _ = TypeError; + s.exports = function (s) { + if (u(s)) throw new _("Can't call method on " + s); + return s; + }; + }, + 14840: (s, o, i) => { + 'use strict'; + var u = i(52623), + _ = i(74284).f, + w = i(61626), + x = i(49724), + C = i(54878), + j = i(76264)('toStringTag'); + s.exports = function (s, o, i, L) { + var B = i ? s : s && s.prototype; + B && + (x(B, j) || _(B, j, { configurable: !0, value: o }), L && !u && w(B, 'toString', C)); + }; + }, + 92522: (s, o, i) => { + 'use strict'; + var u = i(85816), + _ = i(6499), + w = u('keys'); + s.exports = function (s) { + return w[s] || (w[s] = _(s)); + }; + }, + 36128: (s, o, i) => { + 'use strict'; + var u = i(7376), + _ = i(45951), + w = i(2532), + x = '__core-js_shared__', + C = (s.exports = _[x] || w(x, {})); + (C.versions || (C.versions = [])).push({ + version: '3.39.0', + mode: u ? 'pure' : 'global', + copyright: '© 2014-2024 Denis Pushkarev (zloirock.ru)', + license: 'https://github.com/zloirock/core-js/blob/v3.39.0/LICENSE', + source: 'https://github.com/zloirock/core-js' + }); + }, + 85816: (s, o, i) => { + 'use strict'; + var u = i(36128); + s.exports = function (s, o) { + return u[s] || (u[s] = o || {}); + }; + }, + 11470: (s, o, i) => { + 'use strict'; + var u = i(1907), + _ = i(65482), + w = i(90160), + x = i(74239), + C = u(''.charAt), + j = u(''.charCodeAt), + L = u(''.slice), + createMethod = function (s) { + return function (o, i) { + var u, + B, + $ = w(x(o)), + V = _(i), + U = $.length; + return V < 0 || V >= U + ? s + ? '' + : void 0 + : (u = j($, V)) < 55296 || + u > 56319 || + V + 1 === U || + (B = j($, V + 1)) < 56320 || + B > 57343 + ? s + ? C($, V) + : u + : s + ? L($, V, V + 2) + : B - 56320 + ((u - 55296) << 10) + 65536; + }; + }; + s.exports = { codeAt: createMethod(!1), charAt: createMethod(!0) }; + }, + 19846: (s, o, i) => { + 'use strict'; + var u = i(20798), + _ = i(98828), + w = i(45951).String; + s.exports = + !!Object.getOwnPropertySymbols && + !_(function () { + var s = Symbol('symbol detection'); + return !w(s) || !(Object(s) instanceof Symbol) || (!Symbol.sham && u && u < 41); + }); + }, + 34849: (s, o, i) => { + 'use strict'; + var u = i(65482), + _ = Math.max, + w = Math.min; + s.exports = function (s, o) { + var i = u(s); + return i < 0 ? _(i + o, 0) : w(i, o); + }; + }, + 4993: (s, o, i) => { + 'use strict'; + var u = i(16946), + _ = i(74239); + s.exports = function (s) { + return u(_(s)); + }; + }, + 65482: (s, o, i) => { + 'use strict'; + var u = i(41176); + s.exports = function (s) { + var o = +s; + return o != o || 0 === o ? 0 : u(o); + }; + }, + 3121: (s, o, i) => { + 'use strict'; + var u = i(65482), + _ = Math.min; + s.exports = function (s) { + var o = u(s); + return o > 0 ? _(o, 9007199254740991) : 0; + }; + }, + 39298: (s, o, i) => { + 'use strict'; + var u = i(74239), + _ = Object; + s.exports = function (s) { + return _(u(s)); + }; + }, + 46028: (s, o, i) => { + 'use strict'; + var u = i(13930), + _ = i(46285), + w = i(25594), + x = i(29367), + C = i(60581), + j = i(76264), + L = TypeError, + B = j('toPrimitive'); + s.exports = function (s, o) { + if (!_(s) || w(s)) return s; + var i, + j = x(s, B); + if (j) { + if ((void 0 === o && (o = 'default'), (i = u(j, s, o)), !_(i) || w(i))) return i; + throw new L("Can't convert object to primitive value"); + } + return void 0 === o && (o = 'number'), C(s, o); + }; + }, + 70470: (s, o, i) => { + 'use strict'; + var u = i(46028), + _ = i(25594); + s.exports = function (s) { + var o = u(s, 'string'); + return _(o) ? o : o + ''; + }; + }, + 52623: (s, o, i) => { + 'use strict'; + var u = {}; + (u[i(76264)('toStringTag')] = 'z'), (s.exports = '[object z]' === String(u)); + }, + 90160: (s, o, i) => { + 'use strict'; + var u = i(73948), + _ = String; + s.exports = function (s) { + if ('Symbol' === u(s)) throw new TypeError('Cannot convert a Symbol value to a string'); + return _(s); + }; + }, + 4640: (s) => { + 'use strict'; + var o = String; + s.exports = function (s) { + try { + return o(s); + } catch (s) { + return 'Object'; + } + }; + }, + 6499: (s, o, i) => { + 'use strict'; + var u = i(1907), + _ = 0, + w = Math.random(), + x = u((1).toString); + s.exports = function (s) { + return 'Symbol(' + (void 0 === s ? '' : s) + ')_' + x(++_ + w, 36); + }; + }, + 51175: (s, o, i) => { + 'use strict'; + var u = i(19846); + s.exports = u && !Symbol.sham && 'symbol' == typeof Symbol.iterator; + }, + 58661: (s, o, i) => { + 'use strict'; + var u = i(39447), + _ = i(98828); + s.exports = + u && + _(function () { + return ( + 42 !== + Object.defineProperty(function () {}, 'prototype', { value: 42, writable: !1 }) + .prototype + ); + }); + }, + 40551: (s, o, i) => { + 'use strict'; + var u = i(45951), + _ = i(62250), + w = u.WeakMap; + s.exports = _(w) && /native code/.test(String(w)); + }, + 76264: (s, o, i) => { + 'use strict'; + var u = i(45951), + _ = i(85816), + w = i(49724), + x = i(6499), + C = i(19846), + j = i(51175), + L = u.Symbol, + B = _('wks'), + $ = j ? L.for || L : (L && L.withoutSetter) || x; + s.exports = function (s) { + return w(B, s) || (B[s] = C && w(L, s) ? L[s] : $('Symbol.' + s)), B[s]; + }; + }, + 19358: (s, o, i) => { + 'use strict'; + var u = i(85582), + _ = i(49724), + w = i(61626), + x = i(88280), + C = i(79192), + j = i(19595), + L = i(54829), + B = i(34084), + $ = i(32096), + V = i(39259), + U = i(85884), + z = i(39447), + Y = i(7376); + s.exports = function (s, o, i, Z) { + var ee = 'stackTraceLimit', + ie = Z ? 2 : 1, + ae = s.split('.'), + le = ae[ae.length - 1], + ce = u.apply(null, ae); + if (ce) { + var pe = ce.prototype; + if ((!Y && _(pe, 'cause') && delete pe.cause, !i)) return ce; + var de = u('Error'), + fe = o(function (s, o) { + var i = $(Z ? o : s, void 0), + u = Z ? new ce(s) : new ce(); + return ( + void 0 !== i && w(u, 'message', i), + U(u, fe, u.stack, 2), + this && x(pe, this) && B(u, this, fe), + arguments.length > ie && V(u, arguments[ie]), + u + ); + }); + if ( + ((fe.prototype = pe), + 'Error' !== le + ? C + ? C(fe, de) + : j(fe, de, { name: !0 }) + : z && ee in ce && (L(fe, ce, ee), L(fe, ce, 'prepareStackTrace')), + j(fe, ce), + !Y) + ) + try { + pe.name !== le && w(pe, 'name', le), (pe.constructor = fe); + } catch (s) {} + return fe; + } + }; + }, + 36371: (s, o, i) => { + 'use strict'; + var u = i(11091), + _ = i(85582), + w = i(76024), + x = i(98828), + C = i(19358), + j = 'AggregateError', + L = _(j), + B = + !x(function () { + return 1 !== L([1]).errors[0]; + }) && + x(function () { + return 7 !== L([1], j, { cause: 7 }).cause; + }); + u( + { global: !0, constructor: !0, arity: 2, forced: B }, + { + AggregateError: C( + j, + function (s) { + return function AggregateError(o, i) { + return w(s, this, arguments); + }; + }, + B, + !0 + ) + } + ); + }, + 82048: (s, o, i) => { + 'use strict'; + var u = i(11091), + _ = i(88280), + w = i(15972), + x = i(79192), + C = i(19595), + j = i(58075), + L = i(61626), + B = i(75817), + $ = i(39259), + V = i(85884), + U = i(24823), + z = i(32096), + Y = i(76264)('toStringTag'), + Z = Error, + ee = [].push, + ie = function AggregateError(s, o) { + var i, + u = _(ae, this); + x ? (i = x(new Z(), u ? w(this) : ae)) : ((i = u ? this : j(ae)), L(i, Y, 'Error')), + void 0 !== o && L(i, 'message', z(o)), + V(i, ie, i.stack, 1), + arguments.length > 2 && $(i, arguments[2]); + var C = []; + return U(s, ee, { that: C }), L(i, 'errors', C), i; + }; + x ? x(ie, Z) : C(ie, Z, { name: !0 }); + var ae = (ie.prototype = j(Z.prototype, { + constructor: B(1, ie), + message: B(1, ''), + name: B(1, 'AggregateError') + })); + u({ global: !0, constructor: !0, arity: 2 }, { AggregateError: ie }); + }, + 64502: (s, o, i) => { + 'use strict'; + i(82048); + }, + 99363: (s, o, i) => { + 'use strict'; + var u = i(4993), + _ = i(42156), + w = i(93742), + x = i(64932), + C = i(74284).f, + j = i(60183), + L = i(59550), + B = i(7376), + $ = i(39447), + V = 'Array Iterator', + U = x.set, + z = x.getterFor(V); + s.exports = j( + Array, + 'Array', + function (s, o) { + U(this, { type: V, target: u(s), index: 0, kind: o }); + }, + function () { + var s = z(this), + o = s.target, + i = s.index++; + if (!o || i >= o.length) return (s.target = null), L(void 0, !0); + switch (s.kind) { + case 'keys': + return L(i, !1); + case 'values': + return L(o[i], !1); + } + return L([i, o[i]], !1); + }, + 'values' + ); + var Y = (w.Arguments = w.Array); + if ((_('keys'), _('values'), _('entries'), !B && $ && 'values' !== Y.name)) + try { + C(Y, 'name', { value: 'values' }); + } catch (s) {} + }, + 96605: (s, o, i) => { + 'use strict'; + var u = i(11091), + _ = i(45951), + w = i(76024), + x = i(19358), + C = 'WebAssembly', + j = _[C], + L = 7 !== new Error('e', { cause: 7 }).cause, + exportGlobalErrorCauseWrapper = function (s, o) { + var i = {}; + (i[s] = x(s, o, L)), u({ global: !0, constructor: !0, arity: 1, forced: L }, i); + }, + exportWebAssemblyErrorCauseWrapper = function (s, o) { + if (j && j[s]) { + var i = {}; + (i[s] = x(C + '.' + s, o, L)), + u({ target: C, stat: !0, constructor: !0, arity: 1, forced: L }, i); + } + }; + exportGlobalErrorCauseWrapper('Error', function (s) { + return function Error(o) { + return w(s, this, arguments); + }; + }), + exportGlobalErrorCauseWrapper('EvalError', function (s) { + return function EvalError(o) { + return w(s, this, arguments); + }; + }), + exportGlobalErrorCauseWrapper('RangeError', function (s) { + return function RangeError(o) { + return w(s, this, arguments); + }; + }), + exportGlobalErrorCauseWrapper('ReferenceError', function (s) { + return function ReferenceError(o) { + return w(s, this, arguments); + }; + }), + exportGlobalErrorCauseWrapper('SyntaxError', function (s) { + return function SyntaxError(o) { + return w(s, this, arguments); + }; + }), + exportGlobalErrorCauseWrapper('TypeError', function (s) { + return function TypeError(o) { + return w(s, this, arguments); + }; + }), + exportGlobalErrorCauseWrapper('URIError', function (s) { + return function URIError(o) { + return w(s, this, arguments); + }; + }), + exportWebAssemblyErrorCauseWrapper('CompileError', function (s) { + return function CompileError(o) { + return w(s, this, arguments); + }; + }), + exportWebAssemblyErrorCauseWrapper('LinkError', function (s) { + return function LinkError(o) { + return w(s, this, arguments); + }; + }), + exportWebAssemblyErrorCauseWrapper('RuntimeError', function (s) { + return function RuntimeError(o) { + return w(s, this, arguments); + }; + }); + }, + 79307: (s, o, i) => { + 'use strict'; + var u = i(11091), + _ = i(44673); + u({ target: 'Function', proto: !0, forced: Function.bind !== _ }, { bind: _ }); + }, + 71340: (s, o, i) => { + 'use strict'; + var u = i(11091), + _ = i(29538); + u({ target: 'Object', stat: !0, arity: 2, forced: Object.assign !== _ }, { assign: _ }); + }, + 7057: (s, o, i) => { + 'use strict'; + var u = i(11470).charAt, + _ = i(90160), + w = i(64932), + x = i(60183), + C = i(59550), + j = 'String Iterator', + L = w.set, + B = w.getterFor(j); + x( + String, + 'String', + function (s) { + L(this, { type: j, string: _(s), index: 0 }); + }, + function next() { + var s, + o = B(this), + i = o.string, + _ = o.index; + return _ >= i.length + ? C(void 0, !0) + : ((s = u(i, _)), (o.index += s.length), C(s, !1)); + } + ); + }, + 91599: (s, o, i) => { + 'use strict'; + i(64502); + }, + 12560: (s, o, i) => { + 'use strict'; + i(99363); + var u = i(19287), + _ = i(45951), + w = i(14840), + x = i(93742); + for (var C in u) w(_[C], C), (x[C] = x.Array); + }, + 694: (s, o, i) => { + 'use strict'; + i(91599); + var u = i(37257); + i(12560), (s.exports = u); + }, + 19709: (s, o, i) => { + 'use strict'; + var u = i(23034); + s.exports = u; + }, + 40975: (s, o, i) => { + 'use strict'; + var u = i(9748); + s.exports = u; + } + }, + u = {}; + function __webpack_require__(s) { + var o = u[s]; + if (void 0 !== o) return o.exports; + var _ = (u[s] = { id: s, loaded: !1, exports: {} }); + return i[s].call(_.exports, _, _.exports, __webpack_require__), (_.loaded = !0), _.exports; + } + (__webpack_require__.n = (s) => { + var o = s && s.__esModule ? () => s.default : () => s; + return __webpack_require__.d(o, { a: o }), o; + }), + (o = Object.getPrototypeOf ? (s) => Object.getPrototypeOf(s) : (s) => s.__proto__), + (__webpack_require__.t = function (i, u) { + if ((1 & u && (i = this(i)), 8 & u)) return i; + if ('object' == typeof i && i) { + if (4 & u && i.__esModule) return i; + if (16 & u && 'function' == typeof i.then) return i; + } + var _ = Object.create(null); + __webpack_require__.r(_); + var w = {}; + s = s || [null, o({}), o([]), o(o)]; + for (var x = 2 & u && i; 'object' == typeof x && !~s.indexOf(x); x = o(x)) + Object.getOwnPropertyNames(x).forEach((s) => (w[s] = () => i[s])); + return (w.default = () => i), __webpack_require__.d(_, w), _; + }), + (__webpack_require__.d = (s, o) => { + for (var i in o) + __webpack_require__.o(o, i) && + !__webpack_require__.o(s, i) && + Object.defineProperty(s, i, { enumerable: !0, get: o[i] }); + }), + (__webpack_require__.g = (function () { + if ('object' == typeof globalThis) return globalThis; + try { + return this || new Function('return this')(); + } catch (s) { + if ('object' == typeof window) return window; + } + })()), + (__webpack_require__.o = (s, o) => Object.prototype.hasOwnProperty.call(s, o)), + (__webpack_require__.r = (s) => { + 'undefined' != typeof Symbol && + Symbol.toStringTag && + Object.defineProperty(s, Symbol.toStringTag, { value: 'Module' }), + Object.defineProperty(s, '__esModule', { value: !0 }); + }), + (__webpack_require__.nmd = (s) => ((s.paths = []), s.children || (s.children = []), s)); + var _ = {}; + return ( + (() => { + 'use strict'; + __webpack_require__.d(_, { default: () => WI }); + var s = {}; + __webpack_require__.r(s), + __webpack_require__.d(s, { + CLEAR: () => ot, + CLEAR_BY: () => it, + NEW_AUTH_ERR: () => st, + NEW_SPEC_ERR: () => rt, + NEW_SPEC_ERR_BATCH: () => nt, + NEW_THROWN_ERR: () => et, + NEW_THROWN_ERR_BATCH: () => tt, + clear: () => clear, + clearBy: () => clearBy, + newAuthErr: () => newAuthErr, + newSpecErr: () => newSpecErr, + newSpecErrBatch: () => newSpecErrBatch, + newThrownErr: () => newThrownErr, + newThrownErrBatch: () => newThrownErrBatch + }); + var o = {}; + __webpack_require__.r(o), + __webpack_require__.d(o, { + AUTHORIZE: () => Nt, + AUTHORIZE_OAUTH2: () => Lt, + CONFIGURE_AUTH: () => Ft, + LOGOUT: () => Rt, + PRE_AUTHORIZE_OAUTH2: () => Dt, + RESTORE_AUTHORIZATION: () => qt, + SHOW_AUTH_POPUP: () => Tt, + VALIDATE: () => Bt, + authPopup: () => authPopup, + authorize: () => authorize, + authorizeAccessCodeWithBasicAuthentication: () => + authorizeAccessCodeWithBasicAuthentication, + authorizeAccessCodeWithFormParams: () => authorizeAccessCodeWithFormParams, + authorizeApplication: () => authorizeApplication, + authorizeOauth2: () => authorizeOauth2, + authorizeOauth2WithPersistOption: () => authorizeOauth2WithPersistOption, + authorizePassword: () => authorizePassword, + authorizeRequest: () => authorizeRequest, + authorizeWithPersistOption: () => authorizeWithPersistOption, + configureAuth: () => configureAuth, + logout: () => logout, + logoutWithPersistOption: () => logoutWithPersistOption, + persistAuthorizationIfNeeded: () => persistAuthorizationIfNeeded, + preAuthorizeImplicit: () => preAuthorizeImplicit, + restoreAuthorization: () => restoreAuthorization, + showDefinitions: () => showDefinitions + }); + var i = {}; + __webpack_require__.r(i), + __webpack_require__.d(i, { + authorized: () => Ht, + definitionsForRequirements: () => definitionsForRequirements, + definitionsToAuthorize: () => Kt, + getConfigs: () => Jt, + getDefinitionsByNames: () => getDefinitionsByNames, + isAuthorized: () => isAuthorized, + shownDefinitions: () => Wt + }); + var u = {}; + __webpack_require__.r(u), + __webpack_require__.d(u, { + TOGGLE_CONFIGS: () => yn, + UPDATE_CONFIGS: () => gn, + downloadConfig: () => downloadConfig, + getConfigByUrl: () => getConfigByUrl, + loaded: () => actions_loaded, + toggle: () => toggle, + update: () => update + }); + var w = {}; + __webpack_require__.r(w), __webpack_require__.d(w, { get: () => get }); + var x = {}; + __webpack_require__.r(x), __webpack_require__.d(x, { transform: () => transform }); + var C = {}; + __webpack_require__.r(C), + __webpack_require__.d(C, { transform: () => parameter_oneof_transform }); + var j = {}; + __webpack_require__.r(j), + __webpack_require__.d(j, { allErrors: () => Mn, lastError: () => Tn }); + var L = {}; + __webpack_require__.r(L), + __webpack_require__.d(L, { + SHOW: () => Fn, + UPDATE_FILTER: () => Ln, + UPDATE_LAYOUT: () => Dn, + UPDATE_MODE: () => Bn, + changeMode: () => changeMode, + show: () => actions_show, + updateFilter: () => updateFilter, + updateLayout: () => updateLayout + }); + var B = {}; + __webpack_require__.r(B), + __webpack_require__.d(B, { + current: () => current, + currentFilter: () => currentFilter, + isShown: () => isShown, + showSummary: () => $n, + whatMode: () => whatMode + }); + var $ = {}; + __webpack_require__.r($), + __webpack_require__.d($, { taggedOperations: () => taggedOperations }); + var V = {}; + __webpack_require__.r(V), + __webpack_require__.d(V, { + requestSnippetGenerator_curl_bash: () => requestSnippetGenerator_curl_bash, + requestSnippetGenerator_curl_cmd: () => requestSnippetGenerator_curl_cmd, + requestSnippetGenerator_curl_powershell: () => requestSnippetGenerator_curl_powershell + }); + var U = {}; + __webpack_require__.r(U), + __webpack_require__.d(U, { + getActiveLanguage: () => zn, + getDefaultExpanded: () => Wn, + getGenerators: () => Un, + getSnippetGenerators: () => getSnippetGenerators + }); + var z = {}; + __webpack_require__.r(z), + __webpack_require__.d(z, { + JsonSchemaArrayItemFile: () => JsonSchemaArrayItemFile, + JsonSchemaArrayItemText: () => JsonSchemaArrayItemText, + JsonSchemaForm: () => JsonSchemaForm, + JsonSchema_array: () => JsonSchema_array, + JsonSchema_boolean: () => JsonSchema_boolean, + JsonSchema_object: () => JsonSchema_object, + JsonSchema_string: () => JsonSchema_string + }); + var Y = {}; + __webpack_require__.r(Y), + __webpack_require__.d(Y, { + allowTryItOutFor: () => allowTryItOutFor, + basePath: () => Ks, + canExecuteScheme: () => canExecuteScheme, + consumes: () => $s, + consumesOptionsFor: () => consumesOptionsFor, + contentTypeValues: () => contentTypeValues, + currentProducesFor: () => currentProducesFor, + definitions: () => Ws, + externalDocs: () => Rs, + findDefinition: () => findDefinition, + getOAS3RequiredRequestBodyContentType: () => getOAS3RequiredRequestBodyContentType, + getParameter: () => getParameter, + hasHost: () => to, + host: () => Hs, + info: () => Ns, + isMediaTypeSchemaPropertiesEqual: () => isMediaTypeSchemaPropertiesEqual, + isOAS3: () => Ts, + lastError: () => ks, + mutatedRequestFor: () => mutatedRequestFor, + mutatedRequests: () => eo, + operationScheme: () => operationScheme, + operationWithMeta: () => operationWithMeta, + operations: () => qs, + operationsWithRootInherited: () => Gs, + operationsWithTags: () => Xs, + parameterInclusionSettingFor: () => parameterInclusionSettingFor, + parameterValues: () => parameterValues, + parameterWithMeta: () => parameterWithMeta, + parameterWithMetaByIdentity: () => parameterWithMetaByIdentity, + parametersIncludeIn: () => parametersIncludeIn, + parametersIncludeType: () => parametersIncludeType, + paths: () => Bs, + produces: () => Vs, + producesOptionsFor: () => producesOptionsFor, + requestFor: () => requestFor, + requests: () => Qs, + responseFor: () => responseFor, + responses: () => Zs, + schemes: () => Js, + security: () => Us, + securityDefinitions: () => zs, + semver: () => Ls, + spec: () => spec, + specJS: () => Is, + specJson: () => js, + specJsonWithResolvedSubtrees: () => Ms, + specResolved: () => Ps, + specResolvedSubtree: () => specResolvedSubtree, + specSource: () => As, + specStr: () => Os, + tagDetails: () => tagDetails, + taggedOperations: () => selectors_taggedOperations, + tags: () => Ys, + url: () => Cs, + validOperationMethods: () => Fs, + validateBeforeExecute: () => validateBeforeExecute, + validationErrors: () => validationErrors, + version: () => Ds + }); + var Z = {}; + __webpack_require__.r(Z), + __webpack_require__.d(Z, { + CLEAR_REQUEST: () => wo, + CLEAR_RESPONSE: () => Eo, + CLEAR_VALIDATE_PARAMS: () => So, + LOG_REQUEST: () => _o, + SET_MUTATED_REQUEST: () => bo, + SET_REQUEST: () => vo, + SET_RESPONSE: () => yo, + SET_SCHEME: () => Oo, + UPDATE_EMPTY_PARAM_INCLUSION: () => mo, + UPDATE_JSON: () => ho, + UPDATE_OPERATION_META_VALUE: () => xo, + UPDATE_PARAM: () => fo, + UPDATE_RESOLVED: () => ko, + UPDATE_RESOLVED_SUBTREE: () => Co, + UPDATE_SPEC: () => uo, + UPDATE_URL: () => po, + VALIDATE_PARAMS: () => go, + changeConsumesValue: () => changeConsumesValue, + changeParam: () => changeParam, + changeParamByIdentity: () => changeParamByIdentity, + changeProducesValue: () => changeProducesValue, + clearRequest: () => clearRequest, + clearResponse: () => clearResponse, + clearValidateParams: () => clearValidateParams, + execute: () => actions_execute, + executeRequest: () => executeRequest, + invalidateResolvedSubtreeCache: () => invalidateResolvedSubtreeCache, + logRequest: () => logRequest, + parseToJson: () => parseToJson, + requestResolvedSubtree: () => requestResolvedSubtree, + resolveSpec: () => resolveSpec, + setMutatedRequest: () => setMutatedRequest, + setRequest: () => setRequest, + setResponse: () => setResponse, + setScheme: () => setScheme, + updateEmptyParamInclusion: () => updateEmptyParamInclusion, + updateJsonSpec: () => updateJsonSpec, + updateResolved: () => updateResolved, + updateResolvedSubtree: () => updateResolvedSubtree, + updateSpec: () => updateSpec, + updateUrl: () => updateUrl, + validateParams: () => validateParams + }); + var ee = {}; + __webpack_require__.r(ee), + __webpack_require__.d(ee, { + executeRequest: () => wrap_actions_executeRequest, + updateJsonSpec: () => wrap_actions_updateJsonSpec, + updateSpec: () => wrap_actions_updateSpec, + validateParams: () => wrap_actions_validateParams + }); + var ie = {}; + __webpack_require__.r(ie), + __webpack_require__.d(ie, { + JsonPatchError: () => Ro, + _areEquals: () => _areEquals, + applyOperation: () => applyOperation, + applyPatch: () => applyPatch, + applyReducer: () => applyReducer, + deepClone: () => Do, + getValueByPointer: () => getValueByPointer, + validate: () => validate, + validator: () => validator + }); + var ae = {}; + __webpack_require__.r(ae), + __webpack_require__.d(ae, { + compare: () => compare, + generate: () => generate, + observe: () => observe, + unobserve: () => unobserve + }); + var le = {}; + __webpack_require__.r(le), + __webpack_require__.d(le, { + hasElementSourceMap: () => hasElementSourceMap, + includesClasses: () => includesClasses, + includesSymbols: () => includesSymbols, + isAnnotationElement: () => zu, + isArrayElement: () => qu, + isBooleanElement: () => Bu, + isCommentElement: () => Wu, + isElement: () => Nu, + isLinkElement: () => Vu, + isMemberElement: () => $u, + isNullElement: () => Lu, + isNumberElement: () => Du, + isObjectElement: () => Fu, + isParseResultElement: () => Ku, + isPrimitiveElement: () => isPrimitiveElement, + isRefElement: () => Uu, + isSourceMapElement: () => Hu, + isStringElement: () => Ru + }); + var ce = {}; + __webpack_require__.r(ce), + __webpack_require__.d(ce, { + isJSONReferenceElement: () => Nf, + isJSONSchemaElement: () => Tf, + isLinkDescriptionElement: () => Df, + isMediaElement: () => Rf + }); + var pe = {}; + __webpack_require__.r(pe), + __webpack_require__.d(pe, { + isBooleanJsonSchemaElement: () => isBooleanJsonSchemaElement, + isCallbackElement: () => Im, + isComponentsElement: () => Pm, + isContactElement: () => Mm, + isExampleElement: () => Tm, + isExternalDocumentationElement: () => Nm, + isHeaderElement: () => Rm, + isInfoElement: () => Dm, + isLicenseElement: () => Lm, + isLinkElement: () => Bm, + isMediaTypeElement: () => eg, + isOpenApi3_0Element: () => qm, + isOpenapiElement: () => Fm, + isOperationElement: () => $m, + isParameterElement: () => Vm, + isPathItemElement: () => Um, + isPathsElement: () => zm, + isReferenceElement: () => Wm, + isRequestBodyElement: () => Km, + isResponseElement: () => Hm, + isResponsesElement: () => Jm, + isSchemaElement: () => Gm, + isSecurityRequirementElement: () => Ym, + isSecuritySchemeElement: () => Xm, + isServerElement: () => Zm, + isServerVariableElement: () => Qm, + isServersElement: () => rg + }); + var de = {}; + __webpack_require__.r(de), + __webpack_require__.d(de, { + isBooleanJsonSchemaElement: () => predicates_isBooleanJsonSchemaElement, + isCallbackElement: () => T_, + isComponentsElement: () => N_, + isContactElement: () => R_, + isExampleElement: () => D_, + isExternalDocumentationElement: () => L_, + isHeaderElement: () => B_, + isInfoElement: () => F_, + isJsonSchemaDialectElement: () => q_, + isLicenseElement: () => $_, + isLinkElement: () => V_, + isMediaTypeElement: () => sE, + isOpenApi3_1Element: () => z_, + isOpenapiElement: () => U_, + isOperationElement: () => W_, + isParameterElement: () => K_, + isPathItemElement: () => H_, + isPathItemElementExternal: () => isPathItemElementExternal, + isPathsElement: () => J_, + isReferenceElement: () => G_, + isReferenceElementExternal: () => isReferenceElementExternal, + isRequestBodyElement: () => Y_, + isResponseElement: () => X_, + isResponsesElement: () => Z_, + isSchemaElement: () => Q_, + isSecurityRequirementElement: () => eE, + isSecuritySchemeElement: () => tE, + isServerElement: () => rE, + isServerVariableElement: () => nE + }); + var fe = {}; + __webpack_require__.r(fe), + __webpack_require__.d(fe, { + cookie: () => parameter_builders_cookie, + header: () => parameter_builders_header, + path: () => parameter_builders_path, + query: () => parameter_builders_query + }); + var ye = {}; + __webpack_require__.r(ye), + __webpack_require__.d(ye, { + Button: () => Button, + Col: () => Col, + Collapse: () => Collapse, + Container: () => Container, + Input: () => Input, + Link: () => layout_utils_Link, + Row: () => Row, + Select: () => Select, + TextArea: () => TextArea + }); + var be = {}; + __webpack_require__.r(be), + __webpack_require__.d(be, { + basePath: () => KO, + consumes: () => HO, + definitions: () => VO, + findDefinition: () => $O, + hasHost: () => UO, + host: () => WO, + produces: () => JO, + schemes: () => GO, + securityDefinitions: () => zO, + validOperationMethods: () => wrap_selectors_validOperationMethods + }); + var _e = {}; + __webpack_require__.r(_e), __webpack_require__.d(_e, { definitionsToAuthorize: () => YO }); + var we = {}; + __webpack_require__.r(we), + __webpack_require__.d(we, { + callbacksOperations: () => QO, + findSchema: () => findSchema, + isOAS3: () => selectors_isOAS3, + isOAS30: () => selectors_isOAS30, + isSwagger2: () => selectors_isSwagger2, + servers: () => ZO + }); + var Se = {}; + __webpack_require__.r(Se), + __webpack_require__.d(Se, { + CLEAR_REQUEST_BODY_VALIDATE_ERROR: () => bA, + CLEAR_REQUEST_BODY_VALUE: () => _A, + SET_REQUEST_BODY_VALIDATE_ERROR: () => vA, + UPDATE_ACTIVE_EXAMPLES_MEMBER: () => fA, + UPDATE_REQUEST_BODY_INCLUSION: () => dA, + UPDATE_REQUEST_BODY_VALUE: () => pA, + UPDATE_REQUEST_BODY_VALUE_RETAIN_FLAG: () => hA, + UPDATE_REQUEST_CONTENT_TYPE: () => mA, + UPDATE_RESPONSE_CONTENT_TYPE: () => gA, + UPDATE_SELECTED_SERVER: () => uA, + UPDATE_SERVER_VARIABLE_VALUE: () => yA, + clearRequestBodyValidateError: () => clearRequestBodyValidateError, + clearRequestBodyValue: () => clearRequestBodyValue, + initRequestBodyValidateError: () => initRequestBodyValidateError, + setActiveExamplesMember: () => setActiveExamplesMember, + setRequestBodyInclusion: () => setRequestBodyInclusion, + setRequestBodyValidateError: () => setRequestBodyValidateError, + setRequestBodyValue: () => setRequestBodyValue, + setRequestContentType: () => setRequestContentType, + setResponseContentType: () => setResponseContentType, + setRetainRequestBodyValueFlag: () => setRetainRequestBodyValueFlag, + setSelectedServer: () => setSelectedServer, + setServerVariableValue: () => setServerVariableValue + }); + var xe = {}; + __webpack_require__.r(xe), + __webpack_require__.d(xe, { + activeExamplesMember: () => jA, + hasUserEditedBody: () => CA, + requestBodyErrors: () => AA, + requestBodyInclusionSetting: () => OA, + requestBodyValue: () => xA, + requestContentType: () => IA, + responseContentType: () => PA, + selectDefaultRequestBodyValue: () => selectDefaultRequestBodyValue, + selectedServer: () => SA, + serverEffectiveValue: () => NA, + serverVariableValue: () => MA, + serverVariables: () => TA, + shouldRetainRequestBodyValue: () => kA, + validOperationMethods: () => DA, + validateBeforeExecute: () => RA, + validateShallowRequired: () => validateShallowRequired + }); + var Pe = __webpack_require__(96540); + function formatProdErrorMessage(s) { + return `Minified Redux error #${s}; visit https://redux.js.org/Errors?code=${s} for the full message or use the non-minified dev environment for full errors. `; + } + var Te = (() => ('function' == typeof Symbol && Symbol.observable) || '@@observable')(), + randomString = () => Math.random().toString(36).substring(7).split('').join('.'), + Re = { + INIT: `@@redux/INIT${randomString()}`, + REPLACE: `@@redux/REPLACE${randomString()}`, + PROBE_UNKNOWN_ACTION: () => `@@redux/PROBE_UNKNOWN_ACTION${randomString()}` + }; + function isPlainObject(s) { + if ('object' != typeof s || null === s) return !1; + let o = s; + for (; null !== Object.getPrototypeOf(o); ) o = Object.getPrototypeOf(o); + return Object.getPrototypeOf(s) === o || null === Object.getPrototypeOf(s); + } + function createStore(s, o, i) { + if ('function' != typeof s) throw new Error(formatProdErrorMessage(2)); + if ( + ('function' == typeof o && 'function' == typeof i) || + ('function' == typeof i && 'function' == typeof arguments[3]) + ) + throw new Error(formatProdErrorMessage(0)); + if (('function' == typeof o && void 0 === i && ((i = o), (o = void 0)), void 0 !== i)) { + if ('function' != typeof i) throw new Error(formatProdErrorMessage(1)); + return i(createStore)(s, o); + } + let u = s, + _ = o, + w = new Map(), + x = w, + C = 0, + j = !1; + function ensureCanMutateNextListeners() { + x === w && + ((x = new Map()), + w.forEach((s, o) => { + x.set(o, s); + })); + } + function getState() { + if (j) throw new Error(formatProdErrorMessage(3)); + return _; + } + function subscribe(s) { + if ('function' != typeof s) throw new Error(formatProdErrorMessage(4)); + if (j) throw new Error(formatProdErrorMessage(5)); + let o = !0; + ensureCanMutateNextListeners(); + const i = C++; + return ( + x.set(i, s), + function unsubscribe() { + if (o) { + if (j) throw new Error(formatProdErrorMessage(6)); + (o = !1), ensureCanMutateNextListeners(), x.delete(i), (w = null); + } + } + ); + } + function dispatch(s) { + if (!isPlainObject(s)) throw new Error(formatProdErrorMessage(7)); + if (void 0 === s.type) throw new Error(formatProdErrorMessage(8)); + if ('string' != typeof s.type) throw new Error(formatProdErrorMessage(17)); + if (j) throw new Error(formatProdErrorMessage(9)); + try { + (j = !0), (_ = u(_, s)); + } finally { + j = !1; + } + return ( + (w = x).forEach((s) => { + s(); + }), + s + ); + } + dispatch({ type: Re.INIT }); + return { + dispatch, + subscribe, + getState, + replaceReducer: function replaceReducer(s) { + if ('function' != typeof s) throw new Error(formatProdErrorMessage(10)); + (u = s), dispatch({ type: Re.REPLACE }); + }, + [Te]: function observable() { + const s = subscribe; + return { + subscribe(o) { + if ('object' != typeof o || null === o) + throw new Error(formatProdErrorMessage(11)); + function observeState() { + const s = o; + s.next && s.next(getState()); + } + observeState(); + return { unsubscribe: s(observeState) }; + }, + [Te]() { + return this; + } + }; + } + }; + } + function bindActionCreator(s, o) { + return function (...i) { + return o(s.apply(this, i)); + }; + } + function compose(...s) { + return 0 === s.length + ? (s) => s + : 1 === s.length + ? s[0] + : s.reduce( + (s, o) => + (...i) => + s(o(...i)) + ); + } + var qe = __webpack_require__(9404), + $e = __webpack_require__.n(qe), + ze = __webpack_require__(81919), + We = __webpack_require__.n(ze), + He = __webpack_require__(89593), + Ye = __webpack_require__(20334), + Xe = __webpack_require__(55364), + Qe = __webpack_require__.n(Xe); + const et = 'err_new_thrown_err', + tt = 'err_new_thrown_err_batch', + rt = 'err_new_spec_err', + nt = 'err_new_spec_err_batch', + st = 'err_new_auth_err', + ot = 'err_clear', + it = 'err_clear_by'; + function newThrownErr(s) { + return { type: et, payload: (0, Ye.serializeError)(s) }; + } + function newThrownErrBatch(s) { + return { type: tt, payload: s }; + } + function newSpecErr(s) { + return { type: rt, payload: s }; + } + function newSpecErrBatch(s) { + return { type: nt, payload: s }; + } + function newAuthErr(s) { + return { type: st, payload: s }; + } + function clear(s = {}) { + return { type: ot, payload: s }; + } + function clearBy(s = () => !0) { + return { type: it, payload: s }; + } + const at = (function makeWindow() { + var s = { + location: {}, + history: {}, + open: () => {}, + close: () => {}, + File: function () {}, + FormData: function () {} + }; + if ('undefined' == typeof window) return s; + try { + s = window; + for (var o of ['File', 'Blob', 'FormData']) o in window && (s[o] = window[o]); + } catch (s) { + console.error(s); + } + return s; + })(); + var lt = __webpack_require__(16750), + ct = (__webpack_require__(84058), __webpack_require__(55808), __webpack_require__(50104)), + ut = __webpack_require__.n(ct), + pt = __webpack_require__(7309), + ht = __webpack_require__.n(pt), + dt = __webpack_require__(42426), + mt = __webpack_require__.n(dt), + gt = __webpack_require__(75288), + yt = __webpack_require__.n(gt), + vt = __webpack_require__(1882), + bt = __webpack_require__.n(vt), + _t = __webpack_require__(2205), + Et = __webpack_require__.n(_t), + wt = __webpack_require__(53209), + St = __webpack_require__.n(wt), + xt = __webpack_require__(62802), + kt = __webpack_require__.n(xt); + const Ct = $e().Set.of( + 'type', + 'format', + 'items', + 'default', + 'maximum', + 'exclusiveMaximum', + 'minimum', + 'exclusiveMinimum', + 'maxLength', + 'minLength', + 'pattern', + 'maxItems', + 'minItems', + 'uniqueItems', + 'enum', + 'multipleOf' + ); + function getParameterSchema(s, { isOAS3: o } = {}) { + if (!$e().Map.isMap(s)) return { schema: $e().Map(), parameterContentMediaType: null }; + if (!o) + return 'body' === s.get('in') + ? { schema: s.get('schema', $e().Map()), parameterContentMediaType: null } + : { schema: s.filter((s, o) => Ct.includes(o)), parameterContentMediaType: null }; + if (s.get('content')) { + const o = s.get('content', $e().Map({})).keySeq().first(); + return { + schema: s.getIn(['content', o, 'schema'], $e().Map()), + parameterContentMediaType: o + }; + } + return { + schema: s.get('schema') ? s.get('schema', $e().Map()) : $e().Map(), + parameterContentMediaType: null + }; + } + var Ot = __webpack_require__(48287).Buffer; + const At = 'default', + isImmutable = (s) => $e().Iterable.isIterable(s); + function objectify(s) { + return isObject(s) ? (isImmutable(s) ? s.toJS() : s) : {}; + } + function fromJSOrdered(s) { + if (isImmutable(s)) return s; + if (s instanceof at.File) return s; + if (!isObject(s)) return s; + if (Array.isArray(s)) return $e().Seq(s).map(fromJSOrdered).toList(); + if (bt()(s.entries)) { + const o = (function createObjWithHashedKeys(s) { + if (!bt()(s.entries)) return s; + const o = {}, + i = '_**[]', + u = {}; + for (let _ of s.entries()) + if (o[_[0]] || (u[_[0]] && u[_[0]].containsMultiple)) { + if (!u[_[0]]) { + (u[_[0]] = { containsMultiple: !0, length: 1 }), + (o[`${_[0]}${i}${u[_[0]].length}`] = o[_[0]]), + delete o[_[0]]; + } + (u[_[0]].length += 1), (o[`${_[0]}${i}${u[_[0]].length}`] = _[1]); + } else o[_[0]] = _[1]; + return o; + })(s); + return $e().OrderedMap(o).map(fromJSOrdered); + } + return $e().OrderedMap(s).map(fromJSOrdered); + } + function normalizeArray(s) { + return Array.isArray(s) ? s : [s]; + } + function isFn(s) { + return 'function' == typeof s; + } + function isObject(s) { + return !!s && 'object' == typeof s; + } + function isFunc(s) { + return 'function' == typeof s; + } + function isArray(s) { + return Array.isArray(s); + } + const jt = ut(); + function objMap(s, o) { + return Object.keys(s).reduce((i, u) => ((i[u] = o(s[u], u)), i), {}); + } + function objReduce(s, o) { + return Object.keys(s).reduce((i, u) => { + let _ = o(s[u], u); + return _ && 'object' == typeof _ && Object.assign(i, _), i; + }, {}); + } + function systemThunkMiddleware(s) { + return ({ dispatch: o, getState: i }) => + (o) => + (i) => + 'function' == typeof i ? i(s()) : o(i); + } + function validateValueBySchema(s, o, i, u, _) { + if (!o) return []; + let w = [], + x = o.get('nullable'), + C = o.get('required'), + j = o.get('maximum'), + L = o.get('minimum'), + B = o.get('type'), + $ = o.get('format'), + V = o.get('maxLength'), + U = o.get('minLength'), + z = o.get('uniqueItems'), + Y = o.get('maxItems'), + Z = o.get('minItems'), + ee = o.get('pattern'); + const ie = i || !0 === C, + ae = null != s, + le = ie || (ae && 'array' === B) || !(!ie && !ae), + ce = x && null === s; + if (ie && !ae && !ce && !u && !B) return w.push('Required field is not provided'), w; + if (ce || !B || !le) return []; + let pe = 'string' === B && s, + de = 'array' === B && Array.isArray(s) && s.length, + fe = 'array' === B && $e().List.isList(s) && s.count(); + const ye = [ + pe, + de, + fe, + 'array' === B && 'string' == typeof s && s, + 'file' === B && s instanceof at.File, + 'boolean' === B && (s || !1 === s), + 'number' === B && (s || 0 === s), + 'integer' === B && (s || 0 === s), + 'object' === B && 'object' == typeof s && null !== s, + 'object' === B && 'string' == typeof s && s + ].some((s) => !!s); + if (ie && !ye && !u) return w.push('Required field is not provided'), w; + if ('object' === B && (null === _ || 'application/json' === _)) { + let i = s; + if ('string' == typeof s) + try { + i = JSON.parse(s); + } catch (s) { + return w.push('Parameter string value must be valid JSON'), w; + } + o && + o.has('required') && + isFunc(C.isList) && + C.isList() && + C.forEach((s) => { + void 0 === i[s] && w.push({ propKey: s, error: 'Required property not found' }); + }), + o && + o.has('properties') && + o.get('properties').forEach((s, o) => { + const x = validateValueBySchema(i[o], s, !1, u, _); + w.push(...x.map((s) => ({ propKey: o, error: s }))); + }); + } + if (ee) { + let o = ((s, o) => { + if (!new RegExp(o).test(s)) return 'Value must follow pattern ' + o; + })(s, ee); + o && w.push(o); + } + if (Z && 'array' === B) { + let o = ((s, o) => { + if ((!s && o >= 1) || (s && s.length < o)) + return `Array must contain at least ${o} item${1 === o ? '' : 's'}`; + })(s, Z); + o && w.push(o); + } + if (Y && 'array' === B) { + let o = ((s, o) => { + if (s && s.length > o) + return `Array must not contain more then ${o} item${1 === o ? '' : 's'}`; + })(s, Y); + o && w.push({ needRemove: !0, error: o }); + } + if (z && 'array' === B) { + let o = ((s, o) => { + if (s && ('true' === o || !0 === o)) { + const o = (0, qe.fromJS)(s), + i = o.toSet(); + if (s.length > i.size) { + let s = (0, qe.Set)(); + if ( + (o.forEach((i, u) => { + o.filter((s) => (isFunc(s.equals) ? s.equals(i) : s === i)).size > 1 && + (s = s.add(u)); + }), + 0 !== s.size) + ) + return s.map((s) => ({ index: s, error: 'No duplicates allowed.' })).toArray(); + } + } + })(s, z); + o && w.push(...o); + } + if (V || 0 === V) { + let o = ((s, o) => { + if (s.length > o) + return `Value must be no longer than ${o} character${1 !== o ? 's' : ''}`; + })(s, V); + o && w.push(o); + } + if (U) { + let o = ((s, o) => { + if (s.length < o) return `Value must be at least ${o} character${1 !== o ? 's' : ''}`; + })(s, U); + o && w.push(o); + } + if (j || 0 === j) { + let o = ((s, o) => { + if (s > o) return `Value must be less than ${o}`; + })(s, j); + o && w.push(o); + } + if (L || 0 === L) { + let o = ((s, o) => { + if (s < o) return `Value must be greater than ${o}`; + })(s, L); + o && w.push(o); + } + if ('string' === B) { + let o; + if ( + ((o = + 'date-time' === $ + ? ((s) => { + if (isNaN(Date.parse(s))) return 'Value must be a DateTime'; + })(s) + : 'uuid' === $ + ? ((s) => { + if ( + ((s = s.toString().toLowerCase()), + !/^[{(]?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}[)}]?$/.test( + s + )) + ) + return 'Value must be a Guid'; + })(s) + : ((s) => { + if (s && 'string' != typeof s) return 'Value must be a string'; + })(s)), + !o) + ) + return w; + w.push(o); + } else if ('boolean' === B) { + let o = ((s) => { + if ('true' !== s && 'false' !== s && !0 !== s && !1 !== s) + return 'Value must be a boolean'; + })(s); + if (!o) return w; + w.push(o); + } else if ('number' === B) { + let o = ((s) => { + if (!/^-?\d+(\.?\d+)?$/.test(s)) return 'Value must be a number'; + })(s); + if (!o) return w; + w.push(o); + } else if ('integer' === B) { + let o = ((s) => { + if (!/^-?\d+$/.test(s)) return 'Value must be an integer'; + })(s); + if (!o) return w; + w.push(o); + } else if ('array' === B) { + if (!de && !fe) return w; + s && + s.forEach((s, i) => { + const x = validateValueBySchema(s, o.get('items'), !1, u, _); + w.push(...x.map((s) => ({ index: i, error: s }))); + }); + } else if ('file' === B) { + let o = ((s) => { + if (s && !(s instanceof at.File)) return 'Value must be a file'; + })(s); + if (!o) return w; + w.push(o); + } + return w; + } + const utils_btoa = (s) => { + let o; + return (o = s instanceof Ot ? s : Ot.from(s.toString(), 'utf-8')), o.toString('base64'); + }, + It = { + operationsSorter: { + alpha: (s, o) => s.get('path').localeCompare(o.get('path')), + method: (s, o) => s.get('method').localeCompare(o.get('method')) + }, + tagsSorter: { alpha: (s, o) => s.localeCompare(o) } + }, + buildFormData = (s) => { + let o = []; + for (let i in s) { + let u = s[i]; + void 0 !== u && + '' !== u && + o.push([i, '=', encodeURIComponent(u).replace(/%20/g, '+')].join('')); + } + return o.join('&'); + }, + shallowEqualKeys = (s, o, i) => !!ht()(i, (i) => yt()(s[i], o[i])); + function sanitizeUrl(s) { + return 'string' != typeof s || '' === s ? '' : (0, lt.J)(s); + } + function requiresValidationURL(s) { + return !( + !s || + s.indexOf('localhost') >= 0 || + s.indexOf('127.0.0.1') >= 0 || + 'none' === s + ); + } + const createDeepLinkPath = (s) => + 'string' == typeof s || s instanceof String ? s.trim().replace(/\s/g, '%20') : '', + escapeDeepLinkPath = (s) => Et()(createDeepLinkPath(s).replace(/%20/g, '_')), + getExtensions = (s) => s.filter((s, o) => /^x-/.test(o)), + getCommonExtensions = (s) => + s.filter((s, o) => /^pattern|maxLength|minLength|maximum|minimum/.test(o)); + function deeplyStripKey(s, o, i = () => !0) { + if ('object' != typeof s || Array.isArray(s) || null === s || !o) return s; + const u = Object.assign({}, s); + return ( + Object.keys(u).forEach((s) => { + s === o && i(u[s], s) ? delete u[s] : (u[s] = deeplyStripKey(u[s], o, i)); + }), + u + ); + } + function stringify(s) { + if ('string' == typeof s) return s; + if ((s && s.toJS && (s = s.toJS()), 'object' == typeof s && null !== s)) + try { + return JSON.stringify(s, null, 2); + } catch (o) { + return String(s); + } + return null == s ? '' : s.toString(); + } + function paramToIdentifier(s, { returnAll: o = !1, allowHashes: i = !0 } = {}) { + if (!$e().Map.isMap(s)) + throw new Error('paramToIdentifier: received a non-Im.Map parameter as input'); + const u = s.get('name'), + _ = s.get('in'); + let w = []; + return ( + s && s.hashCode && _ && u && i && w.push(`${_}.${u}.hash-${s.hashCode()}`), + _ && u && w.push(`${_}.${u}`), + w.push(u), + o ? w : w[0] || '' + ); + } + function paramToValue(s, o) { + return paramToIdentifier(s, { returnAll: !0 }) + .map((s) => o[s]) + .filter((s) => void 0 !== s)[0]; + } + function b64toB64UrlEncoded(s) { + return s.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, ''); + } + const isEmptyValue = (s) => !s || !(!isImmutable(s) || !s.isEmpty()), + idFn = (s) => s; + function createStoreWithMiddleware(s, o, i) { + let u = [systemThunkMiddleware(i)]; + return createStore( + s, + o, + (at.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose)( + (function applyMiddleware(...s) { + return (o) => (i, u) => { + const _ = o(i, u); + let dispatch = () => { + throw new Error(formatProdErrorMessage(15)); + }; + const w = { getState: _.getState, dispatch: (s, ...o) => dispatch(s, ...o) }, + x = s.map((s) => s(w)); + return (dispatch = compose(...x)(_.dispatch)), { ..._, dispatch }; + }; + })(...u) + ) + ); + } + class Store { + constructor(s = {}) { + We()( + this, + { + state: {}, + plugins: [], + system: { configs: {}, fn: {}, components: {}, rootInjects: {}, statePlugins: {} }, + boundSystem: {}, + toolbox: {} + }, + s + ), + (this.getSystem = this._getSystem.bind(this)), + (this.store = (function configureStore(s, o, i) { + return createStoreWithMiddleware(s, o, i); + })(idFn, (0, qe.fromJS)(this.state), this.getSystem)), + this.buildSystem(!1), + this.register(this.plugins); + } + getStore() { + return this.store; + } + register(s, o = !0) { + var i = combinePlugins(s, this.getSystem()); + systemExtend(this.system, i), o && this.buildSystem(); + callAfterLoad.call(this.system, s, this.getSystem()) && this.buildSystem(); + } + buildSystem(s = !0) { + let o = this.getStore().dispatch, + i = this.getStore().getState; + (this.boundSystem = Object.assign( + {}, + this.getRootInjects(), + this.getWrappedAndBoundActions(o), + this.getWrappedAndBoundSelectors(i, this.getSystem), + this.getStateThunks(i), + this.getFn(), + this.getConfigs() + )), + s && this.rebuildReducer(); + } + _getSystem() { + return this.boundSystem; + } + getRootInjects() { + return Object.assign( + { + getSystem: this.getSystem, + getStore: this.getStore.bind(this), + getComponents: this.getComponents.bind(this), + getState: this.getStore().getState, + getConfigs: this._getConfigs.bind(this), + Im: $e(), + React: Pe + }, + this.system.rootInjects || {} + ); + } + _getConfigs() { + return this.system.configs; + } + getConfigs() { + return { configs: this.system.configs }; + } + setConfigs(s) { + this.system.configs = s; + } + rebuildReducer() { + this.store.replaceReducer( + (function buildReducer(s) { + return (function allReducers(s) { + let o = Object.keys(s).reduce( + (o, i) => ( + (o[i] = (function makeReducer(s) { + return (o = new qe.Map(), i) => { + if (!s) return o; + let u = s[i.type]; + if (u) { + const s = wrapWithTryCatch(u)(o, i); + return null === s ? o : s; + } + return o; + }; + })(s[i])), + o + ), + {} + ); + if (!Object.keys(o).length) return idFn; + return (0, He.H)(o); + })(objMap(s, (s) => s.reducers)); + })(this.system.statePlugins) + ); + } + getType(s) { + let o = s[0].toUpperCase() + s.slice(1); + return objReduce(this.system.statePlugins, (i, u) => { + let _ = i[s]; + if (_) return { [u + o]: _ }; + }); + } + getSelectors() { + return this.getType('selectors'); + } + getActions() { + return objMap(this.getType('actions'), (s) => + objReduce(s, (s, o) => { + if (isFn(s)) return { [o]: s }; + }) + ); + } + getWrappedAndBoundActions(s) { + return objMap(this.getBoundActions(s), (s, o) => { + let i = this.system.statePlugins[o.slice(0, -7)].wrapActions; + return i + ? objMap(s, (s, o) => { + let u = i[o]; + return u + ? (Array.isArray(u) || (u = [u]), + u.reduce((s, o) => { + let newAction = (...i) => o(s, this.getSystem())(...i); + if (!isFn(newAction)) + throw new TypeError( + 'wrapActions needs to return a function that returns a new function (ie the wrapped action)' + ); + return wrapWithTryCatch(newAction); + }, s || Function.prototype)) + : s; + }) + : s; + }); + } + getWrappedAndBoundSelectors(s, o) { + return objMap(this.getBoundSelectors(s, o), (o, i) => { + let u = [i.slice(0, -9)], + _ = this.system.statePlugins[u].wrapSelectors; + return _ + ? objMap(o, (o, i) => { + let w = _[i]; + return w + ? (Array.isArray(w) || (w = [w]), + w.reduce((o, i) => { + let wrappedSelector = (..._) => + i(o, this.getSystem())(s().getIn(u), ..._); + if (!isFn(wrappedSelector)) + throw new TypeError( + 'wrapSelector needs to return a function that returns a new function (ie the wrapped action)' + ); + return wrappedSelector; + }, o || Function.prototype)) + : o; + }) + : o; + }); + } + getStates(s) { + return Object.keys(this.system.statePlugins).reduce( + (o, i) => ((o[i] = s.get(i)), o), + {} + ); + } + getStateThunks(s) { + return Object.keys(this.system.statePlugins).reduce( + (o, i) => ((o[i] = () => s().get(i)), o), + {} + ); + } + getFn() { + return { fn: this.system.fn }; + } + getComponents(s) { + const o = this.system.components[s]; + return Array.isArray(o) + ? o.reduce((s, o) => o(s, this.getSystem())) + : void 0 !== s + ? this.system.components[s] + : this.system.components; + } + getBoundSelectors(s, o) { + return objMap(this.getSelectors(), (i, u) => { + let _ = [u.slice(0, -9)]; + return objMap(i, (i) => (...u) => { + let w = wrapWithTryCatch(i).apply(null, [s().getIn(_), ...u]); + return 'function' == typeof w && (w = wrapWithTryCatch(w)(o())), w; + }); + }); + } + getBoundActions(s) { + s = s || this.getStore().dispatch; + const o = this.getActions(), + process = (s) => + 'function' != typeof s + ? objMap(s, (s) => process(s)) + : (...o) => { + var i = null; + try { + i = s(...o); + } catch (s) { + i = { type: et, error: !0, payload: (0, Ye.serializeError)(s) }; + } finally { + return i; + } + }; + return objMap(o, (o) => + (function bindActionCreators(s, o) { + if ('function' == typeof s) return bindActionCreator(s, o); + if ('object' != typeof s || null === s) throw new Error(formatProdErrorMessage(16)); + const i = {}; + for (const u in s) { + const _ = s[u]; + 'function' == typeof _ && (i[u] = bindActionCreator(_, o)); + } + return i; + })(process(o), s) + ); + } + getMapStateToProps() { + return () => Object.assign({}, this.getSystem()); + } + getMapDispatchToProps(s) { + return (o) => We()({}, this.getWrappedAndBoundActions(o), this.getFn(), s); + } + } + function combinePlugins(s, o) { + return isObject(s) && !isArray(s) + ? Qe()({}, s) + : isFunc(s) + ? combinePlugins(s(o), o) + : isArray(s) + ? s + .map((s) => combinePlugins(s, o)) + .reduce(systemExtend, { components: o.getComponents() }) + : {}; + } + function callAfterLoad(s, o, { hasLoaded: i } = {}) { + let u = i; + return ( + isObject(s) && + !isArray(s) && + 'function' == typeof s.afterLoad && + ((u = !0), wrapWithTryCatch(s.afterLoad).call(this, o)), + isFunc(s) + ? callAfterLoad.call(this, s(o), o, { hasLoaded: u }) + : isArray(s) + ? s.map((s) => callAfterLoad.call(this, s, o, { hasLoaded: u })) + : u + ); + } + function systemExtend(s = {}, o = {}) { + if (!isObject(s)) return {}; + if (!isObject(o)) return s; + o.wrapComponents && + (objMap(o.wrapComponents, (i, u) => { + const _ = s.components && s.components[u]; + _ && Array.isArray(_) + ? ((s.components[u] = _.concat([i])), delete o.wrapComponents[u]) + : _ && ((s.components[u] = [_, i]), delete o.wrapComponents[u]); + }), + Object.keys(o.wrapComponents).length || delete o.wrapComponents); + const { statePlugins: i } = s; + if (isObject(i)) + for (let s in i) { + const u = i[s]; + if (!isObject(u)) continue; + const { wrapActions: _, wrapSelectors: w } = u; + if (isObject(_)) + for (let i in _) { + let u = _[i]; + Array.isArray(u) || ((u = [u]), (_[i] = u)), + o && + o.statePlugins && + o.statePlugins[s] && + o.statePlugins[s].wrapActions && + o.statePlugins[s].wrapActions[i] && + (o.statePlugins[s].wrapActions[i] = _[i].concat( + o.statePlugins[s].wrapActions[i] + )); + } + if (isObject(w)) + for (let i in w) { + let u = w[i]; + Array.isArray(u) || ((u = [u]), (w[i] = u)), + o && + o.statePlugins && + o.statePlugins[s] && + o.statePlugins[s].wrapSelectors && + o.statePlugins[s].wrapSelectors[i] && + (o.statePlugins[s].wrapSelectors[i] = w[i].concat( + o.statePlugins[s].wrapSelectors[i] + )); + } + } + return We()(s, o); + } + function wrapWithTryCatch(s, { logErrors: o = !0 } = {}) { + return 'function' != typeof s + ? s + : function (...i) { + try { + return s.call(this, ...i); + } catch (s) { + return o && console.error(s), null; + } + }; + } + var Pt = __webpack_require__(61160), + Mt = __webpack_require__.n(Pt); + const Tt = 'show_popup', + Nt = 'authorize', + Rt = 'logout', + Dt = 'pre_authorize_oauth2', + Lt = 'authorize_oauth2', + Bt = 'validate', + Ft = 'configure_auth', + qt = 'restore_authorization'; + function showDefinitions(s) { + return { type: Tt, payload: s }; + } + function authorize(s) { + return { type: Nt, payload: s }; + } + const authorizeWithPersistOption = + (s) => + ({ authActions: o }) => { + o.authorize(s), o.persistAuthorizationIfNeeded(); + }; + function logout(s) { + return { type: Rt, payload: s }; + } + const logoutWithPersistOption = + (s) => + ({ authActions: o }) => { + o.logout(s), o.persistAuthorizationIfNeeded(); + }, + preAuthorizeImplicit = + (s) => + ({ authActions: o, errActions: i }) => { + let { auth: u, token: _, isValid: w } = s, + { schema: x, name: C } = u, + j = x.get('flow'); + delete at.swaggerUIRedirectOauth2, + 'accessCode' === j || + w || + i.newAuthErr({ + authId: C, + source: 'auth', + level: 'warning', + message: + "Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server" + }), + _.error + ? i.newAuthErr({ + authId: C, + source: 'auth', + level: 'error', + message: JSON.stringify(_) + }) + : o.authorizeOauth2WithPersistOption({ auth: u, token: _ }); + }; + function authorizeOauth2(s) { + return { type: Lt, payload: s }; + } + const authorizeOauth2WithPersistOption = + (s) => + ({ authActions: o }) => { + o.authorizeOauth2(s), o.persistAuthorizationIfNeeded(); + }, + authorizePassword = + (s) => + ({ authActions: o }) => { + let { + schema: i, + name: u, + username: _, + password: w, + passwordType: x, + clientId: C, + clientSecret: j + } = s, + L = { grant_type: 'password', scope: s.scopes.join(' '), username: _, password: w }, + B = {}; + switch (x) { + case 'request-body': + !(function setClientIdAndSecret(s, o, i) { + o && Object.assign(s, { client_id: o }); + i && Object.assign(s, { client_secret: i }); + })(L, C, j); + break; + case 'basic': + B.Authorization = 'Basic ' + utils_btoa(C + ':' + j); + break; + default: + console.warn( + `Warning: invalid passwordType ${x} was passed, not including client id and secret` + ); + } + return o.authorizeRequest({ + body: buildFormData(L), + url: i.get('tokenUrl'), + name: u, + headers: B, + query: {}, + auth: s + }); + }; + const authorizeApplication = + (s) => + ({ authActions: o }) => { + let { schema: i, scopes: u, name: _, clientId: w, clientSecret: x } = s, + C = { Authorization: 'Basic ' + utils_btoa(w + ':' + x) }, + j = { grant_type: 'client_credentials', scope: u.join(' ') }; + return o.authorizeRequest({ + body: buildFormData(j), + name: _, + url: i.get('tokenUrl'), + auth: s, + headers: C + }); + }, + authorizeAccessCodeWithFormParams = + ({ auth: s, redirectUrl: o }) => + ({ authActions: i }) => { + let { schema: u, name: _, clientId: w, clientSecret: x, codeVerifier: C } = s, + j = { + grant_type: 'authorization_code', + code: s.code, + client_id: w, + client_secret: x, + redirect_uri: o, + code_verifier: C + }; + return i.authorizeRequest({ + body: buildFormData(j), + name: _, + url: u.get('tokenUrl'), + auth: s + }); + }, + authorizeAccessCodeWithBasicAuthentication = + ({ auth: s, redirectUrl: o }) => + ({ authActions: i }) => { + let { schema: u, name: _, clientId: w, clientSecret: x, codeVerifier: C } = s, + j = { Authorization: 'Basic ' + utils_btoa(w + ':' + x) }, + L = { + grant_type: 'authorization_code', + code: s.code, + client_id: w, + redirect_uri: o, + code_verifier: C + }; + return i.authorizeRequest({ + body: buildFormData(L), + name: _, + url: u.get('tokenUrl'), + auth: s, + headers: j + }); + }, + authorizeRequest = + (s) => + ({ + fn: o, + getConfigs: i, + authActions: u, + errActions: _, + oas3Selectors: w, + specSelectors: x, + authSelectors: C + }) => { + let j, + { body: L, query: B = {}, headers: $ = {}, name: V, url: U, auth: z } = s, + { additionalQueryStringParams: Y } = C.getConfigs() || {}; + if (x.isOAS3()) { + let s = w.serverEffectiveValue(w.selectedServer()); + j = Mt()(U, s, !0); + } else j = Mt()(U, x.url(), !0); + 'object' == typeof Y && (j.query = Object.assign({}, j.query, Y)); + const Z = j.toString(); + let ee = Object.assign( + { + Accept: 'application/json, text/plain, */*', + 'Content-Type': 'application/x-www-form-urlencoded', + 'X-Requested-With': 'XMLHttpRequest' + }, + $ + ); + o.fetch({ + url: Z, + method: 'post', + headers: ee, + query: B, + body: L, + requestInterceptor: i().requestInterceptor, + responseInterceptor: i().responseInterceptor + }) + .then(function (s) { + let o = JSON.parse(s.data), + i = o && (o.error || ''), + w = o && (o.parseError || ''); + s.ok + ? i || w + ? _.newAuthErr({ + authId: V, + level: 'error', + source: 'auth', + message: JSON.stringify(o) + }) + : u.authorizeOauth2WithPersistOption({ auth: z, token: o }) + : _.newAuthErr({ + authId: V, + level: 'error', + source: 'auth', + message: s.statusText + }); + }) + .catch((s) => { + let o = new Error(s).message; + if (s.response && s.response.data) { + const i = s.response.data; + try { + const s = 'string' == typeof i ? JSON.parse(i) : i; + s.error && (o += `, error: ${s.error}`), + s.error_description && (o += `, description: ${s.error_description}`); + } catch (s) {} + } + _.newAuthErr({ authId: V, level: 'error', source: 'auth', message: o }); + }); + }; + function configureAuth(s) { + return { type: Ft, payload: s }; + } + function restoreAuthorization(s) { + return { type: qt, payload: s }; + } + const persistAuthorizationIfNeeded = + () => + ({ authSelectors: s, getConfigs: o }) => { + if (!o().persistAuthorization) return; + const i = s.authorized().toJS(); + localStorage.setItem('authorized', JSON.stringify(i)); + }, + authPopup = (s, o) => () => { + (at.swaggerUIRedirectOauth2 = o), at.open(s); + }, + $t = { + [Tt]: (s, { payload: o }) => s.set('showDefinitions', o), + [Nt]: (s, { payload: o }) => { + let i = (0, qe.fromJS)(o), + u = s.get('authorized') || (0, qe.Map)(); + return ( + i.entrySeq().forEach(([o, i]) => { + if (!isFunc(i.getIn)) return s.set('authorized', u); + let _ = i.getIn(['schema', 'type']); + if ('apiKey' === _ || 'http' === _) u = u.set(o, i); + else if ('basic' === _) { + let s = i.getIn(['value', 'username']), + _ = i.getIn(['value', 'password']); + (u = u.setIn([o, 'value'], { + username: s, + header: 'Basic ' + utils_btoa(s + ':' + _) + })), + (u = u.setIn([o, 'schema'], i.get('schema'))); + } + }), + s.set('authorized', u) + ); + }, + [Lt]: (s, { payload: o }) => { + let i, + { auth: u, token: _ } = o; + (u.token = Object.assign({}, _)), (i = (0, qe.fromJS)(u)); + let w = s.get('authorized') || (0, qe.Map)(); + return (w = w.set(i.get('name'), i)), s.set('authorized', w); + }, + [Rt]: (s, { payload: o }) => { + let i = s.get('authorized').withMutations((s) => { + o.forEach((o) => { + s.delete(o); + }); + }); + return s.set('authorized', i); + }, + [Ft]: (s, { payload: o }) => s.set('configs', o), + [qt]: (s, { payload: o }) => s.set('authorized', (0, qe.fromJS)(o.authorized)) + }; + function assertIsFunction(s, o = 'expected a function, instead received ' + typeof s) { + if ('function' != typeof s) throw new TypeError(o); + } + var ensureIsArray = (s) => (Array.isArray(s) ? s : [s]); + function getDependencies(s) { + const o = Array.isArray(s[0]) ? s[0] : s; + return ( + (function assertIsArrayOfFunctions( + s, + o = 'expected all items to be functions, instead received the following types: ' + ) { + if (!s.every((s) => 'function' == typeof s)) { + const i = s + .map((s) => + 'function' == typeof s ? `function ${s.name || 'unnamed'}()` : typeof s + ) + .join(', '); + throw new TypeError(`${o}[${i}]`); + } + })( + o, + 'createSelector expects all input-selectors to be functions, but received the following types: ' + ), + o + ); + } + Symbol(), Object.getPrototypeOf({}); + var Vt = + 'undefined' != typeof WeakRef + ? WeakRef + : class { + constructor(s) { + this.value = s; + } + deref() { + return this.value; + } + }; + function weakMapMemoize(s, o = {}) { + let i = { s: 0, v: void 0, o: null, p: null }; + const { resultEqualityCheck: u } = o; + let _, + w = 0; + function memoized() { + let o = i; + const { length: x } = arguments; + for (let s = 0, i = x; s < i; s++) { + const i = arguments[s]; + if ('function' == typeof i || ('object' == typeof i && null !== i)) { + let s = o.o; + null === s && (o.o = s = new WeakMap()); + const u = s.get(i); + void 0 === u ? ((o = { s: 0, v: void 0, o: null, p: null }), s.set(i, o)) : (o = u); + } else { + let s = o.p; + null === s && (o.p = s = new Map()); + const u = s.get(i); + void 0 === u ? ((o = { s: 0, v: void 0, o: null, p: null }), s.set(i, o)) : (o = u); + } + } + const C = o; + let j; + if (1 === o.s) j = o.v; + else if (((j = s.apply(null, arguments)), w++, u)) { + const s = _?.deref?.() ?? _; + null != s && u(s, j) && ((j = s), 0 !== w && w--); + _ = ('object' == typeof j && null !== j) || 'function' == typeof j ? new Vt(j) : j; + } + return (C.s = 1), (C.v = j), j; + } + return ( + (memoized.clearCache = () => { + (i = { s: 0, v: void 0, o: null, p: null }), memoized.resetResultsCount(); + }), + (memoized.resultsCount = () => w), + (memoized.resetResultsCount = () => { + w = 0; + }), + memoized + ); + } + function createSelectorCreator(s, ...o) { + const i = 'function' == typeof s ? { memoize: s, memoizeOptions: o } : s, + createSelector2 = (...s) => { + let o, + u = 0, + _ = 0, + w = {}, + x = s.pop(); + 'object' == typeof x && ((w = x), (x = s.pop())), + assertIsFunction( + x, + `createSelector expects an output function after the inputs, but received: [${typeof x}]` + ); + const C = { ...i, ...w }, + { + memoize: j, + memoizeOptions: L = [], + argsMemoize: B = weakMapMemoize, + argsMemoizeOptions: $ = [], + devModeChecks: V = {} + } = C, + U = ensureIsArray(L), + z = ensureIsArray($), + Y = getDependencies(s), + Z = j( + function recomputationWrapper() { + return u++, x.apply(null, arguments); + }, + ...U + ); + const ee = B( + function dependenciesChecker() { + _++; + const s = (function collectInputSelectorResults(s, o) { + const i = [], + { length: u } = s; + for (let _ = 0; _ < u; _++) i.push(s[_].apply(null, o)); + return i; + })(Y, arguments); + return (o = Z.apply(null, s)), o; + }, + ...z + ); + return Object.assign(ee, { + resultFunc: x, + memoizedResultFunc: Z, + dependencies: Y, + dependencyRecomputations: () => _, + resetDependencyRecomputations: () => { + _ = 0; + }, + lastResult: () => o, + recomputations: () => u, + resetRecomputations: () => { + u = 0; + }, + memoize: j, + argsMemoize: B + }); + }; + return ( + Object.assign(createSelector2, { withTypes: () => createSelector2 }), createSelector2 + ); + } + var Ut = createSelectorCreator(weakMapMemoize), + zt = Object.assign( + (s, o = Ut) => { + !(function assertIsObject(s, o = 'expected an object, instead received ' + typeof s) { + if ('object' != typeof s) throw new TypeError(o); + })( + s, + 'createStructuredSelector expects first argument to be an object where each property is a selector, instead received a ' + + typeof s + ); + const i = Object.keys(s); + return o( + i.map((o) => s[o]), + (...s) => s.reduce((s, o, u) => ((s[i[u]] = o), s), {}) + ); + }, + { withTypes: () => zt } + ); + const state = (s) => s, + Wt = Ut(state, (s) => s.get('showDefinitions')), + Kt = Ut(state, () => ({ specSelectors: s }) => { + let o = s.securityDefinitions() || (0, qe.Map)({}), + i = (0, qe.List)(); + return ( + o.entrySeq().forEach(([s, o]) => { + let u = (0, qe.Map)(); + (u = u.set(s, o)), (i = i.push(u)); + }), + i + ); + }), + getDefinitionsByNames = + (s, o) => + ({ specSelectors: s }) => { + console.warn( + 'WARNING: getDefinitionsByNames is deprecated and will be removed in the next major version.' + ); + let i = s.securityDefinitions(), + u = (0, qe.List)(); + return ( + o.valueSeq().forEach((s) => { + let o = (0, qe.Map)(); + s.entrySeq().forEach(([s, u]) => { + let _, + w = i.get(s); + 'oauth2' === w.get('type') && + u.size && + ((_ = w.get('scopes')), + _.keySeq().forEach((s) => { + u.contains(s) || (_ = _.delete(s)); + }), + (w = w.set('allowedScopes', _))), + (o = o.set(s, w)); + }), + (u = u.push(o)); + }), + u + ); + }, + definitionsForRequirements = + (s, o = (0, qe.List)()) => + ({ authSelectors: s }) => { + const i = s.definitionsToAuthorize() || (0, qe.List)(); + let u = (0, qe.List)(); + return ( + i.forEach((s) => { + let i = o.find((o) => o.get(s.keySeq().first())); + i && + (s.forEach((o, u) => { + if ('oauth2' === o.get('type')) { + const _ = i.get(u); + let w = o.get('scopes'); + qe.List.isList(_) && + qe.Map.isMap(w) && + (w.keySeq().forEach((s) => { + _.contains(s) || (w = w.delete(s)); + }), + (s = s.set(u, o.set('scopes', w)))); + } + }), + (u = u.push(s))); + }), + u + ); + }, + Ht = Ut(state, (s) => s.get('authorized') || (0, qe.Map)()), + isAuthorized = + (s, o) => + ({ authSelectors: s }) => { + let i = s.authorized(); + return qe.List.isList(o) + ? !!o.toJS().filter( + (s) => + -1 === + Object.keys(s) + .map((s) => !!i.get(s)) + .indexOf(!1) + ).length + : null; + }, + Jt = Ut(state, (s) => s.get('configs')), + execute = + (s, { authSelectors: o, specSelectors: i }) => + ({ path: u, method: _, operation: w, extras: x }) => { + let C = { + authorized: o.authorized() && o.authorized().toJS(), + definitions: i.securityDefinitions() && i.securityDefinitions().toJS(), + specSecurity: i.security() && i.security().toJS() + }; + return s({ path: u, method: _, operation: w, securities: C, ...x }); + }, + loaded = (s, o) => (i) => { + const { getConfigs: u, authActions: _ } = o, + w = u(); + if ((s(i), w.persistAuthorization)) { + const s = localStorage.getItem('authorized'); + s && _.restoreAuthorization({ authorized: JSON.parse(s) }); + } + }, + wrap_actions_authorize = (s, o) => (i) => { + s(i); + if (o.getConfigs().persistAuthorization) + try { + const [{ schema: s, value: o }] = Object.values(i), + u = 'apiKey' === s.get('type'), + _ = 'cookie' === s.get('in'); + u && _ && (document.cookie = `${s.get('name')}=${o}; SameSite=None; Secure`); + } catch (s) { + console.error('Error persisting cookie based apiKey in document.cookie.', s); + } + }, + wrap_actions_logout = (s, o) => (i) => { + const u = o.getConfigs(), + _ = o.authSelectors.authorized(); + try { + u.persistAuthorization && + Array.isArray(i) && + i.forEach((s) => { + const o = _.get(s, {}), + i = 'apiKey' === o.getIn(['schema', 'type']), + u = 'cookie' === o.getIn(['schema', 'in']); + if (i && u) { + const s = o.getIn(['schema', 'name']); + document.cookie = `${s}=; Max-Age=-99999999`; + } + }); + } catch (s) { + console.error('Error deleting cookie based apiKey from document.cookie.', s); + } + s(i); + }; + var Gt = __webpack_require__(90179), + Yt = __webpack_require__.n(Gt); + class LockAuthIcon extends Pe.Component { + mapStateToProps(s, o) { + return { state: s, ownProps: Yt()(o, Object.keys(o.getSystem())) }; + } + render() { + const { getComponent: s, ownProps: o } = this.props, + i = s('LockIcon'); + return Pe.createElement(i, o); + } + } + const Xt = LockAuthIcon; + class UnlockAuthIcon extends Pe.Component { + mapStateToProps(s, o) { + return { state: s, ownProps: Yt()(o, Object.keys(o.getSystem())) }; + } + render() { + const { getComponent: s, ownProps: o } = this.props, + i = s('UnlockIcon'); + return Pe.createElement(i, o); + } + } + const Zt = UnlockAuthIcon; + function auth() { + return { + afterLoad(s) { + (this.rootInjects = this.rootInjects || {}), + (this.rootInjects.initOAuth = s.authActions.configureAuth), + (this.rootInjects.preauthorizeApiKey = preauthorizeApiKey.bind(null, s)), + (this.rootInjects.preauthorizeBasic = preauthorizeBasic.bind(null, s)); + }, + components: { + LockAuthIcon: Xt, + UnlockAuthIcon: Zt, + LockAuthOperationIcon: Xt, + UnlockAuthOperationIcon: Zt + }, + statePlugins: { + auth: { + reducers: $t, + actions: o, + selectors: i, + wrapActions: { authorize: wrap_actions_authorize, logout: wrap_actions_logout } + }, + configs: { wrapActions: { loaded } }, + spec: { wrapActions: { execute } } + } + }; + } + function preauthorizeBasic(s, o, i, u) { + const { + authActions: { authorize: _ }, + specSelectors: { specJson: w, isOAS3: x } + } = s, + C = x() ? ['components', 'securitySchemes'] : ['securityDefinitions'], + j = w().getIn([...C, o]); + return j ? _({ [o]: { value: { username: i, password: u }, schema: j.toJS() } }) : null; + } + function preauthorizeApiKey(s, o, i) { + const { + authActions: { authorize: u }, + specSelectors: { specJson: _, isOAS3: w } + } = s, + x = w() ? ['components', 'securitySchemes'] : ['securityDefinitions'], + C = _().getIn([...x, o]); + return C ? u({ [o]: { value: i, schema: C.toJS() } }) : null; + } + function isNothing(s) { + return null == s; + } + var Qt = function repeat(s, o) { + var i, + u = ''; + for (i = 0; i < o; i += 1) u += s; + return u; + }, + er = function isNegativeZero(s) { + return 0 === s && Number.NEGATIVE_INFINITY === 1 / s; + }, + tr = { + isNothing, + isObject: function js_yaml_isObject(s) { + return 'object' == typeof s && null !== s; + }, + toArray: function toArray(s) { + return Array.isArray(s) ? s : isNothing(s) ? [] : [s]; + }, + repeat: Qt, + isNegativeZero: er, + extend: function extend(s, o) { + var i, u, _, w; + if (o) + for (i = 0, u = (w = Object.keys(o)).length; i < u; i += 1) s[(_ = w[i])] = o[_]; + return s; + } + }; + function formatError(s, o) { + var i = '', + u = s.reason || '(unknown reason)'; + return s.mark + ? (s.mark.name && (i += 'in "' + s.mark.name + '" '), + (i += '(' + (s.mark.line + 1) + ':' + (s.mark.column + 1) + ')'), + !o && s.mark.snippet && (i += '\n\n' + s.mark.snippet), + u + ' ' + i) + : u; + } + function YAMLException$1(s, o) { + Error.call(this), + (this.name = 'YAMLException'), + (this.reason = s), + (this.mark = o), + (this.message = formatError(this, !1)), + Error.captureStackTrace + ? Error.captureStackTrace(this, this.constructor) + : (this.stack = new Error().stack || ''); + } + (YAMLException$1.prototype = Object.create(Error.prototype)), + (YAMLException$1.prototype.constructor = YAMLException$1), + (YAMLException$1.prototype.toString = function toString(s) { + return this.name + ': ' + formatError(this, s); + }); + var rr = YAMLException$1; + function getLine(s, o, i, u, _) { + var w = '', + x = '', + C = Math.floor(_ / 2) - 1; + return ( + u - o > C && (o = u - C + (w = ' ... ').length), + i - u > C && (i = u + C - (x = ' ...').length), + { str: w + s.slice(o, i).replace(/\t/g, '→') + x, pos: u - o + w.length } + ); + } + function padStart(s, o) { + return tr.repeat(' ', o - s.length) + s; + } + var nr = function makeSnippet(s, o) { + if (((o = Object.create(o || null)), !s.buffer)) return null; + o.maxLength || (o.maxLength = 79), + 'number' != typeof o.indent && (o.indent = 1), + 'number' != typeof o.linesBefore && (o.linesBefore = 3), + 'number' != typeof o.linesAfter && (o.linesAfter = 2); + for (var i, u = /\r?\n|\r|\0/g, _ = [0], w = [], x = -1; (i = u.exec(s.buffer)); ) + w.push(i.index), + _.push(i.index + i[0].length), + s.position <= i.index && x < 0 && (x = _.length - 2); + x < 0 && (x = _.length - 1); + var C, + j, + L = '', + B = Math.min(s.line + o.linesAfter, w.length).toString().length, + $ = o.maxLength - (o.indent + B + 3); + for (C = 1; C <= o.linesBefore && !(x - C < 0); C++) + (j = getLine(s.buffer, _[x - C], w[x - C], s.position - (_[x] - _[x - C]), $)), + (L = + tr.repeat(' ', o.indent) + + padStart((s.line - C + 1).toString(), B) + + ' | ' + + j.str + + '\n' + + L); + for ( + j = getLine(s.buffer, _[x], w[x], s.position, $), + L += + tr.repeat(' ', o.indent) + + padStart((s.line + 1).toString(), B) + + ' | ' + + j.str + + '\n', + L += tr.repeat('-', o.indent + B + 3 + j.pos) + '^\n', + C = 1; + C <= o.linesAfter && !(x + C >= w.length); + C++ + ) + (j = getLine(s.buffer, _[x + C], w[x + C], s.position - (_[x] - _[x + C]), $)), + (L += + tr.repeat(' ', o.indent) + + padStart((s.line + C + 1).toString(), B) + + ' | ' + + j.str + + '\n'); + return L.replace(/\n$/, ''); + }, + sr = [ + 'kind', + 'multi', + 'resolve', + 'construct', + 'instanceOf', + 'predicate', + 'represent', + 'representName', + 'defaultStyle', + 'styleAliases' + ], + ir = ['scalar', 'sequence', 'mapping']; + var ar = function Type$1(s, o) { + if ( + ((o = o || {}), + Object.keys(o).forEach(function (o) { + if (-1 === sr.indexOf(o)) + throw new rr( + 'Unknown option "' + o + '" is met in definition of "' + s + '" YAML type.' + ); + }), + (this.options = o), + (this.tag = s), + (this.kind = o.kind || null), + (this.resolve = + o.resolve || + function () { + return !0; + }), + (this.construct = + o.construct || + function (s) { + return s; + }), + (this.instanceOf = o.instanceOf || null), + (this.predicate = o.predicate || null), + (this.represent = o.represent || null), + (this.representName = o.representName || null), + (this.defaultStyle = o.defaultStyle || null), + (this.multi = o.multi || !1), + (this.styleAliases = (function compileStyleAliases(s) { + var o = {}; + return ( + null !== s && + Object.keys(s).forEach(function (i) { + s[i].forEach(function (s) { + o[String(s)] = i; + }); + }), + o + ); + })(o.styleAliases || null)), + -1 === ir.indexOf(this.kind)) + ) + throw new rr( + 'Unknown kind "' + this.kind + '" is specified for "' + s + '" YAML type.' + ); + }; + function compileList(s, o) { + var i = []; + return ( + s[o].forEach(function (s) { + var o = i.length; + i.forEach(function (i, u) { + i.tag === s.tag && i.kind === s.kind && i.multi === s.multi && (o = u); + }), + (i[o] = s); + }), + i + ); + } + function Schema$1(s) { + return this.extend(s); + } + Schema$1.prototype.extend = function extend(s) { + var o = [], + i = []; + if (s instanceof ar) i.push(s); + else if (Array.isArray(s)) i = i.concat(s); + else { + if (!s || (!Array.isArray(s.implicit) && !Array.isArray(s.explicit))) + throw new rr( + 'Schema.extend argument should be a Type, [ Type ], or a schema definition ({ implicit: [...], explicit: [...] })' + ); + s.implicit && (o = o.concat(s.implicit)), s.explicit && (i = i.concat(s.explicit)); + } + o.forEach(function (s) { + if (!(s instanceof ar)) + throw new rr( + 'Specified list of YAML types (or a single Type object) contains a non-Type object.' + ); + if (s.loadKind && 'scalar' !== s.loadKind) + throw new rr( + 'There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.' + ); + if (s.multi) + throw new rr( + 'There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.' + ); + }), + i.forEach(function (s) { + if (!(s instanceof ar)) + throw new rr( + 'Specified list of YAML types (or a single Type object) contains a non-Type object.' + ); + }); + var u = Object.create(Schema$1.prototype); + return ( + (u.implicit = (this.implicit || []).concat(o)), + (u.explicit = (this.explicit || []).concat(i)), + (u.compiledImplicit = compileList(u, 'implicit')), + (u.compiledExplicit = compileList(u, 'explicit')), + (u.compiledTypeMap = (function compileMap() { + var s, + o, + i = { + scalar: {}, + sequence: {}, + mapping: {}, + fallback: {}, + multi: { scalar: [], sequence: [], mapping: [], fallback: [] } + }; + function collectType(s) { + s.multi + ? (i.multi[s.kind].push(s), i.multi.fallback.push(s)) + : (i[s.kind][s.tag] = i.fallback[s.tag] = s); + } + for (s = 0, o = arguments.length; s < o; s += 1) arguments[s].forEach(collectType); + return i; + })(u.compiledImplicit, u.compiledExplicit)), + u + ); + }; + var lr = Schema$1, + cr = new ar('tag:yaml.org,2002:str', { + kind: 'scalar', + construct: function (s) { + return null !== s ? s : ''; + } + }), + ur = new ar('tag:yaml.org,2002:seq', { + kind: 'sequence', + construct: function (s) { + return null !== s ? s : []; + } + }), + pr = new ar('tag:yaml.org,2002:map', { + kind: 'mapping', + construct: function (s) { + return null !== s ? s : {}; + } + }), + dr = new lr({ explicit: [cr, ur, pr] }); + var fr = new ar('tag:yaml.org,2002:null', { + kind: 'scalar', + resolve: function resolveYamlNull(s) { + if (null === s) return !0; + var o = s.length; + return ( + (1 === o && '~' === s) || (4 === o && ('null' === s || 'Null' === s || 'NULL' === s)) + ); + }, + construct: function constructYamlNull() { + return null; + }, + predicate: function isNull(s) { + return null === s; + }, + represent: { + canonical: function () { + return '~'; + }, + lowercase: function () { + return 'null'; + }, + uppercase: function () { + return 'NULL'; + }, + camelcase: function () { + return 'Null'; + }, + empty: function () { + return ''; + } + }, + defaultStyle: 'lowercase' + }); + var mr = new ar('tag:yaml.org,2002:bool', { + kind: 'scalar', + resolve: function resolveYamlBoolean(s) { + if (null === s) return !1; + var o = s.length; + return ( + (4 === o && ('true' === s || 'True' === s || 'TRUE' === s)) || + (5 === o && ('false' === s || 'False' === s || 'FALSE' === s)) + ); + }, + construct: function constructYamlBoolean(s) { + return 'true' === s || 'True' === s || 'TRUE' === s; + }, + predicate: function isBoolean(s) { + return '[object Boolean]' === Object.prototype.toString.call(s); + }, + represent: { + lowercase: function (s) { + return s ? 'true' : 'false'; + }, + uppercase: function (s) { + return s ? 'TRUE' : 'FALSE'; + }, + camelcase: function (s) { + return s ? 'True' : 'False'; + } + }, + defaultStyle: 'lowercase' + }); + function isOctCode(s) { + return 48 <= s && s <= 55; + } + function isDecCode(s) { + return 48 <= s && s <= 57; + } + var gr = new ar('tag:yaml.org,2002:int', { + kind: 'scalar', + resolve: function resolveYamlInteger(s) { + if (null === s) return !1; + var o, + i, + u = s.length, + _ = 0, + w = !1; + if (!u) return !1; + if ((('-' !== (o = s[_]) && '+' !== o) || (o = s[++_]), '0' === o)) { + if (_ + 1 === u) return !0; + if ('b' === (o = s[++_])) { + for (_++; _ < u; _++) + if ('_' !== (o = s[_])) { + if ('0' !== o && '1' !== o) return !1; + w = !0; + } + return w && '_' !== o; + } + if ('x' === o) { + for (_++; _ < u; _++) + if ('_' !== (o = s[_])) { + if ( + !( + (48 <= (i = s.charCodeAt(_)) && i <= 57) || + (65 <= i && i <= 70) || + (97 <= i && i <= 102) + ) + ) + return !1; + w = !0; + } + return w && '_' !== o; + } + if ('o' === o) { + for (_++; _ < u; _++) + if ('_' !== (o = s[_])) { + if (!isOctCode(s.charCodeAt(_))) return !1; + w = !0; + } + return w && '_' !== o; + } + } + if ('_' === o) return !1; + for (; _ < u; _++) + if ('_' !== (o = s[_])) { + if (!isDecCode(s.charCodeAt(_))) return !1; + w = !0; + } + return !(!w || '_' === o); + }, + construct: function constructYamlInteger(s) { + var o, + i = s, + u = 1; + if ( + (-1 !== i.indexOf('_') && (i = i.replace(/_/g, '')), + ('-' !== (o = i[0]) && '+' !== o) || + ('-' === o && (u = -1), (o = (i = i.slice(1))[0])), + '0' === i) + ) + return 0; + if ('0' === o) { + if ('b' === i[1]) return u * parseInt(i.slice(2), 2); + if ('x' === i[1]) return u * parseInt(i.slice(2), 16); + if ('o' === i[1]) return u * parseInt(i.slice(2), 8); + } + return u * parseInt(i, 10); + }, + predicate: function isInteger(s) { + return ( + '[object Number]' === Object.prototype.toString.call(s) && + s % 1 == 0 && + !tr.isNegativeZero(s) + ); + }, + represent: { + binary: function (s) { + return s >= 0 ? '0b' + s.toString(2) : '-0b' + s.toString(2).slice(1); + }, + octal: function (s) { + return s >= 0 ? '0o' + s.toString(8) : '-0o' + s.toString(8).slice(1); + }, + decimal: function (s) { + return s.toString(10); + }, + hexadecimal: function (s) { + return s >= 0 + ? '0x' + s.toString(16).toUpperCase() + : '-0x' + s.toString(16).toUpperCase().slice(1); + } + }, + defaultStyle: 'decimal', + styleAliases: { + binary: [2, 'bin'], + octal: [8, 'oct'], + decimal: [10, 'dec'], + hexadecimal: [16, 'hex'] + } + }), + yr = new RegExp( + '^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$' + ); + var vr = /^[-+]?[0-9]+e/; + var br = new ar('tag:yaml.org,2002:float', { + kind: 'scalar', + resolve: function resolveYamlFloat(s) { + return null !== s && !(!yr.test(s) || '_' === s[s.length - 1]); + }, + construct: function constructYamlFloat(s) { + var o, i; + return ( + (i = '-' === (o = s.replace(/_/g, '').toLowerCase())[0] ? -1 : 1), + '+-'.indexOf(o[0]) >= 0 && (o = o.slice(1)), + '.inf' === o + ? 1 === i + ? Number.POSITIVE_INFINITY + : Number.NEGATIVE_INFINITY + : '.nan' === o + ? NaN + : i * parseFloat(o, 10) + ); + }, + predicate: function isFloat(s) { + return ( + '[object Number]' === Object.prototype.toString.call(s) && + (s % 1 != 0 || tr.isNegativeZero(s)) + ); + }, + represent: function representYamlFloat(s, o) { + var i; + if (isNaN(s)) + switch (o) { + case 'lowercase': + return '.nan'; + case 'uppercase': + return '.NAN'; + case 'camelcase': + return '.NaN'; + } + else if (Number.POSITIVE_INFINITY === s) + switch (o) { + case 'lowercase': + return '.inf'; + case 'uppercase': + return '.INF'; + case 'camelcase': + return '.Inf'; + } + else if (Number.NEGATIVE_INFINITY === s) + switch (o) { + case 'lowercase': + return '-.inf'; + case 'uppercase': + return '-.INF'; + case 'camelcase': + return '-.Inf'; + } + else if (tr.isNegativeZero(s)) return '-0.0'; + return (i = s.toString(10)), vr.test(i) ? i.replace('e', '.e') : i; + }, + defaultStyle: 'lowercase' + }), + _r = dr.extend({ implicit: [fr, mr, gr, br] }), + Er = _r, + wr = new RegExp('^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$'), + Sr = new RegExp( + '^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$' + ); + var xr = new ar('tag:yaml.org,2002:timestamp', { + kind: 'scalar', + resolve: function resolveYamlTimestamp(s) { + return null !== s && (null !== wr.exec(s) || null !== Sr.exec(s)); + }, + construct: function constructYamlTimestamp(s) { + var o, + i, + u, + _, + w, + x, + C, + j, + L = 0, + B = null; + if ((null === (o = wr.exec(s)) && (o = Sr.exec(s)), null === o)) + throw new Error('Date resolve error'); + if (((i = +o[1]), (u = +o[2] - 1), (_ = +o[3]), !o[4])) + return new Date(Date.UTC(i, u, _)); + if (((w = +o[4]), (x = +o[5]), (C = +o[6]), o[7])) { + for (L = o[7].slice(0, 3); L.length < 3; ) L += '0'; + L = +L; + } + return ( + o[9] && ((B = 6e4 * (60 * +o[10] + +(o[11] || 0))), '-' === o[9] && (B = -B)), + (j = new Date(Date.UTC(i, u, _, w, x, C, L))), + B && j.setTime(j.getTime() - B), + j + ); + }, + instanceOf: Date, + represent: function representYamlTimestamp(s) { + return s.toISOString(); + } + }); + var kr = new ar('tag:yaml.org,2002:merge', { + kind: 'scalar', + resolve: function resolveYamlMerge(s) { + return '<<' === s || null === s; + } + }), + Cr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r'; + var Or = new ar('tag:yaml.org,2002:binary', { + kind: 'scalar', + resolve: function resolveYamlBinary(s) { + if (null === s) return !1; + var o, + i, + u = 0, + _ = s.length, + w = Cr; + for (i = 0; i < _; i++) + if (!((o = w.indexOf(s.charAt(i))) > 64)) { + if (o < 0) return !1; + u += 6; + } + return u % 8 == 0; + }, + construct: function constructYamlBinary(s) { + var o, + i, + u = s.replace(/[\r\n=]/g, ''), + _ = u.length, + w = Cr, + x = 0, + C = []; + for (o = 0; o < _; o++) + o % 4 == 0 && + o && + (C.push((x >> 16) & 255), C.push((x >> 8) & 255), C.push(255 & x)), + (x = (x << 6) | w.indexOf(u.charAt(o))); + return ( + 0 === (i = (_ % 4) * 6) + ? (C.push((x >> 16) & 255), C.push((x >> 8) & 255), C.push(255 & x)) + : 18 === i + ? (C.push((x >> 10) & 255), C.push((x >> 2) & 255)) + : 12 === i && C.push((x >> 4) & 255), + new Uint8Array(C) + ); + }, + predicate: function isBinary(s) { + return '[object Uint8Array]' === Object.prototype.toString.call(s); + }, + represent: function representYamlBinary(s) { + var o, + i, + u = '', + _ = 0, + w = s.length, + x = Cr; + for (o = 0; o < w; o++) + o % 3 == 0 && + o && + ((u += x[(_ >> 18) & 63]), + (u += x[(_ >> 12) & 63]), + (u += x[(_ >> 6) & 63]), + (u += x[63 & _])), + (_ = (_ << 8) + s[o]); + return ( + 0 === (i = w % 3) + ? ((u += x[(_ >> 18) & 63]), + (u += x[(_ >> 12) & 63]), + (u += x[(_ >> 6) & 63]), + (u += x[63 & _])) + : 2 === i + ? ((u += x[(_ >> 10) & 63]), + (u += x[(_ >> 4) & 63]), + (u += x[(_ << 2) & 63]), + (u += x[64])) + : 1 === i && + ((u += x[(_ >> 2) & 63]), + (u += x[(_ << 4) & 63]), + (u += x[64]), + (u += x[64])), + u + ); + } + }), + Ar = Object.prototype.hasOwnProperty, + jr = Object.prototype.toString; + var Ir = new ar('tag:yaml.org,2002:omap', { + kind: 'sequence', + resolve: function resolveYamlOmap(s) { + if (null === s) return !0; + var o, + i, + u, + _, + w, + x = [], + C = s; + for (o = 0, i = C.length; o < i; o += 1) { + if (((u = C[o]), (w = !1), '[object Object]' !== jr.call(u))) return !1; + for (_ in u) + if (Ar.call(u, _)) { + if (w) return !1; + w = !0; + } + if (!w) return !1; + if (-1 !== x.indexOf(_)) return !1; + x.push(_); + } + return !0; + }, + construct: function constructYamlOmap(s) { + return null !== s ? s : []; + } + }), + Pr = Object.prototype.toString; + var Mr = new ar('tag:yaml.org,2002:pairs', { + kind: 'sequence', + resolve: function resolveYamlPairs(s) { + if (null === s) return !0; + var o, + i, + u, + _, + w, + x = s; + for (w = new Array(x.length), o = 0, i = x.length; o < i; o += 1) { + if (((u = x[o]), '[object Object]' !== Pr.call(u))) return !1; + if (1 !== (_ = Object.keys(u)).length) return !1; + w[o] = [_[0], u[_[0]]]; + } + return !0; + }, + construct: function constructYamlPairs(s) { + if (null === s) return []; + var o, + i, + u, + _, + w, + x = s; + for (w = new Array(x.length), o = 0, i = x.length; o < i; o += 1) + (u = x[o]), (_ = Object.keys(u)), (w[o] = [_[0], u[_[0]]]); + return w; + } + }), + Tr = Object.prototype.hasOwnProperty; + var Nr = new ar('tag:yaml.org,2002:set', { + kind: 'mapping', + resolve: function resolveYamlSet(s) { + if (null === s) return !0; + var o, + i = s; + for (o in i) if (Tr.call(i, o) && null !== i[o]) return !1; + return !0; + }, + construct: function constructYamlSet(s) { + return null !== s ? s : {}; + } + }), + Rr = Er.extend({ implicit: [xr, kr], explicit: [Or, Ir, Mr, Nr] }), + Dr = Object.prototype.hasOwnProperty, + Lr = + /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/, + Br = /[\x85\u2028\u2029]/, + Fr = /[,\[\]\{\}]/, + qr = /^(?:!|!!|![a-z\-]+!)$/i, + $r = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i; + function _class(s) { + return Object.prototype.toString.call(s); + } + function is_EOL(s) { + return 10 === s || 13 === s; + } + function is_WHITE_SPACE(s) { + return 9 === s || 32 === s; + } + function is_WS_OR_EOL(s) { + return 9 === s || 32 === s || 10 === s || 13 === s; + } + function is_FLOW_INDICATOR(s) { + return 44 === s || 91 === s || 93 === s || 123 === s || 125 === s; + } + function fromHexCode(s) { + var o; + return 48 <= s && s <= 57 ? s - 48 : 97 <= (o = 32 | s) && o <= 102 ? o - 97 + 10 : -1; + } + function simpleEscapeSequence(s) { + return 48 === s + ? '\0' + : 97 === s + ? '' + : 98 === s + ? '\b' + : 116 === s || 9 === s + ? '\t' + : 110 === s + ? '\n' + : 118 === s + ? '\v' + : 102 === s + ? '\f' + : 114 === s + ? '\r' + : 101 === s + ? '' + : 32 === s + ? ' ' + : 34 === s + ? '"' + : 47 === s + ? '/' + : 92 === s + ? '\\' + : 78 === s + ? '…' + : 95 === s + ? ' ' + : 76 === s + ? '\u2028' + : 80 === s + ? '\u2029' + : ''; + } + function charFromCodepoint(s) { + return s <= 65535 + ? String.fromCharCode(s) + : String.fromCharCode(55296 + ((s - 65536) >> 10), 56320 + ((s - 65536) & 1023)); + } + for (var Vr = new Array(256), Ur = new Array(256), zr = 0; zr < 256; zr++) + (Vr[zr] = simpleEscapeSequence(zr) ? 1 : 0), (Ur[zr] = simpleEscapeSequence(zr)); + function State$1(s, o) { + (this.input = s), + (this.filename = o.filename || null), + (this.schema = o.schema || Rr), + (this.onWarning = o.onWarning || null), + (this.legacy = o.legacy || !1), + (this.json = o.json || !1), + (this.listener = o.listener || null), + (this.implicitTypes = this.schema.compiledImplicit), + (this.typeMap = this.schema.compiledTypeMap), + (this.length = s.length), + (this.position = 0), + (this.line = 0), + (this.lineStart = 0), + (this.lineIndent = 0), + (this.firstTabInLine = -1), + (this.documents = []); + } + function generateError(s, o) { + var i = { + name: s.filename, + buffer: s.input.slice(0, -1), + position: s.position, + line: s.line, + column: s.position - s.lineStart + }; + return (i.snippet = nr(i)), new rr(o, i); + } + function throwError(s, o) { + throw generateError(s, o); + } + function throwWarning(s, o) { + s.onWarning && s.onWarning.call(null, generateError(s, o)); + } + var Wr = { + YAML: function handleYamlDirective(s, o, i) { + var u, _, w; + null !== s.version && throwError(s, 'duplication of %YAML directive'), + 1 !== i.length && throwError(s, 'YAML directive accepts exactly one argument'), + null === (u = /^([0-9]+)\.([0-9]+)$/.exec(i[0])) && + throwError(s, 'ill-formed argument of the YAML directive'), + (_ = parseInt(u[1], 10)), + (w = parseInt(u[2], 10)), + 1 !== _ && throwError(s, 'unacceptable YAML version of the document'), + (s.version = i[0]), + (s.checkLineBreaks = w < 2), + 1 !== w && 2 !== w && throwWarning(s, 'unsupported YAML version of the document'); + }, + TAG: function handleTagDirective(s, o, i) { + var u, _; + 2 !== i.length && throwError(s, 'TAG directive accepts exactly two arguments'), + (u = i[0]), + (_ = i[1]), + qr.test(u) || + throwError(s, 'ill-formed tag handle (first argument) of the TAG directive'), + Dr.call(s.tagMap, u) && + throwError(s, 'there is a previously declared suffix for "' + u + '" tag handle'), + $r.test(_) || + throwError(s, 'ill-formed tag prefix (second argument) of the TAG directive'); + try { + _ = decodeURIComponent(_); + } catch (o) { + throwError(s, 'tag prefix is malformed: ' + _); + } + s.tagMap[u] = _; + } + }; + function captureSegment(s, o, i, u) { + var _, w, x, C; + if (o < i) { + if (((C = s.input.slice(o, i)), u)) + for (_ = 0, w = C.length; _ < w; _ += 1) + 9 === (x = C.charCodeAt(_)) || + (32 <= x && x <= 1114111) || + throwError(s, 'expected valid JSON character'); + else Lr.test(C) && throwError(s, 'the stream contains non-printable characters'); + s.result += C; + } + } + function mergeMappings(s, o, i, u) { + var _, w, x, C; + for ( + tr.isObject(i) || + throwError(s, 'cannot merge mappings; the provided source object is unacceptable'), + x = 0, + C = (_ = Object.keys(i)).length; + x < C; + x += 1 + ) + (w = _[x]), Dr.call(o, w) || ((o[w] = i[w]), (u[w] = !0)); + } + function storeMappingPair(s, o, i, u, _, w, x, C, j) { + var L, B; + if (Array.isArray(_)) + for (L = 0, B = (_ = Array.prototype.slice.call(_)).length; L < B; L += 1) + Array.isArray(_[L]) && throwError(s, 'nested arrays are not supported inside keys'), + 'object' == typeof _ && + '[object Object]' === _class(_[L]) && + (_[L] = '[object Object]'); + if ( + ('object' == typeof _ && '[object Object]' === _class(_) && (_ = '[object Object]'), + (_ = String(_)), + null === o && (o = {}), + 'tag:yaml.org,2002:merge' === u) + ) + if (Array.isArray(w)) + for (L = 0, B = w.length; L < B; L += 1) mergeMappings(s, o, w[L], i); + else mergeMappings(s, o, w, i); + else + s.json || + Dr.call(i, _) || + !Dr.call(o, _) || + ((s.line = x || s.line), + (s.lineStart = C || s.lineStart), + (s.position = j || s.position), + throwError(s, 'duplicated mapping key')), + '__proto__' === _ + ? Object.defineProperty(o, _, { + configurable: !0, + enumerable: !0, + writable: !0, + value: w + }) + : (o[_] = w), + delete i[_]; + return o; + } + function readLineBreak(s) { + var o; + 10 === (o = s.input.charCodeAt(s.position)) + ? s.position++ + : 13 === o + ? (s.position++, 10 === s.input.charCodeAt(s.position) && s.position++) + : throwError(s, 'a line break is expected'), + (s.line += 1), + (s.lineStart = s.position), + (s.firstTabInLine = -1); + } + function skipSeparationSpace(s, o, i) { + for (var u = 0, _ = s.input.charCodeAt(s.position); 0 !== _; ) { + for (; is_WHITE_SPACE(_); ) + 9 === _ && -1 === s.firstTabInLine && (s.firstTabInLine = s.position), + (_ = s.input.charCodeAt(++s.position)); + if (o && 35 === _) + do { + _ = s.input.charCodeAt(++s.position); + } while (10 !== _ && 13 !== _ && 0 !== _); + if (!is_EOL(_)) break; + for ( + readLineBreak(s), _ = s.input.charCodeAt(s.position), u++, s.lineIndent = 0; + 32 === _; + + ) + s.lineIndent++, (_ = s.input.charCodeAt(++s.position)); + } + return ( + -1 !== i && 0 !== u && s.lineIndent < i && throwWarning(s, 'deficient indentation'), u + ); + } + function testDocumentSeparator(s) { + var o, + i = s.position; + return !( + (45 !== (o = s.input.charCodeAt(i)) && 46 !== o) || + o !== s.input.charCodeAt(i + 1) || + o !== s.input.charCodeAt(i + 2) || + ((i += 3), 0 !== (o = s.input.charCodeAt(i)) && !is_WS_OR_EOL(o)) + ); + } + function writeFoldedLines(s, o) { + 1 === o ? (s.result += ' ') : o > 1 && (s.result += tr.repeat('\n', o - 1)); + } + function readBlockSequence(s, o) { + var i, + u, + _ = s.tag, + w = s.anchor, + x = [], + C = !1; + if (-1 !== s.firstTabInLine) return !1; + for ( + null !== s.anchor && (s.anchorMap[s.anchor] = x), u = s.input.charCodeAt(s.position); + 0 !== u && + (-1 !== s.firstTabInLine && + ((s.position = s.firstTabInLine), + throwError(s, 'tab characters must not be used in indentation')), + 45 === u) && + is_WS_OR_EOL(s.input.charCodeAt(s.position + 1)); + + ) + if (((C = !0), s.position++, skipSeparationSpace(s, !0, -1) && s.lineIndent <= o)) + x.push(null), (u = s.input.charCodeAt(s.position)); + else if ( + ((i = s.line), + composeNode(s, o, 3, !1, !0), + x.push(s.result), + skipSeparationSpace(s, !0, -1), + (u = s.input.charCodeAt(s.position)), + (s.line === i || s.lineIndent > o) && 0 !== u) + ) + throwError(s, 'bad indentation of a sequence entry'); + else if (s.lineIndent < o) break; + return !!C && ((s.tag = _), (s.anchor = w), (s.kind = 'sequence'), (s.result = x), !0); + } + function readTagProperty(s) { + var o, + i, + u, + _, + w = !1, + x = !1; + if (33 !== (_ = s.input.charCodeAt(s.position))) return !1; + if ( + (null !== s.tag && throwError(s, 'duplication of a tag property'), + 60 === (_ = s.input.charCodeAt(++s.position)) + ? ((w = !0), (_ = s.input.charCodeAt(++s.position))) + : 33 === _ + ? ((x = !0), (i = '!!'), (_ = s.input.charCodeAt(++s.position))) + : (i = '!'), + (o = s.position), + w) + ) { + do { + _ = s.input.charCodeAt(++s.position); + } while (0 !== _ && 62 !== _); + s.position < s.length + ? ((u = s.input.slice(o, s.position)), (_ = s.input.charCodeAt(++s.position))) + : throwError(s, 'unexpected end of the stream within a verbatim tag'); + } else { + for (; 0 !== _ && !is_WS_OR_EOL(_); ) + 33 === _ && + (x + ? throwError(s, 'tag suffix cannot contain exclamation marks') + : ((i = s.input.slice(o - 1, s.position + 1)), + qr.test(i) || throwError(s, 'named tag handle cannot contain such characters'), + (x = !0), + (o = s.position + 1))), + (_ = s.input.charCodeAt(++s.position)); + (u = s.input.slice(o, s.position)), + Fr.test(u) && throwError(s, 'tag suffix cannot contain flow indicator characters'); + } + u && !$r.test(u) && throwError(s, 'tag name cannot contain such characters: ' + u); + try { + u = decodeURIComponent(u); + } catch (o) { + throwError(s, 'tag name is malformed: ' + u); + } + return ( + w + ? (s.tag = u) + : Dr.call(s.tagMap, i) + ? (s.tag = s.tagMap[i] + u) + : '!' === i + ? (s.tag = '!' + u) + : '!!' === i + ? (s.tag = 'tag:yaml.org,2002:' + u) + : throwError(s, 'undeclared tag handle "' + i + '"'), + !0 + ); + } + function readAnchorProperty(s) { + var o, i; + if (38 !== (i = s.input.charCodeAt(s.position))) return !1; + for ( + null !== s.anchor && throwError(s, 'duplication of an anchor property'), + i = s.input.charCodeAt(++s.position), + o = s.position; + 0 !== i && !is_WS_OR_EOL(i) && !is_FLOW_INDICATOR(i); + + ) + i = s.input.charCodeAt(++s.position); + return ( + s.position === o && + throwError(s, 'name of an anchor node must contain at least one character'), + (s.anchor = s.input.slice(o, s.position)), + !0 + ); + } + function composeNode(s, o, i, u, _) { + var w, + x, + C, + j, + L, + B, + $, + V, + U, + z = 1, + Y = !1, + Z = !1; + if ( + (null !== s.listener && s.listener('open', s), + (s.tag = null), + (s.anchor = null), + (s.kind = null), + (s.result = null), + (w = x = C = 4 === i || 3 === i), + u && + skipSeparationSpace(s, !0, -1) && + ((Y = !0), + s.lineIndent > o + ? (z = 1) + : s.lineIndent === o + ? (z = 0) + : s.lineIndent < o && (z = -1)), + 1 === z) + ) + for (; readTagProperty(s) || readAnchorProperty(s); ) + skipSeparationSpace(s, !0, -1) + ? ((Y = !0), + (C = w), + s.lineIndent > o + ? (z = 1) + : s.lineIndent === o + ? (z = 0) + : s.lineIndent < o && (z = -1)) + : (C = !1); + if ( + (C && (C = Y || _), + (1 !== z && 4 !== i) || + ((V = 1 === i || 2 === i ? o : o + 1), + (U = s.position - s.lineStart), + 1 === z + ? (C && + (readBlockSequence(s, U) || + (function readBlockMapping(s, o, i) { + var u, + _, + w, + x, + C, + j, + L, + B = s.tag, + $ = s.anchor, + V = {}, + U = Object.create(null), + z = null, + Y = null, + Z = null, + ee = !1, + ie = !1; + if (-1 !== s.firstTabInLine) return !1; + for ( + null !== s.anchor && (s.anchorMap[s.anchor] = V), + L = s.input.charCodeAt(s.position); + 0 !== L; + + ) { + if ( + (ee || + -1 === s.firstTabInLine || + ((s.position = s.firstTabInLine), + throwError(s, 'tab characters must not be used in indentation')), + (u = s.input.charCodeAt(s.position + 1)), + (w = s.line), + (63 !== L && 58 !== L) || !is_WS_OR_EOL(u)) + ) { + if ( + ((x = s.line), + (C = s.lineStart), + (j = s.position), + !composeNode(s, i, 2, !1, !0)) + ) + break; + if (s.line === w) { + for (L = s.input.charCodeAt(s.position); is_WHITE_SPACE(L); ) + L = s.input.charCodeAt(++s.position); + if (58 === L) + is_WS_OR_EOL((L = s.input.charCodeAt(++s.position))) || + throwError( + s, + 'a whitespace character is expected after the key-value separator within a block mapping' + ), + ee && + (storeMappingPair(s, V, U, z, Y, null, x, C, j), + (z = Y = Z = null)), + (ie = !0), + (ee = !1), + (_ = !1), + (z = s.tag), + (Y = s.result); + else { + if (!ie) return (s.tag = B), (s.anchor = $), !0; + throwError( + s, + 'can not read an implicit mapping pair; a colon is missed' + ); + } + } else { + if (!ie) return (s.tag = B), (s.anchor = $), !0; + throwError( + s, + 'can not read a block mapping entry; a multiline key may not be an implicit key' + ); + } + } else + 63 === L + ? (ee && + (storeMappingPair(s, V, U, z, Y, null, x, C, j), + (z = Y = Z = null)), + (ie = !0), + (ee = !0), + (_ = !0)) + : ee + ? ((ee = !1), (_ = !0)) + : throwError( + s, + 'incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line' + ), + (s.position += 1), + (L = u); + if ( + ((s.line === w || s.lineIndent > o) && + (ee && ((x = s.line), (C = s.lineStart), (j = s.position)), + composeNode(s, o, 4, !0, _) && (ee ? (Y = s.result) : (Z = s.result)), + ee || + (storeMappingPair(s, V, U, z, Y, Z, x, C, j), (z = Y = Z = null)), + skipSeparationSpace(s, !0, -1), + (L = s.input.charCodeAt(s.position))), + (s.line === w || s.lineIndent > o) && 0 !== L) + ) + throwError(s, 'bad indentation of a mapping entry'); + else if (s.lineIndent < o) break; + } + return ( + ee && storeMappingPair(s, V, U, z, Y, null, x, C, j), + ie && ((s.tag = B), (s.anchor = $), (s.kind = 'mapping'), (s.result = V)), + ie + ); + })(s, U, V))) || + (function readFlowCollection(s, o) { + var i, + u, + _, + w, + x, + C, + j, + L, + B, + $, + V, + U, + z = !0, + Y = s.tag, + Z = s.anchor, + ee = Object.create(null); + if (91 === (U = s.input.charCodeAt(s.position))) (x = 93), (L = !1), (w = []); + else { + if (123 !== U) return !1; + (x = 125), (L = !0), (w = {}); + } + for ( + null !== s.anchor && (s.anchorMap[s.anchor] = w), + U = s.input.charCodeAt(++s.position); + 0 !== U; + + ) { + if ( + (skipSeparationSpace(s, !0, o), (U = s.input.charCodeAt(s.position)) === x) + ) + return ( + s.position++, + (s.tag = Y), + (s.anchor = Z), + (s.kind = L ? 'mapping' : 'sequence'), + (s.result = w), + !0 + ); + z + ? 44 === U && throwError(s, "expected the node content, but found ','") + : throwError(s, 'missed comma between flow collection entries'), + (V = null), + (C = j = !1), + 63 === U && + is_WS_OR_EOL(s.input.charCodeAt(s.position + 1)) && + ((C = j = !0), s.position++, skipSeparationSpace(s, !0, o)), + (i = s.line), + (u = s.lineStart), + (_ = s.position), + composeNode(s, o, 1, !1, !0), + ($ = s.tag), + (B = s.result), + skipSeparationSpace(s, !0, o), + (U = s.input.charCodeAt(s.position)), + (!j && s.line !== i) || + 58 !== U || + ((C = !0), + (U = s.input.charCodeAt(++s.position)), + skipSeparationSpace(s, !0, o), + composeNode(s, o, 1, !1, !0), + (V = s.result)), + L + ? storeMappingPair(s, w, ee, $, B, V, i, u, _) + : C + ? w.push(storeMappingPair(s, null, ee, $, B, V, i, u, _)) + : w.push(B), + skipSeparationSpace(s, !0, o), + 44 === (U = s.input.charCodeAt(s.position)) + ? ((z = !0), (U = s.input.charCodeAt(++s.position))) + : (z = !1); + } + throwError(s, 'unexpected end of the stream within a flow collection'); + })(s, V) + ? (Z = !0) + : ((x && + (function readBlockScalar(s, o) { + var i, + u, + _, + w, + x, + C = 1, + j = !1, + L = !1, + B = o, + $ = 0, + V = !1; + if (124 === (w = s.input.charCodeAt(s.position))) u = !1; + else { + if (62 !== w) return !1; + u = !0; + } + for (s.kind = 'scalar', s.result = ''; 0 !== w; ) + if (43 === (w = s.input.charCodeAt(++s.position)) || 45 === w) + 1 === C + ? (C = 43 === w ? 3 : 2) + : throwError(s, 'repeat of a chomping mode identifier'); + else { + if (!((_ = 48 <= (x = w) && x <= 57 ? x - 48 : -1) >= 0)) break; + 0 === _ + ? throwError( + s, + 'bad explicit indentation width of a block scalar; it cannot be less than one' + ) + : L + ? throwError(s, 'repeat of an indentation width identifier') + : ((B = o + _ - 1), (L = !0)); + } + if (is_WHITE_SPACE(w)) { + do { + w = s.input.charCodeAt(++s.position); + } while (is_WHITE_SPACE(w)); + if (35 === w) + do { + w = s.input.charCodeAt(++s.position); + } while (!is_EOL(w) && 0 !== w); + } + for (; 0 !== w; ) { + for ( + readLineBreak(s), s.lineIndent = 0, w = s.input.charCodeAt(s.position); + (!L || s.lineIndent < B) && 32 === w; + + ) + s.lineIndent++, (w = s.input.charCodeAt(++s.position)); + if ((!L && s.lineIndent > B && (B = s.lineIndent), is_EOL(w))) $++; + else { + if (s.lineIndent < B) { + 3 === C + ? (s.result += tr.repeat('\n', j ? 1 + $ : $)) + : 1 === C && j && (s.result += '\n'); + break; + } + for ( + u + ? is_WHITE_SPACE(w) + ? ((V = !0), (s.result += tr.repeat('\n', j ? 1 + $ : $))) + : V + ? ((V = !1), (s.result += tr.repeat('\n', $ + 1))) + : 0 === $ + ? j && (s.result += ' ') + : (s.result += tr.repeat('\n', $)) + : (s.result += tr.repeat('\n', j ? 1 + $ : $)), + j = !0, + L = !0, + $ = 0, + i = s.position; + !is_EOL(w) && 0 !== w; + + ) + w = s.input.charCodeAt(++s.position); + captureSegment(s, i, s.position, !1); + } + } + return !0; + })(s, V)) || + (function readSingleQuotedScalar(s, o) { + var i, u, _; + if (39 !== (i = s.input.charCodeAt(s.position))) return !1; + for ( + s.kind = 'scalar', s.result = '', s.position++, u = _ = s.position; + 0 !== (i = s.input.charCodeAt(s.position)); + + ) + if (39 === i) { + if ( + (captureSegment(s, u, s.position, !0), + 39 !== (i = s.input.charCodeAt(++s.position))) + ) + return !0; + (u = s.position), s.position++, (_ = s.position); + } else + is_EOL(i) + ? (captureSegment(s, u, _, !0), + writeFoldedLines(s, skipSeparationSpace(s, !1, o)), + (u = _ = s.position)) + : s.position === s.lineStart && testDocumentSeparator(s) + ? throwError( + s, + 'unexpected end of the document within a single quoted scalar' + ) + : (s.position++, (_ = s.position)); + throwError(s, 'unexpected end of the stream within a single quoted scalar'); + })(s, V) || + (function readDoubleQuotedScalar(s, o) { + var i, u, _, w, x, C, j; + if (34 !== (C = s.input.charCodeAt(s.position))) return !1; + for ( + s.kind = 'scalar', s.result = '', s.position++, i = u = s.position; + 0 !== (C = s.input.charCodeAt(s.position)); + + ) { + if (34 === C) return captureSegment(s, i, s.position, !0), s.position++, !0; + if (92 === C) { + if ( + (captureSegment(s, i, s.position, !0), + is_EOL((C = s.input.charCodeAt(++s.position)))) + ) + skipSeparationSpace(s, !1, o); + else if (C < 256 && Vr[C]) (s.result += Ur[C]), s.position++; + else if ( + (x = 120 === (j = C) ? 2 : 117 === j ? 4 : 85 === j ? 8 : 0) > 0 + ) { + for (_ = x, w = 0; _ > 0; _--) + (x = fromHexCode((C = s.input.charCodeAt(++s.position)))) >= 0 + ? (w = (w << 4) + x) + : throwError(s, 'expected hexadecimal character'); + (s.result += charFromCodepoint(w)), s.position++; + } else throwError(s, 'unknown escape sequence'); + i = u = s.position; + } else + is_EOL(C) + ? (captureSegment(s, i, u, !0), + writeFoldedLines(s, skipSeparationSpace(s, !1, o)), + (i = u = s.position)) + : s.position === s.lineStart && testDocumentSeparator(s) + ? throwError( + s, + 'unexpected end of the document within a double quoted scalar' + ) + : (s.position++, (u = s.position)); + } + throwError(s, 'unexpected end of the stream within a double quoted scalar'); + })(s, V) + ? (Z = !0) + : !(function readAlias(s) { + var o, i, u; + if (42 !== (u = s.input.charCodeAt(s.position))) return !1; + for ( + u = s.input.charCodeAt(++s.position), o = s.position; + 0 !== u && !is_WS_OR_EOL(u) && !is_FLOW_INDICATOR(u); + + ) + u = s.input.charCodeAt(++s.position); + return ( + s.position === o && + throwError( + s, + 'name of an alias node must contain at least one character' + ), + (i = s.input.slice(o, s.position)), + Dr.call(s.anchorMap, i) || + throwError(s, 'unidentified alias "' + i + '"'), + (s.result = s.anchorMap[i]), + skipSeparationSpace(s, !0, -1), + !0 + ); + })(s) + ? (function readPlainScalar(s, o, i) { + var u, + _, + w, + x, + C, + j, + L, + B, + $ = s.kind, + V = s.result; + if ( + is_WS_OR_EOL((B = s.input.charCodeAt(s.position))) || + is_FLOW_INDICATOR(B) || + 35 === B || + 38 === B || + 42 === B || + 33 === B || + 124 === B || + 62 === B || + 39 === B || + 34 === B || + 37 === B || + 64 === B || + 96 === B + ) + return !1; + if ( + (63 === B || 45 === B) && + (is_WS_OR_EOL((u = s.input.charCodeAt(s.position + 1))) || + (i && is_FLOW_INDICATOR(u))) + ) + return !1; + for ( + s.kind = 'scalar', s.result = '', _ = w = s.position, x = !1; + 0 !== B; + + ) { + if (58 === B) { + if ( + is_WS_OR_EOL((u = s.input.charCodeAt(s.position + 1))) || + (i && is_FLOW_INDICATOR(u)) + ) + break; + } else if (35 === B) { + if (is_WS_OR_EOL(s.input.charCodeAt(s.position - 1))) break; + } else { + if ( + (s.position === s.lineStart && testDocumentSeparator(s)) || + (i && is_FLOW_INDICATOR(B)) + ) + break; + if (is_EOL(B)) { + if ( + ((C = s.line), + (j = s.lineStart), + (L = s.lineIndent), + skipSeparationSpace(s, !1, -1), + s.lineIndent >= o) + ) { + (x = !0), (B = s.input.charCodeAt(s.position)); + continue; + } + (s.position = w), + (s.line = C), + (s.lineStart = j), + (s.lineIndent = L); + break; + } + } + x && + (captureSegment(s, _, w, !1), + writeFoldedLines(s, s.line - C), + (_ = w = s.position), + (x = !1)), + is_WHITE_SPACE(B) || (w = s.position + 1), + (B = s.input.charCodeAt(++s.position)); + } + return ( + captureSegment(s, _, w, !1), + !!s.result || ((s.kind = $), (s.result = V), !1) + ); + })(s, V, 1 === i) && ((Z = !0), null === s.tag && (s.tag = '?')) + : ((Z = !0), + (null === s.tag && null === s.anchor) || + throwError(s, 'alias node should not have any properties')), + null !== s.anchor && (s.anchorMap[s.anchor] = s.result)) + : 0 === z && (Z = C && readBlockSequence(s, U))), + null === s.tag) + ) + null !== s.anchor && (s.anchorMap[s.anchor] = s.result); + else if ('?' === s.tag) { + for ( + null !== s.result && + 'scalar' !== s.kind && + throwError( + s, + 'unacceptable node kind for ! tag; it should be "scalar", not "' + s.kind + '"' + ), + j = 0, + L = s.implicitTypes.length; + j < L; + j += 1 + ) + if (($ = s.implicitTypes[j]).resolve(s.result)) { + (s.result = $.construct(s.result)), + (s.tag = $.tag), + null !== s.anchor && (s.anchorMap[s.anchor] = s.result); + break; + } + } else if ('!' !== s.tag) { + if (Dr.call(s.typeMap[s.kind || 'fallback'], s.tag)) + $ = s.typeMap[s.kind || 'fallback'][s.tag]; + else + for ( + $ = null, j = 0, L = (B = s.typeMap.multi[s.kind || 'fallback']).length; + j < L; + j += 1 + ) + if (s.tag.slice(0, B[j].tag.length) === B[j].tag) { + $ = B[j]; + break; + } + $ || throwError(s, 'unknown tag !<' + s.tag + '>'), + null !== s.result && + $.kind !== s.kind && + throwError( + s, + 'unacceptable node kind for !<' + + s.tag + + '> tag; it should be "' + + $.kind + + '", not "' + + s.kind + + '"' + ), + $.resolve(s.result, s.tag) + ? ((s.result = $.construct(s.result, s.tag)), + null !== s.anchor && (s.anchorMap[s.anchor] = s.result)) + : throwError(s, 'cannot resolve a node with !<' + s.tag + '> explicit tag'); + } + return ( + null !== s.listener && s.listener('close', s), null !== s.tag || null !== s.anchor || Z + ); + } + function readDocument(s) { + var o, + i, + u, + _, + w = s.position, + x = !1; + for ( + s.version = null, + s.checkLineBreaks = s.legacy, + s.tagMap = Object.create(null), + s.anchorMap = Object.create(null); + 0 !== (_ = s.input.charCodeAt(s.position)) && + (skipSeparationSpace(s, !0, -1), + (_ = s.input.charCodeAt(s.position)), + !(s.lineIndent > 0 || 37 !== _)); + + ) { + for ( + x = !0, _ = s.input.charCodeAt(++s.position), o = s.position; + 0 !== _ && !is_WS_OR_EOL(_); + + ) + _ = s.input.charCodeAt(++s.position); + for ( + u = [], + (i = s.input.slice(o, s.position)).length < 1 && + throwError(s, 'directive name must not be less than one character in length'); + 0 !== _; + + ) { + for (; is_WHITE_SPACE(_); ) _ = s.input.charCodeAt(++s.position); + if (35 === _) { + do { + _ = s.input.charCodeAt(++s.position); + } while (0 !== _ && !is_EOL(_)); + break; + } + if (is_EOL(_)) break; + for (o = s.position; 0 !== _ && !is_WS_OR_EOL(_); ) + _ = s.input.charCodeAt(++s.position); + u.push(s.input.slice(o, s.position)); + } + 0 !== _ && readLineBreak(s), + Dr.call(Wr, i) + ? Wr[i](s, i, u) + : throwWarning(s, 'unknown document directive "' + i + '"'); + } + skipSeparationSpace(s, !0, -1), + 0 === s.lineIndent && + 45 === s.input.charCodeAt(s.position) && + 45 === s.input.charCodeAt(s.position + 1) && + 45 === s.input.charCodeAt(s.position + 2) + ? ((s.position += 3), skipSeparationSpace(s, !0, -1)) + : x && throwError(s, 'directives end mark is expected'), + composeNode(s, s.lineIndent - 1, 4, !1, !0), + skipSeparationSpace(s, !0, -1), + s.checkLineBreaks && + Br.test(s.input.slice(w, s.position)) && + throwWarning(s, 'non-ASCII line breaks are interpreted as content'), + s.documents.push(s.result), + s.position === s.lineStart && testDocumentSeparator(s) + ? 46 === s.input.charCodeAt(s.position) && + ((s.position += 3), skipSeparationSpace(s, !0, -1)) + : s.position < s.length - 1 && + throwError(s, 'end of the stream or a document separator is expected'); + } + function loadDocuments(s, o) { + (o = o || {}), + 0 !== (s = String(s)).length && + (10 !== s.charCodeAt(s.length - 1) && + 13 !== s.charCodeAt(s.length - 1) && + (s += '\n'), + 65279 === s.charCodeAt(0) && (s = s.slice(1))); + var i = new State$1(s, o), + u = s.indexOf('\0'); + for ( + -1 !== u && ((i.position = u), throwError(i, 'null byte is not allowed in input')), + i.input += '\0'; + 32 === i.input.charCodeAt(i.position); + + ) + (i.lineIndent += 1), (i.position += 1); + for (; i.position < i.length - 1; ) readDocument(i); + return i.documents; + } + var Kr = { + loadAll: function loadAll$1(s, o, i) { + null !== o && 'object' == typeof o && void 0 === i && ((i = o), (o = null)); + var u = loadDocuments(s, i); + if ('function' != typeof o) return u; + for (var _ = 0, w = u.length; _ < w; _ += 1) o(u[_]); + }, + load: function load$1(s, o) { + var i = loadDocuments(s, o); + if (0 !== i.length) { + if (1 === i.length) return i[0]; + throw new rr('expected a single document in the stream, but found more'); + } + } + }, + Hr = Object.prototype.toString, + Jr = Object.prototype.hasOwnProperty, + Gr = 65279, + Yr = { + 0: '\\0', + 7: '\\a', + 8: '\\b', + 9: '\\t', + 10: '\\n', + 11: '\\v', + 12: '\\f', + 13: '\\r', + 27: '\\e', + 34: '\\"', + 92: '\\\\', + 133: '\\N', + 160: '\\_', + 8232: '\\L', + 8233: '\\P' + }, + Xr = [ + 'y', + 'Y', + 'yes', + 'Yes', + 'YES', + 'on', + 'On', + 'ON', + 'n', + 'N', + 'no', + 'No', + 'NO', + 'off', + 'Off', + 'OFF' + ], + Zr = /^[-+]?[0-9_]+(?::[0-9_]+)+(?:\.[0-9_]*)?$/; + function encodeHex(s) { + var o, i, u; + if (((o = s.toString(16).toUpperCase()), s <= 255)) (i = 'x'), (u = 2); + else if (s <= 65535) (i = 'u'), (u = 4); + else { + if (!(s <= 4294967295)) + throw new rr('code point within a string may not be greater than 0xFFFFFFFF'); + (i = 'U'), (u = 8); + } + return '\\' + i + tr.repeat('0', u - o.length) + o; + } + function State(s) { + (this.schema = s.schema || Rr), + (this.indent = Math.max(1, s.indent || 2)), + (this.noArrayIndent = s.noArrayIndent || !1), + (this.skipInvalid = s.skipInvalid || !1), + (this.flowLevel = tr.isNothing(s.flowLevel) ? -1 : s.flowLevel), + (this.styleMap = (function compileStyleMap(s, o) { + var i, u, _, w, x, C, j; + if (null === o) return {}; + for (i = {}, _ = 0, w = (u = Object.keys(o)).length; _ < w; _ += 1) + (x = u[_]), + (C = String(o[x])), + '!!' === x.slice(0, 2) && (x = 'tag:yaml.org,2002:' + x.slice(2)), + (j = s.compiledTypeMap.fallback[x]) && + Jr.call(j.styleAliases, C) && + (C = j.styleAliases[C]), + (i[x] = C); + return i; + })(this.schema, s.styles || null)), + (this.sortKeys = s.sortKeys || !1), + (this.lineWidth = s.lineWidth || 80), + (this.noRefs = s.noRefs || !1), + (this.noCompatMode = s.noCompatMode || !1), + (this.condenseFlow = s.condenseFlow || !1), + (this.quotingType = '"' === s.quotingType ? 2 : 1), + (this.forceQuotes = s.forceQuotes || !1), + (this.replacer = 'function' == typeof s.replacer ? s.replacer : null), + (this.implicitTypes = this.schema.compiledImplicit), + (this.explicitTypes = this.schema.compiledExplicit), + (this.tag = null), + (this.result = ''), + (this.duplicates = []), + (this.usedDuplicates = null); + } + function indentString(s, o) { + for (var i, u = tr.repeat(' ', o), _ = 0, w = -1, x = '', C = s.length; _ < C; ) + -1 === (w = s.indexOf('\n', _)) + ? ((i = s.slice(_)), (_ = C)) + : ((i = s.slice(_, w + 1)), (_ = w + 1)), + i.length && '\n' !== i && (x += u), + (x += i); + return x; + } + function generateNextLine(s, o) { + return '\n' + tr.repeat(' ', s.indent * o); + } + function isWhitespace(s) { + return 32 === s || 9 === s; + } + function isPrintable(s) { + return ( + (32 <= s && s <= 126) || + (161 <= s && s <= 55295 && 8232 !== s && 8233 !== s) || + (57344 <= s && s <= 65533 && s !== Gr) || + (65536 <= s && s <= 1114111) + ); + } + function isNsCharOrWhitespace(s) { + return isPrintable(s) && s !== Gr && 13 !== s && 10 !== s; + } + function isPlainSafe(s, o, i) { + var u = isNsCharOrWhitespace(s), + _ = u && !isWhitespace(s); + return ( + ((i ? u : u && 44 !== s && 91 !== s && 93 !== s && 123 !== s && 125 !== s) && + 35 !== s && + !(58 === o && !_)) || + (isNsCharOrWhitespace(o) && !isWhitespace(o) && 35 === s) || + (58 === o && _) + ); + } + function codePointAt(s, o) { + var i, + u = s.charCodeAt(o); + return u >= 55296 && + u <= 56319 && + o + 1 < s.length && + (i = s.charCodeAt(o + 1)) >= 56320 && + i <= 57343 + ? 1024 * (u - 55296) + i - 56320 + 65536 + : u; + } + function needIndentIndicator(s) { + return /^\n* /.test(s); + } + function chooseScalarStyle(s, o, i, u, _, w, x, C) { + var j, + L = 0, + B = null, + $ = !1, + V = !1, + U = -1 !== u, + z = -1, + Y = + (function isPlainSafeFirst(s) { + return ( + isPrintable(s) && + s !== Gr && + !isWhitespace(s) && + 45 !== s && + 63 !== s && + 58 !== s && + 44 !== s && + 91 !== s && + 93 !== s && + 123 !== s && + 125 !== s && + 35 !== s && + 38 !== s && + 42 !== s && + 33 !== s && + 124 !== s && + 61 !== s && + 62 !== s && + 39 !== s && + 34 !== s && + 37 !== s && + 64 !== s && + 96 !== s + ); + })(codePointAt(s, 0)) && + (function isPlainSafeLast(s) { + return !isWhitespace(s) && 58 !== s; + })(codePointAt(s, s.length - 1)); + if (o || x) + for (j = 0; j < s.length; L >= 65536 ? (j += 2) : j++) { + if (!isPrintable((L = codePointAt(s, j)))) return 5; + (Y = Y && isPlainSafe(L, B, C)), (B = L); + } + else { + for (j = 0; j < s.length; L >= 65536 ? (j += 2) : j++) { + if (10 === (L = codePointAt(s, j))) + ($ = !0), U && ((V = V || (j - z - 1 > u && ' ' !== s[z + 1])), (z = j)); + else if (!isPrintable(L)) return 5; + (Y = Y && isPlainSafe(L, B, C)), (B = L); + } + V = V || (U && j - z - 1 > u && ' ' !== s[z + 1]); + } + return $ || V + ? i > 9 && needIndentIndicator(s) + ? 5 + : x + ? 2 === w + ? 5 + : 2 + : V + ? 4 + : 3 + : !Y || x || _(s) + ? 2 === w + ? 5 + : 2 + : 1; + } + function writeScalar(s, o, i, u, _) { + s.dump = (function () { + if (0 === o.length) return 2 === s.quotingType ? '""' : "''"; + if (!s.noCompatMode && (-1 !== Xr.indexOf(o) || Zr.test(o))) + return 2 === s.quotingType ? '"' + o + '"' : "'" + o + "'"; + var w = s.indent * Math.max(1, i), + x = -1 === s.lineWidth ? -1 : Math.max(Math.min(s.lineWidth, 40), s.lineWidth - w), + C = u || (s.flowLevel > -1 && i >= s.flowLevel); + switch ( + chooseScalarStyle( + o, + C, + s.indent, + x, + function testAmbiguity(o) { + return (function testImplicitResolving(s, o) { + var i, u; + for (i = 0, u = s.implicitTypes.length; i < u; i += 1) + if (s.implicitTypes[i].resolve(o)) return !0; + return !1; + })(s, o); + }, + s.quotingType, + s.forceQuotes && !u, + _ + ) + ) { + case 1: + return o; + case 2: + return "'" + o.replace(/'/g, "''") + "'"; + case 3: + return '|' + blockHeader(o, s.indent) + dropEndingNewline(indentString(o, w)); + case 4: + return ( + '>' + + blockHeader(o, s.indent) + + dropEndingNewline( + indentString( + (function foldString(s, o) { + var i, + u, + _ = /(\n+)([^\n]*)/g, + w = + ((C = s.indexOf('\n')), + (C = -1 !== C ? C : s.length), + (_.lastIndex = C), + foldLine(s.slice(0, C), o)), + x = '\n' === s[0] || ' ' === s[0]; + var C; + for (; (u = _.exec(s)); ) { + var j = u[1], + L = u[2]; + (i = ' ' === L[0]), + (w += j + (x || i || '' === L ? '' : '\n') + foldLine(L, o)), + (x = i); + } + return w; + })(o, x), + w + ) + ) + ); + case 5: + return ( + '"' + + (function escapeString(s) { + for (var o, i = '', u = 0, _ = 0; _ < s.length; u >= 65536 ? (_ += 2) : _++) + (u = codePointAt(s, _)), + !(o = Yr[u]) && isPrintable(u) + ? ((i += s[_]), u >= 65536 && (i += s[_ + 1])) + : (i += o || encodeHex(u)); + return i; + })(o) + + '"' + ); + default: + throw new rr('impossible error: invalid scalar style'); + } + })(); + } + function blockHeader(s, o) { + var i = needIndentIndicator(s) ? String(o) : '', + u = '\n' === s[s.length - 1]; + return i + (u && ('\n' === s[s.length - 2] || '\n' === s) ? '+' : u ? '' : '-') + '\n'; + } + function dropEndingNewline(s) { + return '\n' === s[s.length - 1] ? s.slice(0, -1) : s; + } + function foldLine(s, o) { + if ('' === s || ' ' === s[0]) return s; + for (var i, u, _ = / [^ ]/g, w = 0, x = 0, C = 0, j = ''; (i = _.exec(s)); ) + (C = i.index) - w > o && + ((u = x > w ? x : C), (j += '\n' + s.slice(w, u)), (w = u + 1)), + (x = C); + return ( + (j += '\n'), + s.length - w > o && x > w + ? (j += s.slice(w, x) + '\n' + s.slice(x + 1)) + : (j += s.slice(w)), + j.slice(1) + ); + } + function writeBlockSequence(s, o, i, u) { + var _, + w, + x, + C = '', + j = s.tag; + for (_ = 0, w = i.length; _ < w; _ += 1) + (x = i[_]), + s.replacer && (x = s.replacer.call(i, String(_), x)), + (writeNode(s, o + 1, x, !0, !0, !1, !0) || + (void 0 === x && writeNode(s, o + 1, null, !0, !0, !1, !0))) && + ((u && '' === C) || (C += generateNextLine(s, o)), + s.dump && 10 === s.dump.charCodeAt(0) ? (C += '-') : (C += '- '), + (C += s.dump)); + (s.tag = j), (s.dump = C || '[]'); + } + function detectType(s, o, i) { + var u, _, w, x, C, j; + for (w = 0, x = (_ = i ? s.explicitTypes : s.implicitTypes).length; w < x; w += 1) + if ( + ((C = _[w]).instanceOf || C.predicate) && + (!C.instanceOf || ('object' == typeof o && o instanceof C.instanceOf)) && + (!C.predicate || C.predicate(o)) + ) { + if ( + (i + ? C.multi && C.representName + ? (s.tag = C.representName(o)) + : (s.tag = C.tag) + : (s.tag = '?'), + C.represent) + ) { + if ( + ((j = s.styleMap[C.tag] || C.defaultStyle), + '[object Function]' === Hr.call(C.represent)) + ) + u = C.represent(o, j); + else { + if (!Jr.call(C.represent, j)) + throw new rr('!<' + C.tag + '> tag resolver accepts not "' + j + '" style'); + u = C.represent[j](o, j); + } + s.dump = u; + } + return !0; + } + return !1; + } + function writeNode(s, o, i, u, _, w, x) { + (s.tag = null), (s.dump = i), detectType(s, i, !1) || detectType(s, i, !0); + var C, + j = Hr.call(s.dump), + L = u; + u && (u = s.flowLevel < 0 || s.flowLevel > o); + var B, + $, + V = '[object Object]' === j || '[object Array]' === j; + if ( + (V && ($ = -1 !== (B = s.duplicates.indexOf(i))), + ((null !== s.tag && '?' !== s.tag) || $ || (2 !== s.indent && o > 0)) && (_ = !1), + $ && s.usedDuplicates[B]) + ) + s.dump = '*ref_' + B; + else { + if ( + (V && $ && !s.usedDuplicates[B] && (s.usedDuplicates[B] = !0), + '[object Object]' === j) + ) + u && 0 !== Object.keys(s.dump).length + ? (!(function writeBlockMapping(s, o, i, u) { + var _, + w, + x, + C, + j, + L, + B = '', + $ = s.tag, + V = Object.keys(i); + if (!0 === s.sortKeys) V.sort(); + else if ('function' == typeof s.sortKeys) V.sort(s.sortKeys); + else if (s.sortKeys) throw new rr('sortKeys must be a boolean or a function'); + for (_ = 0, w = V.length; _ < w; _ += 1) + (L = ''), + (u && '' === B) || (L += generateNextLine(s, o)), + (C = i[(x = V[_])]), + s.replacer && (C = s.replacer.call(i, x, C)), + writeNode(s, o + 1, x, !0, !0, !0) && + ((j = + (null !== s.tag && '?' !== s.tag) || + (s.dump && s.dump.length > 1024)) && + (s.dump && 10 === s.dump.charCodeAt(0) ? (L += '?') : (L += '? ')), + (L += s.dump), + j && (L += generateNextLine(s, o)), + writeNode(s, o + 1, C, !0, j) && + (s.dump && 10 === s.dump.charCodeAt(0) ? (L += ':') : (L += ': '), + (B += L += s.dump))); + (s.tag = $), (s.dump = B || '{}'); + })(s, o, s.dump, _), + $ && (s.dump = '&ref_' + B + s.dump)) + : (!(function writeFlowMapping(s, o, i) { + var u, + _, + w, + x, + C, + j = '', + L = s.tag, + B = Object.keys(i); + for (u = 0, _ = B.length; u < _; u += 1) + (C = ''), + '' !== j && (C += ', '), + s.condenseFlow && (C += '"'), + (x = i[(w = B[u])]), + s.replacer && (x = s.replacer.call(i, w, x)), + writeNode(s, o, w, !1, !1) && + (s.dump.length > 1024 && (C += '? '), + (C += + s.dump + + (s.condenseFlow ? '"' : '') + + ':' + + (s.condenseFlow ? '' : ' ')), + writeNode(s, o, x, !1, !1) && (j += C += s.dump)); + (s.tag = L), (s.dump = '{' + j + '}'); + })(s, o, s.dump), + $ && (s.dump = '&ref_' + B + ' ' + s.dump)); + else if ('[object Array]' === j) + u && 0 !== s.dump.length + ? (s.noArrayIndent && !x && o > 0 + ? writeBlockSequence(s, o - 1, s.dump, _) + : writeBlockSequence(s, o, s.dump, _), + $ && (s.dump = '&ref_' + B + s.dump)) + : (!(function writeFlowSequence(s, o, i) { + var u, + _, + w, + x = '', + C = s.tag; + for (u = 0, _ = i.length; u < _; u += 1) + (w = i[u]), + s.replacer && (w = s.replacer.call(i, String(u), w)), + (writeNode(s, o, w, !1, !1) || + (void 0 === w && writeNode(s, o, null, !1, !1))) && + ('' !== x && (x += ',' + (s.condenseFlow ? '' : ' ')), (x += s.dump)); + (s.tag = C), (s.dump = '[' + x + ']'); + })(s, o, s.dump), + $ && (s.dump = '&ref_' + B + ' ' + s.dump)); + else { + if ('[object String]' !== j) { + if ('[object Undefined]' === j) return !1; + if (s.skipInvalid) return !1; + throw new rr('unacceptable kind of an object to dump ' + j); + } + '?' !== s.tag && writeScalar(s, s.dump, o, w, L); + } + null !== s.tag && + '?' !== s.tag && + ((C = encodeURI('!' === s.tag[0] ? s.tag.slice(1) : s.tag).replace(/!/g, '%21')), + (C = + '!' === s.tag[0] + ? '!' + C + : 'tag:yaml.org,2002:' === C.slice(0, 18) + ? '!!' + C.slice(18) + : '!<' + C + '>'), + (s.dump = C + ' ' + s.dump)); + } + return !0; + } + function getDuplicateReferences(s, o) { + var i, + u, + _ = [], + w = []; + for (inspectNode(s, _, w), i = 0, u = w.length; i < u; i += 1) o.duplicates.push(_[w[i]]); + o.usedDuplicates = new Array(u); + } + function inspectNode(s, o, i) { + var u, _, w; + if (null !== s && 'object' == typeof s) + if (-1 !== (_ = o.indexOf(s))) -1 === i.indexOf(_) && i.push(_); + else if ((o.push(s), Array.isArray(s))) + for (_ = 0, w = s.length; _ < w; _ += 1) inspectNode(s[_], o, i); + else + for (_ = 0, w = (u = Object.keys(s)).length; _ < w; _ += 1) + inspectNode(s[u[_]], o, i); + } + var Qr = function dump$1(s, o) { + var i = new State((o = o || {})); + i.noRefs || getDuplicateReferences(s, i); + var u = s; + return ( + i.replacer && (u = i.replacer.call({ '': u }, '', u)), + writeNode(i, 0, u, !0, !0) ? i.dump + '\n' : '' + ); + }; + function renamed(s, o) { + return function () { + throw new Error( + 'Function yaml.' + + s + + ' is removed in js-yaml 4. Use yaml.' + + o + + ' instead, which is now safe by default.' + ); + }; + } + var en = ar, + tn = lr, + rn = dr, + nn = _r, + sn = Er, + on = Rr, + an = Kr.load, + ln = Kr.loadAll, + cn = { dump: Qr }.dump, + un = rr, + pn = { + binary: Or, + float: br, + map: pr, + null: fr, + pairs: Mr, + set: Nr, + timestamp: xr, + bool: mr, + int: gr, + merge: kr, + omap: Ir, + seq: ur, + str: cr + }, + hn = renamed('safeLoad', 'load'), + dn = renamed('safeLoadAll', 'loadAll'), + fn = renamed('safeDump', 'dump'); + const mn = { + Type: en, + Schema: tn, + FAILSAFE_SCHEMA: rn, + JSON_SCHEMA: nn, + CORE_SCHEMA: sn, + DEFAULT_SCHEMA: on, + load: an, + loadAll: ln, + dump: cn, + YAMLException: un, + types: pn, + safeLoad: hn, + safeLoadAll: dn, + safeDump: fn + }, + gn = 'configs_update', + yn = 'configs_toggle'; + function update(s, o) { + return { type: gn, payload: { [s]: o } }; + } + function toggle(s) { + return { type: yn, payload: s }; + } + const actions_loaded = () => () => {}, + downloadConfig = (s) => (o) => { + const { + fn: { fetch: i } + } = o; + return i(s); + }, + getConfigByUrl = (s, o) => (i) => { + const { specActions: u, configsActions: _ } = i; + if (s) return _.downloadConfig(s).then(next, next); + function next(_) { + _ instanceof Error || _.status >= 400 + ? (u.updateLoadingStatus('failedConfig'), + u.updateLoadingStatus('failedConfig'), + u.updateUrl(''), + console.error(_.statusText + ' ' + s.url), + o(null)) + : o( + ((s, o) => { + try { + return mn.load(s); + } catch (s) { + return o && o.errActions.newThrownErr(new Error(s)), {}; + } + })(_.text, i) + ); + } + }, + get = (s, o) => s.getIn(Array.isArray(o) ? o : [o]), + vn = { + [gn]: (s, o) => s.merge((0, qe.fromJS)(o.payload)), + [yn]: (s, o) => { + const i = o.payload, + u = s.get(i); + return s.set(i, !u); + } + }; + function configsPlugin() { + return { statePlugins: { configs: { reducers: vn, actions: u, selectors: w } } }; + } + const setHash = (s) => + s ? history.pushState(null, null, `#${s}`) : (window.location.hash = ''); + var bn = __webpack_require__(86215), + _n = __webpack_require__.n(bn); + const En = 'layout_scroll_to', + wn = 'layout_clear_scroll'; + const Sn = { + fn: { + getScrollParent: function getScrollParent(s, o) { + const i = document.documentElement; + let u = getComputedStyle(s); + const _ = 'absolute' === u.position, + w = o ? /(auto|scroll|hidden)/ : /(auto|scroll)/; + if ('fixed' === u.position) return i; + for (let o = s; (o = o.parentElement); ) + if ( + ((u = getComputedStyle(o)), + (!_ || 'static' !== u.position) && w.test(u.overflow + u.overflowY + u.overflowX)) + ) + return o; + return i; + } + }, + statePlugins: { + layout: { + actions: { + scrollToElement: (s, o) => (i) => { + try { + (o = o || i.fn.getScrollParent(s)), _n().createScroller(o).to(s); + } catch (s) { + console.error(s); + } + }, + scrollTo: (s) => ({ type: En, payload: Array.isArray(s) ? s : [s] }), + clearScrollTo: () => ({ type: wn }), + readyToScroll: (s, o) => (i) => { + const u = i.layoutSelectors.getScrollToKey(); + $e().is(u, (0, qe.fromJS)(s)) && + (i.layoutActions.scrollToElement(o), i.layoutActions.clearScrollTo()); + }, + parseDeepLinkHash: + (s) => + ({ layoutActions: o, layoutSelectors: i, getConfigs: u }) => { + if (u().deepLinking && s) { + let u = s.slice(1); + '!' === u[0] && (u = u.slice(1)), '/' === u[0] && (u = u.slice(1)); + const _ = u.split('/').map((s) => s || ''), + w = i.isShownKeyFromUrlHashArray(_), + [x, C = '', j = ''] = w; + if ('operations' === x) { + const s = i.isShownKeyFromUrlHashArray([C]); + C.indexOf('_') > -1 && + (console.warn( + 'Warning: escaping deep link whitespace with `_` will be unsupported in v4.0, use `%20` instead.' + ), + o.show( + s.map((s) => s.replace(/_/g, ' ')), + !0 + )), + o.show(s, !0); + } + (C.indexOf('_') > -1 || j.indexOf('_') > -1) && + (console.warn( + 'Warning: escaping deep link whitespace with `_` will be unsupported in v4.0, use `%20` instead.' + ), + o.show( + w.map((s) => s.replace(/_/g, ' ')), + !0 + )), + o.show(w, !0), + o.scrollTo(w); + } + } + }, + selectors: { + getScrollToKey: (s) => s.get('scrollToKey'), + isShownKeyFromUrlHashArray(s, o) { + const [i, u] = o; + return u ? ['operations', i, u] : i ? ['operations-tag', i] : []; + }, + urlHashArrayFromIsShownKey(s, o) { + let [i, u, _] = o; + return 'operations' == i ? [u, _] : 'operations-tag' == i ? [u] : []; + } + }, + reducers: { + [En]: (s, o) => s.set('scrollToKey', $e().fromJS(o.payload)), + [wn]: (s) => s.delete('scrollToKey') + }, + wrapActions: { + show: + (s, { getConfigs: o, layoutSelectors: i }) => + (...u) => { + if ((s(...u), o().deepLinking)) + try { + let [s, o] = u; + s = Array.isArray(s) ? s : [s]; + const _ = i.urlHashArrayFromIsShownKey(s); + if (!_.length) return; + const [w, x] = _; + if (!o) return setHash('/'); + 2 === _.length + ? setHash( + createDeepLinkPath( + `/${encodeURIComponent(w)}/${encodeURIComponent(x)}` + ) + ) + : 1 === _.length && + setHash(createDeepLinkPath(`/${encodeURIComponent(w)}`)); + } catch (s) { + console.error(s); + } + } + } + } + } + }; + var xn = __webpack_require__(2209), + kn = __webpack_require__.n(xn); + const operation_wrapper = (s, o) => + class OperationWrapper extends Pe.Component { + onLoad = (s) => { + const { operation: i } = this.props, + { tag: u, operationId: _ } = i.toObject(); + let { isShownKey: w } = i.toObject(); + (w = w || ['operations', u, _]), o.layoutActions.readyToScroll(w, s); + }; + render() { + return Pe.createElement( + 'span', + { ref: this.onLoad }, + Pe.createElement(s, this.props) + ); + } + }, + operation_tag_wrapper = (s, o) => + class OperationTagWrapper extends Pe.Component { + onLoad = (s) => { + const { tag: i } = this.props, + u = ['operations-tag', i]; + o.layoutActions.readyToScroll(u, s); + }; + render() { + return Pe.createElement( + 'span', + { ref: this.onLoad }, + Pe.createElement(s, this.props) + ); + } + }; + function deep_linking() { + return [ + Sn, + { + statePlugins: { + configs: { + wrapActions: { + loaded: + (s, o) => + (...i) => { + s(...i); + const u = decodeURIComponent(window.location.hash); + o.layoutActions.parseDeepLinkHash(u); + } + } + } + }, + wrapComponents: { operation: operation_wrapper, OperationTag: operation_tag_wrapper } + } + ]; + } + var Cn = __webpack_require__(40860), + On = __webpack_require__.n(Cn); + function transform(s) { + return s.map((s) => { + let o = 'is not of a type(s)', + i = s.get('message').indexOf(o); + if (i > -1) { + let o = s + .get('message') + .slice(i + 19) + .split(','); + return s.set( + 'message', + s.get('message').slice(0, i) + + (function makeNewMessage(s) { + return s.reduce( + (s, o, i, u) => + i === u.length - 1 && u.length > 1 + ? s + 'or ' + o + : u[i + 1] && u.length > 2 + ? s + o + ', ' + : u[i + 1] + ? s + o + ' ' + : s + o, + 'should be a' + ); + })(o) + ); + } + return s; + }); + } + var An = __webpack_require__(58156), + jn = __webpack_require__.n(An); + function parameter_oneof_transform(s, { jsSpec: o }) { + return s; + } + const In = [x, C]; + function transformErrors(s) { + let o = { jsSpec: {} }, + i = On()( + In, + (s, i) => { + try { + return i.transform(s, o).filter((s) => !!s); + } catch (o) { + return console.error('Transformer error:', o), s; + } + }, + s + ); + return i.filter((s) => !!s).map((s) => (!s.get('line') && s.get('path'), s)); + } + let Pn = { line: 0, level: 'error', message: 'Unknown error' }; + const Mn = Ut( + (s) => s, + (s) => s.get('errors', (0, qe.List)()) + ), + Tn = Ut(Mn, (s) => s.last()); + function err(o) { + return { + statePlugins: { + err: { + reducers: { + [et]: (s, { payload: o }) => { + let i = Object.assign(Pn, o, { type: 'thrown' }); + return s + .update('errors', (s) => (s || (0, qe.List)()).push((0, qe.fromJS)(i))) + .update('errors', (s) => transformErrors(s)); + }, + [tt]: (s, { payload: o }) => ( + (o = o.map((s) => (0, qe.fromJS)(Object.assign(Pn, s, { type: 'thrown' })))), + s + .update('errors', (s) => (s || (0, qe.List)()).concat((0, qe.fromJS)(o))) + .update('errors', (s) => transformErrors(s)) + ), + [rt]: (s, { payload: o }) => { + let i = (0, qe.fromJS)(o); + return ( + (i = i.set('type', 'spec')), + s + .update('errors', (s) => + (s || (0, qe.List)()).push((0, qe.fromJS)(i)).sortBy((s) => s.get('line')) + ) + .update('errors', (s) => transformErrors(s)) + ); + }, + [nt]: (s, { payload: o }) => ( + (o = o.map((s) => (0, qe.fromJS)(Object.assign(Pn, s, { type: 'spec' })))), + s + .update('errors', (s) => (s || (0, qe.List)()).concat((0, qe.fromJS)(o))) + .update('errors', (s) => transformErrors(s)) + ), + [st]: (s, { payload: o }) => { + let i = (0, qe.fromJS)(Object.assign({}, o)); + return ( + (i = i.set('type', 'auth')), + s + .update('errors', (s) => (s || (0, qe.List)()).push((0, qe.fromJS)(i))) + .update('errors', (s) => transformErrors(s)) + ); + }, + [ot]: (s, { payload: o }) => { + if (!o || !s.get('errors')) return s; + let i = s.get('errors').filter((s) => + s.keySeq().every((i) => { + const u = s.get(i), + _ = o[i]; + return !_ || u !== _; + }) + ); + return s.merge({ errors: i }); + }, + [it]: (s, { payload: o }) => { + if (!o || 'function' != typeof o) return s; + let i = s.get('errors').filter((s) => o(s)); + return s.merge({ errors: i }); + } + }, + actions: s, + selectors: j + } + } + }; + } + function opsFilter(s, o) { + return s.filter((s, i) => -1 !== i.indexOf(o)); + } + function filter() { + return { fn: { opsFilter } }; + } + var Nn = __webpack_require__(7666), + Rn = __webpack_require__.n(Nn); + const arrow_up = ({ className: s = null, width: o = 20, height: i = 20, ...u }) => + Pe.createElement( + 'svg', + Rn()( + { + xmlns: 'http://www.w3.org/2000/svg', + viewBox: '0 0 20 20', + className: s, + width: o, + height: i, + 'aria-hidden': 'true', + focusable: 'false' + }, + u + ), + Pe.createElement('path', { + d: 'M 17.418 14.908 C 17.69 15.176 18.127 15.176 18.397 14.908 C 18.667 14.64 18.668 14.207 18.397 13.939 L 10.489 6.109 C 10.219 5.841 9.782 5.841 9.51 6.109 L 1.602 13.939 C 1.332 14.207 1.332 14.64 1.602 14.908 C 1.873 15.176 2.311 15.176 2.581 14.908 L 10 7.767 L 17.418 14.908 Z' + }) + ), + arrow_down = ({ className: s = null, width: o = 20, height: i = 20, ...u }) => + Pe.createElement( + 'svg', + Rn()( + { + xmlns: 'http://www.w3.org/2000/svg', + viewBox: '0 0 20 20', + className: s, + width: o, + height: i, + 'aria-hidden': 'true', + focusable: 'false' + }, + u + ), + Pe.createElement('path', { + d: 'M17.418 6.109c.272-.268.709-.268.979 0s.271.701 0 .969l-7.908 7.83c-.27.268-.707.268-.979 0l-7.908-7.83c-.27-.268-.27-.701 0-.969.271-.268.709-.268.979 0L10 13.25l7.418-7.141z' + }) + ), + arrow = ({ className: s = null, width: o = 20, height: i = 20, ...u }) => + Pe.createElement( + 'svg', + Rn()( + { + xmlns: 'http://www.w3.org/2000/svg', + viewBox: '0 0 20 20', + className: s, + width: o, + height: i, + 'aria-hidden': 'true', + focusable: 'false' + }, + u + ), + Pe.createElement('path', { + d: 'M13.25 10L6.109 2.58c-.268-.27-.268-.707 0-.979.268-.27.701-.27.969 0l7.83 7.908c.268.271.268.709 0 .979l-7.83 7.908c-.268.271-.701.27-.969 0-.268-.269-.268-.707 0-.979L13.25 10z' + }) + ), + components_close = ({ className: s = null, width: o = 20, height: i = 20, ...u }) => + Pe.createElement( + 'svg', + Rn()( + { + xmlns: 'http://www.w3.org/2000/svg', + viewBox: '0 0 20 20', + className: s, + width: o, + height: i, + 'aria-hidden': 'true', + focusable: 'false' + }, + u + ), + Pe.createElement('path', { + d: 'M14.348 14.849c-.469.469-1.229.469-1.697 0L10 11.819l-2.651 3.029c-.469.469-1.229.469-1.697 0-.469-.469-.469-1.229 0-1.697l2.758-3.15-2.759-3.152c-.469-.469-.469-1.228 0-1.697.469-.469 1.228-.469 1.697 0L10 8.183l2.651-3.031c.469-.469 1.228-.469 1.697 0 .469.469.469 1.229 0 1.697l-2.758 3.152 2.758 3.15c.469.469.469 1.229 0 1.698z' + }) + ), + copy = ({ className: s = null, width: o = 15, height: i = 16, ...u }) => + Pe.createElement( + 'svg', + Rn()( + { + xmlns: 'http://www.w3.org/2000/svg', + viewBox: '0 0 15 16', + className: s, + width: o, + height: i, + 'aria-hidden': 'true', + focusable: 'false' + }, + u + ), + Pe.createElement( + 'g', + { transform: 'translate(2, -1)' }, + Pe.createElement('path', { + fill: '#ffffff', + fillRule: 'evenodd', + d: 'M2 13h4v1H2v-1zm5-6H2v1h5V7zm2 3V8l-3 3 3 3v-2h5v-2H9zM4.5 9H2v1h2.5V9zM2 12h2.5v-1H2v1zm9 1h1v2c-.02.28-.11.52-.3.7-.19.18-.42.28-.7.3H1c-.55 0-1-.45-1-1V4c0-.55.45-1 1-1h3c0-1.11.89-2 2-2 1.11 0 2 .89 2 2h3c.55 0 1 .45 1 1v5h-1V6H1v9h10v-2zM2 5h8c0-.55-.45-1-1-1H8c-.55 0-1-.45-1-1s-.45-1-1-1-1 .45-1 1-.45 1-1 1H3c-.55 0-1 .45-1 1z' + }) + ) + ), + lock = ({ className: s = null, width: o = 20, height: i = 20, ...u }) => + Pe.createElement( + 'svg', + Rn()( + { + xmlns: 'http://www.w3.org/2000/svg', + viewBox: '0 0 20 20', + className: s, + width: o, + height: i, + 'aria-hidden': 'true', + focusable: 'false' + }, + u + ), + Pe.createElement('path', { + d: 'M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8zM12 8H8V5.199C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8z' + }) + ), + unlock = ({ className: s = null, width: o = 20, height: i = 20, ...u }) => + Pe.createElement( + 'svg', + Rn()( + { + xmlns: 'http://www.w3.org/2000/svg', + viewBox: '0 0 20 20', + className: s, + width: o, + height: i, + 'aria-hidden': 'true', + focusable: 'false' + }, + u + ), + Pe.createElement('path', { + d: 'M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V6h2v-.801C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8z' + }) + ), + icons = () => ({ + components: { + ArrowUpIcon: arrow_up, + ArrowDownIcon: arrow_down, + ArrowIcon: arrow, + CloseIcon: components_close, + CopyIcon: copy, + LockIcon: lock, + UnlockIcon: unlock + } + }), + Dn = 'layout_update_layout', + Ln = 'layout_update_filter', + Bn = 'layout_update_mode', + Fn = 'layout_show'; + function updateLayout(s) { + return { type: Dn, payload: s }; + } + function updateFilter(s) { + return { type: Ln, payload: s }; + } + function actions_show(s, o = !0) { + return (s = normalizeArray(s)), { type: Fn, payload: { thing: s, shown: o } }; + } + function changeMode(s, o = '') { + return (s = normalizeArray(s)), { type: Bn, payload: { thing: s, mode: o } }; + } + const qn = { + [Dn]: (s, o) => s.set('layout', o.payload), + [Ln]: (s, o) => s.set('filter', o.payload), + [Fn]: (s, o) => { + const i = o.payload.shown, + u = (0, qe.fromJS)(o.payload.thing); + return s.update('shown', (0, qe.fromJS)({}), (s) => s.set(u, i)); + }, + [Bn]: (s, o) => { + let i = o.payload.thing, + u = o.payload.mode; + return s.setIn(['modes'].concat(i), (u || '') + ''); + } + }, + current = (s) => s.get('layout'), + currentFilter = (s) => s.get('filter'), + isShown = (s, o, i) => ( + (o = normalizeArray(o)), s.get('shown', (0, qe.fromJS)({})).get((0, qe.fromJS)(o), i) + ), + whatMode = (s, o, i = '') => ((o = normalizeArray(o)), s.getIn(['modes', ...o], i)), + $n = Ut( + (s) => s, + (s) => !isShown(s, 'editor') + ), + taggedOperations = + (s, o) => + (i, ...u) => { + let _ = s(i, ...u); + const { fn: w, layoutSelectors: x, getConfigs: C } = o.getSystem(), + j = C(), + { maxDisplayedTags: L } = j; + let B = x.currentFilter(); + return B && !0 !== B && (_ = w.opsFilter(_, B)), L >= 0 && (_ = _.slice(0, L)), _; + }; + function plugins_layout() { + return { + statePlugins: { + layout: { reducers: qn, actions: L, selectors: B }, + spec: { wrapSelectors: $ } + } + }; + } + function logs({ configs: s }) { + const o = { debug: 0, info: 1, log: 2, warn: 3, error: 4 }, + getLevel = (s) => o[s] || -1; + let { logLevel: i } = s, + u = getLevel(i); + function log(s, ...o) { + getLevel(s) >= u && console[s](...o); + } + return ( + (log.warn = log.bind(null, 'warn')), + (log.error = log.bind(null, 'error')), + (log.info = log.bind(null, 'info')), + (log.debug = log.bind(null, 'debug')), + { rootInjects: { log } } + ); + } + let Vn = !1; + function on_complete() { + return { + statePlugins: { + spec: { + wrapActions: { + updateSpec: + (s) => + (...o) => ((Vn = !0), s(...o)), + updateJsonSpec: + (s, o) => + (...i) => { + const u = o.getConfigs().onComplete; + return Vn && 'function' == typeof u && (setTimeout(u, 0), (Vn = !1)), s(...i); + } + } + } + } + }; + } + const extractKey = (s) => { + const o = '_**[]'; + return s.indexOf(o) < 0 ? s : s.split(o)[0].trim(); + }, + escapeShell = (s) => + '-d ' === s || /^[_\/-]/g.test(s) ? s : "'" + s.replace(/'/g, "'\\''") + "'", + escapeCMD = (s) => + '-d ' === + (s = s + .replace(/\^/g, '^^') + .replace(/\\"/g, '\\\\"') + .replace(/"/g, '""') + .replace(/\n/g, '^\n')) + ? s.replace(/-d /g, '-d ^\n') + : /^[_\/-]/g.test(s) + ? s + : '"' + s + '"', + escapePowershell = (s) => { + if ('-d ' === s) return s; + if (/\n/.test(s)) { + return `@"\n${s.replace(/`/g, '``').replace(/\$/g, '`$')}\n"@`; + } + if (!/^[_\/-]/.test(s)) { + return `'${s.replace(/'/g, "''")}'`; + } + return s; + }; + const curlify = (s, o, i, u = '') => { + let _ = !1, + w = ''; + const addWords = (...s) => (w += ' ' + s.map(o).join(' ')), + addWordsWithoutLeadingSpace = (...s) => (w += s.map(o).join(' ')), + addNewLine = () => (w += ` ${i}`), + addIndent = (s = 1) => (w += ' '.repeat(s)); + let x = s.get('headers'); + w += 'curl' + u; + const C = s.get('curlOptions'); + if ( + (qe.List.isList(C) && !C.isEmpty() && addWords(...s.get('curlOptions')), + addWords('-X', s.get('method')), + addNewLine(), + addIndent(), + addWordsWithoutLeadingSpace(`${s.get('url')}`), + x && x.size) + ) + for (let o of s.get('headers').entries()) { + addNewLine(), addIndent(); + let [s, i] = o; + addWordsWithoutLeadingSpace('-H', `${s}: ${i}`), + (_ = _ || (/^content-type$/i.test(s) && /^multipart\/form-data$/i.test(i))); + } + const j = s.get('body'); + if (j) + if (_ && ['POST', 'PUT', 'PATCH'].includes(s.get('method'))) + for (let [s, o] of j.entrySeq()) { + let i = extractKey(s); + addNewLine(), + addIndent(), + addWordsWithoutLeadingSpace('-F'), + o instanceof at.File && 'string' == typeof o.valueOf() + ? addWords(`${i}=${o.data}${o.type ? `;type=${o.type}` : ''}`) + : o instanceof at.File + ? addWords(`${i}=@${o.name}${o.type ? `;type=${o.type}` : ''}`) + : addWords(`${i}=${o}`); + } + else if (j instanceof at.File) + addNewLine(), + addIndent(), + addWordsWithoutLeadingSpace(`--data-binary '@${j.name}'`); + else { + addNewLine(), addIndent(), addWordsWithoutLeadingSpace('-d '); + let o = j; + qe.Map.isMap(o) + ? addWordsWithoutLeadingSpace( + (function getStringBodyOfMap(s) { + let o = []; + for (let [i, u] of s.get('body').entrySeq()) { + let s = extractKey(i); + u instanceof at.File + ? o.push( + ` "${s}": {\n "name": "${u.name}"${u.type ? `,\n "type": "${u.type}"` : ''}\n }` + ) + : o.push( + ` "${s}": ${JSON.stringify(u, null, 2).replace(/(\r\n|\r|\n)/g, '\n ')}` + ); + } + return `{\n${o.join(',\n')}\n}`; + })(s) + ) + : ('string' != typeof o && (o = JSON.stringify(o)), + addWordsWithoutLeadingSpace(o)); + } + else + j || + 'POST' !== s.get('method') || + (addNewLine(), addIndent(), addWordsWithoutLeadingSpace("-d ''")); + return w; + }, + requestSnippetGenerator_curl_powershell = (s) => + curlify(s, escapePowershell, '`\n', '.exe'), + requestSnippetGenerator_curl_bash = (s) => curlify(s, escapeShell, '\\\n'), + requestSnippetGenerator_curl_cmd = (s) => curlify(s, escapeCMD, '^\n'), + request_snippets_selectors_state = (s) => s || (0, qe.Map)(), + Un = Ut(request_snippets_selectors_state, (s) => { + const o = s.get('languages'), + i = s.get('generators', (0, qe.Map)()); + return !o || o.isEmpty() ? i : i.filter((s, i) => o.includes(i)); + }), + getSnippetGenerators = + (s) => + ({ fn: o }) => + Un(s) + .map((s, i) => { + const u = ((s) => o[`requestSnippetGenerator_${s}`])(i); + return 'function' != typeof u ? null : s.set('fn', u); + }) + .filter((s) => s), + zn = Ut(request_snippets_selectors_state, (s) => s.get('activeLanguage')), + Wn = Ut(request_snippets_selectors_state, (s) => s.get('defaultExpanded')); + var Kn = __webpack_require__(46942), + Hn = __webpack_require__.n(Kn), + Jn = __webpack_require__(59399); + const Gn = { + cursor: 'pointer', + lineHeight: 1, + display: 'inline-flex', + backgroundColor: 'rgb(250, 250, 250)', + paddingBottom: '0', + paddingTop: '0', + border: '1px solid rgb(51, 51, 51)', + borderRadius: '4px 4px 0 0', + boxShadow: 'none', + borderBottom: 'none' + }, + Yn = { + cursor: 'pointer', + lineHeight: 1, + display: 'inline-flex', + backgroundColor: 'rgb(51, 51, 51)', + boxShadow: 'none', + border: '1px solid rgb(51, 51, 51)', + paddingBottom: '0', + paddingTop: '0', + borderRadius: '4px 4px 0 0', + marginTop: '-5px', + marginRight: '-5px', + marginLeft: '-5px', + zIndex: '9999', + borderBottom: 'none' + }, + request_snippets = ({ request: s, requestSnippetsSelectors: o, getComponent: i }) => { + const u = (0, Pe.useRef)(null), + _ = i('ArrowUpIcon'), + w = i('ArrowDownIcon'), + x = i('SyntaxHighlighter', !0), + [C, j] = (0, Pe.useState)(o.getSnippetGenerators()?.keySeq().first()), + [L, B] = (0, Pe.useState)(o?.getDefaultExpanded()), + $ = o.getSnippetGenerators(), + V = $.get(C), + U = V.get('fn')(s), + handleSetIsExpanded = () => { + B(!L); + }, + handleGetBtnStyle = (s) => (s === C ? Yn : Gn), + handlePreventYScrollingBeyondElement = (s) => { + const { target: o, deltaY: i } = s, + { scrollHeight: u, offsetHeight: _, scrollTop: w } = o; + u > _ && ((0 === w && i < 0) || (_ + w >= u && i > 0)) && s.preventDefault(); + }; + return ( + (0, Pe.useEffect)(() => {}, []), + (0, Pe.useEffect)(() => { + const s = Array.from(u.current.childNodes).filter( + (s) => !!s.nodeType && s.classList?.contains('curl-command') + ); + return ( + s.forEach((s) => + s.addEventListener('mousewheel', handlePreventYScrollingBeyondElement, { + passive: !1 + }) + ), + () => { + s.forEach((s) => + s.removeEventListener('mousewheel', handlePreventYScrollingBeyondElement) + ); + } + ); + }, [s]), + Pe.createElement( + 'div', + { className: 'request-snippets', ref: u }, + Pe.createElement( + 'div', + { + style: { + width: '100%', + display: 'flex', + justifyContent: 'flex-start', + alignItems: 'center', + marginBottom: '15px' + } + }, + Pe.createElement( + 'h4', + { onClick: () => handleSetIsExpanded(), style: { cursor: 'pointer' } }, + 'Snippets' + ), + Pe.createElement( + 'button', + { + onClick: () => handleSetIsExpanded(), + style: { border: 'none', background: 'none' }, + title: L ? 'Collapse operation' : 'Expand operation' + }, + L + ? Pe.createElement(w, { className: 'arrow', width: '10', height: '10' }) + : Pe.createElement(_, { className: 'arrow', width: '10', height: '10' }) + ) + ), + L && + Pe.createElement( + 'div', + { className: 'curl-command' }, + Pe.createElement( + 'div', + { + style: { + paddingLeft: '15px', + paddingRight: '10px', + width: '100%', + display: 'flex' + } + }, + $.entrySeq().map(([s, o]) => + Pe.createElement( + 'div', + { + className: Hn()('btn', { active: s === C }), + style: handleGetBtnStyle(s), + key: s, + onClick: () => + ((s) => { + C !== s && j(s); + })(s) + }, + Pe.createElement( + 'h4', + { style: s === C ? { color: 'white' } : {} }, + o.get('title') + ) + ) + ) + ), + Pe.createElement( + 'div', + { className: 'copy-to-clipboard' }, + Pe.createElement( + Jn.CopyToClipboard, + { text: U }, + Pe.createElement('button', null) + ) + ), + Pe.createElement( + 'div', + null, + Pe.createElement( + x, + { + language: V.get('syntax'), + className: 'curl microlight', + renderPlainText: ({ children: s, PlainTextViewer: o }) => + Pe.createElement(o, { className: 'curl' }, s) + }, + U + ) + ) + ) + ) + ); + }, + plugins_request_snippets = () => ({ + components: { RequestSnippets: request_snippets }, + fn: V, + statePlugins: { requestSnippets: { selectors: U } } + }); + class ModelCollapse extends Pe.Component { + static defaultProps = { + collapsedContent: '{...}', + expanded: !1, + title: null, + onToggle: () => {}, + hideSelfOnExpand: !1, + specPath: $e().List([]) + }; + constructor(s, o) { + super(s, o); + let { expanded: i, collapsedContent: u } = this.props; + this.state = { + expanded: i, + collapsedContent: u || ModelCollapse.defaultProps.collapsedContent + }; + } + componentDidMount() { + const { hideSelfOnExpand: s, expanded: o, modelName: i } = this.props; + s && o && this.props.onToggle(i, o); + } + UNSAFE_componentWillReceiveProps(s) { + this.props.expanded !== s.expanded && this.setState({ expanded: s.expanded }); + } + toggleCollapsed = () => { + this.props.onToggle && this.props.onToggle(this.props.modelName, !this.state.expanded), + this.setState({ expanded: !this.state.expanded }); + }; + onLoad = (s) => { + if (s && this.props.layoutSelectors) { + const o = this.props.layoutSelectors.getScrollToKey(); + $e().is(o, this.props.specPath) && this.toggleCollapsed(), + this.props.layoutActions.readyToScroll(this.props.specPath, s.parentElement); + } + }; + render() { + const { title: s, classes: o } = this.props; + return this.state.expanded && this.props.hideSelfOnExpand + ? Pe.createElement('span', { className: o || '' }, this.props.children) + : Pe.createElement( + 'span', + { className: o || '', ref: this.onLoad }, + Pe.createElement( + 'button', + { + 'aria-expanded': this.state.expanded, + className: 'model-box-control', + onClick: this.toggleCollapsed + }, + s && Pe.createElement('span', { className: 'pointer' }, s), + Pe.createElement('span', { + className: 'model-toggle' + (this.state.expanded ? '' : ' collapsed') + }), + !this.state.expanded && + Pe.createElement('span', null, this.state.collapsedContent) + ), + this.state.expanded && this.props.children + ); + } + } + const useTabs = ({ initialTab: s, isExecute: o, schema: i, example: u }) => { + const _ = (0, Pe.useMemo)(() => ({ example: 'example', model: 'model' }), []), + w = (0, Pe.useMemo)(() => Object.keys(_), [_]).includes(s) && i && !o ? s : _.example, + x = ((s) => { + const o = (0, Pe.useRef)(); + return ( + (0, Pe.useEffect)(() => { + o.current = s; + }), + o.current + ); + })(o), + [C, j] = (0, Pe.useState)(w), + L = (0, Pe.useCallback)((s) => { + j(s.target.dataset.name); + }, []); + return ( + (0, Pe.useEffect)(() => { + x && !o && u && j(_.example); + }, [x, o, u]), + { activeTab: C, onTabChange: L, tabs: _ } + ); + }, + model_example = ({ + schema: s, + example: o, + isExecute: i = !1, + specPath: u, + includeWriteOnly: _ = !1, + includeReadOnly: w = !1, + getComponent: x, + getConfigs: C, + specSelectors: j + }) => { + const { defaultModelRendering: L, defaultModelExpandDepth: B } = C(), + $ = x('ModelWrapper'), + V = x('HighlightCode', !0), + U = St()(5).toString('base64'), + z = St()(5).toString('base64'), + Y = St()(5).toString('base64'), + Z = St()(5).toString('base64'), + ee = j.isOAS3(), + { + activeTab: ie, + tabs: ae, + onTabChange: le + } = useTabs({ initialTab: L, isExecute: i, schema: s, example: o }); + return Pe.createElement( + 'div', + { className: 'model-example' }, + Pe.createElement( + 'ul', + { className: 'tab', role: 'tablist' }, + Pe.createElement( + 'li', + { + className: Hn()('tabitem', { active: ie === ae.example }), + role: 'presentation' + }, + Pe.createElement( + 'button', + { + 'aria-controls': z, + 'aria-selected': ie === ae.example, + className: 'tablinks', + 'data-name': 'example', + id: U, + onClick: le, + role: 'tab' + }, + i ? 'Edit Value' : 'Example Value' + ) + ), + s && + Pe.createElement( + 'li', + { + className: Hn()('tabitem', { active: ie === ae.model }), + role: 'presentation' + }, + Pe.createElement( + 'button', + { + 'aria-controls': Z, + 'aria-selected': ie === ae.model, + className: Hn()('tablinks', { inactive: i }), + 'data-name': 'model', + id: Y, + onClick: le, + role: 'tab' + }, + ee ? 'Schema' : 'Model' + ) + ) + ), + ie === ae.example && + Pe.createElement( + 'div', + { + 'aria-hidden': ie !== ae.example, + 'aria-labelledby': U, + 'data-name': 'examplePanel', + id: z, + role: 'tabpanel', + tabIndex: '0' + }, + o || Pe.createElement(V, null, '(no example available') + ), + ie === ae.model && + Pe.createElement( + 'div', + { + 'aria-hidden': ie === ae.example, + 'aria-labelledby': Y, + 'data-name': 'modelPanel', + id: Z, + role: 'tabpanel', + tabIndex: '0' + }, + Pe.createElement($, { + schema: s, + getComponent: x, + getConfigs: C, + specSelectors: j, + expandDepth: B, + specPath: u, + includeReadOnly: w, + includeWriteOnly: _ + }) + ) + ); + }; + class ModelWrapper extends Pe.Component { + onToggle = (s, o) => { + this.props.layoutActions && this.props.layoutActions.show(this.props.fullPath, o); + }; + render() { + let { getComponent: s, getConfigs: o } = this.props; + const i = s('Model'); + let u; + return ( + this.props.layoutSelectors && + (u = this.props.layoutSelectors.isShown(this.props.fullPath)), + Pe.createElement( + 'div', + { className: 'model-box' }, + Pe.createElement( + i, + Rn()({}, this.props, { + getConfigs: o, + expanded: u, + depth: 1, + onToggle: this.onToggle, + expandDepth: this.props.expandDepth || 0 + }) + ) + ) + ); + } + } + function _typeof(s) { + return ( + (_typeof = + 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator + ? function (s) { + return typeof s; + } + : function (s) { + return s && + 'function' == typeof Symbol && + s.constructor === Symbol && + s !== Symbol.prototype + ? 'symbol' + : typeof s; + }), + _typeof(s) + ); + } + function _defineProperties(s, o) { + for (var i = 0; i < o.length; i++) { + var u = o[i]; + (u.enumerable = u.enumerable || !1), + (u.configurable = !0), + 'value' in u && (u.writable = !0), + Object.defineProperty(s, u.key, u); + } + } + function _defineProperty(s, o, i) { + return ( + o in s + ? Object.defineProperty(s, o, { + value: i, + enumerable: !0, + configurable: !0, + writable: !0 + }) + : (s[o] = i), + s + ); + } + function ownKeys(s, o) { + var i = Object.keys(s); + if (Object.getOwnPropertySymbols) { + var u = Object.getOwnPropertySymbols(s); + o && + (u = u.filter(function (o) { + return Object.getOwnPropertyDescriptor(s, o).enumerable; + })), + i.push.apply(i, u); + } + return i; + } + function _getPrototypeOf(s) { + return ( + (_getPrototypeOf = Object.setPrototypeOf + ? Object.getPrototypeOf + : function _getPrototypeOf(s) { + return s.__proto__ || Object.getPrototypeOf(s); + }), + _getPrototypeOf(s) + ); + } + function _setPrototypeOf(s, o) { + return ( + (_setPrototypeOf = + Object.setPrototypeOf || + function _setPrototypeOf(s, o) { + return (s.__proto__ = o), s; + }), + _setPrototypeOf(s, o) + ); + } + function _possibleConstructorReturn(s, o) { + return !o || ('object' != typeof o && 'function' != typeof o) + ? (function _assertThisInitialized(s) { + if (void 0 === s) + throw new ReferenceError( + "this hasn't been initialised - super() hasn't been called" + ); + return s; + })(s) + : o; + } + var Xn = {}; + function react_immutable_pure_component_es_get(s, o, i) { + return (function isInvalid(s) { + return null == s; + })(s) + ? i + : (function isMapLike(s) { + return ( + null !== s && + 'object' === _typeof(s) && + 'function' == typeof s.get && + 'function' == typeof s.has + ); + })(s) + ? s.has(o) + ? s.get(o) + : i + : hasOwnProperty.call(s, o) + ? s[o] + : i; + } + function getIn(s, o, i) { + for (var u = 0; u !== o.length; ) + if ((s = react_immutable_pure_component_es_get(s, o[u++], Xn)) === Xn) return i; + return s; + } + function check(s) { + var o = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, + i = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, + u = (function createChecker(s, o) { + return function (i) { + if ('string' == typeof i) return (0, qe.is)(o[i], s[i]); + if (Array.isArray(i)) return (0, qe.is)(getIn(o, i), getIn(s, i)); + throw new TypeError('Invalid key: expected Array or string: ' + i); + }; + })(o, i), + _ = + s || + Object.keys( + (function _objectSpread2(s) { + for (var o = 1; o < arguments.length; o++) { + var i = null != arguments[o] ? arguments[o] : {}; + o % 2 + ? ownKeys(i, !0).forEach(function (o) { + _defineProperty(s, o, i[o]); + }) + : Object.getOwnPropertyDescriptors + ? Object.defineProperties(s, Object.getOwnPropertyDescriptors(i)) + : ownKeys(i).forEach(function (o) { + Object.defineProperty(s, o, Object.getOwnPropertyDescriptor(i, o)); + }); + } + return s; + })({}, i, {}, o) + ); + return _.every(u); + } + const Zn = (function (s) { + function ImmutablePureComponent() { + return ( + (function _classCallCheck(s, o) { + if (!(s instanceof o)) throw new TypeError('Cannot call a class as a function'); + })(this, ImmutablePureComponent), + _possibleConstructorReturn( + this, + _getPrototypeOf(ImmutablePureComponent).apply(this, arguments) + ) + ); + } + return ( + (function _inherits(s, o) { + if ('function' != typeof o && null !== o) + throw new TypeError('Super expression must either be null or a function'); + (s.prototype = Object.create(o && o.prototype, { + constructor: { value: s, writable: !0, configurable: !0 } + })), + o && _setPrototypeOf(s, o); + })(ImmutablePureComponent, s), + (function _createClass(s, o, i) { + return o && _defineProperties(s.prototype, o), i && _defineProperties(s, i), s; + })(ImmutablePureComponent, [ + { + key: 'shouldComponentUpdate', + value: function shouldComponentUpdate(s) { + var o = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}; + return ( + !check(this.updateOnProps, this.props, s, 'updateOnProps') || + !check(this.updateOnStates, this.state, o, 'updateOnStates') + ); + } + } + ]), + ImmutablePureComponent + ); + })(Pe.Component); + var Qn, + es = __webpack_require__(5556), + ts = __webpack_require__.n(es); + function _extends() { + return ( + (_extends = Object.assign + ? Object.assign.bind() + : function (s) { + for (var o = 1; o < arguments.length; o++) { + var i = arguments[o]; + for (var u in i) ({}).hasOwnProperty.call(i, u) && (s[u] = i[u]); + } + return s; + }), + _extends.apply(null, arguments) + ); + } + const rolling_load = (s) => + Pe.createElement( + 'svg', + _extends( + { + xmlns: 'http://www.w3.org/2000/svg', + width: 200, + height: 200, + className: 'rolling-load_svg__lds-rolling', + preserveAspectRatio: 'xMidYMid', + style: { + backgroundImage: 'none', + backgroundPosition: 'initial initial', + backgroundRepeat: 'initial initial' + }, + viewBox: '0 0 100 100' + }, + s + ), + Qn || + (Qn = Pe.createElement( + 'circle', + { + cx: 50, + cy: 50, + r: 35, + fill: 'none', + stroke: '#555', + strokeDasharray: '164.93361431346415 56.97787143782138', + strokeWidth: 10 + }, + Pe.createElement('animateTransform', { + attributeName: 'transform', + begin: '0s', + calcMode: 'linear', + dur: '1s', + keyTimes: '0;1', + repeatCount: 'indefinite', + type: 'rotate', + values: '0 50 50;360 50 50' + }) + )) + ), + decodeRefName = (s) => { + const o = s.replace(/~1/g, '/').replace(/~0/g, '~'); + try { + return decodeURIComponent(o); + } catch { + return o; + } + }; + class Model extends Zn { + static propTypes = { + schema: kn().map.isRequired, + getComponent: ts().func.isRequired, + getConfigs: ts().func.isRequired, + specSelectors: ts().object.isRequired, + name: ts().string, + displayName: ts().string, + isRef: ts().bool, + required: ts().bool, + expandDepth: ts().number, + depth: ts().number, + specPath: kn().list.isRequired, + includeReadOnly: ts().bool, + includeWriteOnly: ts().bool + }; + getModelName = (s) => + -1 !== s.indexOf('#/definitions/') + ? decodeRefName(s.replace(/^.*#\/definitions\//, '')) + : -1 !== s.indexOf('#/components/schemas/') + ? decodeRefName(s.replace(/^.*#\/components\/schemas\//, '')) + : void 0; + getRefSchema = (s) => { + let { specSelectors: o } = this.props; + return o.findDefinition(s); + }; + render() { + let { + getComponent: s, + getConfigs: o, + specSelectors: i, + schema: u, + required: _, + name: w, + isRef: x, + specPath: C, + displayName: j, + includeReadOnly: L, + includeWriteOnly: B + } = this.props; + const $ = s('ObjectModel'), + V = s('ArrayModel'), + U = s('PrimitiveModel'); + let z = 'object', + Y = u && u.get('$$ref'), + Z = u && u.get('$ref'); + if ((!w && Y && (w = this.getModelName(Y)), Z)) { + const s = this.getModelName(Z), + o = this.getRefSchema(s); + qe.Map.isMap(o) + ? ((u = o.mergeDeep(u)), Y || ((u = u.set('$$ref', Z)), (Y = Z))) + : qe.Map.isMap(u) && 1 === u.size && ((u = null), (w = Z)); + } + if (!u) + return Pe.createElement( + 'span', + { className: 'model model-title' }, + Pe.createElement('span', { className: 'model-title__text' }, j || w), + !Z && Pe.createElement(rolling_load, { height: '20px', width: '20px' }) + ); + const ee = i.isOAS3() && u.get('deprecated'); + switch (((x = void 0 !== x ? x : !!Y), (z = (u && u.get('type')) || z), z)) { + case 'object': + return Pe.createElement( + $, + Rn()({ className: 'object' }, this.props, { + specPath: C, + getConfigs: o, + schema: u, + name: w, + deprecated: ee, + isRef: x, + includeReadOnly: L, + includeWriteOnly: B + }) + ); + case 'array': + return Pe.createElement( + V, + Rn()({ className: 'array' }, this.props, { + getConfigs: o, + schema: u, + name: w, + deprecated: ee, + required: _, + includeReadOnly: L, + includeWriteOnly: B + }) + ); + default: + return Pe.createElement( + U, + Rn()({}, this.props, { + getComponent: s, + getConfigs: o, + schema: u, + name: w, + deprecated: ee, + required: _ + }) + ); + } + } + } + class Models extends Pe.Component { + getSchemaBasePath = () => + this.props.specSelectors.isOAS3() ? ['components', 'schemas'] : ['definitions']; + getCollapsedContent = () => ' '; + handleToggle = (s, o) => { + const { layoutActions: i } = this.props; + i.show([...this.getSchemaBasePath(), s], o), + o && this.props.specActions.requestResolvedSubtree([...this.getSchemaBasePath(), s]); + }; + onLoadModels = (s) => { + s && this.props.layoutActions.readyToScroll(this.getSchemaBasePath(), s); + }; + onLoadModel = (s) => { + if (s) { + const o = s.getAttribute('data-name'); + this.props.layoutActions.readyToScroll([...this.getSchemaBasePath(), o], s); + } + }; + render() { + let { + specSelectors: s, + getComponent: o, + layoutSelectors: i, + layoutActions: u, + getConfigs: _ + } = this.props, + w = s.definitions(), + { docExpansion: x, defaultModelsExpandDepth: C } = _(); + if (!w.size || C < 0) return null; + const j = this.getSchemaBasePath(); + let L = i.isShown(j, C > 0 && 'none' !== x); + const B = s.isOAS3(), + $ = o('ModelWrapper'), + V = o('Collapse'), + U = o('ModelCollapse'), + z = o('JumpToPath', !0), + Y = o('ArrowUpIcon'), + Z = o('ArrowDownIcon'); + return Pe.createElement( + 'section', + { className: L ? 'models is-open' : 'models', ref: this.onLoadModels }, + Pe.createElement( + 'h4', + null, + Pe.createElement( + 'button', + { 'aria-expanded': L, className: 'models-control', onClick: () => u.show(j, !L) }, + Pe.createElement('span', null, B ? 'Schemas' : 'Models'), + L ? Pe.createElement(Y, null) : Pe.createElement(Z, null) + ) + ), + Pe.createElement( + V, + { isOpened: L }, + w + .entrySeq() + .map(([w]) => { + const x = [...j, w], + L = $e().List(x), + B = s.specResolvedSubtree(x), + V = s.specJson().getIn(x), + Y = qe.Map.isMap(B) ? B : $e().Map(), + Z = qe.Map.isMap(V) ? V : $e().Map(), + ee = Y.get('title') || Z.get('title') || w, + ie = i.isShown(x, !1); + ie && + 0 === Y.size && + Z.size > 0 && + this.props.specActions.requestResolvedSubtree(x); + const ae = Pe.createElement($, { + name: w, + expandDepth: C, + schema: Y || $e().Map(), + displayName: ee, + fullPath: x, + specPath: L, + getComponent: o, + specSelectors: s, + getConfigs: _, + layoutSelectors: i, + layoutActions: u, + includeReadOnly: !0, + includeWriteOnly: !0 + }), + le = Pe.createElement( + 'span', + { className: 'model-box' }, + Pe.createElement('span', { className: 'model model-title' }, ee) + ); + return Pe.createElement( + 'div', + { + id: `model-${w}`, + className: 'model-container', + key: `models-section-${w}`, + 'data-name': w, + ref: this.onLoadModel + }, + Pe.createElement( + 'span', + { className: 'models-jump-to-path' }, + Pe.createElement(z, { specPath: L }) + ), + Pe.createElement( + U, + { + classes: 'model-box', + collapsedContent: this.getCollapsedContent(w), + onToggle: this.handleToggle, + title: le, + displayName: ee, + modelName: w, + specPath: L, + layoutSelectors: i, + layoutActions: u, + hideSelfOnExpand: !0, + expanded: C > 0 && ie + }, + ae + ) + ); + }) + .toArray() + ) + ); + } + } + const enum_model = ({ value: s, getComponent: o }) => { + let i = o('ModelCollapse'), + u = Pe.createElement('span', null, 'Array [ ', s.count(), ' ]'); + return Pe.createElement( + 'span', + { className: 'prop-enum' }, + 'Enum:', + Pe.createElement('br', null), + Pe.createElement(i, { collapsedContent: u }, '[ ', s.map(String).join(', '), ' ]') + ); + }; + class ObjectModel extends Pe.Component { + render() { + let { + schema: s, + name: o, + displayName: i, + isRef: u, + getComponent: _, + getConfigs: w, + depth: x, + onToggle: C, + expanded: j, + specPath: L, + ...B + } = this.props, + { specSelectors: $, expandDepth: V, includeReadOnly: U, includeWriteOnly: z } = B; + const { isOAS3: Y } = $; + if (!s) return null; + const { showExtensions: Z } = w(); + let ee = s.get('description'), + ie = s.get('properties'), + ae = s.get('additionalProperties'), + le = s.get('title') || i || o, + ce = s.get('required'), + pe = s.filter( + (s, o) => + -1 !== ['maxProperties', 'minProperties', 'nullable', 'example'].indexOf(o) + ), + de = s.get('deprecated'), + fe = s.getIn(['externalDocs', 'url']), + ye = s.getIn(['externalDocs', 'description']); + const be = _('JumpToPath', !0), + _e = _('Markdown', !0), + we = _('Model'), + Se = _('ModelCollapse'), + xe = _('Property'), + Te = _('Link'), + JumpToPathSection = () => + Pe.createElement( + 'span', + { className: 'model-jump-to-path' }, + Pe.createElement(be, { specPath: L }) + ), + Re = Pe.createElement( + 'span', + null, + Pe.createElement('span', null, '{'), + '...', + Pe.createElement('span', null, '}'), + u ? Pe.createElement(JumpToPathSection, null) : '' + ), + $e = $.isOAS3() ? s.get('allOf') : null, + ze = $.isOAS3() ? s.get('anyOf') : null, + We = $.isOAS3() ? s.get('oneOf') : null, + He = $.isOAS3() ? s.get('not') : null, + Ye = + le && + Pe.createElement( + 'span', + { className: 'model-title' }, + u && + s.get('$$ref') && + Pe.createElement('span', { className: 'model-hint' }, s.get('$$ref')), + Pe.createElement('span', { className: 'model-title__text' }, le) + ); + return Pe.createElement( + 'span', + { className: 'model' }, + Pe.createElement( + Se, + { + modelName: o, + title: Ye, + onToggle: C, + expanded: !!j || x <= V, + collapsedContent: Re + }, + Pe.createElement('span', { className: 'brace-open object' }, '{'), + u ? Pe.createElement(JumpToPathSection, null) : null, + Pe.createElement( + 'span', + { className: 'inner-object' }, + Pe.createElement( + 'table', + { className: 'model' }, + Pe.createElement( + 'tbody', + null, + ee + ? Pe.createElement( + 'tr', + { className: 'description' }, + Pe.createElement('td', null, 'description:'), + Pe.createElement('td', null, Pe.createElement(_e, { source: ee })) + ) + : null, + fe && + Pe.createElement( + 'tr', + { className: 'external-docs' }, + Pe.createElement('td', null, 'externalDocs:'), + Pe.createElement( + 'td', + null, + Pe.createElement( + Te, + { target: '_blank', href: sanitizeUrl(fe) }, + ye || fe + ) + ) + ), + de + ? Pe.createElement( + 'tr', + { className: 'property' }, + Pe.createElement('td', null, 'deprecated:'), + Pe.createElement('td', null, 'true') + ) + : null, + ie && ie.size + ? ie + .entrySeq() + .filter( + ([, s]) => (!s.get('readOnly') || U) && (!s.get('writeOnly') || z) + ) + .map(([s, i]) => { + let u = Y() && i.get('deprecated'), + C = qe.List.isList(ce) && ce.contains(s), + j = ['property-row']; + return ( + u && j.push('deprecated'), + C && j.push('required'), + Pe.createElement( + 'tr', + { key: s, className: j.join(' ') }, + Pe.createElement( + 'td', + null, + s, + C && Pe.createElement('span', { className: 'star' }, '*') + ), + Pe.createElement( + 'td', + null, + Pe.createElement( + we, + Rn()({ key: `object-${o}-${s}_${i}` }, B, { + required: C, + getComponent: _, + specPath: L.push('properties', s), + getConfigs: w, + schema: i, + depth: x + 1 + }) + ) + ) + ) + ); + }) + .toArray() + : null, + Z ? Pe.createElement('tr', null, Pe.createElement('td', null, ' ')) : null, + Z + ? s + .entrySeq() + .map(([s, o]) => { + if ('x-' !== s.slice(0, 2)) return; + const i = o ? (o.toJS ? o.toJS() : o) : null; + return Pe.createElement( + 'tr', + { key: s, className: 'extension' }, + Pe.createElement('td', null, s), + Pe.createElement('td', null, JSON.stringify(i)) + ); + }) + .toArray() + : null, + ae && ae.size + ? Pe.createElement( + 'tr', + null, + Pe.createElement('td', null, '< * >:'), + Pe.createElement( + 'td', + null, + Pe.createElement( + we, + Rn()({}, B, { + required: !1, + getComponent: _, + specPath: L.push('additionalProperties'), + getConfigs: w, + schema: ae, + depth: x + 1 + }) + ) + ) + ) + : null, + $e + ? Pe.createElement( + 'tr', + null, + Pe.createElement('td', null, 'allOf ->'), + Pe.createElement( + 'td', + null, + $e.map((s, o) => + Pe.createElement( + 'div', + { key: o }, + Pe.createElement( + we, + Rn()({}, B, { + required: !1, + getComponent: _, + specPath: L.push('allOf', o), + getConfigs: w, + schema: s, + depth: x + 1 + }) + ) + ) + ) + ) + ) + : null, + ze + ? Pe.createElement( + 'tr', + null, + Pe.createElement('td', null, 'anyOf ->'), + Pe.createElement( + 'td', + null, + ze.map((s, o) => + Pe.createElement( + 'div', + { key: o }, + Pe.createElement( + we, + Rn()({}, B, { + required: !1, + getComponent: _, + specPath: L.push('anyOf', o), + getConfigs: w, + schema: s, + depth: x + 1 + }) + ) + ) + ) + ) + ) + : null, + We + ? Pe.createElement( + 'tr', + null, + Pe.createElement('td', null, 'oneOf ->'), + Pe.createElement( + 'td', + null, + We.map((s, o) => + Pe.createElement( + 'div', + { key: o }, + Pe.createElement( + we, + Rn()({}, B, { + required: !1, + getComponent: _, + specPath: L.push('oneOf', o), + getConfigs: w, + schema: s, + depth: x + 1 + }) + ) + ) + ) + ) + ) + : null, + He + ? Pe.createElement( + 'tr', + null, + Pe.createElement('td', null, 'not ->'), + Pe.createElement( + 'td', + null, + Pe.createElement( + 'div', + null, + Pe.createElement( + we, + Rn()({}, B, { + required: !1, + getComponent: _, + specPath: L.push('not'), + getConfigs: w, + schema: He, + depth: x + 1 + }) + ) + ) + ) + ) + : null + ) + ) + ), + Pe.createElement('span', { className: 'brace-close' }, '}') + ), + pe.size + ? pe.entrySeq().map(([s, o]) => + Pe.createElement(xe, { + key: `${s}-${o}`, + propKey: s, + propVal: o, + propClass: 'property' + }) + ) + : null + ); + } + } + class ArrayModel extends Pe.Component { + render() { + let { + getComponent: s, + getConfigs: o, + schema: i, + depth: u, + expandDepth: _, + name: w, + displayName: x, + specPath: C + } = this.props, + j = i.get('description'), + L = i.get('items'), + B = i.get('title') || x || w, + $ = i.filter( + (s, o) => + -1 === ['type', 'items', 'description', '$$ref', 'externalDocs'].indexOf(o) + ), + V = i.getIn(['externalDocs', 'url']), + U = i.getIn(['externalDocs', 'description']); + const z = s('Markdown', !0), + Y = s('ModelCollapse'), + Z = s('Model'), + ee = s('Property'), + ie = s('Link'), + ae = + B && + Pe.createElement( + 'span', + { className: 'model-title' }, + Pe.createElement('span', { className: 'model-title__text' }, B) + ); + return Pe.createElement( + 'span', + { className: 'model' }, + Pe.createElement( + Y, + { title: ae, expanded: u <= _, collapsedContent: '[...]' }, + '[', + $.size + ? $.entrySeq().map(([s, o]) => + Pe.createElement(ee, { + key: `${s}-${o}`, + propKey: s, + propVal: o, + propClass: 'property' + }) + ) + : null, + j + ? Pe.createElement(z, { source: j }) + : $.size + ? Pe.createElement('div', { className: 'markdown' }) + : null, + V && + Pe.createElement( + 'div', + { className: 'external-docs' }, + Pe.createElement(ie, { target: '_blank', href: sanitizeUrl(V) }, U || V) + ), + Pe.createElement( + 'span', + null, + Pe.createElement( + Z, + Rn()({}, this.props, { + getConfigs: o, + specPath: C.push('items'), + name: null, + schema: L, + required: !1, + depth: u + 1 + }) + ) + ), + ']' + ) + ); + } + } + const rs = 'property primitive'; + class Primitive extends Pe.Component { + render() { + let { + schema: s, + getComponent: o, + getConfigs: i, + name: u, + displayName: _, + depth: w, + expandDepth: x + } = this.props; + const { showExtensions: C } = i(); + if (!s || !s.get) return Pe.createElement('div', null); + let j = s.get('type'), + L = s.get('format'), + B = s.get('xml'), + $ = s.get('enum'), + V = s.get('title') || _ || u, + U = s.get('description'), + z = getExtensions(s), + Y = s + .filter( + (s, o) => + -1 === + ['enum', 'type', 'format', 'description', '$$ref', 'externalDocs'].indexOf(o) + ) + .filterNot((s, o) => z.has(o)), + Z = s.getIn(['externalDocs', 'url']), + ee = s.getIn(['externalDocs', 'description']); + const ie = o('Markdown', !0), + ae = o('EnumModel'), + le = o('Property'), + ce = o('ModelCollapse'), + pe = o('Link'), + de = + V && + Pe.createElement( + 'span', + { className: 'model-title' }, + Pe.createElement('span', { className: 'model-title__text' }, V) + ); + return Pe.createElement( + 'span', + { className: 'model' }, + Pe.createElement( + ce, + { title: de, expanded: w <= x, collapsedContent: '[...]' }, + Pe.createElement( + 'span', + { className: 'prop' }, + u && w > 1 && Pe.createElement('span', { className: 'prop-name' }, V), + Pe.createElement('span', { className: 'prop-type' }, j), + L && Pe.createElement('span', { className: 'prop-format' }, '($', L, ')'), + Y.size + ? Y.entrySeq().map(([s, o]) => + Pe.createElement(le, { + key: `${s}-${o}`, + propKey: s, + propVal: o, + propClass: rs + }) + ) + : null, + C && z.size + ? z.entrySeq().map(([s, o]) => + Pe.createElement(le, { + key: `${s}-${o}`, + propKey: s, + propVal: o, + propClass: rs + }) + ) + : null, + U ? Pe.createElement(ie, { source: U }) : null, + Z && + Pe.createElement( + 'div', + { className: 'external-docs' }, + Pe.createElement(pe, { target: '_blank', href: sanitizeUrl(Z) }, ee || Z) + ), + B && B.size + ? Pe.createElement( + 'span', + null, + Pe.createElement('br', null), + Pe.createElement('span', { className: rs }, 'xml:'), + B.entrySeq() + .map(([s, o]) => + Pe.createElement( + 'span', + { key: `${s}-${o}`, className: rs }, + Pe.createElement('br', null), + '   ', + s, + ': ', + String(o) + ) + ) + .toArray() + ) + : null, + $ && Pe.createElement(ae, { value: $, getComponent: o }) + ) + ) + ); + } + } + class Schemes extends Pe.Component { + UNSAFE_componentWillMount() { + let { schemes: s } = this.props; + this.setScheme(s.first()); + } + UNSAFE_componentWillReceiveProps(s) { + (this.props.currentScheme && s.schemes.includes(this.props.currentScheme)) || + this.setScheme(s.schemes.first()); + } + onChange = (s) => { + this.setScheme(s.target.value); + }; + setScheme = (s) => { + let { path: o, method: i, specActions: u } = this.props; + u.setScheme(s, o, i); + }; + render() { + let { schemes: s, currentScheme: o } = this.props; + return Pe.createElement( + 'label', + { htmlFor: 'schemes' }, + Pe.createElement('span', { className: 'schemes-title' }, 'Schemes'), + Pe.createElement( + 'select', + { onChange: this.onChange, value: o, id: 'schemes' }, + s + .valueSeq() + .map((s) => Pe.createElement('option', { value: s, key: s }, s)) + .toArray() + ) + ); + } + } + class SchemesContainer extends Pe.Component { + render() { + const { specActions: s, specSelectors: o, getComponent: i } = this.props, + u = o.operationScheme(), + _ = o.schemes(), + w = i('schemes'); + return _ && _.size + ? Pe.createElement(w, { currentScheme: u, schemes: _, specActions: s }) + : null; + } + } + var ns = __webpack_require__(24677), + ss = __webpack_require__.n(ns); + const os = { + value: '', + onChange: () => {}, + schema: {}, + keyName: '', + required: !1, + errors: (0, qe.List)() + }; + class JsonSchemaForm extends Pe.Component { + static defaultProps = os; + componentDidMount() { + const { dispatchInitialValue: s, value: o, onChange: i } = this.props; + s ? i(o) : !1 === s && i(''); + } + render() { + let { + schema: s, + errors: o, + value: i, + onChange: u, + getComponent: _, + fn: w, + disabled: x + } = this.props; + const C = s && s.get ? s.get('format') : null, + j = s && s.get ? s.get('type') : null; + let getComponentSilently = (s) => _(s, !1, { failSilently: !0 }), + L = j + ? getComponentSilently(C ? `JsonSchema_${j}_${C}` : `JsonSchema_${j}`) + : _('JsonSchema_string'); + return ( + L || (L = _('JsonSchema_string')), + Pe.createElement( + L, + Rn()({}, this.props, { + errors: o, + fn: w, + getComponent: _, + value: i, + onChange: u, + schema: s, + disabled: x + }) + ) + ); + } + } + class JsonSchema_string extends Pe.Component { + static defaultProps = os; + onChange = (s) => { + const o = + this.props.schema && 'file' === this.props.schema.get('type') + ? s.target.files[0] + : s.target.value; + this.props.onChange(o, this.props.keyName); + }; + onEnumChange = (s) => this.props.onChange(s); + render() { + let { + getComponent: s, + value: o, + schema: i, + errors: u, + required: _, + description: w, + disabled: x + } = this.props; + const C = i && i.get ? i.get('enum') : null, + j = i && i.get ? i.get('format') : null, + L = i && i.get ? i.get('type') : null, + B = i && i.get ? i.get('in') : null; + if ((o || (o = ''), (u = u.toJS ? u.toJS() : []), C)) { + const i = s('Select'); + return Pe.createElement(i, { + className: u.length ? 'invalid' : '', + title: u.length ? u : '', + allowedValues: [...C], + value: o, + allowEmptyValue: !_, + disabled: x, + onChange: this.onEnumChange + }); + } + const $ = x || (B && 'formData' === B && !('FormData' in window)), + V = s('Input'); + return L && 'file' === L + ? Pe.createElement(V, { + type: 'file', + className: u.length ? 'invalid' : '', + title: u.length ? u : '', + onChange: this.onChange, + disabled: $ + }) + : Pe.createElement(ss(), { + type: j && 'password' === j ? 'password' : 'text', + className: u.length ? 'invalid' : '', + title: u.length ? u : '', + value: o, + minLength: 0, + debounceTimeout: 350, + placeholder: w, + onChange: this.onChange, + disabled: $ + }); + } + } + class JsonSchema_array extends Pe.PureComponent { + static defaultProps = os; + constructor(s, o) { + super(s, o), (this.state = { value: valueOrEmptyList(s.value), schema: s.schema }); + } + UNSAFE_componentWillReceiveProps(s) { + const o = valueOrEmptyList(s.value); + o !== this.state.value && this.setState({ value: o }), + s.schema !== this.state.schema && this.setState({ schema: s.schema }); + } + onChange = () => { + this.props.onChange(this.state.value); + }; + onItemChange = (s, o) => { + this.setState(({ value: i }) => ({ value: i.set(o, s) }), this.onChange); + }; + removeItem = (s) => { + this.setState(({ value: o }) => ({ value: o.delete(s) }), this.onChange); + }; + addItem = () => { + const { fn: s } = this.props; + let o = valueOrEmptyList(this.state.value); + this.setState( + () => ({ + value: o.push( + s.getSampleSchema(this.state.schema.get('items'), !1, { includeWriteOnly: !0 }) + ) + }), + this.onChange + ); + }; + onEnumChange = (s) => { + this.setState(() => ({ value: s }), this.onChange); + }; + render() { + let { + getComponent: s, + required: o, + schema: i, + errors: u, + fn: _, + disabled: w + } = this.props; + u = u.toJS ? u.toJS() : Array.isArray(u) ? u : []; + const x = u.filter((s) => 'string' == typeof s), + C = u.filter((s) => void 0 !== s.needRemove).map((s) => s.error), + j = this.state.value, + L = !!(j && j.count && j.count() > 0), + B = i.getIn(['items', 'enum']), + $ = i.getIn(['items', 'type']), + V = i.getIn(['items', 'format']), + U = i.get('items'); + let z, + Y = !1, + Z = 'file' === $ || ('string' === $ && 'binary' === V); + if ( + ($ && V + ? (z = s(`JsonSchema_${$}_${V}`)) + : ('boolean' !== $ && 'array' !== $ && 'object' !== $) || + (z = s(`JsonSchema_${$}`)), + z || Z || (Y = !0), + B) + ) { + const i = s('Select'); + return Pe.createElement(i, { + className: u.length ? 'invalid' : '', + title: u.length ? u : '', + multiple: !0, + value: j, + disabled: w, + allowedValues: B, + allowEmptyValue: !o, + onChange: this.onEnumChange + }); + } + const ee = s('Button'); + return Pe.createElement( + 'div', + { className: 'json-schema-array' }, + L + ? j.map((o, i) => { + const x = (0, qe.fromJS)([ + ...u.filter((s) => s.index === i).map((s) => s.error) + ]); + return Pe.createElement( + 'div', + { key: i, className: 'json-schema-form-item' }, + Z + ? Pe.createElement(JsonSchemaArrayItemFile, { + value: o, + onChange: (s) => this.onItemChange(s, i), + disabled: w, + errors: x, + getComponent: s + }) + : Y + ? Pe.createElement(JsonSchemaArrayItemText, { + value: o, + onChange: (s) => this.onItemChange(s, i), + disabled: w, + errors: x + }) + : Pe.createElement( + z, + Rn()({}, this.props, { + value: o, + onChange: (s) => this.onItemChange(s, i), + disabled: w, + errors: x, + schema: U, + getComponent: s, + fn: _ + }) + ), + w + ? null + : Pe.createElement( + ee, + { + className: `btn btn-sm json-schema-form-item-remove ${C.length ? 'invalid' : null}`, + title: C.length ? C : '', + onClick: () => this.removeItem(i) + }, + ' - ' + ) + ); + }) + : null, + w + ? null + : Pe.createElement( + ee, + { + className: `btn btn-sm json-schema-form-item-add ${x.length ? 'invalid' : null}`, + title: x.length ? x : '', + onClick: this.addItem + }, + 'Add ', + $ ? `${$} ` : '', + 'item' + ) + ); + } + } + class JsonSchemaArrayItemText extends Pe.Component { + static defaultProps = os; + onChange = (s) => { + const o = s.target.value; + this.props.onChange(o, this.props.keyName); + }; + render() { + let { value: s, errors: o, description: i, disabled: u } = this.props; + return ( + s || (s = ''), + (o = o.toJS ? o.toJS() : []), + Pe.createElement(ss(), { + type: 'text', + className: o.length ? 'invalid' : '', + title: o.length ? o : '', + value: s, + minLength: 0, + debounceTimeout: 350, + placeholder: i, + onChange: this.onChange, + disabled: u + }) + ); + } + } + class JsonSchemaArrayItemFile extends Pe.Component { + static defaultProps = os; + onFileChange = (s) => { + const o = s.target.files[0]; + this.props.onChange(o, this.props.keyName); + }; + render() { + let { getComponent: s, errors: o, disabled: i } = this.props; + const u = s('Input'), + _ = i || !('FormData' in window); + return Pe.createElement(u, { + type: 'file', + className: o.length ? 'invalid' : '', + title: o.length ? o : '', + onChange: this.onFileChange, + disabled: _ + }); + } + } + class JsonSchema_boolean extends Pe.Component { + static defaultProps = os; + onEnumChange = (s) => this.props.onChange(s); + render() { + let { + getComponent: s, + value: o, + errors: i, + schema: u, + required: _, + disabled: w + } = this.props; + i = i.toJS ? i.toJS() : []; + let x = u && u.get ? u.get('enum') : null, + C = !x || !_, + j = !x && ['true', 'false']; + const L = s('Select'); + return Pe.createElement(L, { + className: i.length ? 'invalid' : '', + title: i.length ? i : '', + value: String(o), + disabled: w, + allowedValues: x ? [...x] : j, + allowEmptyValue: C, + onChange: this.onEnumChange + }); + } + } + const stringifyObjectErrors = (s) => + s.map((s) => { + const o = void 0 !== s.propKey ? s.propKey : s.index; + let i = 'string' == typeof s ? s : 'string' == typeof s.error ? s.error : null; + if (!o && i) return i; + let u = s.error, + _ = `/${s.propKey}`; + for (; 'object' == typeof u; ) { + const s = void 0 !== u.propKey ? u.propKey : u.index; + if (void 0 === s) break; + if (((_ += `/${s}`), !u.error)) break; + u = u.error; + } + return `${_}: ${u}`; + }); + class JsonSchema_object extends Pe.PureComponent { + constructor() { + super(); + } + static defaultProps = os; + onChange = (s) => { + this.props.onChange(s); + }; + handleOnChange = (s) => { + const o = s.target.value; + this.onChange(o); + }; + render() { + let { getComponent: s, value: o, errors: i, disabled: u } = this.props; + const _ = s('TextArea'); + return ( + (i = i.toJS ? i.toJS() : Array.isArray(i) ? i : []), + Pe.createElement( + 'div', + null, + Pe.createElement(_, { + className: Hn()({ invalid: i.length }), + title: i.length ? stringifyObjectErrors(i).join(', ') : '', + value: stringify(o), + disabled: u, + onChange: this.handleOnChange + }) + ) + ); + } + } + function valueOrEmptyList(s) { + return qe.List.isList(s) ? s : Array.isArray(s) ? (0, qe.fromJS)(s) : (0, qe.List)(); + } + const json_schema_5 = () => ({ + components: { + modelExample: model_example, + ModelWrapper, + ModelCollapse, + Model, + Models, + EnumModel: enum_model, + ObjectModel, + ArrayModel, + PrimitiveModel: Primitive, + schemes: Schemes, + SchemesContainer, + ...z + } + }); + var as = __webpack_require__(19123), + ls = __webpack_require__.n(as), + cs = __webpack_require__(41859), + us = __webpack_require__.n(cs), + ps = __webpack_require__(62193), + hs = __webpack_require__.n(ps); + const shallowArrayEquals = (s) => (o) => + Array.isArray(s) && + Array.isArray(o) && + s.length === o.length && + s.every((s, i) => s === o[i]), + list = (...s) => s; + class Cache extends Map { + delete(s) { + const o = Array.from(this.keys()).find(shallowArrayEquals(s)); + return super.delete(o); + } + get(s) { + const o = Array.from(this.keys()).find(shallowArrayEquals(s)); + return super.get(o); + } + has(s) { + return -1 !== Array.from(this.keys()).findIndex(shallowArrayEquals(s)); + } + } + const utils_memoizeN = (s, o = list) => { + const { Cache: i } = ut(); + ut().Cache = Cache; + const u = ut()(s, o); + return (ut().Cache = i), u; + }, + ds = { + string: (s) => + s.pattern + ? ((s) => { + try { + return new (us())(s).gen(); + } catch (s) { + return 'string'; + } + })(s.pattern) + : 'string', + string_email: () => 'user@example.com', + 'string_date-time': () => new Date().toISOString(), + string_date: () => new Date().toISOString().substring(0, 10), + string_uuid: () => '3fa85f64-5717-4562-b3fc-2c963f66afa6', + string_hostname: () => 'example.com', + string_ipv4: () => '198.51.100.42', + string_ipv6: () => '2001:0db8:5b96:0000:0000:426f:8e17:642a', + number: () => 0, + number_float: () => 0, + integer: () => 0, + boolean: (s) => 'boolean' != typeof s.default || s.default + }, + primitive = (s) => { + s = objectify(s); + let { type: o, format: i } = s, + u = ds[`${o}_${i}`] || ds[o]; + return isFunc(u) ? u(s) : 'Unknown Type: ' + s.type; + }, + sanitizeRef = (s) => + deeplyStripKey(s, '$$ref', (s) => 'string' == typeof s && s.indexOf('#') > -1), + fs = ['maxProperties', 'minProperties'], + ms = ['minItems', 'maxItems'], + gs = ['minimum', 'maximum', 'exclusiveMinimum', 'exclusiveMaximum'], + ys = ['minLength', 'maxLength'], + mergeJsonSchema = (s, o, i = {}) => { + const u = { ...s }; + if ( + (['example', 'default', 'enum', 'xml', 'type', ...fs, ...ms, ...gs, ...ys].forEach( + (s) => + ((s) => { + void 0 === u[s] && void 0 !== o[s] && (u[s] = o[s]); + })(s) + ), + void 0 !== o.required && + Array.isArray(o.required) && + ((void 0 !== u.required && u.required.length) || (u.required = []), + o.required.forEach((s) => { + u.required.includes(s) || u.required.push(s); + })), + o.properties) + ) { + u.properties || (u.properties = {}); + let s = objectify(o.properties); + for (let _ in s) + Object.prototype.hasOwnProperty.call(s, _) && + ((s[_] && s[_].deprecated) || + (s[_] && s[_].readOnly && !i.includeReadOnly) || + (s[_] && s[_].writeOnly && !i.includeWriteOnly) || + u.properties[_] || + ((u.properties[_] = s[_]), + !o.required && + Array.isArray(o.required) && + -1 !== o.required.indexOf(_) && + (u.required ? u.required.push(_) : (u.required = [_])))); + } + return ( + o.items && + (u.items || (u.items = {}), (u.items = mergeJsonSchema(u.items, o.items, i))), + u + ); + }, + sampleFromSchemaGeneric = (s, o = {}, i = void 0, u = !1) => { + s && isFunc(s.toJS) && (s = s.toJS()); + let _ = void 0 !== i || (s && void 0 !== s.example) || (s && void 0 !== s.default); + const w = !_ && s && s.oneOf && s.oneOf.length > 0, + x = !_ && s && s.anyOf && s.anyOf.length > 0; + if (!_ && (w || x)) { + const i = objectify(w ? s.oneOf[0] : s.anyOf[0]); + if ( + (!(s = mergeJsonSchema(s, i, o)).xml && i.xml && (s.xml = i.xml), + void 0 !== s.example && void 0 !== i.example) + ) + _ = !0; + else if (i.properties) { + s.properties || (s.properties = {}); + let u = objectify(i.properties); + for (let _ in u) + Object.prototype.hasOwnProperty.call(u, _) && + ((u[_] && u[_].deprecated) || + (u[_] && u[_].readOnly && !o.includeReadOnly) || + (u[_] && u[_].writeOnly && !o.includeWriteOnly) || + s.properties[_] || + ((s.properties[_] = u[_]), + !i.required && + Array.isArray(i.required) && + -1 !== i.required.indexOf(_) && + (s.required ? s.required.push(_) : (s.required = [_])))); + } + } + const C = {}; + let { + xml: j, + type: L, + example: B, + properties: $, + additionalProperties: V, + items: U + } = s || {}, + { includeReadOnly: z, includeWriteOnly: Y } = o; + j = j || {}; + let Z, + { name: ee, prefix: ie, namespace: ae } = j, + le = {}; + if (u && ((ee = ee || 'notagname'), (Z = (ie ? ie + ':' : '') + ee), ae)) { + C[ie ? 'xmlns:' + ie : 'xmlns'] = ae; + } + u && (le[Z] = []); + const schemaHasAny = (o) => o.some((o) => Object.prototype.hasOwnProperty.call(s, o)); + s && + !L && + ($ || V || schemaHasAny(fs) + ? (L = 'object') + : U || schemaHasAny(ms) + ? (L = 'array') + : schemaHasAny(gs) + ? ((L = 'number'), (s.type = 'number')) + : _ || s.enum || ((L = 'string'), (s.type = 'string'))); + const handleMinMaxItems = (o) => { + if ((null != s?.maxItems && (o = o.slice(0, s?.maxItems)), null != s?.minItems)) { + let i = 0; + for (; o.length < s?.minItems; ) o.push(o[i++ % o.length]); + } + return o; + }, + ce = objectify($); + let pe, + de = 0; + const hasExceededMaxProperties = () => + s && + null !== s.maxProperties && + void 0 !== s.maxProperties && + de >= s.maxProperties, + canAddProperty = (o) => + !s || + null === s.maxProperties || + void 0 === s.maxProperties || + (!hasExceededMaxProperties() && + (!((o) => !(s && s.required && s.required.length && s.required.includes(o)))(o) || + s.maxProperties - + de - + (() => { + if (!s || !s.required) return 0; + let o = 0; + return ( + u + ? s.required.forEach((s) => (o += void 0 === le[s] ? 0 : 1)) + : s.required.forEach( + (s) => (o += void 0 === le[Z]?.find((o) => void 0 !== o[s]) ? 0 : 1) + ), + s.required.length - o + ); + })() > + 0)); + if ( + ((pe = u + ? (i, _ = void 0) => { + if (s && ce[i]) { + if (((ce[i].xml = ce[i].xml || {}), ce[i].xml.attribute)) { + const s = Array.isArray(ce[i].enum) ? ce[i].enum[0] : void 0, + o = ce[i].example, + u = ce[i].default; + return void (C[ce[i].xml.name || i] = + void 0 !== o + ? o + : void 0 !== u + ? u + : void 0 !== s + ? s + : primitive(ce[i])); + } + ce[i].xml.name = ce[i].xml.name || i; + } else ce[i] || !1 === V || (ce[i] = { xml: { name: i } }); + let w = sampleFromSchemaGeneric((s && ce[i]) || void 0, o, _, u); + canAddProperty(i) && + (de++, Array.isArray(w) ? (le[Z] = le[Z].concat(w)) : le[Z].push(w)); + } + : (i, _) => { + if (canAddProperty(i)) { + if ( + Object.prototype.hasOwnProperty.call(s, 'discriminator') && + s.discriminator && + Object.prototype.hasOwnProperty.call(s.discriminator, 'mapping') && + s.discriminator.mapping && + Object.prototype.hasOwnProperty.call(s, '$$ref') && + s.$$ref && + s.discriminator.propertyName === i + ) { + for (let o in s.discriminator.mapping) + if (-1 !== s.$$ref.search(s.discriminator.mapping[o])) { + le[i] = o; + break; + } + } else le[i] = sampleFromSchemaGeneric(ce[i], o, _, u); + de++; + } + }), + _) + ) { + let _; + if (((_ = sanitizeRef(void 0 !== i ? i : void 0 !== B ? B : s.default)), !u)) { + if ('number' == typeof _ && 'string' === L) return `${_}`; + if ('string' != typeof _ || 'string' === L) return _; + try { + return JSON.parse(_); + } catch (s) { + return _; + } + } + if ((s || (L = Array.isArray(_) ? 'array' : typeof _), 'array' === L)) { + if (!Array.isArray(_)) { + if ('string' == typeof _) return _; + _ = [_]; + } + const i = s ? s.items : void 0; + i && ((i.xml = i.xml || j || {}), (i.xml.name = i.xml.name || j.name)); + let w = _.map((s) => sampleFromSchemaGeneric(i, o, s, u)); + return ( + (w = handleMinMaxItems(w)), + j.wrapped ? ((le[Z] = w), hs()(C) || le[Z].push({ _attr: C })) : (le = w), + le + ); + } + if ('object' === L) { + if ('string' == typeof _) return _; + for (let o in _) + Object.prototype.hasOwnProperty.call(_, o) && + ((s && ce[o] && ce[o].readOnly && !z) || + (s && ce[o] && ce[o].writeOnly && !Y) || + (s && ce[o] && ce[o].xml && ce[o].xml.attribute + ? (C[ce[o].xml.name || o] = _[o]) + : pe(o, _[o]))); + return hs()(C) || le[Z].push({ _attr: C }), le; + } + return (le[Z] = hs()(C) ? _ : [{ _attr: C }, _]), le; + } + if ('object' === L) { + for (let s in ce) + Object.prototype.hasOwnProperty.call(ce, s) && + ((ce[s] && ce[s].deprecated) || + (ce[s] && ce[s].readOnly && !z) || + (ce[s] && ce[s].writeOnly && !Y) || + pe(s)); + if ((u && C && le[Z].push({ _attr: C }), hasExceededMaxProperties())) return le; + if (!0 === V) + u + ? le[Z].push({ additionalProp: 'Anything can be here' }) + : (le.additionalProp1 = {}), + de++; + else if (V) { + const i = objectify(V), + _ = sampleFromSchemaGeneric(i, o, void 0, u); + if (u && i.xml && i.xml.name && 'notagname' !== i.xml.name) le[Z].push(_); + else { + const o = + null !== s.minProperties && void 0 !== s.minProperties && de < s.minProperties + ? s.minProperties - de + : 3; + for (let s = 1; s <= o; s++) { + if (hasExceededMaxProperties()) return le; + if (u) { + const o = {}; + (o['additionalProp' + s] = _.notagname), le[Z].push(o); + } else le['additionalProp' + s] = _; + de++; + } + } + } + return le; + } + if ('array' === L) { + if (!U) return; + let i; + if ( + (u && ((U.xml = U.xml || s?.xml || {}), (U.xml.name = U.xml.name || j.name)), + Array.isArray(U.anyOf)) + ) + i = U.anyOf.map((s) => + sampleFromSchemaGeneric(mergeJsonSchema(s, U, o), o, void 0, u) + ); + else if (Array.isArray(U.oneOf)) + i = U.oneOf.map((s) => + sampleFromSchemaGeneric(mergeJsonSchema(s, U, o), o, void 0, u) + ); + else { + if (!(!u || (u && j.wrapped))) return sampleFromSchemaGeneric(U, o, void 0, u); + i = [sampleFromSchemaGeneric(U, o, void 0, u)]; + } + return ( + (i = handleMinMaxItems(i)), + u && j.wrapped ? ((le[Z] = i), hs()(C) || le[Z].push({ _attr: C }), le) : i + ); + } + let fe; + if (s && Array.isArray(s.enum)) fe = normalizeArray(s.enum)[0]; + else { + if (!s) return; + if (((fe = primitive(s)), 'number' == typeof fe)) { + let o = s.minimum; + null != o && (s.exclusiveMinimum && o++, (fe = o)); + let i = s.maximum; + null != i && (s.exclusiveMaximum && i--, (fe = i)); + } + if ( + 'string' == typeof fe && + (null !== s.maxLength && void 0 !== s.maxLength && (fe = fe.slice(0, s.maxLength)), + null !== s.minLength && void 0 !== s.minLength) + ) { + let o = 0; + for (; fe.length < s.minLength; ) fe += fe[o++ % fe.length]; + } + } + if ('file' !== L) return u ? ((le[Z] = hs()(C) ? fe : [{ _attr: C }, fe]), le) : fe; + }, + inferSchema = (s) => (s.schema && (s = s.schema), s.properties && (s.type = 'object'), s), + createXMLExample = (s, o, i) => { + const u = sampleFromSchemaGeneric(s, o, i, !0); + if (u) return 'string' == typeof u ? u : ls()(u, { declaration: !0, indent: '\t' }); + }, + sampleFromSchema = (s, o, i) => sampleFromSchemaGeneric(s, o, i, !1), + resolver = (s, o, i) => [s, JSON.stringify(o), JSON.stringify(i)], + vs = utils_memoizeN(createXMLExample, resolver), + bs = utils_memoizeN(sampleFromSchema, resolver), + _s = [{ when: /json/, shouldStringifyTypes: ['string'] }], + Es = ['object'], + get_json_sample_schema = (s) => (o, i, u, _) => { + const { fn: w } = s(), + x = w.memoizedSampleFromSchema(o, i, _), + C = typeof x, + j = _s.reduce((s, o) => (o.when.test(u) ? [...s, ...o.shouldStringifyTypes] : s), Es); + return mt()(j, (s) => s === C) ? JSON.stringify(x, null, 2) : x; + }, + get_yaml_sample_schema = (s) => (o, i, u, _) => { + const { fn: w } = s(), + x = w.getJsonSampleSchema(o, i, u, _); + let C; + try { + (C = mn.dump(mn.load(x), { lineWidth: -1 }, { schema: nn })), + '\n' === C[C.length - 1] && (C = C.slice(0, C.length - 1)); + } catch (s) { + return console.error(s), 'error: could not generate yaml example'; + } + return C.replace(/\t/g, ' '); + }, + get_xml_sample_schema = (s) => (o, i, u) => { + const { fn: _ } = s(); + if ((o && !o.xml && (o.xml = {}), o && !o.xml.name)) { + if (!o.$$ref && (o.type || o.items || o.properties || o.additionalProperties)) + return '\n\x3c!-- XML example cannot be generated; root element name is undefined --\x3e'; + if (o.$$ref) { + let s = o.$$ref.match(/\S*\/(\S+)$/); + o.xml.name = s[1]; + } + } + return _.memoizedCreateXMLExample(o, i, u); + }, + get_sample_schema = + (s) => + (o, i = '', u = {}, _ = void 0) => { + const { fn: w } = s(); + return ( + 'function' == typeof o?.toJS && (o = o.toJS()), + 'function' == typeof _?.toJS && (_ = _.toJS()), + /xml/.test(i) + ? w.getXmlSampleSchema(o, u, _) + : /(yaml|yml)/.test(i) + ? w.getYamlSampleSchema(o, u, i, _) + : w.getJsonSampleSchema(o, u, i, _) + ); + }, + json_schema_5_samples = ({ getSystem: s }) => { + const o = get_json_sample_schema(s), + i = get_yaml_sample_schema(s), + u = get_xml_sample_schema(s), + _ = get_sample_schema(s); + return { + fn: { + jsonSchema5: { + inferSchema, + sampleFromSchema, + sampleFromSchemaGeneric, + createXMLExample, + memoizedSampleFromSchema: bs, + memoizedCreateXMLExample: vs, + getJsonSampleSchema: o, + getYamlSampleSchema: i, + getXmlSampleSchema: u, + getSampleSchema: _, + mergeJsonSchema + }, + inferSchema, + sampleFromSchema, + sampleFromSchemaGeneric, + createXMLExample, + memoizedSampleFromSchema: bs, + memoizedCreateXMLExample: vs, + getJsonSampleSchema: o, + getYamlSampleSchema: i, + getXmlSampleSchema: u, + getSampleSchema: _, + mergeJsonSchema + } + }; + }; + var ws = __webpack_require__(37334), + Ss = __webpack_require__.n(ws); + const xs = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace'], + spec_selectors_state = (s) => s || (0, qe.Map)(), + ks = Ut(spec_selectors_state, (s) => s.get('lastError')), + Cs = Ut(spec_selectors_state, (s) => s.get('url')), + Os = Ut(spec_selectors_state, (s) => s.get('spec') || ''), + As = Ut(spec_selectors_state, (s) => s.get('specSource') || 'not-editor'), + js = Ut(spec_selectors_state, (s) => s.get('json', (0, qe.Map)())), + Is = Ut(js, (s) => s.toJS()), + Ps = Ut(spec_selectors_state, (s) => s.get('resolved', (0, qe.Map)())), + specResolvedSubtree = (s, o) => s.getIn(['resolvedSubtrees', ...o], void 0), + mergerFn = (s, o) => + qe.Map.isMap(s) && qe.Map.isMap(o) + ? o.get('$$ref') + ? o + : (0, qe.OrderedMap)().mergeWith(mergerFn, s, o) + : o, + Ms = Ut(spec_selectors_state, (s) => + (0, qe.OrderedMap)().mergeWith(mergerFn, s.get('json'), s.get('resolvedSubtrees')) + ), + spec = (s) => js(s), + Ts = Ut(spec, () => !1), + Ns = Ut(spec, (s) => returnSelfOrNewMap(s && s.get('info'))), + Rs = Ut(spec, (s) => returnSelfOrNewMap(s && s.get('externalDocs'))), + Ds = Ut(Ns, (s) => s && s.get('version')), + Ls = Ut(Ds, (s) => /v?([0-9]*)\.([0-9]*)\.([0-9]*)/i.exec(s).slice(1)), + Bs = Ut(Ms, (s) => s.get('paths')), + Fs = Ss()(['get', 'put', 'post', 'delete', 'options', 'head', 'patch']), + qs = Ut(Bs, (s) => { + if (!s || s.size < 1) return (0, qe.List)(); + let o = (0, qe.List)(); + return s && s.forEach + ? (s.forEach((s, i) => { + if (!s || !s.forEach) return {}; + s.forEach((s, u) => { + xs.indexOf(u) < 0 || + (o = o.push( + (0, qe.fromJS)({ path: i, method: u, operation: s, id: `${u}-${i}` }) + )); + }); + }), + o) + : (0, qe.List)(); + }), + $s = Ut(spec, (s) => (0, qe.Set)(s.get('consumes'))), + Vs = Ut(spec, (s) => (0, qe.Set)(s.get('produces'))), + Us = Ut(spec, (s) => s.get('security', (0, qe.List)())), + zs = Ut(spec, (s) => s.get('securityDefinitions')), + findDefinition = (s, o) => { + const i = s.getIn(['resolvedSubtrees', 'definitions', o], null), + u = s.getIn(['json', 'definitions', o], null); + return i || u || null; + }, + Ws = Ut(spec, (s) => { + const o = s.get('definitions'); + return qe.Map.isMap(o) ? o : (0, qe.Map)(); + }), + Ks = Ut(spec, (s) => s.get('basePath')), + Hs = Ut(spec, (s) => s.get('host')), + Js = Ut(spec, (s) => s.get('schemes', (0, qe.Map)())), + Gs = Ut([qs, $s, Vs], (s, o, i) => + s.map((s) => + s.update('operation', (s) => { + if (s) { + if (!qe.Map.isMap(s)) return; + return s.withMutations( + (s) => ( + s.get('consumes') || s.update('consumes', (s) => (0, qe.Set)(s).merge(o)), + s.get('produces') || s.update('produces', (s) => (0, qe.Set)(s).merge(i)), + s + ) + ); + } + return (0, qe.Map)(); + }) + ) + ), + Ys = Ut(spec, (s) => { + const o = s.get('tags', (0, qe.List)()); + return qe.List.isList(o) ? o.filter((s) => qe.Map.isMap(s)) : (0, qe.List)(); + }), + tagDetails = (s, o) => + (Ys(s) || (0, qe.List)()) + .filter(qe.Map.isMap) + .find((s) => s.get('name') === o, (0, qe.Map)()), + Xs = Ut(Gs, Ys, (s, o) => + s.reduce( + (s, o) => { + let i = (0, qe.Set)(o.getIn(['operation', 'tags'])); + return i.count() < 1 + ? s.update('default', (0, qe.List)(), (s) => s.push(o)) + : i.reduce((s, i) => s.update(i, (0, qe.List)(), (s) => s.push(o)), s); + }, + o.reduce((s, o) => s.set(o.get('name'), (0, qe.List)()), (0, qe.OrderedMap)()) + ) + ), + selectors_taggedOperations = + (s) => + ({ getConfigs: o }) => { + let { tagsSorter: i, operationsSorter: u } = o(); + return Xs(s) + .sortBy( + (s, o) => o, + (s, o) => { + let u = 'function' == typeof i ? i : It.tagsSorter[i]; + return u ? u(s, o) : null; + } + ) + .map((o, i) => { + let _ = 'function' == typeof u ? u : It.operationsSorter[u], + w = _ ? o.sort(_) : o; + return (0, qe.Map)({ tagDetails: tagDetails(s, i), operations: w }); + }); + }, + Zs = Ut(spec_selectors_state, (s) => s.get('responses', (0, qe.Map)())), + Qs = Ut(spec_selectors_state, (s) => s.get('requests', (0, qe.Map)())), + eo = Ut(spec_selectors_state, (s) => s.get('mutatedRequests', (0, qe.Map)())), + responseFor = (s, o, i) => Zs(s).getIn([o, i], null), + requestFor = (s, o, i) => Qs(s).getIn([o, i], null), + mutatedRequestFor = (s, o, i) => eo(s).getIn([o, i], null), + allowTryItOutFor = () => !0, + parameterWithMetaByIdentity = (s, o, i) => { + const u = Ms(s).getIn(['paths', ...o, 'parameters'], (0, qe.OrderedMap)()), + _ = s.getIn(['meta', 'paths', ...o, 'parameters'], (0, qe.OrderedMap)()); + return u + .map((s) => { + const o = _.get(`${i.get('in')}.${i.get('name')}`), + u = _.get(`${i.get('in')}.${i.get('name')}.hash-${i.hashCode()}`); + return (0, qe.OrderedMap)().merge(s, o, u); + }) + .find( + (s) => s.get('in') === i.get('in') && s.get('name') === i.get('name'), + (0, qe.OrderedMap)() + ); + }, + parameterInclusionSettingFor = (s, o, i, u) => { + const _ = `${u}.${i}`; + return s.getIn(['meta', 'paths', ...o, 'parameter_inclusions', _], !1); + }, + parameterWithMeta = (s, o, i, u) => { + const _ = Ms(s) + .getIn(['paths', ...o, 'parameters'], (0, qe.OrderedMap)()) + .find((s) => s.get('in') === u && s.get('name') === i, (0, qe.OrderedMap)()); + return parameterWithMetaByIdentity(s, o, _); + }, + operationWithMeta = (s, o, i) => { + const u = Ms(s).getIn(['paths', o, i], (0, qe.OrderedMap)()), + _ = s.getIn(['meta', 'paths', o, i], (0, qe.OrderedMap)()), + w = u + .get('parameters', (0, qe.List)()) + .map((u) => parameterWithMetaByIdentity(s, [o, i], u)); + return (0, qe.OrderedMap)().merge(u, _).set('parameters', w); + }; + function getParameter(s, o, i, u) { + return ( + (o = o || []), + s + .getIn(['meta', 'paths', ...o, 'parameters'], (0, qe.fromJS)([])) + .find((s) => qe.Map.isMap(s) && s.get('name') === i && s.get('in') === u) || + (0, qe.Map)() + ); + } + const to = Ut(spec, (s) => { + const o = s.get('host'); + return 'string' == typeof o && o.length > 0 && '/' !== o[0]; + }); + function parameterValues(s, o, i) { + return ( + (o = o || []), + operationWithMeta(s, ...o) + .get('parameters', (0, qe.List)()) + .reduce( + (s, o) => { + let u = i && 'body' === o.get('in') ? o.get('value_xml') : o.get('value'); + return ( + qe.List.isList(u) && (u = u.filter((s) => '' !== s)), + s.set(paramToIdentifier(o, { allowHashes: !1 }), u) + ); + }, + (0, qe.fromJS)({}) + ) + ); + } + function parametersIncludeIn(s, o = '') { + if (qe.List.isList(s)) return s.some((s) => qe.Map.isMap(s) && s.get('in') === o); + } + function parametersIncludeType(s, o = '') { + if (qe.List.isList(s)) return s.some((s) => qe.Map.isMap(s) && s.get('type') === o); + } + function contentTypeValues(s, o) { + o = o || []; + let i = Ms(s).getIn(['paths', ...o], (0, qe.fromJS)({})), + u = s.getIn(['meta', 'paths', ...o], (0, qe.fromJS)({})), + _ = currentProducesFor(s, o); + const w = i.get('parameters') || new qe.List(), + x = u.get('consumes_value') + ? u.get('consumes_value') + : parametersIncludeType(w, 'file') + ? 'multipart/form-data' + : parametersIncludeType(w, 'formData') + ? 'application/x-www-form-urlencoded' + : void 0; + return (0, qe.fromJS)({ requestContentType: x, responseContentType: _ }); + } + function currentProducesFor(s, o) { + o = o || []; + const i = Ms(s).getIn(['paths', ...o], null); + if (null === i) return; + const u = s.getIn(['meta', 'paths', ...o, 'produces_value'], null), + _ = i.getIn(['produces', 0], null); + return u || _ || 'application/json'; + } + function producesOptionsFor(s, o) { + o = o || []; + const i = Ms(s), + u = i.getIn(['paths', ...o], null); + if (null === u) return; + const [_] = o, + w = u.get('produces', null), + x = i.getIn(['paths', _, 'produces'], null), + C = i.getIn(['produces'], null); + return w || x || C; + } + function consumesOptionsFor(s, o) { + o = o || []; + const i = Ms(s), + u = i.getIn(['paths', ...o], null); + if (null === u) return; + const [_] = o, + w = u.get('consumes', null), + x = i.getIn(['paths', _, 'consumes'], null), + C = i.getIn(['consumes'], null); + return w || x || C; + } + const operationScheme = (s, o, i) => { + let u = s.get('url').match(/^([a-z][a-z0-9+\-.]*):/), + _ = Array.isArray(u) ? u[1] : null; + return s.getIn(['scheme', o, i]) || s.getIn(['scheme', '_defaultScheme']) || _ || ''; + }, + canExecuteScheme = (s, o, i) => ['http', 'https'].indexOf(operationScheme(s, o, i)) > -1, + validationErrors = (s, o) => { + o = o || []; + const i = s.getIn(['meta', 'paths', ...o, 'parameters'], (0, qe.fromJS)([])), + u = []; + if (0 === i.length) return u; + const getErrorsWithPaths = (s, o = []) => { + const getNestedErrorsWithPaths = (s, o) => { + const i = [...o, s.get('propKey') || s.get('index')]; + return qe.Map.isMap(s.get('error')) + ? getErrorsWithPaths(s.get('error'), i) + : { error: s.get('error'), path: i }; + }; + return qe.List.isList(s) + ? s.map((s) => + qe.Map.isMap(s) ? getNestedErrorsWithPaths(s, o) : { error: s, path: o } + ) + : getNestedErrorsWithPaths(s, o); + }; + return ( + i.forEach((s, o) => { + const i = o.split('.').slice(1, -1).join('.'), + _ = s.get('errors'); + if (_ && _.count()) { + getErrorsWithPaths(_).forEach(({ error: s, path: o }) => { + u.push( + ((s, o, i) => + `For '${i}'${(o = o.reduce((s, o) => ('number' == typeof o ? `${s}[${o}]` : s ? `${s}.${o}` : o), '')) ? ` at path '${o}'` : ''}: ${s}.`)( + s, + o, + i + ) + ); + }); + } + }), + u + ); + }, + validateBeforeExecute = (s, o) => 0 === validationErrors(s, o).length, + getOAS3RequiredRequestBodyContentType = (s, o) => { + let i = { requestBody: !1, requestContentType: {} }, + u = s.getIn(['resolvedSubtrees', 'paths', ...o, 'requestBody'], (0, qe.fromJS)([])); + return ( + u.size < 1 || + (u.getIn(['required']) && (i.requestBody = u.getIn(['required'])), + u + .getIn(['content']) + .entrySeq() + .forEach((s) => { + const o = s[0]; + if (s[1].getIn(['schema', 'required'])) { + const u = s[1].getIn(['schema', 'required']).toJS(); + i.requestContentType[o] = u; + } + })), + i + ); + }, + isMediaTypeSchemaPropertiesEqual = (s, o, i, u) => { + if ((i || u) && i === u) return !0; + let _ = s.getIn( + ['resolvedSubtrees', 'paths', ...o, 'requestBody', 'content'], + (0, qe.fromJS)([]) + ); + if (_.size < 2 || !i || !u) return !1; + let w = _.getIn([i, 'schema', 'properties'], (0, qe.fromJS)([])), + x = _.getIn([u, 'schema', 'properties'], (0, qe.fromJS)([])); + return !!w.equals(x); + }; + function returnSelfOrNewMap(s) { + return qe.Map.isMap(s) ? s : new qe.Map(); + } + var ro = __webpack_require__(85015), + no = __webpack_require__.n(ro), + so = __webpack_require__(38221), + oo = __webpack_require__.n(so), + io = __webpack_require__(63560), + ao = __webpack_require__.n(io), + lo = __webpack_require__(56367), + co = __webpack_require__.n(lo); + const uo = 'spec_update_spec', + po = 'spec_update_url', + ho = 'spec_update_json', + fo = 'spec_update_param', + mo = 'spec_update_empty_param_inclusion', + go = 'spec_validate_param', + yo = 'spec_set_response', + vo = 'spec_set_request', + bo = 'spec_set_mutated_request', + _o = 'spec_log_request', + Eo = 'spec_clear_response', + wo = 'spec_clear_request', + So = 'spec_clear_validate_param', + xo = 'spec_update_operation_meta_value', + ko = 'spec_update_resolved', + Co = 'spec_update_resolved_subtree', + Oo = 'set_scheme', + toStr = (s) => (no()(s) ? s : ''); + function updateSpec(s) { + const o = toStr(s).replace(/\t/g, ' '); + if ('string' == typeof s) return { type: uo, payload: o }; + } + function updateResolved(s) { + return { type: ko, payload: s }; + } + function updateUrl(s) { + return { type: po, payload: s }; + } + function updateJsonSpec(s) { + return { type: ho, payload: s }; + } + const parseToJson = + (s) => + ({ specActions: o, specSelectors: i, errActions: u }) => { + let { specStr: _ } = i, + w = null; + try { + (s = s || _()), u.clear({ source: 'parser' }), (w = mn.load(s, { schema: nn })); + } catch (s) { + return ( + console.error(s), + u.newSpecErr({ + source: 'parser', + level: 'error', + message: s.reason, + line: s.mark && s.mark.line ? s.mark.line + 1 : void 0 + }) + ); + } + return w && 'object' == typeof w ? o.updateJsonSpec(w) : {}; + }; + let Ao = !1; + const resolveSpec = + (s, o) => + ({ + specActions: i, + specSelectors: u, + errActions: _, + fn: { fetch: w, resolve: x, AST: C = {} }, + getConfigs: j + }) => { + Ao || + (console.warn( + 'specActions.resolveSpec is deprecated since v3.10.0 and will be removed in v4.0.0; use requestResolvedSubtree instead!' + ), + (Ao = !0)); + const { + modelPropertyMacro: L, + parameterMacro: B, + requestInterceptor: $, + responseInterceptor: V + } = j(); + void 0 === s && (s = u.specJson()), void 0 === o && (o = u.url()); + let U = C.getLineNumberForPath ? C.getLineNumberForPath : () => {}, + z = u.specStr(); + return x({ + fetch: w, + spec: s, + baseDoc: String(new URL(o, document.baseURI)), + modelPropertyMacro: L, + parameterMacro: B, + requestInterceptor: $, + responseInterceptor: V + }).then(({ spec: s, errors: o }) => { + if ((_.clear({ type: 'thrown' }), Array.isArray(o) && o.length > 0)) { + let s = o.map( + (s) => ( + console.error(s), + (s.line = s.fullPath ? U(z, s.fullPath) : null), + (s.path = s.fullPath ? s.fullPath.join('.') : null), + (s.level = 'error'), + (s.type = 'thrown'), + (s.source = 'resolver'), + Object.defineProperty(s, 'message', { enumerable: !0, value: s.message }), + s + ) + ); + _.newThrownErrBatch(s); + } + return i.updateResolved(s); + }); + }; + let jo = []; + const Io = oo()(() => { + const s = jo.reduce( + (s, { path: o, system: i }) => (s.has(i) || s.set(i, []), s.get(i).push(o), s), + new Map() + ); + (jo = []), + s.forEach(async (s, o) => { + if (!o) + return void console.error( + "debResolveSubtrees: don't have a system to operate on, aborting." + ); + if (!o.fn.resolveSubtree) + return void console.error( + 'Error: Swagger-Client did not provide a `resolveSubtree` method, doing nothing.' + ); + const { + errActions: i, + errSelectors: u, + fn: { resolveSubtree: _, fetch: w, AST: x = {} }, + specSelectors: C, + specActions: j + } = o, + L = x.getLineNumberForPath ?? Ss()(void 0), + B = C.specStr(), + { + modelPropertyMacro: $, + parameterMacro: V, + requestInterceptor: U, + responseInterceptor: z + } = o.getConfigs(); + try { + const o = await s.reduce( + async (s, o) => { + let { resultMap: x, specWithCurrentSubtrees: j } = await s; + const { errors: Y, spec: Z } = await _(j, o, { + baseDoc: String(new URL(C.url(), document.baseURI)), + modelPropertyMacro: $, + parameterMacro: V, + requestInterceptor: U, + responseInterceptor: z + }); + if ( + (u.allErrors().size && + i.clearBy( + (s) => + 'thrown' !== s.get('type') || + 'resolver' !== s.get('source') || + !s.get('fullPath').every((s, i) => s === o[i] || void 0 === o[i]) + ), + Array.isArray(Y) && Y.length > 0) + ) { + let s = Y.map( + (s) => ( + (s.line = s.fullPath ? L(B, s.fullPath) : null), + (s.path = s.fullPath ? s.fullPath.join('.') : null), + (s.level = 'error'), + (s.type = 'thrown'), + (s.source = 'resolver'), + Object.defineProperty(s, 'message', { + enumerable: !0, + value: s.message + }), + s + ) + ); + i.newThrownErrBatch(s); + } + return ( + Z && + C.isOAS3() && + 'components' === o[0] && + 'securitySchemes' === o[1] && + (await Promise.all( + Object.values(Z) + .filter((s) => 'openIdConnect' === s.type) + .map(async (s) => { + const o = { + url: s.openIdConnectUrl, + requestInterceptor: U, + responseInterceptor: z + }; + try { + const i = await w(o); + i instanceof Error || i.status >= 400 + ? console.error(i.statusText + ' ' + o.url) + : (s.openIdConnectData = JSON.parse(i.text)); + } catch (s) { + console.error(s); + } + }) + )), + ao()(x, o, Z), + (j = co()(o, Z, j)), + { resultMap: x, specWithCurrentSubtrees: j } + ); + }, + Promise.resolve({ + resultMap: (C.specResolvedSubtree([]) || (0, qe.Map)()).toJS(), + specWithCurrentSubtrees: C.specJS() + }) + ); + j.updateResolvedSubtree([], o.resultMap); + } catch (s) { + console.error(s); + } + }); + }, 35), + requestResolvedSubtree = (s) => (o) => { + jo.find(({ path: i, system: u }) => u === o && i.toString() === s.toString()) || + (jo.push({ path: s, system: o }), Io()); + }; + function changeParam(s, o, i, u, _) { + return { type: fo, payload: { path: s, value: u, paramName: o, paramIn: i, isXml: _ } }; + } + function changeParamByIdentity(s, o, i, u) { + return { type: fo, payload: { path: s, param: o, value: i, isXml: u } }; + } + const updateResolvedSubtree = (s, o) => ({ type: Co, payload: { path: s, value: o } }), + invalidateResolvedSubtreeCache = () => ({ + type: Co, + payload: { path: [], value: (0, qe.Map)() } + }), + validateParams = (s, o) => ({ type: go, payload: { pathMethod: s, isOAS3: o } }), + updateEmptyParamInclusion = (s, o, i, u) => ({ + type: mo, + payload: { pathMethod: s, paramName: o, paramIn: i, includeEmptyValue: u } + }); + function clearValidateParams(s) { + return { type: So, payload: { pathMethod: s } }; + } + function changeConsumesValue(s, o) { + return { type: xo, payload: { path: s, value: o, key: 'consumes_value' } }; + } + function changeProducesValue(s, o) { + return { type: xo, payload: { path: s, value: o, key: 'produces_value' } }; + } + const setResponse = (s, o, i) => ({ payload: { path: s, method: o, res: i }, type: yo }), + setRequest = (s, o, i) => ({ payload: { path: s, method: o, req: i }, type: vo }), + setMutatedRequest = (s, o, i) => ({ payload: { path: s, method: o, req: i }, type: bo }), + logRequest = (s) => ({ payload: s, type: _o }), + executeRequest = + (s) => + ({ fn: o, specActions: i, specSelectors: u, getConfigs: _, oas3Selectors: w }) => { + let { pathName: x, method: C, operation: j } = s, + { requestInterceptor: L, responseInterceptor: B } = _(), + $ = j.toJS(); + if ( + (j && + j.get('parameters') && + j + .get('parameters') + .filter((s) => s && !0 === s.get('allowEmptyValue')) + .forEach((o) => { + if (u.parameterInclusionSettingFor([x, C], o.get('name'), o.get('in'))) { + s.parameters = s.parameters || {}; + const i = paramToValue(o, s.parameters); + (!i || (i && 0 === i.size)) && (s.parameters[o.get('name')] = ''); + } + }), + (s.contextUrl = Mt()(u.url()).toString()), + $ && $.operationId + ? (s.operationId = $.operationId) + : $ && x && C && (s.operationId = o.opId($, x, C)), + u.isOAS3()) + ) { + const o = `${x}:${C}`; + s.server = w.selectedServer(o) || w.selectedServer(); + const i = w.serverVariables({ server: s.server, namespace: o }).toJS(), + u = w.serverVariables({ server: s.server }).toJS(); + (s.serverVariables = Object.keys(i).length ? i : u), + (s.requestContentType = w.requestContentType(x, C)), + (s.responseContentType = w.responseContentType(x, C) || '*/*'); + const _ = w.requestBodyValue(x, C), + j = w.requestBodyInclusionSetting(x, C); + _ && _.toJS + ? (s.requestBody = _.map((s) => (qe.Map.isMap(s) ? s.get('value') : s)) + .filter( + (s, o) => (Array.isArray(s) ? 0 !== s.length : !isEmptyValue(s)) || j.get(o) + ) + .toJS()) + : (s.requestBody = _); + } + let V = Object.assign({}, s); + (V = o.buildRequest(V)), i.setRequest(s.pathName, s.method, V); + (s.requestInterceptor = async (o) => { + let u = await L.apply(void 0, [o]), + _ = Object.assign({}, u); + return i.setMutatedRequest(s.pathName, s.method, _), u; + }), + (s.responseInterceptor = B); + const U = Date.now(); + return o + .execute(s) + .then((o) => { + (o.duration = Date.now() - U), i.setResponse(s.pathName, s.method, o); + }) + .catch((o) => { + 'Failed to fetch' === o.message && + ((o.name = ''), + (o.message = + '**Failed to fetch.** \n**Possible Reasons:** \n - CORS \n - Network Failure \n - URL scheme must be "http" or "https" for CORS request.')), + i.setResponse(s.pathName, s.method, { error: !0, err: o }); + }); + }, + actions_execute = + ({ path: s, method: o, ...i } = {}) => + (u) => { + let { + fn: { fetch: _ }, + specSelectors: w, + specActions: x + } = u, + C = w.specJsonWithResolvedSubtrees().toJS(), + j = w.operationScheme(s, o), + { requestContentType: L, responseContentType: B } = w + .contentTypeValues([s, o]) + .toJS(), + $ = /xml/i.test(L), + V = w.parameterValues([s, o], $).toJS(); + return x.executeRequest({ + ...i, + fetch: _, + spec: C, + pathName: s, + method: o, + parameters: V, + requestContentType: L, + scheme: j, + responseContentType: B + }); + }; + function clearResponse(s, o) { + return { type: Eo, payload: { path: s, method: o } }; + } + function clearRequest(s, o) { + return { type: wo, payload: { path: s, method: o } }; + } + function setScheme(s, o, i) { + return { type: Oo, payload: { scheme: s, path: o, method: i } }; + } + const Po = { + [uo]: (s, o) => ('string' == typeof o.payload ? s.set('spec', o.payload) : s), + [po]: (s, o) => s.set('url', o.payload + ''), + [ho]: (s, o) => s.set('json', fromJSOrdered(o.payload)), + [ko]: (s, o) => s.setIn(['resolved'], fromJSOrdered(o.payload)), + [Co]: (s, o) => { + const { value: i, path: u } = o.payload; + return s.setIn(['resolvedSubtrees', ...u], fromJSOrdered(i)); + }, + [fo]: (s, { payload: o }) => { + let { path: i, paramName: u, paramIn: _, param: w, value: x, isXml: C } = o, + j = w ? paramToIdentifier(w) : `${_}.${u}`; + const L = C ? 'value_xml' : 'value'; + return s.setIn(['meta', 'paths', ...i, 'parameters', j, L], (0, qe.fromJS)(x)); + }, + [mo]: (s, { payload: o }) => { + let { pathMethod: i, paramName: u, paramIn: _, includeEmptyValue: w } = o; + if (!u || !_) + return ( + console.warn( + 'Warning: UPDATE_EMPTY_PARAM_INCLUSION could not generate a paramKey.' + ), + s + ); + const x = `${_}.${u}`; + return s.setIn(['meta', 'paths', ...i, 'parameter_inclusions', x], w); + }, + [go]: (s, { payload: { pathMethod: o, isOAS3: i } }) => { + const u = Ms(s).getIn(['paths', ...o]), + _ = parameterValues(s, o).toJS(); + return s.updateIn(['meta', 'paths', ...o, 'parameters'], (0, qe.fromJS)({}), (w) => + u.get('parameters', (0, qe.List)()).reduce((u, w) => { + const x = paramToValue(w, _), + C = parameterInclusionSettingFor(s, o, w.get('name'), w.get('in')), + j = ((s, o, { isOAS3: i = !1, bypassRequiredCheck: u = !1 } = {}) => { + let _ = s.get('required'), + { schema: w, parameterContentMediaType: x } = getParameterSchema(s, { + isOAS3: i + }); + return validateValueBySchema(o, w, _, u, x); + })(w, x, { bypassRequiredCheck: C, isOAS3: i }); + return u.setIn([paramToIdentifier(w), 'errors'], (0, qe.fromJS)(j)); + }, w) + ); + }, + [So]: (s, { payload: { pathMethod: o } }) => + s.updateIn(['meta', 'paths', ...o, 'parameters'], (0, qe.fromJS)([]), (s) => + s.map((s) => s.set('errors', (0, qe.fromJS)([]))) + ), + [yo]: (s, { payload: { res: o, path: i, method: u } }) => { + let _; + (_ = o.error + ? Object.assign( + { + error: !0, + name: o.err.name, + message: o.err.message, + statusCode: o.err.statusCode + }, + o.err.response + ) + : o), + (_.headers = _.headers || {}); + let w = s.setIn(['responses', i, u], fromJSOrdered(_)); + return ( + at.Blob && + _.data instanceof at.Blob && + (w = w.setIn(['responses', i, u, 'text'], _.data)), + w + ); + }, + [vo]: (s, { payload: { req: o, path: i, method: u } }) => + s.setIn(['requests', i, u], fromJSOrdered(o)), + [bo]: (s, { payload: { req: o, path: i, method: u } }) => + s.setIn(['mutatedRequests', i, u], fromJSOrdered(o)), + [xo]: (s, { payload: { path: o, value: i, key: u } }) => { + let _ = ['paths', ...o], + w = ['meta', 'paths', ...o]; + return s.getIn(['json', ..._]) || + s.getIn(['resolved', ..._]) || + s.getIn(['resolvedSubtrees', ..._]) + ? s.setIn([...w, u], (0, qe.fromJS)(i)) + : s; + }, + [Eo]: (s, { payload: { path: o, method: i } }) => s.deleteIn(['responses', o, i]), + [wo]: (s, { payload: { path: o, method: i } }) => s.deleteIn(['requests', o, i]), + [Oo]: (s, { payload: { scheme: o, path: i, method: u } }) => + i && u + ? s.setIn(['scheme', i, u], o) + : i || u + ? void 0 + : s.setIn(['scheme', '_defaultScheme'], o) + }, + wrap_actions_updateSpec = + (s, { specActions: o }) => + (...i) => { + s(...i), o.parseToJson(...i); + }, + wrap_actions_updateJsonSpec = + (s, { specActions: o }) => + (...i) => { + s(...i), o.invalidateResolvedSubtreeCache(); + const [u] = i, + _ = jn()(u, ['paths']) || {}; + Object.keys(_).forEach((s) => { + jn()(_, [s]).$ref && o.requestResolvedSubtree(['paths', s]); + }), + o.requestResolvedSubtree(['components', 'securitySchemes']); + }, + wrap_actions_executeRequest = + (s, { specActions: o }) => + (i) => (o.logRequest(i), s(i)), + wrap_actions_validateParams = + (s, { specSelectors: o }) => + (i) => + s(i, o.isOAS3()), + plugins_spec = () => ({ + statePlugins: { + spec: { + wrapActions: { ...ee }, + reducers: { ...Po }, + actions: { ...Z }, + selectors: { ...Y } + } + } + }); + var Mo = (function () { + var extendStatics = function (s, o) { + return ( + (extendStatics = + Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && + function (s, o) { + s.__proto__ = o; + }) || + function (s, o) { + for (var i in o) o.hasOwnProperty(i) && (s[i] = o[i]); + }), + extendStatics(s, o) + ); + }; + return function (s, o) { + function __() { + this.constructor = s; + } + extendStatics(s, o), + (s.prototype = + null === o ? Object.create(o) : ((__.prototype = o.prototype), new __())); + }; + })(), + To = Object.prototype.hasOwnProperty; + function module_helpers_hasOwnProperty(s, o) { + return To.call(s, o); + } + function _objectKeys(s) { + if (Array.isArray(s)) { + for (var o = new Array(s.length), i = 0; i < o.length; i++) o[i] = '' + i; + return o; + } + if (Object.keys) return Object.keys(s); + var u = []; + for (var _ in s) module_helpers_hasOwnProperty(s, _) && u.push(_); + return u; + } + function _deepClone(s) { + switch (typeof s) { + case 'object': + return JSON.parse(JSON.stringify(s)); + case 'undefined': + return null; + default: + return s; + } + } + function helpers_isInteger(s) { + for (var o, i = 0, u = s.length; i < u; ) { + if (!((o = s.charCodeAt(i)) >= 48 && o <= 57)) return !1; + i++; + } + return !0; + } + function escapePathComponent(s) { + return -1 === s.indexOf('/') && -1 === s.indexOf('~') + ? s + : s.replace(/~/g, '~0').replace(/\//g, '~1'); + } + function unescapePathComponent(s) { + return s.replace(/~1/g, '/').replace(/~0/g, '~'); + } + function hasUndefined(s) { + if (void 0 === s) return !0; + if (s) + if (Array.isArray(s)) { + for (var o = 0, i = s.length; o < i; o++) if (hasUndefined(s[o])) return !0; + } else if ('object' == typeof s) + for (var u = _objectKeys(s), _ = u.length, w = 0; w < _; w++) + if (hasUndefined(s[u[w]])) return !0; + return !1; + } + function patchErrorMessageFormatter(s, o) { + var i = [s]; + for (var u in o) { + var _ = 'object' == typeof o[u] ? JSON.stringify(o[u], null, 2) : o[u]; + void 0 !== _ && i.push(u + ': ' + _); + } + return i.join('\n'); + } + var No = (function (s) { + function PatchError(o, i, u, _, w) { + var x = this.constructor, + C = + s.call( + this, + patchErrorMessageFormatter(o, { name: i, index: u, operation: _, tree: w }) + ) || this; + return ( + (C.name = i), + (C.index = u), + (C.operation = _), + (C.tree = w), + Object.setPrototypeOf(C, x.prototype), + (C.message = patchErrorMessageFormatter(o, { + name: i, + index: u, + operation: _, + tree: w + })), + C + ); + } + return Mo(PatchError, s), PatchError; + })(Error), + Ro = No, + Do = _deepClone, + Lo = { + add: function (s, o, i) { + return (s[o] = this.value), { newDocument: i }; + }, + remove: function (s, o, i) { + var u = s[o]; + return delete s[o], { newDocument: i, removed: u }; + }, + replace: function (s, o, i) { + var u = s[o]; + return (s[o] = this.value), { newDocument: i, removed: u }; + }, + move: function (s, o, i) { + var u = getValueByPointer(i, this.path); + u && (u = _deepClone(u)); + var _ = applyOperation(i, { op: 'remove', path: this.from }).removed; + return ( + applyOperation(i, { op: 'add', path: this.path, value: _ }), + { newDocument: i, removed: u } + ); + }, + copy: function (s, o, i) { + var u = getValueByPointer(i, this.from); + return ( + applyOperation(i, { op: 'add', path: this.path, value: _deepClone(u) }), + { newDocument: i } + ); + }, + test: function (s, o, i) { + return { newDocument: i, test: _areEquals(s[o], this.value) }; + }, + _get: function (s, o, i) { + return (this.value = s[o]), { newDocument: i }; + } + }, + Bo = { + add: function (s, o, i) { + return ( + helpers_isInteger(o) ? s.splice(o, 0, this.value) : (s[o] = this.value), + { newDocument: i, index: o } + ); + }, + remove: function (s, o, i) { + return { newDocument: i, removed: s.splice(o, 1)[0] }; + }, + replace: function (s, o, i) { + var u = s[o]; + return (s[o] = this.value), { newDocument: i, removed: u }; + }, + move: Lo.move, + copy: Lo.copy, + test: Lo.test, + _get: Lo._get + }; + function getValueByPointer(s, o) { + if ('' == o) return s; + var i = { op: '_get', path: o }; + return applyOperation(s, i), i.value; + } + function applyOperation(s, o, i, u, _, w) { + if ( + (void 0 === i && (i = !1), + void 0 === u && (u = !0), + void 0 === _ && (_ = !0), + void 0 === w && (w = 0), + i && ('function' == typeof i ? i(o, 0, s, o.path) : validator(o, 0)), + '' === o.path) + ) { + var x = { newDocument: s }; + if ('add' === o.op) return (x.newDocument = o.value), x; + if ('replace' === o.op) return (x.newDocument = o.value), (x.removed = s), x; + if ('move' === o.op || 'copy' === o.op) + return ( + (x.newDocument = getValueByPointer(s, o.from)), + 'move' === o.op && (x.removed = s), + x + ); + if ('test' === o.op) { + if (((x.test = _areEquals(s, o.value)), !1 === x.test)) + throw new Ro('Test operation failed', 'TEST_OPERATION_FAILED', w, o, s); + return (x.newDocument = s), x; + } + if ('remove' === o.op) return (x.removed = s), (x.newDocument = null), x; + if ('_get' === o.op) return (o.value = s), x; + if (i) + throw new Ro( + 'Operation `op` property is not one of operations defined in RFC-6902', + 'OPERATION_OP_INVALID', + w, + o, + s + ); + return x; + } + u || (s = _deepClone(s)); + var C = (o.path || '').split('/'), + j = s, + L = 1, + B = C.length, + $ = void 0, + V = void 0, + U = void 0; + for (U = 'function' == typeof i ? i : validator; ; ) { + if ( + ((V = C[L]) && -1 != V.indexOf('~') && (V = unescapePathComponent(V)), + _ && ('__proto__' == V || ('prototype' == V && L > 0 && 'constructor' == C[L - 1]))) + ) + throw new TypeError( + 'JSON-Patch: modifying `__proto__` or `constructor/prototype` prop is banned for security reasons, if this was on purpose, please set `banPrototypeModifications` flag false and pass it to this function. More info in fast-json-patch README' + ); + if ( + (i && + void 0 === $ && + (void 0 === j[V] ? ($ = C.slice(0, L).join('/')) : L == B - 1 && ($ = o.path), + void 0 !== $ && U(o, 0, s, $)), + L++, + Array.isArray(j)) + ) { + if ('-' === V) V = j.length; + else { + if (i && !helpers_isInteger(V)) + throw new Ro( + 'Expected an unsigned base-10 integer value, making the new referenced value the array element with the zero-based index', + 'OPERATION_PATH_ILLEGAL_ARRAY_INDEX', + w, + o, + s + ); + helpers_isInteger(V) && (V = ~~V); + } + if (L >= B) { + if (i && 'add' === o.op && V > j.length) + throw new Ro( + 'The specified index MUST NOT be greater than the number of elements in the array', + 'OPERATION_VALUE_OUT_OF_BOUNDS', + w, + o, + s + ); + if (!1 === (x = Bo[o.op].call(o, j, V, s)).test) + throw new Ro('Test operation failed', 'TEST_OPERATION_FAILED', w, o, s); + return x; + } + } else if (L >= B) { + if (!1 === (x = Lo[o.op].call(o, j, V, s)).test) + throw new Ro('Test operation failed', 'TEST_OPERATION_FAILED', w, o, s); + return x; + } + if (((j = j[V]), i && L < B && (!j || 'object' != typeof j))) + throw new Ro( + 'Cannot perform operation at the desired path', + 'OPERATION_PATH_UNRESOLVABLE', + w, + o, + s + ); + } + } + function applyPatch(s, o, i, u, _) { + if ((void 0 === u && (u = !0), void 0 === _ && (_ = !0), i && !Array.isArray(o))) + throw new Ro('Patch sequence must be an array', 'SEQUENCE_NOT_AN_ARRAY'); + u || (s = _deepClone(s)); + for (var w = new Array(o.length), x = 0, C = o.length; x < C; x++) + (w[x] = applyOperation(s, o[x], i, !0, _, x)), (s = w[x].newDocument); + return (w.newDocument = s), w; + } + function applyReducer(s, o, i) { + var u = applyOperation(s, o); + if (!1 === u.test) + throw new Ro('Test operation failed', 'TEST_OPERATION_FAILED', i, o, s); + return u.newDocument; + } + function validator(s, o, i, u) { + if ('object' != typeof s || null === s || Array.isArray(s)) + throw new Ro('Operation is not an object', 'OPERATION_NOT_AN_OBJECT', o, s, i); + if (!Lo[s.op]) + throw new Ro( + 'Operation `op` property is not one of operations defined in RFC-6902', + 'OPERATION_OP_INVALID', + o, + s, + i + ); + if ('string' != typeof s.path) + throw new Ro( + 'Operation `path` property is not a string', + 'OPERATION_PATH_INVALID', + o, + s, + i + ); + if (0 !== s.path.indexOf('/') && s.path.length > 0) + throw new Ro( + 'Operation `path` property must start with "/"', + 'OPERATION_PATH_INVALID', + o, + s, + i + ); + if (('move' === s.op || 'copy' === s.op) && 'string' != typeof s.from) + throw new Ro( + 'Operation `from` property is not present (applicable in `move` and `copy` operations)', + 'OPERATION_FROM_REQUIRED', + o, + s, + i + ); + if (('add' === s.op || 'replace' === s.op || 'test' === s.op) && void 0 === s.value) + throw new Ro( + 'Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)', + 'OPERATION_VALUE_REQUIRED', + o, + s, + i + ); + if (('add' === s.op || 'replace' === s.op || 'test' === s.op) && hasUndefined(s.value)) + throw new Ro( + 'Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)', + 'OPERATION_VALUE_CANNOT_CONTAIN_UNDEFINED', + o, + s, + i + ); + if (i) + if ('add' == s.op) { + var _ = s.path.split('/').length, + w = u.split('/').length; + if (_ !== w + 1 && _ !== w) + throw new Ro( + 'Cannot perform an `add` operation at the desired path', + 'OPERATION_PATH_CANNOT_ADD', + o, + s, + i + ); + } else if ('replace' === s.op || 'remove' === s.op || '_get' === s.op) { + if (s.path !== u) + throw new Ro( + 'Cannot perform the operation at a path that does not exist', + 'OPERATION_PATH_UNRESOLVABLE', + o, + s, + i + ); + } else if ('move' === s.op || 'copy' === s.op) { + var x = validate([{ op: '_get', path: s.from, value: void 0 }], i); + if (x && 'OPERATION_PATH_UNRESOLVABLE' === x.name) + throw new Ro( + 'Cannot perform the operation from a path that does not exist', + 'OPERATION_FROM_UNRESOLVABLE', + o, + s, + i + ); + } + } + function validate(s, o, i) { + try { + if (!Array.isArray(s)) + throw new Ro('Patch sequence must be an array', 'SEQUENCE_NOT_AN_ARRAY'); + if (o) applyPatch(_deepClone(o), _deepClone(s), i || !0); + else { + i = i || validator; + for (var u = 0; u < s.length; u++) i(s[u], u, o, void 0); + } + } catch (s) { + if (s instanceof Ro) return s; + throw s; + } + } + function _areEquals(s, o) { + if (s === o) return !0; + if (s && o && 'object' == typeof s && 'object' == typeof o) { + var i, + u, + _, + w = Array.isArray(s), + x = Array.isArray(o); + if (w && x) { + if ((u = s.length) != o.length) return !1; + for (i = u; 0 != i--; ) if (!_areEquals(s[i], o[i])) return !1; + return !0; + } + if (w != x) return !1; + var C = Object.keys(s); + if ((u = C.length) !== Object.keys(o).length) return !1; + for (i = u; 0 != i--; ) if (!o.hasOwnProperty(C[i])) return !1; + for (i = u; 0 != i--; ) if (!_areEquals(s[(_ = C[i])], o[_])) return !1; + return !0; + } + return s != s && o != o; + } + var Fo = new WeakMap(), + qo = function qo(s) { + (this.observers = new Map()), (this.obj = s); + }, + $o = function $o(s, o) { + (this.callback = s), (this.observer = o); + }; + function unobserve(s, o) { + o.unobserve(); + } + function observe(s, o) { + var i, + u = (function getMirror(s) { + return Fo.get(s); + })(s); + if (u) { + var _ = (function getObserverFromMirror(s, o) { + return s.observers.get(o); + })(u, o); + i = _ && _.observer; + } else (u = new qo(s)), Fo.set(s, u); + if (i) return i; + if (((i = {}), (u.value = _deepClone(s)), o)) { + (i.callback = o), (i.next = null); + var dirtyCheck = function () { + generate(i); + }, + fastCheck = function () { + clearTimeout(i.next), (i.next = setTimeout(dirtyCheck)); + }; + 'undefined' != typeof window && + (window.addEventListener('mouseup', fastCheck), + window.addEventListener('keyup', fastCheck), + window.addEventListener('mousedown', fastCheck), + window.addEventListener('keydown', fastCheck), + window.addEventListener('change', fastCheck)); + } + return ( + (i.patches = []), + (i.object = s), + (i.unobserve = function () { + generate(i), + clearTimeout(i.next), + (function removeObserverFromMirror(s, o) { + s.observers.delete(o.callback); + })(u, i), + 'undefined' != typeof window && + (window.removeEventListener('mouseup', fastCheck), + window.removeEventListener('keyup', fastCheck), + window.removeEventListener('mousedown', fastCheck), + window.removeEventListener('keydown', fastCheck), + window.removeEventListener('change', fastCheck)); + }), + u.observers.set(o, new $o(o, i)), + i + ); + } + function generate(s, o) { + void 0 === o && (o = !1); + var i = Fo.get(s.object); + _generate(i.value, s.object, s.patches, '', o), + s.patches.length && applyPatch(i.value, s.patches); + var u = s.patches; + return u.length > 0 && ((s.patches = []), s.callback && s.callback(u)), u; + } + function _generate(s, o, i, u, _) { + if (o !== s) { + 'function' == typeof o.toJSON && (o = o.toJSON()); + for ( + var w = _objectKeys(o), x = _objectKeys(s), C = !1, j = x.length - 1; + j >= 0; + j-- + ) { + var L = s[($ = x[j])]; + if ( + !module_helpers_hasOwnProperty(o, $) || + (void 0 === o[$] && void 0 !== L && !1 === Array.isArray(o)) + ) + Array.isArray(s) === Array.isArray(o) + ? (_ && + i.push({ + op: 'test', + path: u + '/' + escapePathComponent($), + value: _deepClone(L) + }), + i.push({ op: 'remove', path: u + '/' + escapePathComponent($) }), + (C = !0)) + : (_ && i.push({ op: 'test', path: u, value: s }), + i.push({ op: 'replace', path: u, value: o }), + !0); + else { + var B = o[$]; + 'object' == typeof L && + null != L && + 'object' == typeof B && + null != B && + Array.isArray(L) === Array.isArray(B) + ? _generate(L, B, i, u + '/' + escapePathComponent($), _) + : L !== B && + (_ && + i.push({ + op: 'test', + path: u + '/' + escapePathComponent($), + value: _deepClone(L) + }), + i.push({ + op: 'replace', + path: u + '/' + escapePathComponent($), + value: _deepClone(B) + })); + } + } + if (C || w.length != x.length) + for (j = 0; j < w.length; j++) { + var $; + module_helpers_hasOwnProperty(s, ($ = w[j])) || + void 0 === o[$] || + i.push({ + op: 'add', + path: u + '/' + escapePathComponent($), + value: _deepClone(o[$]) + }); + } + } + } + function compare(s, o, i) { + void 0 === i && (i = !1); + var u = []; + return _generate(s, o, u, '', i), u; + } + Object.assign({}, ie, ae, { + JsonPatchError: No, + deepClone: _deepClone, + escapePathComponent, + unescapePathComponent + }); + var Vo = __webpack_require__(14744), + Uo = __webpack_require__.n(Vo); + const zo = { + add: function add(s, o) { + return { op: 'add', path: s, value: o }; + }, + replace, + remove: function remove(s) { + return { op: 'remove', path: s }; + }, + merge: function lib_merge(s, o) { + return { type: 'mutation', op: 'merge', path: s, value: o }; + }, + mergeDeep: function mergeDeep(s, o) { + return { type: 'mutation', op: 'mergeDeep', path: s, value: o }; + }, + context: function context(s, o) { + return { type: 'context', path: s, value: o }; + }, + getIn: function lib_getIn(s, o) { + return o.reduce((s, o) => (void 0 !== o && s ? s[o] : s), s); + }, + applyPatch: function lib_applyPatch(s, o, i) { + if ( + ((i = i || {}), + 'merge' === (o = { ...o, path: o.path && normalizeJSONPath(o.path) }).op) + ) { + const i = getInByJsonPath(s, o.path); + Object.assign(i, o.value), applyPatch(s, [replace(o.path, i)]); + } else if ('mergeDeep' === o.op) { + const i = getInByJsonPath(s, o.path), + u = Uo()(i, o.value); + s = applyPatch(s, [replace(o.path, u)]).newDocument; + } else if ('add' === o.op && '' === o.path && lib_isObject(o.value)) { + applyPatch( + s, + Object.keys(o.value).reduce( + (s, i) => ( + s.push({ op: 'add', path: `/${normalizeJSONPath(i)}`, value: o.value[i] }), s + ), + [] + ) + ); + } else if ('replace' === o.op && '' === o.path) { + let { value: u } = o; + i.allowMetaPatches && + o.meta && + isAdditiveMutation(o) && + (Array.isArray(o.value) || lib_isObject(o.value)) && + (u = { ...u, ...o.meta }), + (s = u); + } else if ( + (applyPatch(s, [o]), + i.allowMetaPatches && + o.meta && + isAdditiveMutation(o) && + (Array.isArray(o.value) || lib_isObject(o.value))) + ) { + const i = { ...getInByJsonPath(s, o.path), ...o.meta }; + applyPatch(s, [replace(o.path, i)]); + } + return s; + }, + parentPathMatch: function parentPathMatch(s, o) { + if (!Array.isArray(o)) return !1; + for (let i = 0, u = o.length; i < u; i += 1) if (o[i] !== s[i]) return !1; + return !0; + }, + flatten, + fullyNormalizeArray: function fullyNormalizeArray(s) { + return cleanArray(flatten(lib_normalizeArray(s))); + }, + normalizeArray: lib_normalizeArray, + isPromise: function isPromise(s) { + return lib_isObject(s) && lib_isFunction(s.then); + }, + forEachNew: function forEachNew(s, o) { + try { + return forEachNewPatch(s, forEach, o); + } catch (s) { + return s; + } + }, + forEachNewPrimitive: function forEachNewPrimitive(s, o) { + try { + return forEachNewPatch(s, forEachPrimitive, o); + } catch (s) { + return s; + } + }, + isJsonPatch, + isContextPatch: function isContextPatch(s) { + return isPatch(s) && 'context' === s.type; + }, + isPatch, + isMutation, + isAdditiveMutation, + isGenerator: function isGenerator(s) { + return '[object GeneratorFunction]' === Object.prototype.toString.call(s); + }, + isFunction: lib_isFunction, + isObject: lib_isObject, + isError: function lib_isError(s) { + return s instanceof Error; + } + }; + function normalizeJSONPath(s) { + return Array.isArray(s) + ? s.length < 1 + ? '' + : `/${s.map((s) => (s + '').replace(/~/g, '~0').replace(/\//g, '~1')).join('/')}` + : s; + } + function replace(s, o, i) { + return { op: 'replace', path: s, value: o, meta: i }; + } + function forEachNewPatch(s, o, i) { + return cleanArray( + flatten(s.filter(isAdditiveMutation).map((s) => o(s.value, i, s.path)) || []) + ); + } + function forEachPrimitive(s, o, i) { + return ( + (i = i || []), + Array.isArray(s) + ? s.map((s, u) => forEachPrimitive(s, o, i.concat(u))) + : lib_isObject(s) + ? Object.keys(s).map((u) => forEachPrimitive(s[u], o, i.concat(u))) + : o(s, i[i.length - 1], i) + ); + } + function forEach(s, o, i) { + let u = []; + if ((i = i || []).length > 0) { + const _ = o(s, i[i.length - 1], i); + _ && (u = u.concat(_)); + } + if (Array.isArray(s)) { + const _ = s.map((s, u) => forEach(s, o, i.concat(u))); + _ && (u = u.concat(_)); + } else if (lib_isObject(s)) { + const _ = Object.keys(s).map((u) => forEach(s[u], o, i.concat(u))); + _ && (u = u.concat(_)); + } + return (u = flatten(u)), u; + } + function lib_normalizeArray(s) { + return Array.isArray(s) ? s : [s]; + } + function flatten(s) { + return [].concat(...s.map((s) => (Array.isArray(s) ? flatten(s) : s))); + } + function cleanArray(s) { + return s.filter((s) => void 0 !== s); + } + function lib_isObject(s) { + return s && 'object' == typeof s; + } + function lib_isFunction(s) { + return s && 'function' == typeof s; + } + function isJsonPatch(s) { + if (isPatch(s)) { + const { op: o } = s; + return 'add' === o || 'remove' === o || 'replace' === o; + } + return !1; + } + function isMutation(s) { + return isJsonPatch(s) || (isPatch(s) && 'mutation' === s.type); + } + function isAdditiveMutation(s) { + return ( + isMutation(s) && + ('add' === s.op || 'replace' === s.op || 'merge' === s.op || 'mergeDeep' === s.op) + ); + } + function isPatch(s) { + return s && 'object' == typeof s; + } + function getInByJsonPath(s, o) { + try { + return getValueByPointer(s, o); + } catch (s) { + return console.error(s), {}; + } + } + var Wo = __webpack_require__(48675); + const Ko = class ApiDOMAggregateError extends Wo { + constructor(s, o, i) { + if ( + (super(s, o, i), + (this.name = this.constructor.name), + 'string' == typeof o && (this.message = o), + 'function' == typeof Error.captureStackTrace + ? Error.captureStackTrace(this, this.constructor) + : (this.stack = new Error(o).stack), + null != i && 'object' == typeof i && Object.hasOwn(i, 'cause') && !('cause' in this)) + ) { + const { cause: s } = i; + (this.cause = s), + s instanceof Error && + 'stack' in s && + (this.stack = `${this.stack}\nCAUSE: ${s.stack}`); + } + } + }; + class ApiDOMError extends Error { + static [Symbol.hasInstance](s) { + return ( + super[Symbol.hasInstance](s) || Function.prototype[Symbol.hasInstance].call(Ko, s) + ); + } + constructor(s, o) { + if ( + (super(s, o), + (this.name = this.constructor.name), + 'string' == typeof s && (this.message = s), + 'function' == typeof Error.captureStackTrace + ? Error.captureStackTrace(this, this.constructor) + : (this.stack = new Error(s).stack), + null != o && 'object' == typeof o && Object.hasOwn(o, 'cause') && !('cause' in this)) + ) { + const { cause: s } = o; + (this.cause = s), + s instanceof Error && + 'stack' in s && + (this.stack = `${this.stack}\nCAUSE: ${s.stack}`); + } + } + } + const Ho = ApiDOMError; + const Jo = class ApiDOMStructuredError extends Ho { + constructor(s, o) { + if ((super(s, o), null != o && 'object' == typeof o)) { + const { cause: s, ...i } = o; + Object.assign(this, i); + } + } + }; + var Go = __webpack_require__(65606); + function _isPlaceholder(s) { + return null != s && 'object' == typeof s && !0 === s['@@functional/placeholder']; + } + function _curry1(s) { + return function f1(o) { + return 0 === arguments.length || _isPlaceholder(o) ? f1 : s.apply(this, arguments); + }; + } + function _curry2(s) { + return function f2(o, i) { + switch (arguments.length) { + case 0: + return f2; + case 1: + return _isPlaceholder(o) + ? f2 + : _curry1(function (i) { + return s(o, i); + }); + default: + return _isPlaceholder(o) && _isPlaceholder(i) + ? f2 + : _isPlaceholder(o) + ? _curry1(function (o) { + return s(o, i); + }) + : _isPlaceholder(i) + ? _curry1(function (i) { + return s(o, i); + }) + : s(o, i); + } + }; + } + function _curry3(s) { + return function f3(o, i, u) { + switch (arguments.length) { + case 0: + return f3; + case 1: + return _isPlaceholder(o) + ? f3 + : _curry2(function (i, u) { + return s(o, i, u); + }); + case 2: + return _isPlaceholder(o) && _isPlaceholder(i) + ? f3 + : _isPlaceholder(o) + ? _curry2(function (o, u) { + return s(o, i, u); + }) + : _isPlaceholder(i) + ? _curry2(function (i, u) { + return s(o, i, u); + }) + : _curry1(function (u) { + return s(o, i, u); + }); + default: + return _isPlaceholder(o) && _isPlaceholder(i) && _isPlaceholder(u) + ? f3 + : _isPlaceholder(o) && _isPlaceholder(i) + ? _curry2(function (o, i) { + return s(o, i, u); + }) + : _isPlaceholder(o) && _isPlaceholder(u) + ? _curry2(function (o, u) { + return s(o, i, u); + }) + : _isPlaceholder(i) && _isPlaceholder(u) + ? _curry2(function (i, u) { + return s(o, i, u); + }) + : _isPlaceholder(o) + ? _curry1(function (o) { + return s(o, i, u); + }) + : _isPlaceholder(i) + ? _curry1(function (i) { + return s(o, i, u); + }) + : _isPlaceholder(u) + ? _curry1(function (u) { + return s(o, i, u); + }) + : s(o, i, u); + } + }; + } + const Yo = + Number.isInteger || + function _isInteger(s) { + return (s | 0) === s; + }; + function _isString(s) { + return '[object String]' === Object.prototype.toString.call(s); + } + function _nth(s, o) { + var i = s < 0 ? o.length + s : s; + return _isString(o) ? o.charAt(i) : o[i]; + } + function _path(s, o) { + for (var i = o, u = 0; u < s.length; u += 1) { + if (null == i) return; + var _ = s[u]; + i = Yo(_) ? _nth(_, i) : i[_]; + } + return i; + } + const Xo = _curry3(function pathSatisfies(s, o, i) { + return s(_path(o, i)); + }); + function _cloneRegExp(s) { + return new RegExp( + s.source, + s.flags + ? s.flags + : (s.global ? 'g' : '') + + (s.ignoreCase ? 'i' : '') + + (s.multiline ? 'm' : '') + + (s.sticky ? 'y' : '') + + (s.unicode ? 'u' : '') + + (s.dotAll ? 's' : '') + ); + } + function _arrayFromIterator(s) { + for (var o, i = []; !(o = s.next()).done; ) i.push(o.value); + return i; + } + function _includesWith(s, o, i) { + for (var u = 0, _ = i.length; u < _; ) { + if (s(o, i[u])) return !0; + u += 1; + } + return !1; + } + function _has(s, o) { + return Object.prototype.hasOwnProperty.call(o, s); + } + const Zo = + 'function' == typeof Object.is + ? Object.is + : function _objectIs(s, o) { + return s === o ? 0 !== s || 1 / s == 1 / o : s != s && o != o; + }; + var Qo = Object.prototype.toString; + const _i = (function () { + return '[object Arguments]' === Qo.call(arguments) + ? function _isArguments(s) { + return '[object Arguments]' === Qo.call(s); + } + : function _isArguments(s) { + return _has('callee', s); + }; + })(); + var Ei = !{ toString: null }.propertyIsEnumerable('toString'), + Oi = [ + 'constructor', + 'valueOf', + 'isPrototypeOf', + 'toString', + 'propertyIsEnumerable', + 'hasOwnProperty', + 'toLocaleString' + ], + Pi = (function () { + return arguments.propertyIsEnumerable('length'); + })(), + Mi = function contains(s, o) { + for (var i = 0; i < s.length; ) { + if (s[i] === o) return !0; + i += 1; + } + return !1; + }, + Ri = + 'function' != typeof Object.keys || Pi + ? _curry1(function keys(s) { + if (Object(s) !== s) return []; + var o, + i, + u = [], + _ = Pi && _i(s); + for (o in s) !_has(o, s) || (_ && 'length' === o) || (u[u.length] = o); + if (Ei) + for (i = Oi.length - 1; i >= 0; ) + _has((o = Oi[i]), s) && !Mi(u, o) && (u[u.length] = o), (i -= 1); + return u; + }) + : _curry1(function keys(s) { + return Object(s) !== s ? [] : Object.keys(s); + }); + const Wi = Ri; + const ea = _curry1(function type(s) { + return null === s + ? 'Null' + : void 0 === s + ? 'Undefined' + : Object.prototype.toString.call(s).slice(8, -1); + }); + function _uniqContentEquals(s, o, i, u) { + var _ = _arrayFromIterator(s); + function eq(s, o) { + return _equals(s, o, i.slice(), u.slice()); + } + return !_includesWith( + function (s, o) { + return !_includesWith(eq, o, s); + }, + _arrayFromIterator(o), + _ + ); + } + function _equals(s, o, i, u) { + if (Zo(s, o)) return !0; + var _ = ea(s); + if (_ !== ea(o)) return !1; + if ( + 'function' == typeof s['fantasy-land/equals'] || + 'function' == typeof o['fantasy-land/equals'] + ) + return ( + 'function' == typeof s['fantasy-land/equals'] && + s['fantasy-land/equals'](o) && + 'function' == typeof o['fantasy-land/equals'] && + o['fantasy-land/equals'](s) + ); + if ('function' == typeof s.equals || 'function' == typeof o.equals) + return ( + 'function' == typeof s.equals && + s.equals(o) && + 'function' == typeof o.equals && + o.equals(s) + ); + switch (_) { + case 'Arguments': + case 'Array': + case 'Object': + if ( + 'function' == typeof s.constructor && + 'Promise' === + (function _functionName(s) { + var o = String(s).match(/^function (\w*)/); + return null == o ? '' : o[1]; + })(s.constructor) + ) + return s === o; + break; + case 'Boolean': + case 'Number': + case 'String': + if (typeof s != typeof o || !Zo(s.valueOf(), o.valueOf())) return !1; + break; + case 'Date': + if (!Zo(s.valueOf(), o.valueOf())) return !1; + break; + case 'Error': + return s.name === o.name && s.message === o.message; + case 'RegExp': + if ( + s.source !== o.source || + s.global !== o.global || + s.ignoreCase !== o.ignoreCase || + s.multiline !== o.multiline || + s.sticky !== o.sticky || + s.unicode !== o.unicode + ) + return !1; + } + for (var w = i.length - 1; w >= 0; ) { + if (i[w] === s) return u[w] === o; + w -= 1; + } + switch (_) { + case 'Map': + return ( + s.size === o.size && + _uniqContentEquals(s.entries(), o.entries(), i.concat([s]), u.concat([o])) + ); + case 'Set': + return ( + s.size === o.size && + _uniqContentEquals(s.values(), o.values(), i.concat([s]), u.concat([o])) + ); + case 'Arguments': + case 'Array': + case 'Object': + case 'Boolean': + case 'Number': + case 'String': + case 'Date': + case 'Error': + case 'RegExp': + case 'Int8Array': + case 'Uint8Array': + case 'Uint8ClampedArray': + case 'Int16Array': + case 'Uint16Array': + case 'Int32Array': + case 'Uint32Array': + case 'Float32Array': + case 'Float64Array': + case 'ArrayBuffer': + break; + default: + return !1; + } + var x = Wi(s); + if (x.length !== Wi(o).length) return !1; + var C = i.concat([s]), + j = u.concat([o]); + for (w = x.length - 1; w >= 0; ) { + var L = x[w]; + if (!_has(L, o) || !_equals(o[L], s[L], C, j)) return !1; + w -= 1; + } + return !0; + } + const ra = _curry2(function equals(s, o) { + return _equals(s, o, [], []); + }); + function _includes(s, o) { + return ( + (function _indexOf(s, o, i) { + var u, _; + if ('function' == typeof s.indexOf) + switch (typeof o) { + case 'number': + if (0 === o) { + for (u = 1 / o; i < s.length; ) { + if (0 === (_ = s[i]) && 1 / _ === u) return i; + i += 1; + } + return -1; + } + if (o != o) { + for (; i < s.length; ) { + if ('number' == typeof (_ = s[i]) && _ != _) return i; + i += 1; + } + return -1; + } + return s.indexOf(o, i); + case 'string': + case 'boolean': + case 'function': + case 'undefined': + return s.indexOf(o, i); + case 'object': + if (null === o) return s.indexOf(o, i); + } + for (; i < s.length; ) { + if (ra(s[i], o)) return i; + i += 1; + } + return -1; + })(o, s, 0) >= 0 + ); + } + function _map(s, o) { + for (var i = 0, u = o.length, _ = Array(u); i < u; ) (_[i] = s(o[i])), (i += 1); + return _; + } + function _quote(s) { + return ( + '"' + + s + .replace(/\\/g, '\\\\') + .replace(/[\b]/g, '\\b') + .replace(/\f/g, '\\f') + .replace(/\n/g, '\\n') + .replace(/\r/g, '\\r') + .replace(/\t/g, '\\t') + .replace(/\v/g, '\\v') + .replace(/\0/g, '\\0') + .replace(/"/g, '\\"') + + '"' + ); + } + var na = function pad(s) { + return (s < 10 ? '0' : '') + s; + }; + const ia = + 'function' == typeof Date.prototype.toISOString + ? function _toISOString(s) { + return s.toISOString(); + } + : function _toISOString(s) { + return ( + s.getUTCFullYear() + + '-' + + na(s.getUTCMonth() + 1) + + '-' + + na(s.getUTCDate()) + + 'T' + + na(s.getUTCHours()) + + ':' + + na(s.getUTCMinutes()) + + ':' + + na(s.getUTCSeconds()) + + '.' + + (s.getUTCMilliseconds() / 1e3).toFixed(3).slice(2, 5) + + 'Z' + ); + }; + function _complement(s) { + return function () { + return !s.apply(this, arguments); + }; + } + function _arrayReduce(s, o, i) { + for (var u = 0, _ = i.length; u < _; ) (o = s(o, i[u])), (u += 1); + return o; + } + const aa = + Array.isArray || + function _isArray(s) { + return ( + null != s && s.length >= 0 && '[object Array]' === Object.prototype.toString.call(s) + ); + }; + function _dispatchable(s, o, i) { + return function () { + if (0 === arguments.length) return i(); + var u = arguments[arguments.length - 1]; + if (!aa(u)) { + for (var _ = 0; _ < s.length; ) { + if ('function' == typeof u[s[_]]) + return u[s[_]].apply(u, Array.prototype.slice.call(arguments, 0, -1)); + _ += 1; + } + if ( + (function _isTransformer(s) { + return null != s && 'function' == typeof s['@@transducer/step']; + })(u) + ) + return o.apply(null, Array.prototype.slice.call(arguments, 0, -1))(u); + } + return i.apply(this, arguments); + }; + } + function _isObject(s) { + return '[object Object]' === Object.prototype.toString.call(s); + } + const _xfBase_init = function () { + return this.xf['@@transducer/init'](); + }, + _xfBase_result = function (s) { + return this.xf['@@transducer/result'](s); + }; + var la = (function () { + function XFilter(s, o) { + (this.xf = o), (this.f = s); + } + return ( + (XFilter.prototype['@@transducer/init'] = _xfBase_init), + (XFilter.prototype['@@transducer/result'] = _xfBase_result), + (XFilter.prototype['@@transducer/step'] = function (s, o) { + return this.f(o) ? this.xf['@@transducer/step'](s, o) : s; + }), + XFilter + ); + })(); + function _xfilter(s) { + return function (o) { + return new la(s, o); + }; + } + var ca = _curry2( + _dispatchable(['fantasy-land/filter', 'filter'], _xfilter, function (s, o) { + return _isObject(o) + ? _arrayReduce( + function (i, u) { + return s(o[u]) && (i[u] = o[u]), i; + }, + {}, + Wi(o) + ) + : (function _filter(s, o) { + for (var i = 0, u = o.length, _ = []; i < u; ) + s(o[i]) && (_[_.length] = o[i]), (i += 1); + return _; + })(s, o); + }) + ); + const ua = ca; + const da = _curry2(function reject(s, o) { + return ua(_complement(s), o); + }); + function _toString_toString(s, o) { + var i = function recur(i) { + var u = o.concat([s]); + return _includes(i, u) ? '' : _toString_toString(i, u); + }, + mapPairs = function (s, o) { + return _map(function (o) { + return _quote(o) + ': ' + i(s[o]); + }, o.slice().sort()); + }; + switch (Object.prototype.toString.call(s)) { + case '[object Arguments]': + return '(function() { return arguments; }(' + _map(i, s).join(', ') + '))'; + case '[object Array]': + return ( + '[' + + _map(i, s) + .concat( + mapPairs( + s, + da(function (s) { + return /^\d+$/.test(s); + }, Wi(s)) + ) + ) + .join(', ') + + ']' + ); + case '[object Boolean]': + return 'object' == typeof s ? 'new Boolean(' + i(s.valueOf()) + ')' : s.toString(); + case '[object Date]': + return 'new Date(' + (isNaN(s.valueOf()) ? i(NaN) : _quote(ia(s))) + ')'; + case '[object Map]': + return 'new Map(' + i(Array.from(s)) + ')'; + case '[object Null]': + return 'null'; + case '[object Number]': + return 'object' == typeof s + ? 'new Number(' + i(s.valueOf()) + ')' + : 1 / s == -1 / 0 + ? '-0' + : s.toString(10); + case '[object Set]': + return 'new Set(' + i(Array.from(s).sort()) + ')'; + case '[object String]': + return 'object' == typeof s ? 'new String(' + i(s.valueOf()) + ')' : _quote(s); + case '[object Undefined]': + return 'undefined'; + default: + if ('function' == typeof s.toString) { + var u = s.toString(); + if ('[object Object]' !== u) return u; + } + return '{' + mapPairs(s, Wi(s)).join(', ') + '}'; + } + } + const ma = _curry1(function toString(s) { + return _toString_toString(s, []); + }); + var ga = _curry2(function test(s, o) { + if ( + !(function _isRegExp(s) { + return '[object RegExp]' === Object.prototype.toString.call(s); + })(s) + ) + throw new TypeError( + '‘test’ requires a value of type RegExp as its first argument; received ' + ma(s) + ); + return _cloneRegExp(s).test(o); + }); + const ya = ga; + function _arity(s, o) { + switch (s) { + case 0: + return function () { + return o.apply(this, arguments); + }; + case 1: + return function (s) { + return o.apply(this, arguments); + }; + case 2: + return function (s, i) { + return o.apply(this, arguments); + }; + case 3: + return function (s, i, u) { + return o.apply(this, arguments); + }; + case 4: + return function (s, i, u, _) { + return o.apply(this, arguments); + }; + case 5: + return function (s, i, u, _, w) { + return o.apply(this, arguments); + }; + case 6: + return function (s, i, u, _, w, x) { + return o.apply(this, arguments); + }; + case 7: + return function (s, i, u, _, w, x, C) { + return o.apply(this, arguments); + }; + case 8: + return function (s, i, u, _, w, x, C, j) { + return o.apply(this, arguments); + }; + case 9: + return function (s, i, u, _, w, x, C, j, L) { + return o.apply(this, arguments); + }; + case 10: + return function (s, i, u, _, w, x, C, j, L, B) { + return o.apply(this, arguments); + }; + default: + throw new Error( + 'First argument to _arity must be a non-negative integer no greater than ten' + ); + } + } + function _pipe(s, o) { + return function () { + return o.call(this, s.apply(this, arguments)); + }; + } + const va = _curry1(function isArrayLike(s) { + return ( + !!aa(s) || + (!!s && + 'object' == typeof s && + !_isString(s) && + (0 === s.length || + (s.length > 0 && s.hasOwnProperty(0) && s.hasOwnProperty(s.length - 1)))) + ); + }); + var ba = 'undefined' != typeof Symbol ? Symbol.iterator : '@@iterator'; + function _createReduce(s, o, i) { + return function _reduce(u, _, w) { + if (va(w)) return s(u, _, w); + if (null == w) return _; + if ('function' == typeof w['fantasy-land/reduce']) + return o(u, _, w, 'fantasy-land/reduce'); + if (null != w[ba]) return i(u, _, w[ba]()); + if ('function' == typeof w.next) return i(u, _, w); + if ('function' == typeof w.reduce) return o(u, _, w, 'reduce'); + throw new TypeError('reduce: list must be array or iterable'); + }; + } + function _xArrayReduce(s, o, i) { + for (var u = 0, _ = i.length; u < _; ) { + if ((o = s['@@transducer/step'](o, i[u])) && o['@@transducer/reduced']) { + o = o['@@transducer/value']; + break; + } + u += 1; + } + return s['@@transducer/result'](o); + } + var _a = _curry2(function bind(s, o) { + return _arity(s.length, function () { + return s.apply(o, arguments); + }); + }); + const Ea = _a; + function _xIterableReduce(s, o, i) { + for (var u = i.next(); !u.done; ) { + if ((o = s['@@transducer/step'](o, u.value)) && o['@@transducer/reduced']) { + o = o['@@transducer/value']; + break; + } + u = i.next(); + } + return s['@@transducer/result'](o); + } + function _xMethodReduce(s, o, i, u) { + return s['@@transducer/result'](i[u](Ea(s['@@transducer/step'], s), o)); + } + const wa = _createReduce(_xArrayReduce, _xMethodReduce, _xIterableReduce); + var xa = (function () { + function XWrap(s) { + this.f = s; + } + return ( + (XWrap.prototype['@@transducer/init'] = function () { + throw new Error('init not implemented on XWrap'); + }), + (XWrap.prototype['@@transducer/result'] = function (s) { + return s; + }), + (XWrap.prototype['@@transducer/step'] = function (s, o) { + return this.f(s, o); + }), + XWrap + ); + })(); + function _xwrap(s) { + return new xa(s); + } + var ka = _curry3(function (s, o, i) { + return wa('function' == typeof s ? _xwrap(s) : s, o, i); + }); + const Ca = ka; + function _checkForMethod(s, o) { + return function () { + var i = arguments.length; + if (0 === i) return o(); + var u = arguments[i - 1]; + return aa(u) || 'function' != typeof u[s] + ? o.apply(this, arguments) + : u[s].apply(u, Array.prototype.slice.call(arguments, 0, i - 1)); + }; + } + var Aa = _curry3( + _checkForMethod('slice', function slice(s, o, i) { + return Array.prototype.slice.call(i, s, o); + }) + ); + const ja = Aa; + const Ia = _curry1(_checkForMethod('tail', ja(1, 1 / 0))); + function pipe() { + if (0 === arguments.length) throw new Error('pipe requires at least one argument'); + return _arity(arguments[0].length, Ca(_pipe, arguments[0], Ia(arguments))); + } + const Na = _curry2(function defaultTo(s, o) { + return null == o || o != o ? s : o; + }); + const Da = _curry2(function prop(s, o) { + if (null != o) return Yo(s) ? _nth(s, o) : o[s]; + }); + const La = _curry3(function propOr(s, o, i) { + return Na(s, Da(o, i)); + }); + var Ba = _curry1(function (s) { + return _nth(-1, s); + }); + const Fa = Ba; + function _curryN(s, o, i) { + return function () { + for (var u = [], _ = 0, w = s, x = 0, C = !1; x < o.length || _ < arguments.length; ) { + var j; + x < o.length && (!_isPlaceholder(o[x]) || _ >= arguments.length) + ? (j = o[x]) + : ((j = arguments[_]), (_ += 1)), + (u[x] = j), + _isPlaceholder(j) ? (C = !0) : (w -= 1), + (x += 1); + } + return !C && w <= 0 ? i.apply(this, u) : _arity(Math.max(0, w), _curryN(s, u, i)); + }; + } + var $a = _curry2(function curryN(s, o) { + return 1 === s ? _curry1(o) : _arity(s, _curryN(s, [], o)); + }); + const za = $a; + var Ha = _curry1(function curry(s) { + return za(s.length, s); + }); + const Ja = Ha; + function _isFunction(s) { + var o = Object.prototype.toString.call(s); + return ( + '[object Function]' === o || + '[object AsyncFunction]' === o || + '[object GeneratorFunction]' === o || + '[object AsyncGeneratorFunction]' === o + ); + } + const Ga = _curry2(function invoker(s, o) { + return za(s + 1, function () { + var i = arguments[s]; + if (null != i && _isFunction(i[o])) + return i[o].apply(i, Array.prototype.slice.call(arguments, 0, s)); + throw new TypeError(ma(i) + ' does not have a method named "' + o + '"'); + }); + }); + const tl = Ga(1, 'split'); + function dropLastWhile(s, o) { + for (var i = o.length - 1; i >= 0 && s(o[i]); ) i -= 1; + return ja(0, i + 1, o); + } + var sl = (function () { + function XDropLastWhile(s, o) { + (this.f = s), (this.retained = []), (this.xf = o); + } + return ( + (XDropLastWhile.prototype['@@transducer/init'] = _xfBase_init), + (XDropLastWhile.prototype['@@transducer/result'] = function (s) { + return (this.retained = null), this.xf['@@transducer/result'](s); + }), + (XDropLastWhile.prototype['@@transducer/step'] = function (s, o) { + return this.f(o) ? this.retain(s, o) : this.flush(s, o); + }), + (XDropLastWhile.prototype.flush = function (s, o) { + return ( + (s = wa(this.xf, s, this.retained)), + (this.retained = []), + this.xf['@@transducer/step'](s, o) + ); + }), + (XDropLastWhile.prototype.retain = function (s, o) { + return this.retained.push(o), s; + }), + XDropLastWhile + ); + })(); + function _xdropLastWhile(s) { + return function (o) { + return new sl(s, o); + }; + } + const ul = _curry2(_dispatchable([], _xdropLastWhile, dropLastWhile)); + const yl = Ga(1, 'join'); + var vl = _curry1(function flip(s) { + return za(s.length, function (o, i) { + var u = Array.prototype.slice.call(arguments, 0); + return (u[0] = i), (u[1] = o), s.apply(this, u); + }); + }); + const _l = vl(_curry2(_includes)); + const El = Ja(function (s, o) { + return pipe(tl(''), ul(_l(s)), yl(''))(o); + }); + function _iterableReduce(s, o, i) { + for (var u = i.next(); !u.done; ) (o = s(o, u.value)), (u = i.next()); + return o; + } + function _methodReduce(s, o, i, u) { + return i[u](s, o); + } + const wl = _createReduce(_arrayReduce, _methodReduce, _iterableReduce); + var Sl = (function () { + function XMap(s, o) { + (this.xf = o), (this.f = s); + } + return ( + (XMap.prototype['@@transducer/init'] = _xfBase_init), + (XMap.prototype['@@transducer/result'] = _xfBase_result), + (XMap.prototype['@@transducer/step'] = function (s, o) { + return this.xf['@@transducer/step'](s, this.f(o)); + }), + XMap + ); + })(); + var xl = _curry2( + _dispatchable( + ['fantasy-land/map', 'map'], + function _xmap(s) { + return function (o) { + return new Sl(s, o); + }; + }, + function map(s, o) { + switch (Object.prototype.toString.call(o)) { + case '[object Function]': + return za(o.length, function () { + return s.call(this, o.apply(this, arguments)); + }); + case '[object Object]': + return _arrayReduce( + function (i, u) { + return (i[u] = s(o[u])), i; + }, + {}, + Wi(o) + ); + default: + return _map(s, o); + } + } + ) + ); + const kl = xl; + const Cl = _curry2(function ap(s, o) { + return 'function' == typeof o['fantasy-land/ap'] + ? o['fantasy-land/ap'](s) + : 'function' == typeof s.ap + ? s.ap(o) + : 'function' == typeof s + ? function (i) { + return s(i)(o(i)); + } + : wl( + function (s, i) { + return (function _concat(s, o) { + var i; + o = o || []; + var u = (s = s || []).length, + _ = o.length, + w = []; + for (i = 0; i < u; ) (w[w.length] = s[i]), (i += 1); + for (i = 0; i < _; ) (w[w.length] = o[i]), (i += 1); + return w; + })(s, kl(i, o)); + }, + [], + s + ); + }); + var Ol = _curry2(function liftN(s, o) { + var i = za(s, o); + return za(s, function () { + return _arrayReduce(Cl, kl(i, arguments[0]), Array.prototype.slice.call(arguments, 1)); + }); + }); + const Al = Ol; + var Il = _curry1(function lift(s) { + return Al(s.length, s); + }); + const Pl = Il; + const Ml = Pl( + _curry1(function not(s) { + return !s; + }) + ); + const Tl = _curry1(function always(s) { + return function () { + return s; + }; + }); + const Nl = Tl(void 0); + const Rl = ra(Nl()); + const Dl = Ml(Rl); + const Ll = _curry2(function max(s, o) { + if (s === o) return o; + function safeMax(s, o) { + if (s > o != o > s) return o > s ? o : s; + } + var i = safeMax(s, o); + if (void 0 !== i) return i; + var u = safeMax(typeof s, typeof o); + if (void 0 !== u) return u === typeof s ? s : o; + var _ = ma(s), + w = safeMax(_, ma(o)); + return void 0 !== w && w === _ ? s : o; + }); + var Bl = _curry2(function pluck(s, o) { + return kl(Da(s), o); + }); + const Fl = Bl; + const $l = _curry1(function anyPass(s) { + return za(Ca(Ll, 0, Fl('length', s)), function () { + for (var o = 0, i = s.length; o < i; ) { + if (s[o].apply(this, arguments)) return !0; + o += 1; + } + return !1; + }); + }); + var identical = function (s, o) { + switch (arguments.length) { + case 0: + return identical; + case 1: + return function unaryIdentical(o) { + return 0 === arguments.length ? unaryIdentical : Zo(s, o); + }; + default: + return Zo(s, o); + } + }; + const Vl = identical; + const Ul = za(1, pipe(ea, Vl('GeneratorFunction'))); + const zl = za(1, pipe(ea, Vl('AsyncFunction'))); + const Wl = $l([pipe(ea, Vl('Function')), Ul, zl]); + var Kl = _curry3(function replace(s, o, i) { + return i.replace(s, o); + }); + const Hl = Kl; + const Jl = za(1, pipe(ea, Vl('RegExp'))); + const Gl = _curry3(function when(s, o, i) { + return s(i) ? o(i) : i; + }); + const Yl = za(1, pipe(ea, Vl('String'))); + const Xl = Gl(Yl, Hl(/[.*+?^${}()|[\]\\-]/g, '\\$&')); + var Zl = function checkValue(s, o) { + if ('string' != typeof s && !(s instanceof String)) + throw TypeError('`'.concat(o, '` must be a string')); + }; + const Ql = function replaceAll(s, o, i) { + !(function checkArguments(s, o, i) { + if (null == i || null == s || null == o) + throw TypeError('Input values must not be `null` or `undefined`'); + })(s, o, i), + Zl(i, 'str'), + Zl(o, 'replaceValue'), + (function checkSearchValue(s) { + if (!('string' == typeof s || s instanceof String || s instanceof RegExp)) + throw TypeError('`searchValue` must be a string or an regexp'); + })(s); + var u = new RegExp(Jl(s) ? s : Xl(s), 'g'); + return Hl(u, o, i); + }; + var ec = za(3, Ql), + rc = Ga(2, 'replaceAll'); + const sc = Wl(String.prototype.replaceAll) ? rc : ec, + isWindows = () => Xo(ya(/^win/), ['platform'], Go), + getProtocol = (s) => { + try { + const o = new URL(s); + return El(':', o.protocol); + } catch { + return; + } + }, + oc = + (pipe(getProtocol, Dl), + (s) => { + if (Go.browser) return !1; + const o = getProtocol(s); + return Rl(o) || 'file' === o || /^[a-zA-Z]$/.test(o); + }), + isHttpUrl = (s) => { + const o = getProtocol(s); + return 'http' === o || 'https' === o; + }, + toFileSystemPath = (s, o) => { + const i = [/%23/g, '#', /%24/g, '$', /%26/g, '&', /%2C/g, ',', /%40/g, '@'], + u = La(!1, 'keepFileProtocol', o), + _ = La(isWindows, 'isWindows', o); + let w = decodeURI(s); + for (let s = 0; s < i.length; s += 2) w = w.replace(i[s], i[s + 1]); + let x = 'file://' === w.substring(0, 7).toLowerCase(); + return ( + x && + ((w = '/' === w[7] ? w.substring(8) : w.substring(7)), + _() && '/' === w[1] && (w = `${w[0]}:${w.substring(1)}`), + u ? (w = `file:///${w}`) : ((x = !1), (w = _() ? w : `/${w}`))), + _() && + !x && + ((w = sc('/', '\\', w)), + ':\\' === w.substring(1, 3) && (w = w[0].toUpperCase() + w.substring(1))), + w + ); + }, + getHash = (s) => { + const o = s.indexOf('#'); + return -1 !== o ? s.substring(o) : '#'; + }, + stripHash = (s) => { + const o = s.indexOf('#'); + let i = s; + return o >= 0 && (i = s.substring(0, o)), i; + }, + url_cwd = () => { + if (Go.browser) return stripHash(globalThis.location.href); + const s = Go.cwd(), + o = Fa(s); + return ['/', '\\'].includes(o) ? s : s + (isWindows() ? '\\' : '/'); + }, + resolve = (s, o) => { + const i = new URL(o, new URL(s, 'resolve://')); + if ('resolve:' === i.protocol) { + const { pathname: s, search: o, hash: u } = i; + return s + o + u; + } + return i.toString(); + }, + sanitize = (s) => { + if (oc(s)) + return ((s) => { + const o = [/\?/g, '%3F', /#/g, '%23']; + let i = s; + isWindows() && (i = i.replace(/\\/g, '/')), (i = encodeURI(i)); + for (let s = 0; s < o.length; s += 2) i = i.replace(o[s], o[s + 1]); + return i; + })(toFileSystemPath(s)); + try { + return new URL(s).toString(); + } catch { + return encodeURI(decodeURI(s)).replace(/%5B/g, '[').replace(/%5D/g, ']'); + } + }, + unsanitize = (s) => (oc(s) ? toFileSystemPath(s) : decodeURI(s)), + { + fetch: ic, + Response: ac, + Headers: lc, + Request: cc, + FormData: pc, + File: hc, + Blob: dc + } = globalThis; + function _array_like_to_array(s, o) { + (null == o || o > s.length) && (o = s.length); + for (var i = 0, u = new Array(o); i < o; i++) u[i] = s[i]; + return u; + } + function legacy_defineProperties(s, o) { + for (var i = 0; i < o.length; i++) { + var u = o[i]; + (u.enumerable = u.enumerable || !1), + (u.configurable = !0), + 'value' in u && (u.writable = !0), + Object.defineProperty(s, u.key, u); + } + } + function _instanceof(s, o) { + return null != o && 'undefined' != typeof Symbol && o[Symbol.hasInstance] + ? !!o[Symbol.hasInstance](s) + : s instanceof o; + } + function _sliced_to_array(s, o) { + return ( + (function _array_with_holes(s) { + if (Array.isArray(s)) return s; + })(s) || + (function _iterable_to_array_limit(s, o) { + var i = + null == s + ? null + : ('undefined' != typeof Symbol && s[Symbol.iterator]) || s['@@iterator']; + if (null != i) { + var u, + _, + w = [], + x = !0, + C = !1; + try { + for ( + i = i.call(s); + !(x = (u = i.next()).done) && (w.push(u.value), !o || w.length !== o); + x = !0 + ); + } catch (s) { + (C = !0), (_ = s); + } finally { + try { + x || null == i.return || i.return(); + } finally { + if (C) throw _; + } + } + return w; + } + })(s, o) || + (function _unsupported_iterable_to_array(s, o) { + if (!s) return; + if ('string' == typeof s) return _array_like_to_array(s, o); + var i = Object.prototype.toString.call(s).slice(8, -1); + 'Object' === i && s.constructor && (i = s.constructor.name); + if ('Map' === i || 'Set' === i) return Array.from(i); + if ('Arguments' === i || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(i)) + return _array_like_to_array(s, o); + })(s, o) || + (function _non_iterable_rest() { + throw new TypeError( + 'Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.' + ); + })() + ); + } + function _type_of(s) { + return s && 'undefined' != typeof Symbol && s.constructor === Symbol + ? 'symbol' + : typeof s; + } + void 0 === globalThis.fetch && (globalThis.fetch = ic), + void 0 === globalThis.Headers && (globalThis.Headers = lc), + void 0 === globalThis.Request && (globalThis.Request = cc), + void 0 === globalThis.Response && (globalThis.Response = ac), + void 0 === globalThis.FormData && (globalThis.FormData = pc), + void 0 === globalThis.File && (globalThis.File = hc), + void 0 === globalThis.Blob && (globalThis.Blob = dc); + var __typeError = function (s) { + throw TypeError(s); + }, + __accessCheck = function (s, o, i) { + return o.has(s) || __typeError('Cannot ' + i); + }, + __privateGet = function (s, o, i) { + return __accessCheck(s, o, 'read from private field'), i ? i.call(s) : o.get(s); + }, + __privateAdd = function (s, o, i) { + return o.has(s) + ? __typeError('Cannot add the same private member more than once') + : _instanceof(o, WeakSet) + ? o.add(s) + : o.set(s, i); + }, + __privateSet = function (s, o, i, u) { + return __accessCheck(s, o, 'write to private field'), u ? u.call(s, i) : o.set(s, i), i; + }, + to_string = function (s) { + return Object.prototype.toString.call(s); + }, + is_typed_array = function (s) { + return ArrayBuffer.isView(s) && !_instanceof(s, DataView); + }, + fc = Array.isArray, + gc = Object.getOwnPropertyDescriptor, + bc = Object.prototype.propertyIsEnumerable, + _c = Object.getOwnPropertySymbols, + Ec = Object.prototype.hasOwnProperty; + function own_enumerable_keys(s) { + for (var o = Object.keys(s), i = _c(s), u = 0; u < i.length; u++) + bc.call(s, i[u]) && o.push(i[u]); + return o; + } + function is_writable(s, o) { + var i; + return !(null === (i = gc(s, o)) || void 0 === i ? void 0 : i.writable); + } + function legacy_copy(s, o) { + if ('object' === (void 0 === s ? 'undefined' : _type_of(s)) && null !== s) { + var i; + if (fc(s)) i = []; + else if ('[object Date]' === to_string(s)) i = new Date(s.getTime ? s.getTime() : s); + else if ( + (function (s) { + return '[object RegExp]' === to_string(s); + })(s) + ) + i = new RegExp(s); + else if ( + (function (s) { + return '[object Error]' === to_string(s); + })(s) + ) + i = { message: s.message }; + else if ( + (function (s) { + return '[object Boolean]' === to_string(s); + })(s) || + (function (s) { + return '[object Number]' === to_string(s); + })(s) || + (function (s) { + return '[object String]' === to_string(s); + })(s) + ) + i = Object(s); + else { + if (is_typed_array(s)) return s.slice(); + i = Object.create(Object.getPrototypeOf(s)); + } + var u = o.includeSymbols ? own_enumerable_keys : Object.keys, + _ = !0, + w = !1, + x = void 0; + try { + for (var C, j = u(s)[Symbol.iterator](); !(_ = (C = j.next()).done); _ = !0) { + var L = C.value; + i[L] = s[L]; + } + } catch (s) { + (w = !0), (x = s); + } finally { + try { + _ || null == j.return || j.return(); + } finally { + if (w) throw x; + } + } + return i; + } + return s; + } + var kc, + Oc, + jc = { includeSymbols: !1, immutable: !1 }; + function walk(s, o) { + var i = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : jc, + u = [], + _ = [], + w = !0, + x = i.includeSymbols ? own_enumerable_keys : Object.keys, + C = !!i.immutable; + return (function walker(s) { + var j = C ? legacy_copy(s, i) : s, + L = {}, + B = !0, + $ = { + node: j, + node_: s, + path: [].concat(u), + parent: _[_.length - 1], + parents: _, + key: u[u.length - 1], + isRoot: 0 === u.length, + level: u.length, + circular: void 0, + isLeaf: !1, + notLeaf: !0, + notRoot: !0, + isFirst: !1, + isLast: !1, + update: function update(s) { + var o = arguments.length > 1 && void 0 !== arguments[1] && arguments[1]; + $.isRoot || ($.parent.node[$.key] = s), ($.node = s), o && (B = !1); + }, + delete: function _delete(s) { + delete $.parent.node[$.key], s && (B = !1); + }, + remove: function remove(s) { + fc($.parent.node) ? $.parent.node.splice($.key, 1) : delete $.parent.node[$.key], + s && (B = !1); + }, + keys: null, + before: function before(s) { + L.before = s; + }, + after: function after(s) { + L.after = s; + }, + pre: function pre(s) { + L.pre = s; + }, + post: function post(s) { + L.post = s; + }, + stop: function stop() { + w = !1; + }, + block: function block() { + B = !1; + } + }; + if (!w) return $; + function update_state() { + if ('object' === _type_of($.node) && null !== $.node) { + ($.keys && $.node_ === $.node) || ($.keys = x($.node)), + ($.isLeaf = 0 === $.keys.length); + for (var o = 0; o < _.length; o++) + if (_[o].node_ === s) { + $.circular = _[o]; + break; + } + } else ($.isLeaf = !0), ($.keys = null); + ($.notLeaf = !$.isLeaf), ($.notRoot = !$.isRoot); + } + update_state(); + var V = o.call($, $.node); + if ((void 0 !== V && $.update && $.update(V), L.before && L.before.call($, $.node), !B)) + return $; + if ('object' === _type_of($.node) && null !== $.node && !$.circular) { + var U; + _.push($), update_state(); + var z = !0, + Y = !1, + Z = void 0; + try { + for ( + var ee, + ie = Object.entries(null !== (U = $.keys) && void 0 !== U ? U : [])[ + Symbol.iterator + ](); + !(z = (ee = ie.next()).done); + z = !0 + ) { + var ae, + le = _sliced_to_array(ee.value, 2), + ce = le[0], + pe = le[1]; + u.push(pe), L.pre && L.pre.call($, $.node[pe], pe); + var de = walker($.node[pe]); + C && Ec.call($.node, pe) && !is_writable($.node, pe) && ($.node[pe] = de.node), + (de.isLast = + !!(null === (ae = $.keys) || void 0 === ae ? void 0 : ae.length) && + +ce == $.keys.length - 1), + (de.isFirst = 0 == +ce), + L.post && L.post.call($, de), + u.pop(); + } + } catch (s) { + (Y = !0), (Z = s); + } finally { + try { + z || null == ie.return || ie.return(); + } finally { + if (Y) throw Z; + } + } + _.pop(); + } + return L.after && L.after.call($, $.node), $; + })(s).node; + } + var Ic = (function () { + function Traverse(s) { + var o = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : jc; + !(function _class_call_check(s, o) { + if (!(s instanceof o)) throw new TypeError('Cannot call a class as a function'); + })(this, Traverse), + __privateAdd(this, kc), + __privateAdd(this, Oc), + __privateSet(this, kc, s), + __privateSet(this, Oc, o); + } + return ( + (function _create_class(s, o, i) { + return ( + o && legacy_defineProperties(s.prototype, o), i && legacy_defineProperties(s, i), s + ); + })(Traverse, [ + { + key: 'get', + value: function get(s) { + for (var o = __privateGet(this, kc), i = 0; o && i < s.length; i++) { + var u = s[i]; + if ( + !Ec.call(o, u) || + (!__privateGet(this, Oc).includeSymbols && + 'symbol' === (void 0 === u ? 'undefined' : _type_of(u))) + ) + return; + o = o[u]; + } + return o; + } + }, + { + key: 'has', + value: function has(s) { + for (var o = __privateGet(this, kc), i = 0; o && i < s.length; i++) { + var u = s[i]; + if ( + !Ec.call(o, u) || + (!__privateGet(this, Oc).includeSymbols && + 'symbol' === (void 0 === u ? 'undefined' : _type_of(u))) + ) + return !1; + o = o[u]; + } + return !0; + } + }, + { + key: 'set', + value: function set(s, o) { + var i = __privateGet(this, kc), + u = 0; + for (u = 0; u < s.length - 1; u++) { + var _ = s[u]; + Ec.call(i, _) || (i[_] = {}), (i = i[_]); + } + return (i[s[u]] = o), o; + } + }, + { + key: 'map', + value: function map(s) { + return walk(__privateGet(this, kc), s, { + immutable: !0, + includeSymbols: !!__privateGet(this, Oc).includeSymbols + }); + } + }, + { + key: 'forEach', + value: function forEach(s) { + return ( + __privateSet(this, kc, walk(__privateGet(this, kc), s, __privateGet(this, Oc))), + __privateGet(this, kc) + ); + } + }, + { + key: 'reduce', + value: function reduce(s, o) { + var i = 1 === arguments.length, + u = i ? __privateGet(this, kc) : o; + return ( + this.forEach(function (o) { + (this.isRoot && i) || (u = s.call(this, u, o)); + }), + u + ); + } + }, + { + key: 'paths', + value: function paths() { + var s = []; + return ( + this.forEach(function () { + s.push(this.path); + }), + s + ); + } + }, + { + key: 'nodes', + value: function nodes() { + var s = []; + return ( + this.forEach(function () { + s.push(this.node); + }), + s + ); + } + }, + { + key: 'clone', + value: function clone() { + var s = [], + o = [], + i = __privateGet(this, Oc); + return is_typed_array(__privateGet(this, kc)) + ? __privateGet(this, kc).slice() + : (function clone(u) { + for (var _ = 0; _ < s.length; _++) if (s[_] === u) return o[_]; + if ('object' === (void 0 === u ? 'undefined' : _type_of(u)) && null !== u) { + var w = legacy_copy(u, i); + s.push(u), o.push(w); + var x = i.includeSymbols ? own_enumerable_keys : Object.keys, + C = !0, + j = !1, + L = void 0; + try { + for ( + var B, $ = x(u)[Symbol.iterator](); + !(C = (B = $.next()).done); + C = !0 + ) { + var V = B.value; + w[V] = clone(u[V]); + } + } catch (s) { + (j = !0), (L = s); + } finally { + try { + C || null == $.return || $.return(); + } finally { + if (j) throw L; + } + } + return s.pop(), o.pop(), w; + } + return u; + })(__privateGet(this, kc)); + } + } + ]), + Traverse + ); + })(); + (kc = new WeakMap()), (Oc = new WeakMap()); + var traverse = function (s, o) { + return new Ic(s, o); + }; + (traverse.get = function (s, o, i) { + return new Ic(s, i).get(o); + }), + (traverse.set = function (s, o, i, u) { + return new Ic(s, u).set(o, i); + }), + (traverse.has = function (s, o, i) { + return new Ic(s, i).has(o); + }), + (traverse.map = function (s, o, i) { + return new Ic(s, i).map(o); + }), + (traverse.forEach = function (s, o, i) { + return new Ic(s, i).forEach(o); + }), + (traverse.reduce = function (s, o, i, u) { + return new Ic(s, u).reduce(o, i); + }), + (traverse.paths = function (s, o) { + return new Ic(s, o).paths(); + }), + (traverse.nodes = function (s, o) { + return new Ic(s, o).nodes(); + }), + (traverse.clone = function (s, o) { + return new Ic(s, o).clone(); + }); + var Pc = traverse; + const Mc = 'application/json, application/yaml', + Nc = 'https://swagger.io', + Rc = Object.freeze({ url: '/' }), + Lc = ['properties'], + Fc = ['properties'], + qc = [ + 'definitions', + 'parameters', + 'responses', + 'securityDefinitions', + 'components/schemas', + 'components/responses', + 'components/parameters', + 'components/securitySchemes' + ], + Kc = ['schema/example', 'items/example']; + function isFreelyNamed(s) { + const o = s[s.length - 1], + i = s[s.length - 2], + u = s.join('/'); + return ( + (Lc.indexOf(o) > -1 && -1 === Fc.indexOf(i)) || + qc.indexOf(u) > -1 || + Kc.some((s) => u.indexOf(s) > -1) + ); + } + function absolutifyPointer(s, o) { + const [i, u] = s.split('#'), + _ = null != o ? o : '', + w = null != i ? i : ''; + let x; + if (isHttpUrl(_)) x = resolve(_, w); + else { + const s = resolve(Nc, _), + o = resolve(s, w).replace(Nc, ''); + x = w.startsWith('/') ? o : o.substring(1); + } + return u ? `${x}#${u}` : x; + } + const Hc = /^([a-z]+:\/\/|\/\/)/i; + class JSONRefError extends Jo {} + const Jc = {}, + Gc = new WeakMap(), + Qc = [ + (s) => 'paths' === s[0] && 'responses' === s[3] && 'examples' === s[5], + (s) => + 'paths' === s[0] && 'responses' === s[3] && 'content' === s[5] && 'example' === s[7], + (s) => + 'paths' === s[0] && + 'responses' === s[3] && + 'content' === s[5] && + 'examples' === s[7] && + 'value' === s[9], + (s) => + 'paths' === s[0] && + 'requestBody' === s[3] && + 'content' === s[4] && + 'example' === s[6], + (s) => + 'paths' === s[0] && + 'requestBody' === s[3] && + 'content' === s[4] && + 'examples' === s[6] && + 'value' === s[8], + (s) => 'paths' === s[0] && 'parameters' === s[2] && 'example' === s[4], + (s) => 'paths' === s[0] && 'parameters' === s[3] && 'example' === s[5], + (s) => + 'paths' === s[0] && 'parameters' === s[2] && 'examples' === s[4] && 'value' === s[6], + (s) => + 'paths' === s[0] && 'parameters' === s[3] && 'examples' === s[5] && 'value' === s[7], + (s) => + 'paths' === s[0] && 'parameters' === s[2] && 'content' === s[4] && 'example' === s[6], + (s) => + 'paths' === s[0] && + 'parameters' === s[2] && + 'content' === s[4] && + 'examples' === s[6] && + 'value' === s[8], + (s) => + 'paths' === s[0] && 'parameters' === s[3] && 'content' === s[4] && 'example' === s[7], + (s) => + 'paths' === s[0] && + 'parameters' === s[3] && + 'content' === s[5] && + 'examples' === s[7] && + 'value' === s[9] + ], + eu = { + key: '$ref', + plugin: (s, o, i, u) => { + const _ = u.getInstance(), + w = i.slice(0, -1); + if (isFreelyNamed(w) || ((s) => Qc.some((o) => o(s)))(w)) return; + const { baseDoc: x } = u.getContext(i); + if ('string' != typeof s) + return new JSONRefError('$ref: must be a string (JSON-Ref)', { + $ref: s, + baseDoc: x, + fullPath: i + }); + const C = refs_split(s), + j = C[0], + L = C[1] || ''; + let B, $, V; + try { + B = x || j ? absoluteify(j, x) : null; + } catch (o) { + return wrapError(o, { pointer: L, $ref: s, basePath: B, fullPath: i }); + } + if ( + (function pointerAlreadyInPath(s, o, i, u) { + let _ = Gc.get(u); + _ || ((_ = {}), Gc.set(u, _)); + const w = (function arrayToJsonPointer(s) { + if (0 === s.length) return ''; + return `/${s.map(escapeJsonPointerToken).join('/')}`; + })(i), + x = `${o || ''}#${s}`, + C = w.replace(/allOf\/\d+\/?/g, ''), + j = u.contextTree.get([]).baseDoc; + if (o === j && pointerIsAParent(C, s)) return !0; + let L = ''; + const B = i.some( + (s) => ( + (L = `${L}/${escapeJsonPointerToken(s)}`), + _[L] && _[L].some((s) => pointerIsAParent(s, x) || pointerIsAParent(x, s)) + ) + ); + if (B) return !0; + return void (_[C] = (_[C] || []).concat(x)); + })(L, B, w, u) && + !_.useCircularStructures + ) { + const o = absolutifyPointer(s, B); + return s === o ? null : zo.replace(i, o); + } + if ( + (null == B + ? ((V = jsonPointerToArray(L)), + ($ = u.get(V)), + void 0 === $ && + ($ = new JSONRefError(`Could not resolve reference: ${s}`, { + pointer: L, + $ref: s, + baseDoc: x, + fullPath: i + }))) + : (($ = extractFromDoc(B, L)), + ($ = + null != $.__value + ? $.__value + : $.catch((o) => { + throw wrapError(o, { pointer: L, $ref: s, baseDoc: x, fullPath: i }); + }))), + $ instanceof Error) + ) + return [zo.remove(i), $]; + const U = absolutifyPointer(s, B), + z = zo.replace(w, $, { $$ref: U }); + if (B && B !== x) return [z, zo.context(w, { baseDoc: B })]; + try { + if ( + !(function patchValueAlreadyInPath(s, o) { + const i = [s]; + return ( + o.path.reduce((s, o) => (i.push(s[o]), s[o]), s), pointToAncestor(o.value) + ); + function pointToAncestor(s) { + return ( + zo.isObject(s) && + (i.indexOf(s) >= 0 || Object.keys(s).some((o) => pointToAncestor(s[o]))) + ); + } + })(u.state, z) || + _.useCircularStructures + ) + return z; + } catch (s) { + return null; + } + } + }, + tu = Object.assign(eu, { + docCache: Jc, + absoluteify, + clearCache: function clearCache(s) { + void 0 !== s + ? delete Jc[s] + : Object.keys(Jc).forEach((s) => { + delete Jc[s]; + }); + }, + JSONRefError, + wrapError, + getDoc, + split: refs_split, + extractFromDoc, + fetchJSON: function fetchJSON(s) { + return fetch(s, { headers: { Accept: Mc }, loadSpec: !0 }) + .then((s) => s.text()) + .then((s) => mn.load(s)); + }, + extract, + jsonPointerToArray, + unescapeJsonPointerToken + }), + ru = tu; + function absoluteify(s, o) { + if (!Hc.test(s)) { + if (!o) + throw new JSONRefError( + `Tried to resolve a relative URL, without having a basePath. path: '${s}' basePath: '${o}'` + ); + return resolve(o, s); + } + return s; + } + function wrapError(s, o) { + let i; + return ( + (i = + s && s.response && s.response.body + ? `${s.response.body.code} ${s.response.body.message}` + : s.message), + new JSONRefError(`Could not resolve reference: ${i}`, { ...o, cause: s }) + ); + } + function refs_split(s) { + return (s + '').split('#'); + } + function extractFromDoc(s, o) { + const i = Jc[s]; + if (i && !zo.isPromise(i)) + try { + const s = extract(o, i); + return Object.assign(Promise.resolve(s), { __value: s }); + } catch (s) { + return Promise.reject(s); + } + return getDoc(s).then((s) => extract(o, s)); + } + function getDoc(s) { + const o = Jc[s]; + return o + ? zo.isPromise(o) + ? o + : Promise.resolve(o) + : ((Jc[s] = tu.fetchJSON(s).then((o) => ((Jc[s] = o), o))), Jc[s]); + } + function extract(s, o) { + const i = jsonPointerToArray(s); + if (i.length < 1) return o; + const u = zo.getIn(o, i); + if (void 0 === u) + throw new JSONRefError(`Could not resolve pointer: ${s} does not exist in document`, { + pointer: s + }); + return u; + } + function jsonPointerToArray(s) { + if ('string' != typeof s) throw new TypeError('Expected a string, got a ' + typeof s); + return ( + '/' === s[0] && (s = s.substr(1)), + '' === s ? [] : s.split('/').map(unescapeJsonPointerToken) + ); + } + function unescapeJsonPointerToken(s) { + if ('string' != typeof s) return s; + return new URLSearchParams(`=${s.replace(/~1/g, '/').replace(/~0/g, '~')}`).get(''); + } + function escapeJsonPointerToken(s) { + return new URLSearchParams([['', s.replace(/~/g, '~0').replace(/\//g, '~1')]]) + .toString() + .slice(1); + } + const pointerBoundaryChar = (s) => !s || '/' === s || '#' === s; + function pointerIsAParent(s, o) { + if (pointerBoundaryChar(o)) return !0; + const i = s.charAt(o.length), + u = o.slice(-1); + return 0 === s.indexOf(o) && (!i || '/' === i || '#' === i) && '#' !== u; + } + const nu = { + key: 'allOf', + plugin: (s, o, i, u, _) => { + if (_.meta && _.meta.$$ref) return; + const w = i.slice(0, -1); + if (isFreelyNamed(w)) return; + if (!Array.isArray(s)) { + const s = new TypeError('allOf must be an array'); + return (s.fullPath = i), s; + } + let x = !1, + C = _.value; + if ( + (w.forEach((s) => { + C && (C = C[s]); + }), + (C = { ...C }), + 0 === Object.keys(C).length) + ) + return; + delete C.allOf; + const j = []; + return ( + j.push(u.replace(w, {})), + s.forEach((s, o) => { + if (!u.isObject(s)) { + if (x) return null; + x = !0; + const s = new TypeError('Elements in allOf must be objects'); + return (s.fullPath = i), j.push(s); + } + j.push(u.mergeDeep(w, s)); + const _ = (function generateAbsoluteRefPatches( + s, + o, + { + specmap: i, + getBaseUrlForNodePath: u = (s) => i.getContext([...o, ...s]).baseDoc, + targetKeys: _ = ['$ref', '$$ref'] + } = {} + ) { + const w = []; + return ( + Pc(s).forEach(function callback() { + if (_.includes(this.key) && 'string' == typeof this.node) { + const s = this.path, + _ = o.concat(this.path), + x = absolutifyPointer(this.node, u(s)); + w.push(i.replace(_, x)); + } + }), + w + ); + })(s, i.slice(0, -1), { + getBaseUrlForNodePath: (s) => u.getContext([...i, o, ...s]).baseDoc, + specmap: u + }); + j.push(..._); + }), + C.example && j.push(u.remove([].concat(w, 'example'))), + j.push(u.mergeDeep(w, C)), + C.$$ref || j.push(u.remove([].concat(w, '$$ref'))), + j + ); + } + }, + su = { + key: 'parameters', + plugin: (s, o, i, u) => { + if (Array.isArray(s) && s.length) { + const o = Object.assign([], s), + _ = i.slice(0, -1), + w = { ...zo.getIn(u.spec, _) }; + for (let _ = 0; _ < s.length; _ += 1) { + const x = s[_]; + try { + o[_].default = u.parameterMacro(w, x); + } catch (s) { + const o = new Error(s); + return (o.fullPath = i), o; + } + } + return zo.replace(i, o); + } + return zo.replace(i, s); + } + }, + ou = { + key: 'properties', + plugin: (s, o, i, u) => { + const _ = { ...s }; + for (const o in s) + try { + _[o].default = u.modelPropertyMacro(_[o]); + } catch (s) { + const o = new Error(s); + return (o.fullPath = i), o; + } + return zo.replace(i, _); + } + }; + class ContextTree { + constructor(s) { + this.root = context_tree_createNode(s || {}); + } + set(s, o) { + const i = this.getParent(s, !0); + if (!i) return void context_tree_updateNode(this.root, o, null); + const u = s[s.length - 1], + { children: _ } = i; + _[u] ? context_tree_updateNode(_[u], o, i) : (_[u] = context_tree_createNode(o, i)); + } + get(s) { + if ((s = s || []).length < 1) return this.root.value; + let o, + i, + u = this.root; + for (let _ = 0; _ < s.length && ((i = s[_]), (o = u.children), o[i]); _ += 1) u = o[i]; + return u && u.protoValue; + } + getParent(s, o) { + return !s || s.length < 1 + ? null + : s.length < 2 + ? this.root + : s.slice(0, -1).reduce((s, i) => { + if (!s) return s; + const { children: u } = s; + return !u[i] && o && (u[i] = context_tree_createNode(null, s)), u[i]; + }, this.root); + } + } + function context_tree_createNode(s, o) { + return context_tree_updateNode({ children: {} }, s, o); + } + function context_tree_updateNode(s, o, i) { + return ( + (s.value = o || {}), + (s.protoValue = i ? { ...i.protoValue, ...s.value } : s.value), + Object.keys(s.children).forEach((o) => { + const i = s.children[o]; + s.children[o] = context_tree_updateNode(i, i.value, s); + }), + s + ); + } + const specmap_noop = () => {}; + class SpecMap { + static getPluginName(s) { + return s.pluginName; + } + static getPatchesOfType(s, o) { + return s.filter(o); + } + constructor(s) { + Object.assign( + this, + { + spec: '', + debugLevel: 'info', + plugins: [], + pluginHistory: {}, + errors: [], + mutations: [], + promisedPatches: [], + state: {}, + patches: [], + context: {}, + contextTree: new ContextTree(), + showDebug: !1, + allPatches: [], + pluginProp: 'specMap', + libMethods: Object.assign(Object.create(this), zo, { getInstance: () => this }), + allowMetaPatches: !1 + }, + s + ), + (this.get = this._get.bind(this)), + (this.getContext = this._getContext.bind(this)), + (this.hasRun = this._hasRun.bind(this)), + (this.wrappedPlugins = this.plugins + .map(this.wrapPlugin.bind(this)) + .filter(zo.isFunction)), + this.patches.push(zo.add([], this.spec)), + this.patches.push(zo.context([], this.context)), + this.updatePatches(this.patches); + } + debug(s, ...o) { + this.debugLevel === s && console.log(...o); + } + verbose(s, ...o) { + 'verbose' === this.debugLevel && console.log(`[${s}] `, ...o); + } + wrapPlugin(s, o) { + const { pathDiscriminator: i } = this; + let u, + _ = null; + return ( + s[this.pluginProp] + ? ((_ = s), (u = s[this.pluginProp])) + : zo.isFunction(s) + ? (u = s) + : zo.isObject(s) && + (u = (function createKeyBasedPlugin(s) { + const isSubPath = (s, o) => + !Array.isArray(s) || s.every((s, i) => s === o[i]); + return function* generator(o, u) { + const _ = {}; + for (const [s, i] of o.filter(zo.isAdditiveMutation).entries()) { + if (!(s < 3e3)) return; + yield* traverse(i.value, i.path, i); + } + function* traverse(o, w, x) { + if (zo.isObject(o)) { + const C = w.length - 1, + j = w[C], + L = w.indexOf('properties'), + B = 'properties' === j && C === L, + $ = u.allowMetaPatches && _[o.$$ref]; + for (const C of Object.keys(o)) { + const j = o[C], + L = w.concat(C), + V = zo.isObject(j), + U = o.$$ref; + if ( + ($ || + (V && + (u.allowMetaPatches && U && (_[U] = !0), + yield* traverse(j, L, x))), + !B && C === s.key) + ) { + const o = isSubPath(i, w); + (i && !o) || (yield s.plugin(j, C, L, u, x)); + } + } + } else s.key === w[w.length - 1] && (yield s.plugin(o, s.key, w, u)); + } + }; + })(s)), + Object.assign(u.bind(_), { pluginName: s.name || o, isGenerator: zo.isGenerator(u) }) + ); + } + nextPlugin() { + return this.wrappedPlugins.find((s) => this.getMutationsForPlugin(s).length > 0); + } + nextPromisedPatch() { + if (this.promisedPatches.length > 0) + return Promise.race(this.promisedPatches.map((s) => s.value)); + } + getPluginHistory(s) { + const o = this.constructor.getPluginName(s); + return this.pluginHistory[o] || []; + } + getPluginRunCount(s) { + return this.getPluginHistory(s).length; + } + getPluginHistoryTip(s) { + const o = this.getPluginHistory(s); + return (o && o[o.length - 1]) || {}; + } + getPluginMutationIndex(s) { + const o = this.getPluginHistoryTip(s).mutationIndex; + return 'number' != typeof o ? -1 : o; + } + updatePluginHistory(s, o) { + const i = this.constructor.getPluginName(s); + (this.pluginHistory[i] = this.pluginHistory[i] || []), this.pluginHistory[i].push(o); + } + updatePatches(s) { + zo.normalizeArray(s).forEach((s) => { + if (s instanceof Error) this.errors.push(s); + else + try { + if (!zo.isObject(s)) + return void this.debug('updatePatches', 'Got a non-object patch', s); + if ((this.showDebug && this.allPatches.push(s), zo.isPromise(s.value))) + return this.promisedPatches.push(s), void this.promisedPatchThen(s); + if (zo.isContextPatch(s)) return void this.setContext(s.path, s.value); + zo.isMutation(s) && this.updateMutations(s); + } catch (s) { + console.error(s), this.errors.push(s); + } + }); + } + updateMutations(s) { + 'object' == typeof s.value && + !Array.isArray(s.value) && + this.allowMetaPatches && + (s.value = { ...s.value }); + const o = zo.applyPatch(this.state, s, { allowMetaPatches: this.allowMetaPatches }); + o && (this.mutations.push(s), (this.state = o)); + } + removePromisedPatch(s) { + const o = this.promisedPatches.indexOf(s); + o < 0 + ? this.debug("Tried to remove a promisedPatch that isn't there!") + : this.promisedPatches.splice(o, 1); + } + promisedPatchThen(s) { + return ( + (s.value = s.value + .then((o) => { + const i = { ...s, value: o }; + this.removePromisedPatch(s), this.updatePatches(i); + }) + .catch((o) => { + this.removePromisedPatch(s), this.updatePatches(o); + })), + s.value + ); + } + getMutations(s, o) { + return ( + (s = s || 0), + 'number' != typeof o && (o = this.mutations.length), + this.mutations.slice(s, o) + ); + } + getCurrentMutations() { + return this.getMutationsForPlugin(this.getCurrentPlugin()); + } + getMutationsForPlugin(s) { + const o = this.getPluginMutationIndex(s); + return this.getMutations(o + 1); + } + getCurrentPlugin() { + return this.currentPlugin; + } + getLib() { + return this.libMethods; + } + _get(s) { + return zo.getIn(this.state, s); + } + _getContext(s) { + return this.contextTree.get(s); + } + setContext(s, o) { + return this.contextTree.set(s, o); + } + _hasRun(s) { + return this.getPluginRunCount(this.getCurrentPlugin()) > (s || 0); + } + dispatch() { + const s = this, + o = this.nextPlugin(); + if (!o) { + const s = this.nextPromisedPatch(); + if (s) return s.then(() => this.dispatch()).catch(() => this.dispatch()); + const o = { spec: this.state, errors: this.errors }; + return this.showDebug && (o.patches = this.allPatches), Promise.resolve(o); + } + if ( + ((s.pluginCount = s.pluginCount || new WeakMap()), + s.pluginCount.set(o, (s.pluginCount.get(o) || 0) + 1), + s.pluginCount[o] > 100) + ) + return Promise.resolve({ + spec: s.state, + errors: s.errors.concat(new Error("We've reached a hard limit of 100 plugin runs")) + }); + if (o !== this.currentPlugin && this.promisedPatches.length) { + const s = this.promisedPatches.map((s) => s.value); + return Promise.all(s.map((s) => s.then(specmap_noop, specmap_noop))).then(() => + this.dispatch() + ); + } + return (function executePlugin() { + s.currentPlugin = o; + const i = s.getCurrentMutations(), + u = s.mutations.length - 1; + try { + if (o.isGenerator) for (const u of o(i, s.getLib())) updatePatches(u); + else { + updatePatches(o(i, s.getLib())); + } + } catch (s) { + console.error(s), updatePatches([Object.assign(Object.create(s), { plugin: o })]); + } finally { + s.updatePluginHistory(o, { mutationIndex: u }); + } + return s.dispatch(); + })(); + function updatePatches(i) { + i && ((i = zo.fullyNormalizeArray(i)), s.updatePatches(i, o)); + } + } + } + const iu = { refs: ru, allOf: nu, parameters: su, properties: ou }; + function makeFetchJSON(s, o = {}) { + const { requestInterceptor: i, responseInterceptor: u } = o, + _ = s.withCredentials ? 'include' : 'same-origin'; + return (o) => + s({ + url: o, + loadSpec: !0, + requestInterceptor: i, + responseInterceptor: u, + headers: { Accept: Mc }, + credentials: _ + }).then((s) => s.body); + } + function isFile(s, o) { + return ( + o || 'undefined' == typeof navigator || (o = navigator), + o && 'ReactNative' === o.product + ? !(!s || 'object' != typeof s || 'string' != typeof s.uri) + : ('undefined' != typeof File && s instanceof File) || + ('undefined' != typeof Blob && s instanceof Blob) || + !!ArrayBuffer.isView(s) || + (null !== s && 'object' == typeof s && 'function' == typeof s.pipe) + ); + } + function isArrayOfFile(s, o) { + return Array.isArray(s) && s.some((s) => isFile(s, o)); + } + class FileWithData extends File { + constructor(s, o = '', i = {}) { + super([s], o, i), (this.data = s); + } + valueOf() { + return this.data; + } + toString() { + return this.valueOf(); + } + } + const isRfc3986Reserved = (s) => ":/?#[]@!$&'()*+,;=".indexOf(s) > -1, + isRfc3986Unreserved = (s) => /^[a-z0-9\-._~]+$/i.test(s); + function encodeCharacters(s, o = 'reserved') { + return [...s] + .map((s) => { + if (isRfc3986Unreserved(s)) return s; + if (isRfc3986Reserved(s) && 'unsafe' === o) return s; + const i = new TextEncoder(); + return Array.from(i.encode(s)) + .map((s) => `0${s.toString(16).toUpperCase()}`.slice(-2)) + .map((s) => `%${s}`) + .join(''); + }) + .join(''); + } + function stylize(s) { + const { value: o } = s; + return Array.isArray(o) + ? (function encodeArray({ key: s, value: o, style: i, explode: u, escape: _ }) { + if ('simple' === i) return o.map((s) => valueEncoder(s, _)).join(','); + if ('label' === i) return `.${o.map((s) => valueEncoder(s, _)).join('.')}`; + if ('matrix' === i) + return o + .map((s) => valueEncoder(s, _)) + .reduce((o, i) => (!o || u ? `${o || ''};${s}=${i}` : `${o},${i}`), ''); + if ('form' === i) { + const i = u ? `&${s}=` : ','; + return o.map((s) => valueEncoder(s, _)).join(i); + } + if ('spaceDelimited' === i) { + const i = u ? `${s}=` : ''; + return o.map((s) => valueEncoder(s, _)).join(` ${i}`); + } + if ('pipeDelimited' === i) { + const i = u ? `${s}=` : ''; + return o.map((s) => valueEncoder(s, _)).join(`|${i}`); + } + return; + })(s) + : 'object' == typeof o + ? (function encodeObject({ key: s, value: o, style: i, explode: u, escape: _ }) { + const w = Object.keys(o); + if ('simple' === i) + return w.reduce((s, i) => { + const w = valueEncoder(o[i], _); + return `${s ? `${s},` : ''}${i}${u ? '=' : ','}${w}`; + }, ''); + if ('label' === i) + return w.reduce((s, i) => { + const w = valueEncoder(o[i], _); + return `${s ? `${s}.` : '.'}${i}${u ? '=' : '.'}${w}`; + }, ''); + if ('matrix' === i && u) + return w.reduce( + (s, i) => `${s ? `${s};` : ';'}${i}=${valueEncoder(o[i], _)}`, + '' + ); + if ('matrix' === i) + return w.reduce((i, u) => { + const w = valueEncoder(o[u], _); + return `${i ? `${i},` : `;${s}=`}${u},${w}`; + }, ''); + if ('form' === i) + return w.reduce((s, i) => { + const w = valueEncoder(o[i], _); + return `${s ? `${s}${u ? '&' : ','}` : ''}${i}${u ? '=' : ','}${w}`; + }, ''); + return; + })(s) + : (function encodePrimitive({ key: s, value: o, style: i, escape: u }) { + if ('simple' === i) return valueEncoder(o, u); + if ('label' === i) return `.${valueEncoder(o, u)}`; + if ('matrix' === i) return `;${s}=${valueEncoder(o, u)}`; + if ('form' === i) return valueEncoder(o, u); + if ('deepObject' === i) return valueEncoder(o, u); + return; + })(s); + } + function valueEncoder(s, o = !1) { + return ( + Array.isArray(s) || (null !== s && 'object' == typeof s) + ? (s = JSON.stringify(s)) + : ('number' != typeof s && 'boolean' != typeof s) || (s = String(s)), + o && s.length > 0 ? encodeCharacters(s, o) : s + ); + } + const au = { form: ',', spaceDelimited: '%20', pipeDelimited: '|' }, + lu = { csv: ',', ssv: '%20', tsv: '%09', pipes: '|' }; + function formatKeyValue(s, o, i = !1) { + const { + collectionFormat: u, + allowEmptyValue: _, + serializationOption: w, + encoding: x + } = o, + C = 'object' != typeof o || Array.isArray(o) ? o : o.value, + j = i ? (s) => s.toString() : (s) => encodeURIComponent(s), + L = j(s); + if (void 0 === C && _) return [[L, '']]; + if (isFile(C) || isArrayOfFile(C)) return [[L, C]]; + if (w) return formatKeyValueBySerializationOption(s, C, i, w); + if (x) { + if ( + [typeof x.style, typeof x.explode, typeof x.allowReserved].some( + (s) => 'undefined' !== s + ) + ) { + const { style: o, explode: u, allowReserved: _ } = x; + return formatKeyValueBySerializationOption(s, C, i, { + style: o, + explode: u, + allowReserved: _ + }); + } + if ('string' == typeof x.contentType) { + if (x.contentType.startsWith('application/json')) { + const s = j('string' == typeof C ? C : JSON.stringify(C)); + return [[L, new FileWithData(s, 'blob', { type: x.contentType })]]; + } + const s = j(String(C)); + return [[L, new FileWithData(s, 'blob', { type: x.contentType })]]; + } + return 'object' != typeof C + ? [[L, j(C)]] + : Array.isArray(C) && C.every((s) => 'object' != typeof s) + ? [[L, C.map(j).join(',')]] + : [[L, j(JSON.stringify(C))]]; + } + return 'object' != typeof C + ? [[L, j(C)]] + : Array.isArray(C) + ? 'multi' === u + ? [[L, C.map(j)]] + : [[L, C.map(j).join(lu[u || 'csv'])]] + : [[L, '']]; + } + function formatKeyValueBySerializationOption(s, o, i, u) { + const _ = u.style || 'form', + w = void 0 === u.explode ? 'form' === _ : u.explode, + x = !i && (u && u.allowReserved ? 'unsafe' : 'reserved'), + encodeFn = (s) => valueEncoder(s, x), + C = i ? (s) => s : (s) => encodeFn(s); + return 'object' != typeof o + ? [[C(s), encodeFn(o)]] + : Array.isArray(o) + ? w + ? [[C(s), o.map(encodeFn)]] + : [[C(s), o.map(encodeFn).join(au[_])]] + : 'deepObject' === _ + ? Object.keys(o).map((i) => [C(`${s}[${i}]`), encodeFn(o[i])]) + : w + ? Object.keys(o).map((s) => [C(s), encodeFn(o[s])]) + : [ + [ + C(s), + Object.keys(o) + .map((s) => [`${C(s)},${encodeFn(o[s])}`]) + .join(',') + ] + ]; + } + function encodeFormOrQuery(s) { + return ((s, { encode: o = !0 } = {}) => { + const buildNestedParams = (s, o, i) => ( + null == i + ? s.append(o, '') + : Array.isArray(i) + ? i.reduce((i, u) => buildNestedParams(s, o, u), s) + : i instanceof Date + ? s.append(o, i.toISOString()) + : 'object' == typeof i + ? Object.entries(i).reduce( + (i, [u, _]) => buildNestedParams(s, `${o}[${u}]`, _), + s + ) + : s.append(o, i), + s + ), + i = Object.entries(s).reduce( + (s, [o, i]) => buildNestedParams(s, o, i), + new URLSearchParams() + ), + u = String(i); + return o ? u : decodeURIComponent(u); + })( + Object.keys(s).reduce((o, i) => { + for (const [u, _] of formatKeyValue(i, s[i])) + o[u] = _ instanceof FileWithData ? _.valueOf() : _; + return o; + }, {}), + { encode: !1 } + ); + } + function serializeRequest(s = {}) { + const { url: o = '', query: i, form: u } = s; + if (u) { + const o = Object.keys(u).some((s) => { + const { value: o } = u[s]; + return isFile(o) || isArrayOfFile(o); + }), + i = s.headers['content-type'] || s.headers['Content-Type']; + if (o || /multipart\/form-data/i.test(i)) { + const o = (function request_buildFormData(s) { + return Object.entries(s).reduce((s, [o, i]) => { + for (const [u, _] of formatKeyValue(o, i, !0)) + if (Array.isArray(_)) + for (const o of _) + if (ArrayBuffer.isView(o)) { + const i = new Blob([o]); + s.append(u, i); + } else s.append(u, o); + else if (ArrayBuffer.isView(_)) { + const o = new Blob([_]); + s.append(u, o); + } else s.append(u, _); + return s; + }, new FormData()); + })(s.form); + (s.formdata = o), (s.body = o); + } else s.body = encodeFormOrQuery(u); + delete s.form; + } + if (i) { + const [u, _] = o.split('?'); + let w = ''; + if (_) { + const s = new URLSearchParams(_); + Object.keys(i).forEach((o) => s.delete(o)), (w = String(s)); + } + const x = ((...s) => { + const o = s.filter((s) => s).join('&'); + return o ? `?${o}` : ''; + })(w, encodeFormOrQuery(i)); + (s.url = u + x), delete s.query; + } + return s; + } + function serializeHeaders(s = {}) { + return 'function' != typeof s.entries + ? {} + : Array.from(s.entries()).reduce( + (s, [o, i]) => ( + (s[o] = (function serializeHeaderValue(s) { + return s.includes(', ') ? s.split(', ') : s; + })(i)), + s + ), + {} + ); + } + function serializeResponse(s, o, { loadSpec: i = !1 } = {}) { + const u = { + ok: s.ok, + url: s.url || o, + status: s.status, + statusText: s.statusText, + headers: serializeHeaders(s.headers) + }, + _ = u.headers['content-type'], + w = i || ((s = '') => /(json|xml|yaml|text)\b/.test(s))(_); + return (w ? s.text : s.blob || s.buffer).call(s).then((s) => { + if (((u.text = s), (u.data = s), w)) + try { + const o = (function parseBody(s, o) { + return o && (0 === o.indexOf('application/json') || o.indexOf('+json') > 0) + ? JSON.parse(s) + : mn.load(s); + })(s, _); + (u.body = o), (u.obj = o); + } catch (s) { + u.parseError = s; + } + return u; + }); + } + async function http_http(s, o = {}) { + 'object' == typeof s && (s = (o = s).url), + (o.headers = o.headers || {}), + (o = serializeRequest(o)).headers && + Object.keys(o.headers).forEach((s) => { + const i = o.headers[s]; + 'string' == typeof i && (o.headers[s] = i.replace(/\n+/g, ' ')); + }), + o.requestInterceptor && (o = (await o.requestInterceptor(o)) || o); + const i = o.headers['content-type'] || o.headers['Content-Type']; + let u; + /multipart\/form-data/i.test(i) && + (delete o.headers['content-type'], delete o.headers['Content-Type']); + try { + (u = await (o.userFetch || fetch)(o.url, o)), + (u = await serializeResponse(u, s, o)), + o.responseInterceptor && (u = (await o.responseInterceptor(u)) || u); + } catch (s) { + if (!u) throw s; + const o = new Error(u.statusText || `response status is ${u.status}`); + throw ((o.status = u.status), (o.statusCode = u.status), (o.responseError = s), o); + } + if (!u.ok) { + const s = new Error(u.statusText || `response status is ${u.status}`); + throw ((s.status = u.status), (s.statusCode = u.status), (s.response = u), s); + } + return u; + } + const options_retrievalURI = (s) => { + var o, i; + const { baseDoc: u, url: _ } = s, + w = null !== (o = null != u ? u : _) && void 0 !== o ? o : ''; + return 'string' == + typeof (null === (i = globalThis.document) || void 0 === i ? void 0 : i.baseURI) + ? String(new URL(w, globalThis.document.baseURI)) + : w; + }, + options_httpClient = (s) => { + const { fetch: o, http: i } = s; + return o || i || http_http; + }; + async function resolveGenericStrategy(s) { + const { + spec: o, + mode: i, + allowMetaPatches: u = !0, + pathDiscriminator: _, + modelPropertyMacro: w, + parameterMacro: x, + requestInterceptor: C, + responseInterceptor: j, + skipNormalization: L = !1, + useCircularStructures: B, + strategies: $ + } = s, + V = options_retrievalURI(s), + U = options_httpClient(s), + z = $.find((s) => s.match(o)); + return (async function doResolve(s) { + V && (iu.refs.docCache[V] = s); + iu.refs.fetchJSON = makeFetchJSON(U, { requestInterceptor: C, responseInterceptor: j }); + const o = [iu.refs]; + 'function' == typeof x && o.push(iu.parameters); + 'function' == typeof w && o.push(iu.properties); + 'strict' !== i && o.push(iu.allOf); + const $ = await (function mapSpec(s) { + return new SpecMap(s).dispatch(); + })({ + spec: s, + context: { baseDoc: V }, + plugins: o, + allowMetaPatches: u, + pathDiscriminator: _, + parameterMacro: x, + modelPropertyMacro: w, + useCircularStructures: B + }); + L || ($.spec = z.normalize($.spec)); + return $; + })(o); + } + const replace_special_chars_with_underscore = (s) => s.replace(/\W/gi, '_'); + function opId(s, o, i = '', { v2OperationIdCompatibilityMode: u } = {}) { + if (!s || 'object' != typeof s) return null; + return (s.operationId || '').replace(/\s/g, '').length + ? replace_special_chars_with_underscore(s.operationId) + : (function idFromPathMethod(s, o, { v2OperationIdCompatibilityMode: i } = {}) { + if (i) { + let i = `${o.toLowerCase()}_${s}`.replace( + /[\s!@#$%^&*()_+=[{\]};:<>|./?,\\'""-]/g, + '_' + ); + return ( + (i = i || `${s.substring(1)}_${o}`), + i + .replace(/((_){2,})/g, '_') + .replace(/^(_)*/g, '') + .replace(/([_])*$/g, '') + ); + } + return `${o.toLowerCase()}${replace_special_chars_with_underscore(s)}`; + })(o, i, { v2OperationIdCompatibilityMode: u }); + } + function normalize(s) { + const { spec: o } = s, + { paths: i } = o, + u = {}; + if (!i || o.$$normalized) return s; + for (const s in i) { + const _ = i[s]; + if (null == _ || !['object', 'function'].includes(typeof _)) continue; + const w = _.parameters; + for (const i in _) { + const x = _[i]; + if (null == x || !['object', 'function'].includes(typeof x)) continue; + const C = opId(x, s, i); + if (C) { + u[C] ? u[C].push(x) : (u[C] = [x]); + const s = u[C]; + if (s.length > 1) + s.forEach((s, o) => { + (s.__originalOperationId = s.__originalOperationId || s.operationId), + (s.operationId = `${C}${o + 1}`); + }); + else if (void 0 !== x.operationId) { + const o = s[0]; + (o.__originalOperationId = o.__originalOperationId || x.operationId), + (o.operationId = C); + } + } + if ('parameters' !== i) { + const s = [], + i = {}; + for (const u in o) + ('produces' !== u && 'consumes' !== u && 'security' !== u) || + ((i[u] = o[u]), s.push(i)); + if ((w && ((i.parameters = w), s.push(i)), s.length)) + for (const o of s) + for (const s in o) + if (x[s]) { + if ('parameters' === s) + for (const i of o[s]) { + x[s].some( + (s) => + (s.name && s.name === i.name) || + (s.$ref && s.$ref === i.$ref) || + (s.$$ref && s.$$ref === i.$$ref) || + s === i + ) || x[s].push(i); + } + } else x[s] = o[s]; + } + } + } + return (o.$$normalized = !0), s; + } + const cu = { + name: 'generic', + match: () => !0, + normalize(s) { + const { spec: o } = normalize({ spec: s }); + return o; + }, + resolve: async (s) => resolveGenericStrategy(s) + }, + uu = cu; + const isOpenAPI30 = (s) => { + try { + const { openapi: o } = s; + return 'string' == typeof o && /^3\.0\.([0123])(?:-rc[012])?$/.test(o); + } catch { + return !1; + } + }, + isOpenAPI31 = (s) => { + try { + const { openapi: o } = s; + return 'string' == typeof o && /^3\.1\.(?:[1-9]\d*|0)$/.test(o); + } catch { + return !1; + } + }, + isOpenAPI3 = (s) => isOpenAPI30(s) || isOpenAPI31(s), + pu = { + name: 'openapi-2', + match: (s) => + ((s) => { + try { + const { swagger: o } = s; + return '2.0' === o; + } catch { + return !1; + } + })(s), + normalize(s) { + const { spec: o } = normalize({ spec: s }); + return o; + }, + resolve: async (s) => + (async function resolveOpenAPI2Strategy(s) { + return resolveGenericStrategy(s); + })(s) + }, + hu = pu; + const du = { + name: 'openapi-3-0', + match: (s) => isOpenAPI30(s), + normalize(s) { + const { spec: o } = normalize({ spec: s }); + return o; + }, + resolve: async (s) => + (async function resolveOpenAPI30Strategy(s) { + return resolveGenericStrategy(s); + })(s) + }, + fu = du; + const mu = _curry2(function and(s, o) { + return s && o; + }); + const gu = _curry2(function both(s, o) { + return _isFunction(s) + ? function _both() { + return s.apply(this, arguments) && o.apply(this, arguments); + } + : Pl(mu)(s, o); + }); + const yu = ra(null); + const vu = Ml(yu); + function isOfTypeObject_typeof(s) { + return ( + (isOfTypeObject_typeof = + 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator + ? function (s) { + return typeof s; + } + : function (s) { + return s && + 'function' == typeof Symbol && + s.constructor === Symbol && + s !== Symbol.prototype + ? 'symbol' + : typeof s; + }), + isOfTypeObject_typeof(s) + ); + } + const bu = function isOfTypeObject(s) { + return 'object' === isOfTypeObject_typeof(s); + }; + const _u = za(1, gu(vu, bu)); + var Eu = pipe(ea, Vl('Object')), + wu = pipe(ma, ra(ma(Object))), + Su = Xo(gu(Wl, wu), ['constructor']), + xu = za(1, function (s) { + if (!_u(s) || !Eu(s)) return !1; + var o = Object.getPrototypeOf(s); + return !!yu(o) || Su(o); + }); + const ku = xu; + var Cu = __webpack_require__(34035); + function _reduced(s) { + return s && s['@@transducer/reduced'] + ? s + : { '@@transducer/value': s, '@@transducer/reduced': !0 }; + } + var Ou = (function () { + function XAll(s, o) { + (this.xf = o), (this.f = s), (this.all = !0); + } + return ( + (XAll.prototype['@@transducer/init'] = _xfBase_init), + (XAll.prototype['@@transducer/result'] = function (s) { + return ( + this.all && (s = this.xf['@@transducer/step'](s, !0)), + this.xf['@@transducer/result'](s) + ); + }), + (XAll.prototype['@@transducer/step'] = function (s, o) { + return ( + this.f(o) || ((this.all = !1), (s = _reduced(this.xf['@@transducer/step'](s, !1)))), + s + ); + }), + XAll + ); + })(); + function _xall(s) { + return function (o) { + return new Ou(s, o); + }; + } + var Au = _curry2( + _dispatchable(['all'], _xall, function all(s, o) { + for (var i = 0; i < o.length; ) { + if (!s(o[i])) return !1; + i += 1; + } + return !0; + }) + ); + const ju = Au; + class Annotation extends Cu.Om { + constructor(s, o, i) { + super(s, o, i), (this.element = 'annotation'); + } + get code() { + return this.attributes.get('code'); + } + set code(s) { + this.attributes.set('code', s); + } + } + const Iu = Annotation; + class Comment extends Cu.Om { + constructor(s, o, i) { + super(s, o, i), (this.element = 'comment'); + } + } + const Pu = Comment; + class ParseResult extends Cu.wE { + constructor(s, o, i) { + super(s, o, i), (this.element = 'parseResult'); + } + get api() { + return this.children.filter((s) => s.classes.contains('api')).first; + } + get results() { + return this.children.filter((s) => s.classes.contains('result')); + } + get result() { + return this.results.first; + } + get annotations() { + return this.children.filter((s) => 'annotation' === s.element); + } + get warnings() { + return this.children.filter( + (s) => 'annotation' === s.element && s.classes.contains('warning') + ); + } + get errors() { + return this.children.filter( + (s) => 'annotation' === s.element && s.classes.contains('error') + ); + } + get isEmpty() { + return this.children.reject((s) => 'annotation' === s.element).isEmpty; + } + replaceResult(s) { + const { result: o } = this; + if (Rl(o)) return !1; + const i = this.content.findIndex((s) => s === o); + return -1 !== i && ((this.content[i] = s), !0); + } + } + const Mu = ParseResult; + class SourceMap extends Cu.wE { + constructor(s, o, i) { + super(s, o, i), (this.element = 'sourceMap'); + } + get positionStart() { + return this.children.filter((s) => s.classes.contains('position')).get(0); + } + get positionEnd() { + return this.children.filter((s) => s.classes.contains('position')).get(1); + } + set position(s) { + if (void 0 === s) return; + const o = new Cu.wE([s.start.row, s.start.column, s.start.char]), + i = new Cu.wE([s.end.row, s.end.column, s.end.char]); + o.classes.push('position'), i.classes.push('position'), this.push(o).push(i); + } + } + const Tu = SourceMap, + hasMethod = (s, o) => + 'object' == typeof o && null !== o && s in o && 'function' == typeof o[s], + hasBasicElementProps = (s) => + 'object' == typeof s && + null != s && + '_storedElement' in s && + 'string' == typeof s._storedElement && + '_content' in s, + primitiveEq = (s, o) => + 'object' == typeof o && + null !== o && + 'primitive' in o && + 'function' == typeof o.primitive && + o.primitive() === s, + hasClass = (s, o) => + 'object' == typeof o && + null !== o && + 'classes' in o && + (Array.isArray(o.classes) || o.classes instanceof Cu.wE) && + o.classes.includes(s), + isElementType = (s, o) => + 'object' == typeof o && null !== o && 'element' in o && o.element === s, + helpers = (s) => + s({ hasMethod, hasBasicElementProps, primitiveEq, isElementType, hasClass }), + Nu = helpers( + ({ hasBasicElementProps: s, primitiveEq: o }) => + (i) => + i instanceof Cu.Hg || (s(i) && o(void 0, i)) + ), + Ru = helpers( + ({ hasBasicElementProps: s, primitiveEq: o }) => + (i) => + i instanceof Cu.Om || (s(i) && o('string', i)) + ), + Du = helpers( + ({ hasBasicElementProps: s, primitiveEq: o }) => + (i) => + i instanceof Cu.kT || (s(i) && o('number', i)) + ), + Lu = helpers( + ({ hasBasicElementProps: s, primitiveEq: o }) => + (i) => + i instanceof Cu.Os || (s(i) && o('null', i)) + ), + Bu = helpers( + ({ hasBasicElementProps: s, primitiveEq: o }) => + (i) => + i instanceof Cu.bd || (s(i) && o('boolean', i)) + ), + Fu = helpers( + ({ hasBasicElementProps: s, primitiveEq: o, hasMethod: i }) => + (u) => + u instanceof Cu.Sh || + (s(u) && o('object', u) && i('keys', u) && i('values', u) && i('items', u)) + ), + qu = helpers( + ({ hasBasicElementProps: s, primitiveEq: o, hasMethod: i }) => + (u) => + (u instanceof Cu.wE && !(u instanceof Cu.Sh)) || + (s(u) && + o('array', u) && + i('push', u) && + i('unshift', u) && + i('map', u) && + i('reduce', u)) + ), + $u = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Cu.Pr || (s(u) && o('member', u) && i(void 0, u)) + ), + Vu = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Cu.Ft || (s(u) && o('link', u) && i(void 0, u)) + ), + Uu = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Cu.sI || (s(u) && o('ref', u) && i(void 0, u)) + ), + zu = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Iu || (s(u) && o('annotation', u) && i('array', u)) + ), + Wu = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Pu || (s(u) && o('comment', u) && i('string', u)) + ), + Ku = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Mu || (s(u) && o('parseResult', u) && i('array', u)) + ), + Hu = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Tu || (s(u) && o('sourceMap', u) && i('array', u)) + ), + isPrimitiveElement = (s) => + isElementType('object', s) || + isElementType('array', s) || + isElementType('boolean', s) || + isElementType('number', s) || + isElementType('string', s) || + isElementType('null', s) || + isElementType('member', s), + hasElementSourceMap = (s) => Hu(s.meta.get('sourceMap')), + includesSymbols = (s, o) => { + if (0 === s.length) return !0; + const i = o.attributes.get('symbols'); + return !!qu(i) && ju(_l(i.toValue()), s); + }, + includesClasses = (s, o) => 0 === s.length || ju(_l(o.classes.toValue()), s); + const es_T = function () { + return !0; + }; + const es_F = function () { + return !1; + }, + getVisitFn = (s, o, i) => { + const u = s[o]; + if (null != u) { + if (!i && 'function' == typeof u) return u; + const s = i ? u.leave : u.enter; + if ('function' == typeof s) return s; + } else { + const u = i ? s.leave : s.enter; + if (null != u) { + if ('function' == typeof u) return u; + const s = u[o]; + if ('function' == typeof s) return s; + } + } + return null; + }, + Ju = {}, + getNodeType = (s) => (null == s ? void 0 : s.type), + isNode = (s) => 'string' == typeof getNodeType(s), + cloneNode = (s) => + Object.create(Object.getPrototypeOf(s), Object.getOwnPropertyDescriptors(s)), + mergeAll = ( + s, + { + visitFnGetter: o = getVisitFn, + nodeTypeGetter: i = getNodeType, + breakSymbol: u = Ju, + deleteNodeSymbol: _ = null, + skipVisitingNodeSymbol: w = !1, + exposeEdits: x = !1 + } = {} + ) => { + const C = Symbol('skip'), + j = new Array(s.length).fill(C); + return { + enter(L, B, $, V, U, z) { + let Y = L, + Z = !1; + const ee = { + ...z, + replaceWith(s, o) { + z.replaceWith(s, o), (Y = s); + } + }; + for (let L = 0; L < s.length; L += 1) + if (j[L] === C) { + const C = o(s[L], i(Y), !1); + if ('function' == typeof C) { + const o = C.call(s[L], Y, B, $, V, U, ee); + if ('function' == typeof (null == o ? void 0 : o.then)) + throw new Jo('Async visitor not supported in sync mode', { + visitor: s[L], + visitFn: C + }); + if (o === w) j[L] = Y; + else if (o === u) j[L] = u; + else { + if (o === _) return o; + if (void 0 !== o) { + if (!x) return o; + (Y = o), (Z = !0); + } + } + } + } + return Z ? Y : void 0; + }, + leave(_, x, L, B, $, V) { + let U = _; + const z = { + ...V, + replaceWith(s, o) { + V.replaceWith(s, o), (U = s); + } + }; + for (let _ = 0; _ < s.length; _ += 1) + if (j[_] === C) { + const C = o(s[_], i(U), !0); + if ('function' == typeof C) { + const o = C.call(s[_], U, x, L, B, $, z); + if ('function' == typeof (null == o ? void 0 : o.then)) + throw new Jo('Async visitor not supported in sync mode', { + visitor: s[_], + visitFn: C + }); + if (o === u) j[_] = u; + else if (void 0 !== o && o !== w) return o; + } + } else j[_] === U && (j[_] = C); + } + }; + }; + mergeAll[Symbol.for('nodejs.util.promisify.custom')] = ( + s, + { + visitFnGetter: o = getVisitFn, + nodeTypeGetter: i = getNodeType, + breakSymbol: u = Ju, + deleteNodeSymbol: _ = null, + skipVisitingNodeSymbol: w = !1, + exposeEdits: x = !1 + } = {} + ) => { + const C = Symbol('skip'), + j = new Array(s.length).fill(C); + return { + async enter(L, B, $, V, U, z) { + let Y = L, + Z = !1; + const ee = { + ...z, + replaceWith(s, o) { + z.replaceWith(s, o), (Y = s); + } + }; + for (let L = 0; L < s.length; L += 1) + if (j[L] === C) { + const C = o(s[L], i(Y), !1); + if ('function' == typeof C) { + const o = await C.call(s[L], Y, B, $, V, U, ee); + if (o === w) j[L] = Y; + else if (o === u) j[L] = u; + else { + if (o === _) return o; + if (void 0 !== o) { + if (!x) return o; + (Y = o), (Z = !0); + } + } + } + } + return Z ? Y : void 0; + }, + async leave(_, x, L, B, $, V) { + let U = _; + const z = { + ...V, + replaceWith(s, o) { + V.replaceWith(s, o), (U = s); + } + }; + for (let _ = 0; _ < s.length; _ += 1) + if (j[_] === C) { + const C = o(s[_], i(U), !0); + if ('function' == typeof C) { + const o = await C.call(s[_], U, x, L, B, $, z); + if (o === u) j[_] = u; + else if (void 0 !== o && o !== w) return o; + } + } else j[_] === U && (j[_] = C); + } + }; + }; + const visit = ( + s, + o, + { + keyMap: i = null, + state: u = {}, + breakSymbol: _ = Ju, + deleteNodeSymbol: w = null, + skipVisitingNodeSymbol: x = !1, + visitFnGetter: C = getVisitFn, + nodeTypeGetter: j = getNodeType, + nodePredicate: L = isNode, + nodeCloneFn: B = cloneNode, + detectCycles: $ = !0 + } = {} + ) => { + const V = i || {}; + let U, + z, + Y = Array.isArray(s), + Z = [s], + ee = -1, + ie = [], + ae = s; + const le = [], + ce = []; + do { + ee += 1; + const s = ee === Z.length; + let i; + const fe = s && 0 !== ie.length; + if (s) { + if (((i = 0 === ce.length ? void 0 : le.pop()), (ae = z), (z = ce.pop()), fe)) + if (Y) { + ae = ae.slice(); + let s = 0; + for (const [o, i] of ie) { + const u = o - s; + i === w ? (ae.splice(u, 1), (s += 1)) : (ae[u] = i); + } + } else { + ae = B(ae); + for (const [s, o] of ie) ae[s] = o; + } + (ee = U.index), (Z = U.keys), (ie = U.edits), (Y = U.inArray), (U = U.prev); + } else if (z !== w && void 0 !== z) { + if (((i = Y ? ee : Z[ee]), (ae = z[i]), ae === w || void 0 === ae)) continue; + le.push(i); + } + let ye; + if (!Array.isArray(ae)) { + var pe; + if (!L(ae)) throw new Jo(`Invalid AST Node: ${String(ae)}`, { node: ae }); + if ($ && ce.includes(ae)) { + le.pop(); + continue; + } + const w = C(o, j(ae), s); + if (w) { + for (const [s, i] of Object.entries(u)) o[s] = i; + const _ = { + replaceWith(o, u) { + 'function' == typeof u ? u(o, ae, i, z, le, ce) : z && (z[i] = o), + s || (ae = o); + } + }; + ye = w.call(o, ae, i, z, le, ce, _); + } + if ('function' == typeof (null === (pe = ye) || void 0 === pe ? void 0 : pe.then)) + throw new Jo('Async visitor not supported in sync mode', { + visitor: o, + visitFn: w + }); + if (ye === _) break; + if (ye === x) { + if (!s) { + le.pop(); + continue; + } + } else if (void 0 !== ye && (ie.push([i, ye]), !s)) { + if (!L(ye)) { + le.pop(); + continue; + } + ae = ye; + } + } + var de; + if ((void 0 === ye && fe && ie.push([i, ae]), !s)) + (U = { inArray: Y, index: ee, keys: Z, edits: ie, prev: U }), + (Y = Array.isArray(ae)), + (Z = Y ? ae : null !== (de = V[j(ae)]) && void 0 !== de ? de : []), + (ee = -1), + (ie = []), + z !== w && void 0 !== z && ce.push(z), + (z = ae); + } while (void 0 !== U); + return 0 !== ie.length ? ie[ie.length - 1][1] : s; + }; + visit[Symbol.for('nodejs.util.promisify.custom')] = async ( + s, + o, + { + keyMap: i = null, + state: u = {}, + breakSymbol: _ = Ju, + deleteNodeSymbol: w = null, + skipVisitingNodeSymbol: x = !1, + visitFnGetter: C = getVisitFn, + nodeTypeGetter: j = getNodeType, + nodePredicate: L = isNode, + nodeCloneFn: B = cloneNode, + detectCycles: $ = !0 + } = {} + ) => { + const V = i || {}; + let U, + z, + Y = Array.isArray(s), + Z = [s], + ee = -1, + ie = [], + ae = s; + const le = [], + ce = []; + do { + ee += 1; + const s = ee === Z.length; + let i; + const de = s && 0 !== ie.length; + if (s) { + if (((i = 0 === ce.length ? void 0 : le.pop()), (ae = z), (z = ce.pop()), de)) + if (Y) { + ae = ae.slice(); + let s = 0; + for (const [o, i] of ie) { + const u = o - s; + i === w ? (ae.splice(u, 1), (s += 1)) : (ae[u] = i); + } + } else { + ae = B(ae); + for (const [s, o] of ie) ae[s] = o; + } + (ee = U.index), (Z = U.keys), (ie = U.edits), (Y = U.inArray), (U = U.prev); + } else if (z !== w && void 0 !== z) { + if (((i = Y ? ee : Z[ee]), (ae = z[i]), ae === w || void 0 === ae)) continue; + le.push(i); + } + let fe; + if (!Array.isArray(ae)) { + if (!L(ae)) throw new Jo(`Invalid AST Node: ${String(ae)}`, { node: ae }); + if ($ && ce.includes(ae)) { + le.pop(); + continue; + } + const w = C(o, j(ae), s); + if (w) { + for (const [s, i] of Object.entries(u)) o[s] = i; + const _ = { + replaceWith(o, u) { + 'function' == typeof u ? u(o, ae, i, z, le, ce) : z && (z[i] = o), + s || (ae = o); + } + }; + fe = await w.call(o, ae, i, z, le, ce, _); + } + if (fe === _) break; + if (fe === x) { + if (!s) { + le.pop(); + continue; + } + } else if (void 0 !== fe && (ie.push([i, fe]), !s)) { + if (!L(fe)) { + le.pop(); + continue; + } + ae = fe; + } + } + var pe; + if ((void 0 === fe && de && ie.push([i, ae]), !s)) + (U = { inArray: Y, index: ee, keys: Z, edits: ie, prev: U }), + (Y = Array.isArray(ae)), + (Z = Y ? ae : null !== (pe = V[j(ae)]) && void 0 !== pe ? pe : []), + (ee = -1), + (ie = []), + z !== w && void 0 !== z && ce.push(z), + (z = ae); + } while (void 0 !== U); + return 0 !== ie.length ? ie[ie.length - 1][1] : s; + }; + const Gu = class CloneError extends Jo { + value; + constructor(s, o) { + super(s, o), void 0 !== o && (this.value = o.value); + } + }; + const Yu = class DeepCloneError extends Gu {}; + const Xu = class ShallowCloneError extends Gu {}, + cloneDeep = (s, o = {}) => { + const { visited: i = new WeakMap() } = o, + u = { ...o, visited: i }; + if (i.has(s)) return i.get(s); + if (s instanceof Cu.KeyValuePair) { + const { key: o, value: _ } = s, + w = Nu(o) ? cloneDeep(o, u) : o, + x = Nu(_) ? cloneDeep(_, u) : _, + C = new Cu.KeyValuePair(w, x); + return i.set(s, C), C; + } + if (s instanceof Cu.ot) { + const mapper = (s) => cloneDeep(s, u), + o = [...s].map(mapper), + _ = new Cu.ot(o); + return i.set(s, _), _; + } + if (s instanceof Cu.G6) { + const mapper = (s) => cloneDeep(s, u), + o = [...s].map(mapper), + _ = new Cu.G6(o); + return i.set(s, _), _; + } + if (Nu(s)) { + const o = cloneShallow(s); + if ((i.set(s, o), s.content)) + if (Nu(s.content)) o.content = cloneDeep(s.content, u); + else if (s.content instanceof Cu.KeyValuePair) o.content = cloneDeep(s.content, u); + else if (Array.isArray(s.content)) { + const mapper = (s) => cloneDeep(s, u); + o.content = s.content.map(mapper); + } else o.content = s.content; + else o.content = s.content; + return o; + } + throw new Yu("Value provided to cloneDeep function couldn't be cloned", { value: s }); + }; + cloneDeep.safe = (s) => { + try { + return cloneDeep(s); + } catch { + return s; + } + }; + const cloneShallowKeyValuePair = (s) => { + const { key: o, value: i } = s; + return new Cu.KeyValuePair(o, i); + }, + cloneShallowElement = (s) => { + const o = new s.constructor(); + if ( + ((o.element = s.element), + s.meta.length > 0 && (o._meta = cloneDeep(s.meta)), + s.attributes.length > 0 && (o._attributes = cloneDeep(s.attributes)), + Nu(s.content)) + ) { + const i = s.content; + o.content = cloneShallowElement(i); + } else + Array.isArray(s.content) + ? (o.content = [...s.content]) + : s.content instanceof Cu.KeyValuePair + ? (o.content = cloneShallowKeyValuePair(s.content)) + : (o.content = s.content); + return o; + }, + cloneShallow = (s) => { + if (s instanceof Cu.KeyValuePair) return cloneShallowKeyValuePair(s); + if (s instanceof Cu.ot) + return ((s) => { + const o = [...s]; + return new Cu.ot(o); + })(s); + if (s instanceof Cu.G6) + return ((s) => { + const o = [...s]; + return new Cu.G6(o); + })(s); + if (Nu(s)) return cloneShallowElement(s); + throw new Xu("Value provided to cloneShallow function couldn't be cloned", { + value: s + }); + }; + cloneShallow.safe = (s) => { + try { + return cloneShallow(s); + } catch { + return s; + } + }; + const visitor_getNodeType = (s) => + Fu(s) + ? 'ObjectElement' + : qu(s) + ? 'ArrayElement' + : $u(s) + ? 'MemberElement' + : Ru(s) + ? 'StringElement' + : Bu(s) + ? 'BooleanElement' + : Du(s) + ? 'NumberElement' + : Lu(s) + ? 'NullElement' + : Vu(s) + ? 'LinkElement' + : Uu(s) + ? 'RefElement' + : void 0, + visitor_cloneNode = (s) => (Nu(s) ? cloneShallow(s) : cloneNode(s)), + Zu = pipe(visitor_getNodeType, Yl), + Qu = { + ObjectElement: ['content'], + ArrayElement: ['content'], + MemberElement: ['key', 'value'], + StringElement: [], + BooleanElement: [], + NumberElement: [], + NullElement: [], + RefElement: [], + LinkElement: [], + Annotation: [], + Comment: [], + ParseResultElement: ['content'], + SourceMap: ['content'] + }; + class PredicateVisitor { + result; + predicate; + returnOnTrue; + returnOnFalse; + constructor({ predicate: s = es_F, returnOnTrue: o, returnOnFalse: i } = {}) { + (this.result = []), + (this.predicate = s), + (this.returnOnTrue = o), + (this.returnOnFalse = i); + } + enter(s) { + return this.predicate(s) + ? (this.result.push(s), this.returnOnTrue) + : this.returnOnFalse; + } + } + const visitor_visit = (s, o, { keyMap: i = Qu, ...u } = {}) => + visit(s, o, { + keyMap: i, + nodeTypeGetter: visitor_getNodeType, + nodePredicate: Zu, + nodeCloneFn: visitor_cloneNode, + ...u + }); + visitor_visit[Symbol.for('nodejs.util.promisify.custom')] = async ( + s, + o, + { keyMap: i = Qu, ...u } = {} + ) => + visit[Symbol.for('nodejs.util.promisify.custom')](s, o, { + keyMap: i, + nodeTypeGetter: visitor_getNodeType, + nodePredicate: Zu, + nodeCloneFn: visitor_cloneNode, + ...u + }); + const nodeTypeGetter = (s) => + 'string' == typeof (null == s ? void 0 : s.type) ? s.type : visitor_getNodeType(s), + ep = { EphemeralObject: ['content'], EphemeralArray: ['content'], ...Qu }, + value_visitor_visit = (s, o, { keyMap: i = ep, ...u } = {}) => + visitor_visit(s, o, { + keyMap: i, + nodeTypeGetter, + nodePredicate: es_T, + detectCycles: !1, + deleteNodeSymbol: Symbol.for('delete-node'), + skipVisitingNodeSymbol: Symbol.for('skip-visiting-node'), + ...u + }); + value_visitor_visit[Symbol.for('nodejs.util.promisify.custom')] = async ( + s, + { keyMap: o = ep, ...i } = {} + ) => + visitor_visit[Symbol.for('nodejs.util.promisify.custom')](s, visitor, { + keyMap: o, + nodeTypeGetter, + nodePredicate: es_T, + detectCycles: !1, + deleteNodeSymbol: Symbol.for('delete-node'), + skipVisitingNodeSymbol: Symbol.for('skip-visiting-node'), + ...i + }); + const tp = class EphemeralArray { + type = 'EphemeralArray'; + content = []; + reference = void 0; + constructor(s) { + (this.content = s), (this.reference = []); + } + toReference() { + return this.reference; + } + toArray() { + return this.reference.push(...this.content), this.reference; + } + }; + const rp = class EphemeralObject { + type = 'EphemeralObject'; + content = []; + reference = void 0; + constructor(s) { + (this.content = s), (this.reference = {}); + } + toReference() { + return this.reference; + } + toObject() { + return Object.assign(this.reference, Object.fromEntries(this.content)); + } + }; + class Visitor { + ObjectElement = { + enter: (s) => { + if (this.references.has(s)) return this.references.get(s).toReference(); + const o = new rp(s.content); + return this.references.set(s, o), o; + } + }; + EphemeralObject = { leave: (s) => s.toObject() }; + MemberElement = { enter: (s) => [s.key, s.value] }; + ArrayElement = { + enter: (s) => { + if (this.references.has(s)) return this.references.get(s).toReference(); + const o = new tp(s.content); + return this.references.set(s, o), o; + } + }; + EphemeralArray = { leave: (s) => s.toArray() }; + references = new WeakMap(); + BooleanElement(s) { + return s.toValue(); + } + NumberElement(s) { + return s.toValue(); + } + StringElement(s) { + return s.toValue(); + } + NullElement() { + return null; + } + RefElement(s, ...o) { + var i; + const u = o[3]; + return 'EphemeralObject' === + (null === (i = u[u.length - 1]) || void 0 === i ? void 0 : i.type) + ? Symbol.for('delete-node') + : String(s.toValue()); + } + LinkElement(s) { + return Ru(s.href) ? s.href.toValue() : ''; + } + } + const serializers_value = (s) => + Nu(s) + ? Ru(s) || Du(s) || Bu(s) || Lu(s) + ? s.toValue() + : value_visitor_visit(s, new Visitor()) + : s; + var np = _curry3(function mergeWithKey(s, o, i) { + var u, + _ = {}; + for (u in ((i = i || {}), (o = o || {}))) + _has(u, o) && (_[u] = _has(u, i) ? s(u, o[u], i[u]) : o[u]); + for (u in i) _has(u, i) && !_has(u, _) && (_[u] = i[u]); + return _; + }); + const sp = np; + var op = _curry3(function mergeDeepWithKey(s, o, i) { + return sp( + function (o, i, u) { + return _isObject(i) && _isObject(u) ? mergeDeepWithKey(s, i, u) : s(o, i, u); + }, + o, + i + ); + }); + const ip = op; + const lp = _curry2(function mergeDeepRight(s, o) { + return ip( + function (s, o, i) { + return i; + }, + s, + o + ); + }); + const cp = _curry2(_path); + const up = ja(0, -1); + var pp = _curry2(function apply(s, o) { + return s.apply(this, o); + }); + const hp = pp; + const dp = Ml(Wl); + var fp = _curry1(function empty(s) { + return null != s && 'function' == typeof s['fantasy-land/empty'] + ? s['fantasy-land/empty']() + : null != s && + null != s.constructor && + 'function' == typeof s.constructor['fantasy-land/empty'] + ? s.constructor['fantasy-land/empty']() + : null != s && 'function' == typeof s.empty + ? s.empty() + : null != s && null != s.constructor && 'function' == typeof s.constructor.empty + ? s.constructor.empty() + : aa(s) + ? [] + : _isString(s) + ? '' + : _isObject(s) + ? {} + : _i(s) + ? (function () { + return arguments; + })() + : (function _isTypedArray(s) { + var o = Object.prototype.toString.call(s); + return ( + '[object Uint8ClampedArray]' === o || + '[object Int8Array]' === o || + '[object Uint8Array]' === o || + '[object Int16Array]' === o || + '[object Uint16Array]' === o || + '[object Int32Array]' === o || + '[object Uint32Array]' === o || + '[object Float32Array]' === o || + '[object Float64Array]' === o || + '[object BigInt64Array]' === o || + '[object BigUint64Array]' === o + ); + })(s) + ? s.constructor.from('') + : void 0; + }); + const mp = fp; + const gp = _curry1(function isEmpty(s) { + return null != s && ra(s, mp(s)); + }); + const yp = za(1, Wl(Array.isArray) ? Array.isArray : pipe(ea, Vl('Array'))); + const vp = gu(yp, gp); + var bp = za(3, function (s, o, i) { + var u = cp(s, i), + _ = cp(up(s), i); + if (!dp(u) && !vp(s)) { + var w = Ea(u, _); + return hp(w, o); + } + }); + const _p = bp; + class Namespace extends Cu.g$ { + constructor() { + super(), + this.register('annotation', Iu), + this.register('comment', Pu), + this.register('parseResult', Mu), + this.register('sourceMap', Tu); + } + } + const Ep = new Namespace(), + createNamespace = (s) => { + const o = new Namespace(); + return ku(s) && o.use(s), o; + }, + wp = Ep, + toolbox = () => ({ predicates: { ...le }, namespace: wp }), + Sp = { + toolboxCreator: toolbox, + visitorOptions: { nodeTypeGetter: visitor_getNodeType, exposeEdits: !0 } + }, + dispatchPluginsSync = (s, o, i = {}) => { + if (0 === o.length) return s; + const u = lp(Sp, i), + { toolboxCreator: _, visitorOptions: w } = u, + x = _(), + C = o.map((s) => s(x)), + j = mergeAll(C.map(La({}, 'visitor')), { ...w }); + C.forEach(_p(['pre'], [])); + const L = visitor_visit(s, j, w); + return C.forEach(_p(['post'], [])), L; + }; + dispatchPluginsSync[Symbol.for('nodejs.util.promisify.custom')] = async (s, o, i = {}) => { + if (0 === o.length) return s; + const u = lp(Sp, i), + { toolboxCreator: _, visitorOptions: w } = u, + x = _(), + C = o.map((s) => s(x)), + j = mergeAll[Symbol.for('nodejs.util.promisify.custom')], + L = visitor_visit[Symbol.for('nodejs.util.promisify.custom')], + B = j(C.map(La({}, 'visitor')), { ...w }); + await Promise.allSettled(C.map(_p(['pre'], []))); + const $ = await L(s, B, w); + return await Promise.allSettled(C.map(_p(['post'], []))), $; + }; + const refract = (s, { Type: o, plugins: i = [] }) => { + const u = new o(s); + return ( + Nu(s) && + (s.meta.length > 0 && (u.meta = cloneDeep(s.meta)), + s.attributes.length > 0 && (u.attributes = cloneDeep(s.attributes))), + dispatchPluginsSync(u, i, { + toolboxCreator: toolbox, + visitorOptions: { nodeTypeGetter: visitor_getNodeType } + }) + ); + }, + createRefractor = + (s) => + (o, i = {}) => + refract(o, { ...i, Type: s }); + (Cu.Sh.refract = createRefractor(Cu.Sh)), + (Cu.wE.refract = createRefractor(Cu.wE)), + (Cu.Om.refract = createRefractor(Cu.Om)), + (Cu.bd.refract = createRefractor(Cu.bd)), + (Cu.Os.refract = createRefractor(Cu.Os)), + (Cu.kT.refract = createRefractor(Cu.kT)), + (Cu.Ft.refract = createRefractor(Cu.Ft)), + (Cu.sI.refract = createRefractor(Cu.sI)), + (Iu.refract = createRefractor(Iu)), + (Pu.refract = createRefractor(Pu)), + (Mu.refract = createRefractor(Mu)), + (Tu.refract = createRefractor(Tu)); + const computeEdges = (s, o = new WeakMap()) => ( + $u(s) + ? (o.set(s.key, s), computeEdges(s.key, o), o.set(s.value, s), computeEdges(s.value, o)) + : s.children.forEach((i) => { + o.set(i, s), computeEdges(i, o); + }), + o + ); + const xp = class Transcluder_Transcluder { + element; + edges; + constructor({ element: s }) { + this.element = s; + } + transclude(s, o) { + var i; + if (s === this.element) return o; + if (s === o) return this.element; + this.edges = + null !== (i = this.edges) && void 0 !== i ? i : computeEdges(this.element); + const u = this.edges.get(s); + return Rl(u) + ? void 0 + : (Fu(u) + ? ((s, o, i) => { + const u = i.get(s); + Fu(u) && + (u.content = u.map((_, w, x) => + x === s ? (i.delete(s), i.set(o, u), o) : x + )); + })(s, o, this.edges) + : qu(u) + ? ((s, o, i) => { + const u = i.get(s); + qu(u) && + (u.content = u.map((_) => + _ === s ? (i.delete(s), i.set(o, u), o) : _ + )); + })(s, o, this.edges) + : $u(u) && + ((s, o, i) => { + const u = i.get(s); + $u(u) && + (u.key === s && ((u.key = o), i.delete(s), i.set(o, u)), + u.value === s && ((u.value = o), i.delete(s), i.set(o, u))); + })(s, o, this.edges), + this.element); + } + }, + kp = pipe(Hl(/~/g, '~0'), Hl(/\//g, '~1'), encodeURIComponent); + const Cp = class JsonPointerError extends Jo {}; + const Op = class CompilationJsonPointerError extends Cp { + tokens; + constructor(s, o) { + super(s, o), void 0 !== o && (this.tokens = [...o.tokens]); + } + }, + es_compile = (s) => { + try { + return 0 === s.length ? '' : `/${s.map(kp).join('/')}`; + } catch (o) { + throw new Op('JSON Pointer compilation of tokens encountered an error.', { + tokens: s, + cause: o + }); + } + }; + var Ap = _curry2(function converge(s, o) { + return za(Ca(Ll, 0, Fl('length', o)), function () { + var i = arguments, + u = this; + return s.apply( + u, + _map(function (s) { + return s.apply(u, i); + }, o) + ); + }); + }); + const jp = Ap; + function _identity(s) { + return s; + } + const Ip = _curry1(_identity); + var Pp = gu(za(1, pipe(ea, Vl('Number'))), isFinite); + var Mp = za(1, Pp); + var Tp = gu( + Wl(Number.isFinite) ? za(1, Ea(Number.isFinite, Number)) : Mp, + jp(ra, [Math.floor, Ip]) + ); + var Np = za(1, Tp); + const Rp = Wl(Number.isInteger) ? za(1, Ea(Number.isInteger, Number)) : Np; + var Dp = (function () { + function XTake(s, o) { + (this.xf = o), (this.n = s), (this.i = 0); + } + return ( + (XTake.prototype['@@transducer/init'] = _xfBase_init), + (XTake.prototype['@@transducer/result'] = _xfBase_result), + (XTake.prototype['@@transducer/step'] = function (s, o) { + this.i += 1; + var i = 0 === this.n ? s : this.xf['@@transducer/step'](s, o); + return this.n >= 0 && this.i >= this.n ? _reduced(i) : i; + }), + XTake + ); + })(); + function _xtake(s) { + return function (o) { + return new Dp(s, o); + }; + } + const Lp = _curry2( + _dispatchable(['take'], _xtake, function take(s, o) { + return ja(0, s < 0 ? 1 / 0 : s, o); + }) + ); + var Bp = _curry2(function (s, o) { + return ra(Lp(s.length, o), s); + }); + const Fp = Bp; + const qp = ra(''); + var $p = (function () { + function XDropWhile(s, o) { + (this.xf = o), (this.f = s); + } + return ( + (XDropWhile.prototype['@@transducer/init'] = _xfBase_init), + (XDropWhile.prototype['@@transducer/result'] = _xfBase_result), + (XDropWhile.prototype['@@transducer/step'] = function (s, o) { + if (this.f) { + if (this.f(o)) return s; + this.f = null; + } + return this.xf['@@transducer/step'](s, o); + }), + XDropWhile + ); + })(); + function _xdropWhile(s) { + return function (o) { + return new $p(s, o); + }; + } + const Vp = _curry2( + _dispatchable(['dropWhile'], _xdropWhile, function dropWhile(s, o) { + for (var i = 0, u = o.length; i < u && s(o[i]); ) i += 1; + return ja(i, 1 / 0, o); + }) + ); + const Up = Ja(function (s, o) { + return pipe(tl(''), Vp(_l(s)), yl(''))(o); + }), + zp = pipe(Hl(/~1/g, '/'), Hl(/~0/g, '~'), (s) => { + try { + return decodeURIComponent(s); + } catch { + return s; + } + }); + const Wp = class InvalidJsonPointerError extends Cp { + pointer; + constructor(s, o) { + super(s, o), void 0 !== o && (this.pointer = o.pointer); + } + }, + uriToPointer = (s) => { + const o = ((s) => { + const o = s.indexOf('#'); + return -1 !== o ? s.substring(o) : '#'; + })(s); + return Up('#', o); + }, + es_parse = (s) => { + if (qp(s)) return []; + if (!Fp('/', s)) + throw new Wp(`Invalid JSON Pointer "${s}". JSON Pointers must begin with "/"`, { + pointer: s + }); + try { + const o = pipe(tl('/'), kl(zp))(s); + return Ia(o); + } catch (o) { + throw new Wp(`JSON Pointer parsing of "${s}" encountered an error.`, { + pointer: s, + cause: o + }); + } + }; + const Kp = class EvaluationJsonPointerError extends Cp { + pointer; + tokens; + failedToken; + failedTokenPosition; + element; + constructor(s, o) { + super(s, o), + void 0 !== o && + ((this.pointer = o.pointer), + Array.isArray(o.tokens) && (this.tokens = [...o.tokens]), + (this.failedToken = o.failedToken), + (this.failedTokenPosition = o.failedTokenPosition), + (this.element = o.element)); + } + }, + es_evaluate = (s, o) => { + let i; + try { + i = es_parse(s); + } catch (i) { + throw new Kp(`JSON Pointer evaluation failed while parsing the pointer "${s}".`, { + pointer: s, + element: cloneDeep(o), + cause: i + }); + } + return i.reduce((o, u, _) => { + if (Fu(o)) { + if (!o.hasKey(u)) + throw new Kp( + `JSON Pointer evaluation failed while evaluating token "${u}" against an ObjectElement`, + { + pointer: s, + tokens: i, + failedToken: u, + failedTokenPosition: _, + element: cloneDeep(o) + } + ); + return o.get(u); + } + if (qu(o)) { + if (!(u in o.content) || !Rp(Number(u))) + throw new Kp( + `JSON Pointer evaluation failed while evaluating token "${u}" against an ArrayElement`, + { + pointer: s, + tokens: i, + failedToken: u, + failedTokenPosition: _, + element: cloneDeep(o) + } + ); + return o.get(Number(u)); + } + throw new Kp( + `JSON Pointer evaluation failed while evaluating token "${u}" against an unexpected Element`, + { + pointer: s, + tokens: i, + failedToken: u, + failedTokenPosition: _, + element: cloneDeep(o) + } + ); + }, o); + }; + class Callback extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'callback'); + } + } + const Hp = Callback; + class Components extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'components'); + } + get schemas() { + return this.get('schemas'); + } + set schemas(s) { + this.set('schemas', s); + } + get responses() { + return this.get('responses'); + } + set responses(s) { + this.set('responses', s); + } + get parameters() { + return this.get('parameters'); + } + set parameters(s) { + this.set('parameters', s); + } + get examples() { + return this.get('examples'); + } + set examples(s) { + this.set('examples', s); + } + get requestBodies() { + return this.get('requestBodies'); + } + set requestBodies(s) { + this.set('requestBodies', s); + } + get headers() { + return this.get('headers'); + } + set headers(s) { + this.set('headers', s); + } + get securitySchemes() { + return this.get('securitySchemes'); + } + set securitySchemes(s) { + this.set('securitySchemes', s); + } + get links() { + return this.get('links'); + } + set links(s) { + this.set('links', s); + } + get callbacks() { + return this.get('callbacks'); + } + set callbacks(s) { + this.set('callbacks', s); + } + } + const Jp = Components; + class Contact extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'contact'); + } + get name() { + return this.get('name'); + } + set name(s) { + this.set('name', s); + } + get url() { + return this.get('url'); + } + set url(s) { + this.set('url', s); + } + get email() { + return this.get('email'); + } + set email(s) { + this.set('email', s); + } + } + const Gp = Contact; + class Discriminator extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'discriminator'); + } + get propertyName() { + return this.get('propertyName'); + } + set propertyName(s) { + this.set('propertyName', s); + } + get mapping() { + return this.get('mapping'); + } + set mapping(s) { + this.set('mapping', s); + } + } + const Yp = Discriminator; + class Encoding extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'encoding'); + } + get contentType() { + return this.get('contentType'); + } + set contentType(s) { + this.set('contentType', s); + } + get headers() { + return this.get('headers'); + } + set headers(s) { + this.set('headers', s); + } + get style() { + return this.get('style'); + } + set style(s) { + this.set('style', s); + } + get explode() { + return this.get('explode'); + } + set explode(s) { + this.set('explode', s); + } + get allowedReserved() { + return this.get('allowedReserved'); + } + set allowedReserved(s) { + this.set('allowedReserved', s); + } + } + const Xp = Encoding; + class Example extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'example'); + } + get summary() { + return this.get('summary'); + } + set summary(s) { + this.set('summary', s); + } + get description() { + return this.get('description'); + } + set description(s) { + this.set('description', s); + } + get value() { + return this.get('value'); + } + set value(s) { + this.set('value', s); + } + get externalValue() { + return this.get('externalValue'); + } + set externalValue(s) { + this.set('externalValue', s); + } + } + const Zp = Example; + class ExternalDocumentation extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'externalDocumentation'); + } + get description() { + return this.get('description'); + } + set description(s) { + this.set('description', s); + } + get url() { + return this.get('url'); + } + set url(s) { + this.set('url', s); + } + } + const Qp = ExternalDocumentation; + class Header extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'header'); + } + get required() { + return this.hasKey('required') ? this.get('required') : new Cu.bd(!1); + } + set required(s) { + this.set('required', s); + } + get deprecated() { + return this.hasKey('deprecated') ? this.get('deprecated') : new Cu.bd(!1); + } + set deprecated(s) { + this.set('deprecated', s); + } + get allowEmptyValue() { + return this.get('allowEmptyValue'); + } + set allowEmptyValue(s) { + this.set('allowEmptyValue', s); + } + get style() { + return this.get('style'); + } + set style(s) { + this.set('style', s); + } + get explode() { + return this.get('explode'); + } + set explode(s) { + this.set('explode', s); + } + get allowReserved() { + return this.get('allowReserved'); + } + set allowReserved(s) { + this.set('allowReserved', s); + } + get schema() { + return this.get('schema'); + } + set schema(s) { + this.set('schema', s); + } + get example() { + return this.get('example'); + } + set example(s) { + this.set('example', s); + } + get examples() { + return this.get('examples'); + } + set examples(s) { + this.set('examples', s); + } + get contentProp() { + return this.get('content'); + } + set contentProp(s) { + this.set('content', s); + } + } + Object.defineProperty(Header.prototype, 'description', { + get() { + return this.get('description'); + }, + set(s) { + this.set('description', s); + }, + enumerable: !0 + }); + const th = Header; + class Info extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'info'), this.classes.push('info'); + } + get title() { + return this.get('title'); + } + set title(s) { + this.set('title', s); + } + get description() { + return this.get('description'); + } + set description(s) { + this.set('description', s); + } + get termsOfService() { + return this.get('termsOfService'); + } + set termsOfService(s) { + this.set('termsOfService', s); + } + get contact() { + return this.get('contact'); + } + set contact(s) { + this.set('contact', s); + } + get license() { + return this.get('license'); + } + set license(s) { + this.set('license', s); + } + get version() { + return this.get('version'); + } + set version(s) { + this.set('version', s); + } + } + const rh = Info; + class License extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'license'); + } + get name() { + return this.get('name'); + } + set name(s) { + this.set('name', s); + } + get url() { + return this.get('url'); + } + set url(s) { + this.set('url', s); + } + } + const uh = License; + class Link extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'link'); + } + get operationRef() { + return this.get('operationRef'); + } + set operationRef(s) { + this.set('operationRef', s); + } + get operationId() { + return this.get('operationId'); + } + set operationId(s) { + this.set('operationId', s); + } + get operation() { + var s, o; + return Ru(this.operationRef) + ? null === (s = this.operationRef) || void 0 === s + ? void 0 + : s.meta.get('operation') + : Ru(this.operationId) + ? null === (o = this.operationId) || void 0 === o + ? void 0 + : o.meta.get('operation') + : void 0; + } + set operation(s) { + this.set('operation', s); + } + get parameters() { + return this.get('parameters'); + } + set parameters(s) { + this.set('parameters', s); + } + get requestBody() { + return this.get('requestBody'); + } + set requestBody(s) { + this.set('requestBody', s); + } + get description() { + return this.get('description'); + } + set description(s) { + this.set('description', s); + } + get server() { + return this.get('server'); + } + set server(s) { + this.set('server', s); + } + } + const dh = Link; + class MediaType extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'mediaType'); + } + get schema() { + return this.get('schema'); + } + set schema(s) { + this.set('schema', s); + } + get example() { + return this.get('example'); + } + set example(s) { + this.set('example', s); + } + get examples() { + return this.get('examples'); + } + set examples(s) { + this.set('examples', s); + } + get encoding() { + return this.get('encoding'); + } + set encoding(s) { + this.set('encoding', s); + } + } + const fh = MediaType; + class OAuthFlow extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'oAuthFlow'); + } + get authorizationUrl() { + return this.get('authorizationUrl'); + } + set authorizationUrl(s) { + this.set('authorizationUrl', s); + } + get tokenUrl() { + return this.get('tokenUrl'); + } + set tokenUrl(s) { + this.set('tokenUrl', s); + } + get refreshUrl() { + return this.get('refreshUrl'); + } + set refreshUrl(s) { + this.set('refreshUrl', s); + } + get scopes() { + return this.get('scopes'); + } + set scopes(s) { + this.set('scopes', s); + } + } + const vh = OAuthFlow; + class OAuthFlows extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'oAuthFlows'); + } + get implicit() { + return this.get('implicit'); + } + set implicit(s) { + this.set('implicit', s); + } + get password() { + return this.get('password'); + } + set password(s) { + this.set('password', s); + } + get clientCredentials() { + return this.get('clientCredentials'); + } + set clientCredentials(s) { + this.set('clientCredentials', s); + } + get authorizationCode() { + return this.get('authorizationCode'); + } + set authorizationCode(s) { + this.set('authorizationCode', s); + } + } + const _h = OAuthFlows; + class Openapi extends Cu.Om { + constructor(s, o, i) { + super(s, o, i), + (this.element = 'openapi'), + this.classes.push('spec-version'), + this.classes.push('version'); + } + } + const wh = Openapi; + class OpenApi3_0 extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'openApi3_0'), this.classes.push('api'); + } + get openapi() { + return this.get('openapi'); + } + set openapi(s) { + this.set('openapi', s); + } + get info() { + return this.get('info'); + } + set info(s) { + this.set('info', s); + } + get servers() { + return this.get('servers'); + } + set servers(s) { + this.set('servers', s); + } + get paths() { + return this.get('paths'); + } + set paths(s) { + this.set('paths', s); + } + get components() { + return this.get('components'); + } + set components(s) { + this.set('components', s); + } + get security() { + return this.get('security'); + } + set security(s) { + this.set('security', s); + } + get tags() { + return this.get('tags'); + } + set tags(s) { + this.set('tags', s); + } + get externalDocs() { + return this.get('externalDocs'); + } + set externalDocs(s) { + this.set('externalDocs', s); + } + } + const Oh = OpenApi3_0; + class Operation extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'operation'); + } + get tags() { + return this.get('tags'); + } + set tags(s) { + this.set('tags', s); + } + get summary() { + return this.get('summary'); + } + set summary(s) { + this.set('summary', s); + } + get description() { + return this.get('description'); + } + set description(s) { + this.set('description', s); + } + set externalDocs(s) { + this.set('externalDocs', s); + } + get externalDocs() { + return this.get('externalDocs'); + } + get operationId() { + return this.get('operationId'); + } + set operationId(s) { + this.set('operationId', s); + } + get parameters() { + return this.get('parameters'); + } + set parameters(s) { + this.set('parameters', s); + } + get requestBody() { + return this.get('requestBody'); + } + set requestBody(s) { + this.set('requestBody', s); + } + get responses() { + return this.get('responses'); + } + set responses(s) { + this.set('responses', s); + } + get callbacks() { + return this.get('callbacks'); + } + set callbacks(s) { + this.set('callbacks', s); + } + get deprecated() { + return this.hasKey('deprecated') ? this.get('deprecated') : new Cu.bd(!1); + } + set deprecated(s) { + this.set('deprecated', s); + } + get security() { + return this.get('security'); + } + set security(s) { + this.set('security', s); + } + get servers() { + return this.get('severs'); + } + set servers(s) { + this.set('servers', s); + } + } + const jh = Operation; + class Parameter extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'parameter'); + } + get name() { + return this.get('name'); + } + set name(s) { + this.set('name', s); + } + get in() { + return this.get('in'); + } + set in(s) { + this.set('in', s); + } + get required() { + return this.hasKey('required') ? this.get('required') : new Cu.bd(!1); + } + set required(s) { + this.set('required', s); + } + get deprecated() { + return this.hasKey('deprecated') ? this.get('deprecated') : new Cu.bd(!1); + } + set deprecated(s) { + this.set('deprecated', s); + } + get allowEmptyValue() { + return this.get('allowEmptyValue'); + } + set allowEmptyValue(s) { + this.set('allowEmptyValue', s); + } + get style() { + return this.get('style'); + } + set style(s) { + this.set('style', s); + } + get explode() { + return this.get('explode'); + } + set explode(s) { + this.set('explode', s); + } + get allowReserved() { + return this.get('allowReserved'); + } + set allowReserved(s) { + this.set('allowReserved', s); + } + get schema() { + return this.get('schema'); + } + set schema(s) { + this.set('schema', s); + } + get example() { + return this.get('example'); + } + set example(s) { + this.set('example', s); + } + get examples() { + return this.get('examples'); + } + set examples(s) { + this.set('examples', s); + } + get contentProp() { + return this.get('content'); + } + set contentProp(s) { + this.set('content', s); + } + } + Object.defineProperty(Parameter.prototype, 'description', { + get() { + return this.get('description'); + }, + set(s) { + this.set('description', s); + }, + enumerable: !0 + }); + const Ih = Parameter; + class PathItem extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'pathItem'); + } + get $ref() { + return this.get('$ref'); + } + set $ref(s) { + this.set('$ref', s); + } + get summary() { + return this.get('summary'); + } + set summary(s) { + this.set('summary', s); + } + get description() { + return this.get('description'); + } + set description(s) { + this.set('description', s); + } + get GET() { + return this.get('get'); + } + set GET(s) { + this.set('GET', s); + } + get PUT() { + return this.get('put'); + } + set PUT(s) { + this.set('PUT', s); + } + get POST() { + return this.get('post'); + } + set POST(s) { + this.set('POST', s); + } + get DELETE() { + return this.get('delete'); + } + set DELETE(s) { + this.set('DELETE', s); + } + get OPTIONS() { + return this.get('options'); + } + set OPTIONS(s) { + this.set('OPTIONS', s); + } + get HEAD() { + return this.get('head'); + } + set HEAD(s) { + this.set('HEAD', s); + } + get PATCH() { + return this.get('patch'); + } + set PATCH(s) { + this.set('PATCH', s); + } + get TRACE() { + return this.get('trace'); + } + set TRACE(s) { + this.set('TRACE', s); + } + get servers() { + return this.get('servers'); + } + set servers(s) { + this.set('servers', s); + } + get parameters() { + return this.get('parameters'); + } + set parameters(s) { + this.set('parameters', s); + } + } + const Ph = PathItem; + class Paths extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'paths'); + } + } + const Rh = Paths; + class Reference extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'reference'), this.classes.push('openapi-reference'); + } + get $ref() { + return this.get('$ref'); + } + set $ref(s) { + this.set('$ref', s); + } + } + const Dh = Reference; + class RequestBody extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'requestBody'); + } + get description() { + return this.get('description'); + } + set description(s) { + this.set('description', s); + } + get contentProp() { + return this.get('content'); + } + set contentProp(s) { + this.set('content', s); + } + get required() { + return this.hasKey('required') ? this.get('required') : new Cu.bd(!1); + } + set required(s) { + this.set('required', s); + } + } + const Lh = RequestBody; + class Response_Response extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'response'); + } + get description() { + return this.get('description'); + } + set description(s) { + this.set('description', s); + } + get headers() { + return this.get('headers'); + } + set headers(s) { + this.set('headers', s); + } + get contentProp() { + return this.get('content'); + } + set contentProp(s) { + this.set('content', s); + } + get links() { + return this.get('links'); + } + set links(s) { + this.set('links', s); + } + } + const Fh = Response_Response; + class Responses extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'responses'); + } + get default() { + return this.get('default'); + } + set default(s) { + this.set('default', s); + } + } + const Kh = Responses; + const Hh = class UnsupportedOperationError extends Ho {}; + class JSONSchema extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'JSONSchemaDraft4'); + } + get idProp() { + return this.get('id'); + } + set idProp(s) { + this.set('id', s); + } + get $schema() { + return this.get('$schema'); + } + set $schema(s) { + this.set('$schema', s); + } + get multipleOf() { + return this.get('multipleOf'); + } + set multipleOf(s) { + this.set('multipleOf', s); + } + get maximum() { + return this.get('maximum'); + } + set maximum(s) { + this.set('maximum', s); + } + get exclusiveMaximum() { + return this.get('exclusiveMaximum'); + } + set exclusiveMaximum(s) { + this.set('exclusiveMaximum', s); + } + get minimum() { + return this.get('minimum'); + } + set minimum(s) { + this.set('minimum', s); + } + get exclusiveMinimum() { + return this.get('exclusiveMinimum'); + } + set exclusiveMinimum(s) { + this.set('exclusiveMinimum', s); + } + get maxLength() { + return this.get('maxLength'); + } + set maxLength(s) { + this.set('maxLength', s); + } + get minLength() { + return this.get('minLength'); + } + set minLength(s) { + this.set('minLength', s); + } + get pattern() { + return this.get('pattern'); + } + set pattern(s) { + this.set('pattern', s); + } + get additionalItems() { + return this.get('additionalItems'); + } + set additionalItems(s) { + this.set('additionalItems', s); + } + get items() { + return this.get('items'); + } + set items(s) { + this.set('items', s); + } + get maxItems() { + return this.get('maxItems'); + } + set maxItems(s) { + this.set('maxItems', s); + } + get minItems() { + return this.get('minItems'); + } + set minItems(s) { + this.set('minItems', s); + } + get uniqueItems() { + return this.get('uniqueItems'); + } + set uniqueItems(s) { + this.set('uniqueItems', s); + } + get maxProperties() { + return this.get('maxProperties'); + } + set maxProperties(s) { + this.set('maxProperties', s); + } + get minProperties() { + return this.get('minProperties'); + } + set minProperties(s) { + this.set('minProperties', s); + } + get required() { + return this.get('required'); + } + set required(s) { + this.set('required', s); + } + get properties() { + return this.get('properties'); + } + set properties(s) { + this.set('properties', s); + } + get additionalProperties() { + return this.get('additionalProperties'); + } + set additionalProperties(s) { + this.set('additionalProperties', s); + } + get patternProperties() { + return this.get('patternProperties'); + } + set patternProperties(s) { + this.set('patternProperties', s); + } + get dependencies() { + return this.get('dependencies'); + } + set dependencies(s) { + this.set('dependencies', s); + } + get enum() { + return this.get('enum'); + } + set enum(s) { + this.set('enum', s); + } + get type() { + return this.get('type'); + } + set type(s) { + this.set('type', s); + } + get allOf() { + return this.get('allOf'); + } + set allOf(s) { + this.set('allOf', s); + } + get anyOf() { + return this.get('anyOf'); + } + set anyOf(s) { + this.set('anyOf', s); + } + get oneOf() { + return this.get('oneOf'); + } + set oneOf(s) { + this.set('oneOf', s); + } + get not() { + return this.get('not'); + } + set not(s) { + this.set('not', s); + } + get definitions() { + return this.get('definitions'); + } + set definitions(s) { + this.set('definitions', s); + } + get title() { + return this.get('title'); + } + set title(s) { + this.set('title', s); + } + get description() { + return this.get('description'); + } + set description(s) { + this.set('description', s); + } + get default() { + return this.get('default'); + } + set default(s) { + this.set('default', s); + } + get format() { + return this.get('format'); + } + set format(s) { + this.set('format', s); + } + get base() { + return this.get('base'); + } + set base(s) { + this.set('base', s); + } + get links() { + return this.get('links'); + } + set links(s) { + this.set('links', s); + } + get media() { + return this.get('media'); + } + set media(s) { + this.set('media', s); + } + get readOnly() { + return this.get('readOnly'); + } + set readOnly(s) { + this.set('readOnly', s); + } + } + const Jh = JSONSchema; + class JSONReference extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'JSONReference'), this.classes.push('json-reference'); + } + get $ref() { + return this.get('$ref'); + } + set $ref(s) { + this.set('$ref', s); + } + } + const Gh = JSONReference; + class Media extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'media'); + } + get binaryEncoding() { + return this.get('binaryEncoding'); + } + set binaryEncoding(s) { + this.set('binaryEncoding', s); + } + get type() { + return this.get('type'); + } + set type(s) { + this.set('type', s); + } + } + const Qh = Media; + class LinkDescription extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'linkDescription'); + } + get href() { + return this.get('href'); + } + set href(s) { + this.set('href', s); + } + get rel() { + return this.get('rel'); + } + set rel(s) { + this.set('rel', s); + } + get title() { + return this.get('title'); + } + set title(s) { + this.set('title', s); + } + get targetSchema() { + return this.get('targetSchema'); + } + set targetSchema(s) { + this.set('targetSchema', s); + } + get mediaType() { + return this.get('mediaType'); + } + set mediaType(s) { + this.set('mediaType', s); + } + get method() { + return this.get('method'); + } + set method(s) { + this.set('method', s); + } + get encType() { + return this.get('encType'); + } + set encType(s) { + this.set('encType', s); + } + get schema() { + return this.get('schema'); + } + set schema(s) { + this.set('schema', s); + } + } + const td = LinkDescription; + var sd = _curry2(function mapObjIndexed(s, o) { + return _arrayReduce( + function (i, u) { + return (i[u] = s(o[u], u, o)), i; + }, + {}, + Wi(o) + ); + }); + const id = sd; + const ld = _curry1(function isNil(s) { + return null == s; + }); + var cd = _curry2(function hasPath(s, o) { + if (0 === s.length || ld(o)) return !1; + for (var i = o, u = 0; u < s.length; ) { + if (ld(i) || !_has(s[u], i)) return !1; + (i = i[s[u]]), (u += 1); + } + return !0; + }); + const ud = cd; + var dd = _curry2(function has(s, o) { + return ud([s], o); + }); + const md = dd; + const yd = _curry3(function propSatisfies(s, o, i) { + return s(Da(o, i)); + }), + dereference = (s, o) => { + const i = Na(s, o); + return id((s) => { + if (ku(s) && md('$ref', s) && yd(Yl, '$ref', s)) { + const o = cp(['$ref'], s), + u = Up('#/', o); + return cp(u.split('/'), i); + } + return ku(s) ? dereference(s, i) : s; + }, s); + }, + emptyElement = (s) => { + const o = s.meta.length > 0 ? cloneDeep(s.meta) : void 0, + i = s.attributes.length > 0 ? cloneDeep(s.attributes) : void 0; + return new s.constructor(void 0, o, i); + }, + cloneUnlessOtherwiseSpecified = (s, o) => + o.clone && o.isMergeableElement(s) ? deepmerge(emptyElement(s), s, o) : s, + getMetaMergeFunction = (s) => + 'function' != typeof s.customMetaMerge ? (s) => cloneDeep(s) : s.customMetaMerge, + getAttributesMergeFunction = (s) => + 'function' != typeof s.customAttributesMerge + ? (s) => cloneDeep(s) + : s.customAttributesMerge, + vd = { + clone: !0, + isMergeableElement: (s) => Fu(s) || qu(s), + arrayElementMerge: (s, o, i) => + s.concat(o)['fantasy-land/map']((s) => cloneUnlessOtherwiseSpecified(s, i)), + objectElementMerge: (s, o, i) => { + const u = Fu(s) ? emptyElement(s) : emptyElement(o); + return ( + Fu(s) && + s.forEach((s, o, _) => { + const w = cloneShallow(_); + (w.value = cloneUnlessOtherwiseSpecified(s, i)), u.content.push(w); + }), + o.forEach((o, _, w) => { + const x = serializers_value(_); + let C; + if (Fu(s) && s.hasKey(x) && i.isMergeableElement(o)) { + const u = s.get(x); + (C = cloneShallow(w)), + (C.value = ((s, o) => { + if ('function' != typeof o.customMerge) return deepmerge; + const i = o.customMerge(s, o); + return 'function' == typeof i ? i : deepmerge; + })(_, i)(u, o)); + } else (C = cloneShallow(w)), (C.value = cloneUnlessOtherwiseSpecified(o, i)); + u.remove(x), u.content.push(C); + }), + u + ); + }, + customMerge: void 0, + customMetaMerge: void 0, + customAttributesMerge: void 0 + }; + function deepmerge(s, o, i) { + var u, _, w; + const x = { ...vd, ...i }; + (x.isMergeableElement = + null !== (u = x.isMergeableElement) && void 0 !== u ? u : vd.isMergeableElement), + (x.arrayElementMerge = + null !== (_ = x.arrayElementMerge) && void 0 !== _ ? _ : vd.arrayElementMerge), + (x.objectElementMerge = + null !== (w = x.objectElementMerge) && void 0 !== w ? w : vd.objectElementMerge); + const C = qu(o); + if (!(C === qu(s))) return cloneUnlessOtherwiseSpecified(o, x); + const j = + C && 'function' == typeof x.arrayElementMerge + ? x.arrayElementMerge(s, o, x) + : x.objectElementMerge(s, o, x); + return ( + (j.meta = getMetaMergeFunction(x)(s.meta, o.meta)), + (j.attributes = getAttributesMergeFunction(x)(s.attributes, o.attributes)), + j + ); + } + deepmerge.all = (s, o) => { + if (!Array.isArray(s)) + throw new TypeError('First argument of deepmerge should be an array.'); + return 0 === s.length + ? new Cu.Sh() + : s.reduce((s, i) => deepmerge(s, i, o), emptyElement(s[0])); + }; + const _d = class Visitor_Visitor { + element; + constructor(s) { + Object.assign(this, s); + } + copyMetaAndAttributes(s, o) { + (s.meta.length > 0 || o.meta.length > 0) && + ((o.meta = deepmerge(o.meta, s.meta)), + hasElementSourceMap(s) && o.meta.set('sourceMap', s.meta.get('sourceMap'))), + (s.attributes.length > 0 || s.meta.length > 0) && + (o.attributes = deepmerge(o.attributes, s.attributes)); + } + }; + const Ed = class FallbackVisitor extends _d { + enter(s) { + return (this.element = cloneDeep(s)), Ju; + } + }, + copyProps = (s, o, i = []) => { + const u = Object.getOwnPropertyDescriptors(o); + for (let s of i) delete u[s]; + Object.defineProperties(s, u); + }, + protoChain = (s, o = [s]) => { + const i = Object.getPrototypeOf(s); + return null === i ? o : protoChain(i, [...o, i]); + }, + hardMixProtos = (s, o, i = []) => { + var u; + const _ = + null !== + (u = ((...s) => { + if (0 === s.length) return; + let o; + const i = s.map((s) => protoChain(s)); + for (; i.every((s) => s.length > 0); ) { + const s = i.map((s) => s.pop()), + u = s[0]; + if (!s.every((s) => s === u)) break; + o = u; + } + return o; + })(...s)) && void 0 !== u + ? u + : Object.prototype, + w = Object.create(_), + x = protoChain(_); + for (let o of s) { + let s = protoChain(o); + for (let o = s.length - 1; o >= 0; o--) { + let u = s[o]; + -1 === x.indexOf(u) && (copyProps(w, u, ['constructor', ...i]), x.push(u)); + } + } + return (w.constructor = o), w; + }, + unique = (s) => s.filter((o, i) => s.indexOf(o) == i), + getIngredientWithProp = (s, o) => { + const i = o.map((s) => protoChain(s)); + let u = 0, + _ = !0; + for (; _; ) { + _ = !1; + for (let w = o.length - 1; w >= 0; w--) { + const o = i[w][u]; + if (null != o && ((_ = !0), null != Object.getOwnPropertyDescriptor(o, s))) + return i[w][0]; + } + u++; + } + }, + proxyMix = (s, o = Object.prototype) => + new Proxy( + {}, + { + getPrototypeOf: () => o, + setPrototypeOf() { + throw Error('Cannot set prototype of Proxies created by ts-mixer'); + }, + getOwnPropertyDescriptor: (o, i) => + Object.getOwnPropertyDescriptor(getIngredientWithProp(i, s) || {}, i), + defineProperty() { + throw new Error('Cannot define new properties on Proxies created by ts-mixer'); + }, + has: (i, u) => void 0 !== getIngredientWithProp(u, s) || void 0 !== o[u], + get: (i, u) => (getIngredientWithProp(u, s) || o)[u], + set(o, i, u) { + const _ = getIngredientWithProp(i, s); + if (void 0 === _) + throw new Error('Cannot set new properties on Proxies created by ts-mixer'); + return (_[i] = u), !0; + }, + deleteProperty() { + throw new Error('Cannot delete properties on Proxies created by ts-mixer'); + }, + ownKeys: () => + s + .map(Object.getOwnPropertyNames) + .reduce((s, o) => o.concat(s.filter((s) => o.indexOf(s) < 0))) + } + ), + wd = null, + Sd = 'copy', + xd = 'copy', + kd = 'deep', + Cd = new WeakMap(), + getMixinsForClass = (s) => Cd.get(s), + mergeObjectsOfDecorators = (s, o) => { + var i, u; + const _ = unique([...Object.getOwnPropertyNames(s), ...Object.getOwnPropertyNames(o)]), + w = {}; + for (let x of _) + w[x] = unique([ + ...(null !== (i = null == s ? void 0 : s[x]) && void 0 !== i ? i : []), + ...(null !== (u = null == o ? void 0 : o[x]) && void 0 !== u ? u : []) + ]); + return w; + }, + mergePropertyAndMethodDecorators = (s, o) => { + var i, u, _, w; + return { + property: mergeObjectsOfDecorators( + null !== (i = null == s ? void 0 : s.property) && void 0 !== i ? i : {}, + null !== (u = null == o ? void 0 : o.property) && void 0 !== u ? u : {} + ), + method: mergeObjectsOfDecorators( + null !== (_ = null == s ? void 0 : s.method) && void 0 !== _ ? _ : {}, + null !== (w = null == o ? void 0 : o.method) && void 0 !== w ? w : {} + ) + }; + }, + mergeDecorators = (s, o) => { + var i, u, _, w, x, C; + return { + class: unique([ + ...(null !== (i = null == s ? void 0 : s.class) && void 0 !== i ? i : []), + ...(null !== (u = null == o ? void 0 : o.class) && void 0 !== u ? u : []) + ]), + static: mergePropertyAndMethodDecorators( + null !== (_ = null == s ? void 0 : s.static) && void 0 !== _ ? _ : {}, + null !== (w = null == o ? void 0 : o.static) && void 0 !== w ? w : {} + ), + instance: mergePropertyAndMethodDecorators( + null !== (x = null == s ? void 0 : s.instance) && void 0 !== x ? x : {}, + null !== (C = null == o ? void 0 : o.instance) && void 0 !== C ? C : {} + ) + }; + }, + Od = new Map(), + deepDecoratorSearch = (...s) => { + const o = ((...s) => { + var o; + const i = new Set(), + u = new Set([...s]); + for (; u.size > 0; ) + for (let s of u) { + const _ = protoChain(s.prototype).map((s) => s.constructor), + w = [ + ..._, + ...(null !== (o = getMixinsForClass(s)) && void 0 !== o ? o : []) + ].filter((s) => !i.has(s)); + for (let s of w) u.add(s); + i.add(s), u.delete(s); + } + return [...i]; + })(...s) + .map((s) => Od.get(s)) + .filter((s) => !!s); + return 0 == o.length + ? {} + : 1 == o.length + ? o[0] + : o.reduce((s, o) => mergeDecorators(s, o)); + }, + getDecoratorsForClass = (s) => { + let o = Od.get(s); + return o || ((o = {}), Od.set(s, o)), o; + }; + function Mixin(...s) { + var o, i, u; + const _ = s.map((s) => s.prototype), + w = wd; + if (null !== w) { + const s = _.map((s) => s[w]).filter((s) => 'function' == typeof s), + combinedInitFunction = function (...o) { + for (let i of s) i.apply(this, o); + }, + o = { [w]: combinedInitFunction }; + _.push(o); + } + function MixedClass(...o) { + for (const i of s) copyProps(this, new i(...o)); + null !== w && 'function' == typeof this[w] && this[w].apply(this, o); + } + var x, C; + (MixedClass.prototype = + 'copy' === xd + ? hardMixProtos(_, MixedClass) + : ((x = _), (C = MixedClass), proxyMix([...x, { constructor: C }]))), + Object.setPrototypeOf( + MixedClass, + 'copy' === Sd + ? hardMixProtos(s, null, ['prototype']) + : proxyMix(s, Function.prototype) + ); + let j = MixedClass; + if ('none' !== kd) { + const _ = + 'deep' === kd + ? deepDecoratorSearch(...s) + : ((...s) => { + const o = s.map((s) => getDecoratorsForClass(s)); + return 0 === o.length + ? {} + : 1 === o.length + ? o[0] + : o.reduce((s, o) => mergeDecorators(s, o)); + })(...s); + for (let s of null !== (o = null == _ ? void 0 : _.class) && void 0 !== o ? o : []) { + const o = s(j); + o && (j = o); + } + applyPropAndMethodDecorators( + null !== (i = null == _ ? void 0 : _.static) && void 0 !== i ? i : {}, + j + ), + applyPropAndMethodDecorators( + null !== (u = null == _ ? void 0 : _.instance) && void 0 !== u ? u : {}, + j.prototype + ); + } + var L, B; + return (L = j), (B = s), Cd.set(L, B), j; + } + const applyPropAndMethodDecorators = (s, o) => { + const i = s.property, + u = s.method; + if (i) for (let s in i) for (let u of i[s]) u(o, s); + if (u) + for (let s in u) for (let i of u[s]) i(o, s, Object.getOwnPropertyDescriptor(o, s)); + }; + const Ad = _curry2(function pick(s, o) { + for (var i = {}, u = 0; u < s.length; ) s[u] in o && (i[s[u]] = o[s[u]]), (u += 1); + return i; + }); + const Id = class SpecificationVisitor extends _d { + specObj; + passingOptionsNames = ['specObj']; + constructor({ specObj: s, ...o }) { + super({ ...o }), (this.specObj = s); + } + retrievePassingOptions() { + return Ad(this.passingOptionsNames, this); + } + retrieveFixedFields(s) { + const o = cp(['visitors', ...s, 'fixedFields'], this.specObj); + return 'object' == typeof o && null !== o ? Object.keys(o) : []; + } + retrieveVisitor(s) { + return Xo(Wl, ['visitors', ...s], this.specObj) + ? cp(['visitors', ...s], this.specObj) + : cp(['visitors', ...s, '$visitor'], this.specObj); + } + retrieveVisitorInstance(s, o = {}) { + const i = this.retrievePassingOptions(); + return new (this.retrieveVisitor(s))({ ...i, ...o }); + } + toRefractedElement(s, o, i = {}) { + const u = this.retrieveVisitorInstance(s, i); + return u instanceof Ed && (null == u ? void 0 : u.constructor) === Ed + ? cloneDeep(o) + : (visitor_visit(o, u, i), u.element); + } + }; + const Md = class FixedFieldsVisitor extends Id { + specPath; + ignoredFields; + constructor({ specPath: s, ignoredFields: o, ...i }) { + super({ ...i }), (this.specPath = s), (this.ignoredFields = o || []); + } + ObjectElement(s) { + const o = this.specPath(s), + i = this.retrieveFixedFields(o); + return ( + s.forEach((s, u, _) => { + if ( + Ru(u) && + i.includes(serializers_value(u)) && + !this.ignoredFields.includes(serializers_value(u)) + ) { + const i = this.toRefractedElement([...o, 'fixedFields', serializers_value(u)], s), + w = new Cu.Pr(cloneDeep(u), i); + this.copyMetaAndAttributes(_, w), + w.classes.push('fixed-field'), + this.element.content.push(w); + } else + this.ignoredFields.includes(serializers_value(u)) || + this.element.content.push(cloneDeep(_)); + }), + this.copyMetaAndAttributes(s, this.element), + Ju + ); + } + }; + class JSONSchemaVisitor extends Mixin(Md, Ed) { + constructor(s) { + super(s), + (this.element = new Jh()), + (this.specPath = Tl(['document', 'objects', 'JSONSchema'])); + } + } + const Td = JSONSchemaVisitor; + const Nd = class ParentSchemaAwareVisitor { + parent; + constructor({ parent: s }) { + this.parent = s; + } + }, + isJSONReferenceLikeElement = (s) => Fu(s) && s.hasKey('$ref'); + class ItemsVisitor extends Mixin(Id, Nd, Ed) { + ObjectElement(s) { + const o = isJSONReferenceLikeElement(s) + ? ['document', 'objects', 'JSONReference'] + : ['document', 'objects', 'JSONSchema']; + return (this.element = this.toRefractedElement(o, s)), Ju; + } + ArrayElement(s) { + return ( + (this.element = new Cu.wE()), + this.element.classes.push('json-schema-items'), + s.forEach((s) => { + const o = isJSONReferenceLikeElement(s) + ? ['document', 'objects', 'JSONReference'] + : ['document', 'objects', 'JSONSchema'], + i = this.toRefractedElement(o, s); + this.element.push(i); + }), + this.copyMetaAndAttributes(s, this.element), + Ju + ); + } + } + const Rd = ItemsVisitor; + const Dd = class RequiredVisitor extends Ed { + ArrayElement(s) { + const o = this.enter(s); + return this.element.classes.push('json-schema-required'), o; + } + }; + const Ld = _curry1(function allPass(s) { + return za(Ca(Ll, 0, Fl('length', s)), function () { + for (var o = 0, i = s.length; o < i; ) { + if (!s[o].apply(this, arguments)) return !1; + o += 1; + } + return !0; + }); + }); + const Bd = _curry1(function isNotEmpty(s) { + return !gp(s); + }); + const Fd = _curry2(function or(s, o) { + return s || o; + }); + var $d = Ml( + za( + 1, + gu( + vu, + _curry2(function either(s, o) { + return _isFunction(s) + ? function _either() { + return s.apply(this, arguments) || o.apply(this, arguments); + } + : Pl(Fd)(s, o); + })(bu, Wl) + ) + ) + ); + const Vd = Ld([Yl, $d, Bd]); + const Ud = class PatternedFieldsVisitor extends Id { + specPath; + ignoredFields; + fieldPatternPredicate = es_F; + constructor({ specPath: s, ignoredFields: o, fieldPatternPredicate: i, ...u }) { + super({ ...u }), + (this.specPath = s), + (this.ignoredFields = o || []), + 'function' == typeof i && (this.fieldPatternPredicate = i); + } + ObjectElement(s) { + return ( + s.forEach((s, o, i) => { + if ( + !this.ignoredFields.includes(serializers_value(o)) && + this.fieldPatternPredicate(serializers_value(o)) + ) { + const u = this.specPath(s), + _ = this.toRefractedElement(u, s), + w = new Cu.Pr(cloneDeep(o), _); + this.copyMetaAndAttributes(i, w), + w.classes.push('patterned-field'), + this.element.content.push(w); + } else + this.ignoredFields.includes(serializers_value(o)) || + this.element.content.push(cloneDeep(i)); + }), + this.copyMetaAndAttributes(s, this.element), + Ju + ); + } + }; + const Wd = class MapVisitor extends Ud { + constructor(s) { + super(s), (this.fieldPatternPredicate = Vd); + } + }; + class PropertiesVisitor extends Mixin(Wd, Nd, Ed) { + constructor(s) { + super(s), + (this.element = new Cu.Sh()), + this.element.classes.push('json-schema-properties'), + (this.specPath = (s) => + isJSONReferenceLikeElement(s) + ? ['document', 'objects', 'JSONReference'] + : ['document', 'objects', 'JSONSchema']); + } + } + const Kd = PropertiesVisitor; + class PatternPropertiesVisitor extends Mixin(Wd, Nd, Ed) { + constructor(s) { + super(s), + (this.element = new Cu.Sh()), + this.element.classes.push('json-schema-patternProperties'), + (this.specPath = (s) => + isJSONReferenceLikeElement(s) + ? ['document', 'objects', 'JSONReference'] + : ['document', 'objects', 'JSONSchema']); + } + } + const Hd = PatternPropertiesVisitor; + class DependenciesVisitor extends Mixin(Wd, Nd, Ed) { + constructor(s) { + super(s), + (this.element = new Cu.Sh()), + this.element.classes.push('json-schema-dependencies'), + (this.specPath = (s) => + isJSONReferenceLikeElement(s) + ? ['document', 'objects', 'JSONReference'] + : ['document', 'objects', 'JSONSchema']); + } + } + const Jd = DependenciesVisitor; + const Gd = class EnumVisitor extends Ed { + ArrayElement(s) { + const o = this.enter(s); + return this.element.classes.push('json-schema-enum'), o; + } + }; + const Yd = class TypeVisitor extends Ed { + StringElement(s) { + const o = this.enter(s); + return this.element.classes.push('json-schema-type'), o; + } + ArrayElement(s) { + const o = this.enter(s); + return this.element.classes.push('json-schema-type'), o; + } + }; + class AllOfVisitor extends Mixin(Id, Nd, Ed) { + constructor(s) { + super(s), (this.element = new Cu.wE()), this.element.classes.push('json-schema-allOf'); + } + ArrayElement(s) { + return ( + s.forEach((s) => { + const o = isJSONReferenceLikeElement(s) + ? ['document', 'objects', 'JSONReference'] + : ['document', 'objects', 'JSONSchema'], + i = this.toRefractedElement(o, s); + this.element.push(i); + }), + this.copyMetaAndAttributes(s, this.element), + Ju + ); + } + } + const Xd = AllOfVisitor; + class AnyOfVisitor extends Mixin(Id, Nd, Ed) { + constructor(s) { + super(s), (this.element = new Cu.wE()), this.element.classes.push('json-schema-anyOf'); + } + ArrayElement(s) { + return ( + s.forEach((s) => { + const o = isJSONReferenceLikeElement(s) + ? ['document', 'objects', 'JSONReference'] + : ['document', 'objects', 'JSONSchema'], + i = this.toRefractedElement(o, s); + this.element.push(i); + }), + this.copyMetaAndAttributes(s, this.element), + Ju + ); + } + } + const Zd = AnyOfVisitor; + class OneOfVisitor extends Mixin(Id, Nd, Ed) { + constructor(s) { + super(s), (this.element = new Cu.wE()), this.element.classes.push('json-schema-oneOf'); + } + ArrayElement(s) { + return ( + s.forEach((s) => { + const o = isJSONReferenceLikeElement(s) + ? ['document', 'objects', 'JSONReference'] + : ['document', 'objects', 'JSONSchema'], + i = this.toRefractedElement(o, s); + this.element.push(i); + }), + this.copyMetaAndAttributes(s, this.element), + Ju + ); + } + } + const Qd = OneOfVisitor; + class DefinitionsVisitor extends Mixin(Wd, Nd, Ed) { + constructor(s) { + super(s), + (this.element = new Cu.Sh()), + this.element.classes.push('json-schema-definitions'), + (this.specPath = (s) => + isJSONReferenceLikeElement(s) + ? ['document', 'objects', 'JSONReference'] + : ['document', 'objects', 'JSONSchema']); + } + } + const ef = DefinitionsVisitor; + class LinksVisitor extends Mixin(Id, Nd, Ed) { + constructor(s) { + super(s), (this.element = new Cu.wE()), this.element.classes.push('json-schema-links'); + } + ArrayElement(s) { + return ( + s.forEach((s) => { + const o = this.toRefractedElement(['document', 'objects', 'LinkDescription'], s); + this.element.push(o); + }), + this.copyMetaAndAttributes(s, this.element), + Ju + ); + } + } + const rf = LinksVisitor; + class JSONReferenceVisitor extends Mixin(Md, Ed) { + constructor(s) { + super(s), + (this.element = new Gh()), + (this.specPath = Tl(['document', 'objects', 'JSONReference'])); + } + ObjectElement(s) { + const o = Md.prototype.ObjectElement.call(this, s); + return Ru(this.element.$ref) && this.element.classes.push('reference-element'), o; + } + } + const of = JSONReferenceVisitor; + const af = class $RefVisitor extends Ed { + StringElement(s) { + const o = this.enter(s); + return this.element.classes.push('reference-value'), o; + } + }; + const lf = _curry3(function ifElse(s, o, i) { + return za(Math.max(s.length, o.length, i.length), function _ifElse() { + return s.apply(this, arguments) ? o.apply(this, arguments) : i.apply(this, arguments); + }); + }); + const cf = _curry1(function comparator(s) { + return function (o, i) { + return s(o, i) ? -1 : s(i, o) ? 1 : 0; + }; + }); + var uf = _curry2(function sort(s, o) { + return Array.prototype.slice.call(o, 0).sort(s); + }); + const hf = uf; + var df = _curry1(function (s) { + return _nth(0, s); + }); + const mf = df; + const gf = _curry1(_reduced); + const yf = Ml(ld); + const bf = gu(yp, Bd); + function _toConsumableArray(s) { + return ( + (function _arrayWithoutHoles(s) { + if (Array.isArray(s)) return _arrayLikeToArray(s); + })(s) || + (function _iterableToArray(s) { + if ( + ('undefined' != typeof Symbol && null != s[Symbol.iterator]) || + null != s['@@iterator'] + ) + return Array.from(s); + })(s) || + (function _unsupportedIterableToArray(s, o) { + if (s) { + if ('string' == typeof s) return _arrayLikeToArray(s, o); + var i = {}.toString.call(s).slice(8, -1); + return ( + 'Object' === i && s.constructor && (i = s.constructor.name), + 'Map' === i || 'Set' === i + ? Array.from(s) + : 'Arguments' === i || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(i) + ? _arrayLikeToArray(s, o) + : void 0 + ); + } + })(s) || + (function _nonIterableSpread() { + throw new TypeError( + 'Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.' + ); + })() + ); + } + function _arrayLikeToArray(s, o) { + (null == o || o > s.length) && (o = s.length); + for (var i = 0, u = Array(o); i < o; i++) u[i] = s[i]; + return u; + } + var _f = pipe( + hf( + cf(function (s, o) { + return s.length > o.length; + }) + ), + mf, + Da('length') + ), + Sf = Ja(function (s, o, i) { + var u = i.apply(void 0, _toConsumableArray(s)); + return yf(u) ? gf(u) : o; + }); + const xf = lf( + bf, + function dispatchImpl(s) { + var o = _f(s); + return za(o, function () { + for (var o = arguments.length, i = new Array(o), u = 0; u < o; u++) + i[u] = arguments[u]; + return Ca(Sf(i), void 0, s); + }); + }, + Nl + ); + const kf = class AlternatingVisitor extends Id { + alternator; + constructor({ alternator: s, ...o }) { + super({ ...o }), (this.alternator = s); + } + enter(s) { + const o = this.alternator.map(({ predicate: s, specPath: o }) => lf(s, Tl(o), Nl)), + i = xf(o)(s); + return (this.element = this.toRefractedElement(i, s)), Ju; + } + }; + const Cf = class SchemaOrReferenceVisitor extends kf { + constructor(s) { + super(s), + (this.alternator = [ + { + predicate: isJSONReferenceLikeElement, + specPath: ['document', 'objects', 'JSONReference'] + }, + { predicate: es_T, specPath: ['document', 'objects', 'JSONSchema'] } + ]); + } + }; + class MediaVisitor extends Mixin(Md, Ed) { + constructor(s) { + super(s), + (this.element = new Qh()), + (this.specPath = Tl(['document', 'objects', 'Media'])); + } + } + const Of = MediaVisitor; + class LinkDescriptionVisitor extends Mixin(Md, Ed) { + constructor(s) { + super(s), + (this.element = new td()), + (this.specPath = Tl(['document', 'objects', 'LinkDescription'])); + } + } + const jf = { + visitors: { + value: Ed, + JSONSchemaOrJSONReferenceVisitor: Cf, + document: { + objects: { + JSONSchema: { + $visitor: Td, + fixedFields: { + id: { $ref: '#/visitors/value' }, + $schema: { $ref: '#/visitors/value' }, + multipleOf: { $ref: '#/visitors/value' }, + maximum: { $ref: '#/visitors/value' }, + exclusiveMaximum: { $ref: '#/visitors/value' }, + minimum: { $ref: '#/visitors/value' }, + exclusiveMinimum: { $ref: '#/visitors/value' }, + maxLength: { $ref: '#/visitors/value' }, + minLength: { $ref: '#/visitors/value' }, + pattern: { $ref: '#/visitors/value' }, + additionalItems: Cf, + items: Rd, + maxItems: { $ref: '#/visitors/value' }, + minItems: { $ref: '#/visitors/value' }, + uniqueItems: { $ref: '#/visitors/value' }, + maxProperties: { $ref: '#/visitors/value' }, + minProperties: { $ref: '#/visitors/value' }, + required: Dd, + properties: Kd, + additionalProperties: Cf, + patternProperties: Hd, + dependencies: Jd, + enum: Gd, + type: Yd, + allOf: Xd, + anyOf: Zd, + oneOf: Qd, + not: Cf, + definitions: ef, + title: { $ref: '#/visitors/value' }, + description: { $ref: '#/visitors/value' }, + default: { $ref: '#/visitors/value' }, + format: { $ref: '#/visitors/value' }, + base: { $ref: '#/visitors/value' }, + links: rf, + media: { $ref: '#/visitors/document/objects/Media' }, + readOnly: { $ref: '#/visitors/value' } + } + }, + JSONReference: { $visitor: of, fixedFields: { $ref: af } }, + Media: { + $visitor: Of, + fixedFields: { + binaryEncoding: { $ref: '#/visitors/value' }, + type: { $ref: '#/visitors/value' } + } + }, + LinkDescription: { + $visitor: LinkDescriptionVisitor, + fixedFields: { + href: { $ref: '#/visitors/value' }, + rel: { $ref: '#/visitors/value' }, + title: { $ref: '#/visitors/value' }, + targetSchema: Cf, + mediaType: { $ref: '#/visitors/value' }, + method: { $ref: '#/visitors/value' }, + encType: { $ref: '#/visitors/value' }, + schema: Cf + } + } + } + } + } + }, + traversal_visitor_getNodeType = (s) => { + if (Nu(s)) return `${s.element.charAt(0).toUpperCase() + s.element.slice(1)}Element`; + }, + Pf = { + JSONSchemaDraft4Element: ['content'], + JSONReferenceElement: ['content'], + MediaElement: ['content'], + LinkDescriptionElement: ['content'], + ...Qu + }, + Tf = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Jh || (s(u) && o('JSONSchemaDraft4', u) && i('object', u)) + ), + Nf = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Gh || (s(u) && o('JSONReference', u) && i('object', u)) + ), + Rf = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Qh || (s(u) && o('media', u) && i('object', u)) + ), + Df = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof td || (s(u) && o('linkDescription', u) && i('object', u)) + ), + Ff = { + namespace: (s) => { + const { base: o } = s; + return ( + o.register('jSONSchemaDraft4', Jh), + o.register('jSONReference', Gh), + o.register('media', Qh), + o.register('linkDescription', td), + o + ); + } + }, + Vf = Ff, + refractor_toolbox = () => { + const s = createNamespace(Vf); + return { predicates: { ...ce, isStringElement: Ru }, namespace: s }; + }, + refractor_refract = ( + s, + { + specPath: o = ['visitors', 'document', 'objects', 'JSONSchema', '$visitor'], + plugins: i = [], + specificationObj: u = jf + } = {} + ) => { + const _ = (0, Cu.e)(s), + w = dereference(u), + x = new (cp(o, w))({ specObj: w }); + return ( + visitor_visit(_, x), + dispatchPluginsSync(x.element, i, { + toolboxCreator: refractor_toolbox, + visitorOptions: { keyMap: Pf, nodeTypeGetter: traversal_visitor_getNodeType } + }) + ); + }, + refractor_createRefractor = + (s) => + (o, i = {}) => + refractor_refract(o, { specPath: s, ...i }); + (Jh.refract = refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'JSONSchema', + '$visitor' + ])), + (Gh.refract = refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'JSONReference', + '$visitor' + ])), + (Qh.refract = refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Media', + '$visitor' + ])), + (td.refract = refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'LinkDescription', + '$visitor' + ])); + const Wf = class Schema_Schema extends Jh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'schema'), this.classes.push('json-schema-draft-4'); + } + get idProp() { + throw new Hh('idProp getter in Schema class is not not supported.'); + } + set idProp(s) { + throw new Hh('idProp setter in Schema class is not not supported.'); + } + get $schema() { + throw new Hh('$schema getter in Schema class is not not supported.'); + } + set $schema(s) { + throw new Hh('$schema setter in Schema class is not not supported.'); + } + get additionalItems() { + return this.get('additionalItems'); + } + set additionalItems(s) { + this.set('additionalItems', s); + } + get items() { + return this.get('items'); + } + set items(s) { + this.set('items', s); + } + get additionalProperties() { + return this.get('additionalProperties'); + } + set additionalProperties(s) { + this.set('additionalProperties', s); + } + get patternProperties() { + throw new Hh('patternProperties getter in Schema class is not not supported.'); + } + set patternProperties(s) { + throw new Hh('patternProperties setter in Schema class is not not supported.'); + } + get dependencies() { + throw new Hh('dependencies getter in Schema class is not not supported.'); + } + set dependencies(s) { + throw new Hh('dependencies setter in Schema class is not not supported.'); + } + get type() { + return this.get('type'); + } + set type(s) { + this.set('type', s); + } + get not() { + return this.get('not'); + } + set not(s) { + this.set('not', s); + } + get definitions() { + throw new Hh('definitions getter in Schema class is not not supported.'); + } + set definitions(s) { + throw new Hh('definitions setter in Schema class is not not supported.'); + } + get base() { + throw new Hh('base getter in Schema class is not not supported.'); + } + set base(s) { + throw new Hh('base setter in Schema class is not not supported.'); + } + get links() { + throw new Hh('links getter in Schema class is not not supported.'); + } + set links(s) { + throw new Hh('links setter in Schema class is not not supported.'); + } + get media() { + throw new Hh('media getter in Schema class is not not supported.'); + } + set media(s) { + throw new Hh('media setter in Schema class is not not supported.'); + } + get nullable() { + return this.get('nullable'); + } + set nullable(s) { + this.set('nullable', s); + } + get discriminator() { + return this.get('discriminator'); + } + set discriminator(s) { + this.set('discriminator', s); + } + get writeOnly() { + return this.get('writeOnly'); + } + set writeOnly(s) { + this.set('writeOnly', s); + } + get xml() { + return this.get('xml'); + } + set xml(s) { + this.set('xml', s); + } + get externalDocs() { + return this.get('externalDocs'); + } + set externalDocs(s) { + this.set('externalDocs', s); + } + get example() { + return this.get('example'); + } + set example(s) { + this.set('example', s); + } + get deprecated() { + return this.get('deprecated'); + } + set deprecated(s) { + this.set('deprecated', s); + } + }; + class SecurityRequirement extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'securityRequirement'); + } + } + const Hf = SecurityRequirement; + class SecurityScheme extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'securityScheme'); + } + get type() { + return this.get('type'); + } + set type(s) { + this.set('type', s); + } + get description() { + return this.get('description'); + } + set description(s) { + this.set('description', s); + } + get name() { + return this.get('name'); + } + set name(s) { + this.set('name', s); + } + get in() { + return this.get('in'); + } + set in(s) { + this.set('in', s); + } + get scheme() { + return this.get('scheme'); + } + set scheme(s) { + this.set('scheme', s); + } + get bearerFormat() { + return this.get('bearerFormat'); + } + set bearerFormat(s) { + this.set('bearerFormat', s); + } + get flows() { + return this.get('flows'); + } + set flows(s) { + this.set('flows', s); + } + get openIdConnectUrl() { + return this.get('openIdConnectUrl'); + } + set openIdConnectUrl(s) { + this.set('openIdConnectUrl', s); + } + } + const Jf = SecurityScheme; + class Server extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'server'); + } + get url() { + return this.get('url'); + } + set url(s) { + this.set('url', s); + } + get description() { + return this.get('description'); + } + set description(s) { + this.set('description', s); + } + get variables() { + return this.get('variables'); + } + set variables(s) { + this.set('variables', s); + } + } + const Gf = Server; + class ServerVariable extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'serverVariable'); + } + get enum() { + return this.get('enum'); + } + set enum(s) { + this.set('enum', s); + } + get default() { + return this.get('default'); + } + set default(s) { + this.set('default', s); + } + get description() { + return this.get('description'); + } + set description(s) { + this.set('description', s); + } + } + const Xf = ServerVariable; + class Tag extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'tag'); + } + get name() { + return this.get('name'); + } + set name(s) { + this.set('name', s); + } + get description() { + return this.get('description'); + } + set description(s) { + this.set('description', s); + } + get externalDocs() { + return this.get('externalDocs'); + } + set externalDocs(s) { + this.set('externalDocs', s); + } + } + const Qf = Tag; + class Xml extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'xml'); + } + get name() { + return this.get('name'); + } + set name(s) { + this.set('name', s); + } + get namespace() { + return this.get('namespace'); + } + set namespace(s) { + this.set('namespace', s); + } + get prefix() { + return this.get('prefix'); + } + set prefix(s) { + this.set('prefix', s); + } + get attribute() { + return this.get('attribute'); + } + set attribute(s) { + this.set('attribute', s); + } + get wrapped() { + return this.get('wrapped'); + } + set wrapped(s) { + this.set('wrapped', s); + } + } + const em = Xml; + const tm = class visitors_Visitor_Visitor { + element; + constructor(s = {}) { + Object.assign(this, s); + } + copyMetaAndAttributes(s, o) { + (s.meta.length > 0 || o.meta.length > 0) && + ((o.meta = deepmerge(o.meta, s.meta)), + hasElementSourceMap(s) && o.meta.set('sourceMap', s.meta.get('sourceMap'))), + (s.attributes.length > 0 || s.meta.length > 0) && + (o.attributes = deepmerge(o.attributes, s.attributes)); + } + }; + const rm = class FallbackVisitor_FallbackVisitor extends tm { + enter(s) { + return (this.element = cloneDeep(s)), Ju; + } + }; + const nm = class SpecificationVisitor_SpecificationVisitor extends tm { + specObj; + passingOptionsNames = ['specObj', 'openApiGenericElement', 'openApiSemanticElement']; + openApiGenericElement; + openApiSemanticElement; + constructor({ + specObj: s, + passingOptionsNames: o, + openApiGenericElement: i, + openApiSemanticElement: u, + ..._ + }) { + super({ ..._ }), + (this.specObj = s), + (this.openApiGenericElement = i), + (this.openApiSemanticElement = u), + Array.isArray(o) && (this.passingOptionsNames = o); + } + retrievePassingOptions() { + return Ad(this.passingOptionsNames, this); + } + retrieveFixedFields(s) { + const o = cp(['visitors', ...s, 'fixedFields'], this.specObj); + return 'object' == typeof o && null !== o ? Object.keys(o) : []; + } + retrieveVisitor(s) { + return Xo(Wl, ['visitors', ...s], this.specObj) + ? cp(['visitors', ...s], this.specObj) + : cp(['visitors', ...s, '$visitor'], this.specObj); + } + retrieveVisitorInstance(s, o = {}) { + const i = this.retrievePassingOptions(); + return new (this.retrieveVisitor(s))({ ...i, ...o }); + } + toRefractedElement(s, o, i = {}) { + const u = this.retrieveVisitorInstance(s, i); + return u instanceof rm && (null == u ? void 0 : u.constructor) === rm + ? cloneDeep(o) + : (visitor_visit(o, u, i), u.element); + } + }, + isReferenceLikeElement = (s) => Fu(s) && s.hasKey('$ref'), + sm = Fu, + om = Fu, + isOpenApiExtension = (s) => Ru(s.key) && Fp('x-', serializers_value(s.key)); + const im = class FixedFieldsVisitor_FixedFieldsVisitor extends nm { + specPath; + ignoredFields; + canSupportSpecificationExtensions = !0; + specificationExtensionPredicate = isOpenApiExtension; + constructor({ + specPath: s, + ignoredFields: o, + canSupportSpecificationExtensions: i, + specificationExtensionPredicate: u, + ..._ + }) { + super({ ..._ }), + (this.specPath = s), + (this.ignoredFields = o || []), + 'boolean' == typeof i && (this.canSupportSpecificationExtensions = i), + 'function' == typeof u && (this.specificationExtensionPredicate = u); + } + ObjectElement(s) { + const o = this.specPath(s), + i = this.retrieveFixedFields(o); + return ( + s.forEach((s, u, _) => { + if ( + Ru(u) && + i.includes(serializers_value(u)) && + !this.ignoredFields.includes(serializers_value(u)) + ) { + const i = this.toRefractedElement([...o, 'fixedFields', serializers_value(u)], s), + w = new Cu.Pr(cloneDeep(u), i); + this.copyMetaAndAttributes(_, w), + w.classes.push('fixed-field'), + this.element.content.push(w); + } else if ( + this.canSupportSpecificationExtensions && + this.specificationExtensionPredicate(_) + ) { + const s = this.toRefractedElement(['document', 'extension'], _); + this.element.content.push(s); + } else + this.ignoredFields.includes(serializers_value(u)) || + this.element.content.push(cloneDeep(_)); + }), + this.copyMetaAndAttributes(s, this.element), + Ju + ); + } + }; + class OpenApi3_0Visitor extends Mixin(im, rm) { + constructor(s) { + super(s), + (this.element = new Oh()), + (this.specPath = Tl(['document', 'objects', 'OpenApi'])), + (this.canSupportSpecificationExtensions = !0); + } + ObjectElement(s) { + return im.prototype.ObjectElement.call(this, s); + } + } + const am = OpenApi3_0Visitor; + class OpenapiVisitor extends Mixin(nm, rm) { + StringElement(s) { + const o = new wh(serializers_value(s)); + return this.copyMetaAndAttributes(s, o), (this.element = o), Ju; + } + } + const lm = OpenapiVisitor; + const cm = class SpecificationExtensionVisitor extends nm { + MemberElement(s) { + return ( + (this.element = cloneDeep(s)), + this.element.classes.push('specification-extension'), + Ju + ); + } + }; + class InfoVisitor extends Mixin(im, rm) { + constructor(s) { + super(s), + (this.element = new rh()), + (this.specPath = Tl(['document', 'objects', 'Info'])), + (this.canSupportSpecificationExtensions = !0); + } + } + const um = InfoVisitor; + const pm = class VersionVisitor extends rm { + StringElement(s) { + const o = super.enter(s); + return ( + this.element.classes.push('api-version'), this.element.classes.push('version'), o + ); + } + }; + class ContactVisitor extends Mixin(im, rm) { + constructor(s) { + super(s), + (this.element = new Gp()), + (this.specPath = Tl(['document', 'objects', 'Contact'])), + (this.canSupportSpecificationExtensions = !0); + } + } + const hm = ContactVisitor; + class LicenseVisitor extends Mixin(im, rm) { + constructor(s) { + super(s), + (this.element = new uh()), + (this.specPath = Tl(['document', 'objects', 'License'])), + (this.canSupportSpecificationExtensions = !0); + } + } + const dm = LicenseVisitor; + class LinkVisitor extends Mixin(im, rm) { + constructor(s) { + super(s), + (this.element = new dh()), + (this.specPath = Tl(['document', 'objects', 'Link'])), + (this.canSupportSpecificationExtensions = !0); + } + ObjectElement(s) { + const o = im.prototype.ObjectElement.call(this, s); + return ( + (Ru(this.element.operationId) || Ru(this.element.operationRef)) && + this.element.classes.push('reference-element'), + o + ); + } + } + const fm = LinkVisitor; + const mm = class OperationRefVisitor extends rm { + StringElement(s) { + const o = super.enter(s); + return this.element.classes.push('reference-value'), o; + } + }; + const gm = class OperationIdVisitor extends rm { + StringElement(s) { + const o = super.enter(s); + return this.element.classes.push('reference-value'), o; + } + }; + const ym = class PatternedFieldsVisitor_PatternedFieldsVisitor extends nm { + specPath; + ignoredFields; + fieldPatternPredicate = es_F; + canSupportSpecificationExtensions = !1; + specificationExtensionPredicate = isOpenApiExtension; + constructor({ + specPath: s, + ignoredFields: o, + fieldPatternPredicate: i, + canSupportSpecificationExtensions: u, + specificationExtensionPredicate: _, + ...w + }) { + super({ ...w }), + (this.specPath = s), + (this.ignoredFields = o || []), + 'function' == typeof i && (this.fieldPatternPredicate = i), + 'boolean' == typeof u && (this.canSupportSpecificationExtensions = u), + 'function' == typeof _ && (this.specificationExtensionPredicate = _); + } + ObjectElement(s) { + return ( + s.forEach((s, o, i) => { + if ( + this.canSupportSpecificationExtensions && + this.specificationExtensionPredicate(i) + ) { + const s = this.toRefractedElement(['document', 'extension'], i); + this.element.content.push(s); + } else if ( + !this.ignoredFields.includes(serializers_value(o)) && + this.fieldPatternPredicate(serializers_value(o)) + ) { + const u = this.specPath(s), + _ = this.toRefractedElement(u, s), + w = new Cu.Pr(cloneDeep(o), _); + this.copyMetaAndAttributes(i, w), + w.classes.push('patterned-field'), + this.element.content.push(w); + } else + this.ignoredFields.includes(serializers_value(o)) || + this.element.content.push(cloneDeep(i)); + }), + this.copyMetaAndAttributes(s, this.element), + Ju + ); + } + }; + const vm = class MapVisitor_MapVisitor extends ym { + constructor(s) { + super(s), (this.fieldPatternPredicate = Vd); + } + }; + class LinkParameters extends Cu.Sh { + static primaryClass = 'link-parameters'; + constructor(s, o, i) { + super(s, o, i), this.classes.push(LinkParameters.primaryClass); + } + } + const bm = LinkParameters; + class ParametersVisitor extends Mixin(vm, rm) { + constructor(s) { + super(s), (this.element = new bm()), (this.specPath = Tl(['value'])); + } + } + const _m = ParametersVisitor; + class ServerVisitor extends Mixin(im, rm) { + constructor(s) { + super(s), + (this.element = new Gf()), + (this.specPath = Tl(['document', 'objects', 'Server'])), + (this.canSupportSpecificationExtensions = !0); + } + } + const Em = ServerVisitor; + const wm = class UrlVisitor extends rm { + StringElement(s) { + const o = super.enter(s); + return this.element.classes.push('server-url'), o; + } + }; + class Servers extends Cu.wE { + static primaryClass = 'servers'; + constructor(s, o, i) { + super(s, o, i), this.classes.push(Servers.primaryClass); + } + } + const Sm = Servers; + class ServersVisitor extends Mixin(nm, rm) { + constructor(s) { + super(s), (this.element = new Sm()); + } + ArrayElement(s) { + return ( + s.forEach((s) => { + const o = sm(s) ? ['document', 'objects', 'Server'] : ['value'], + i = this.toRefractedElement(o, s); + this.element.push(i); + }), + this.copyMetaAndAttributes(s, this.element), + Ju + ); + } + } + const xm = ServersVisitor; + class ServerVariableVisitor extends Mixin(im, rm) { + constructor(s) { + super(s), + (this.element = new Xf()), + (this.specPath = Tl(['document', 'objects', 'ServerVariable'])), + (this.canSupportSpecificationExtensions = !0); + } + } + const km = ServerVariableVisitor; + class ServerVariables extends Cu.Sh { + static primaryClass = 'server-variables'; + constructor(s, o, i) { + super(s, o, i), this.classes.push(ServerVariables.primaryClass); + } + } + const Cm = ServerVariables; + class VariablesVisitor extends Mixin(vm, rm) { + constructor(s) { + super(s), + (this.element = new Cm()), + (this.specPath = Tl(['document', 'objects', 'ServerVariable'])); + } + } + const Om = VariablesVisitor; + class MediaTypeVisitor extends Mixin(im, rm) { + constructor(s) { + super(s), + (this.element = new fh()), + (this.specPath = Tl(['document', 'objects', 'MediaType'])), + (this.canSupportSpecificationExtensions = !0); + } + } + const Am = MediaTypeVisitor; + const jm = class AlternatingVisitor_AlternatingVisitor extends nm { + alternator; + constructor({ alternator: s, ...o }) { + super({ ...o }), (this.alternator = s || []); + } + enter(s) { + const o = this.alternator.map(({ predicate: s, specPath: o }) => lf(s, Tl(o), Nl)), + i = xf(o)(s); + return (this.element = this.toRefractedElement(i, s)), Ju; + } + }, + Im = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Hp || (s(u) && o('callback', u) && i('object', u)) + ), + Pm = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Jp || (s(u) && o('components', u) && i('object', u)) + ), + Mm = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Gp || (s(u) && o('contact', u) && i('object', u)) + ), + Tm = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Zp || (s(u) && o('example', u) && i('object', u)) + ), + Nm = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Qp || (s(u) && o('externalDocumentation', u) && i('object', u)) + ), + Rm = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof th || (s(u) && o('header', u) && i('object', u)) + ), + Dm = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof rh || (s(u) && o('info', u) && i('object', u)) + ), + Lm = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof uh || (s(u) && o('license', u) && i('object', u)) + ), + Bm = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof dh || (s(u) && o('link', u) && i('object', u)) + ), + Fm = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof wh || (s(u) && o('openapi', u) && i('string', u)) + ), + qm = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i, hasClass: u }) => + (_) => + _ instanceof Oh || (s(_) && o('openApi3_0', _) && i('object', _) && u('api', _)) + ), + $m = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof jh || (s(u) && o('operation', u) && i('object', u)) + ), + Vm = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Ih || (s(u) && o('parameter', u) && i('object', u)) + ), + Um = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Ph || (s(u) && o('pathItem', u) && i('object', u)) + ), + zm = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Rh || (s(u) && o('paths', u) && i('object', u)) + ), + Wm = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Dh || (s(u) && o('reference', u) && i('object', u)) + ), + Km = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Lh || (s(u) && o('requestBody', u) && i('object', u)) + ), + Hm = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Fh || (s(u) && o('response', u) && i('object', u)) + ), + Jm = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Kh || (s(u) && o('responses', u) && i('object', u)) + ), + Gm = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Wf || (s(u) && o('schema', u) && i('object', u)) + ), + isBooleanJsonSchemaElement = (s) => Bu(s) && s.classes.includes('boolean-json-schema'), + Ym = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Hf || (s(u) && o('securityRequirement', u) && i('object', u)) + ), + Xm = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Jf || (s(u) && o('securityScheme', u) && i('object', u)) + ), + Zm = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Gf || (s(u) && o('server', u) && i('object', u)) + ), + Qm = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Xf || (s(u) && o('serverVariable', u) && i('object', u)) + ), + eg = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof fh || (s(u) && o('mediaType', u) && i('object', u)) + ), + rg = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i, hasClass: u }) => + (_) => + _ instanceof Sm || (s(_) && o('array', _) && i('array', _) && u('servers', _)) + ); + class SchemaVisitor extends Mixin(jm, rm) { + constructor(s) { + super(s), + (this.alternator = [ + { + predicate: isReferenceLikeElement, + specPath: ['document', 'objects', 'Reference'] + }, + { predicate: es_T, specPath: ['document', 'objects', 'Schema'] } + ]); + } + ObjectElement(s) { + const o = jm.prototype.enter.call(this, s); + return ( + Wm(this.element) && this.element.setMetaProperty('referenced-element', 'schema'), o + ); + } + } + const ng = SchemaVisitor; + class ExamplesVisitor extends Mixin(vm, rm) { + constructor(s) { + super(s), + (this.element = new Cu.Sh()), + this.element.classes.push('examples'), + (this.specPath = (s) => + isReferenceLikeElement(s) + ? ['document', 'objects', 'Reference'] + : ['document', 'objects', 'Example']), + (this.canSupportSpecificationExtensions = !0); + } + ObjectElement(s) { + const o = vm.prototype.ObjectElement.call(this, s); + return ( + this.element.filter(Wm).forEach((s) => { + s.setMetaProperty('referenced-element', 'example'); + }), + o + ); + } + } + const sg = ExamplesVisitor; + class MediaTypeExamples extends Cu.Sh { + static primaryClass = 'media-type-examples'; + constructor(s, o, i) { + super(s, o, i), + this.classes.push(MediaTypeExamples.primaryClass), + this.classes.push('examples'); + } + } + const og = MediaTypeExamples; + const lg = class ExamplesVisitor_ExamplesVisitor extends sg { + constructor(s) { + super(s), (this.element = new og()); + } + }; + class MediaTypeEncoding extends Cu.Sh { + static primaryClass = 'media-type-encoding'; + constructor(s, o, i) { + super(s, o, i), this.classes.push(MediaTypeEncoding.primaryClass); + } + } + const pg = MediaTypeEncoding; + class EncodingVisitor extends Mixin(vm, rm) { + constructor(s) { + super(s), + (this.element = new pg()), + (this.specPath = Tl(['document', 'objects', 'Encoding'])); + } + } + const fg = EncodingVisitor; + class SecurityRequirementVisitor extends Mixin(vm, rm) { + constructor(s) { + super(s), (this.element = new Hf()), (this.specPath = Tl(['value'])); + } + } + const mg = SecurityRequirementVisitor; + class Security extends Cu.wE { + static primaryClass = 'security'; + constructor(s, o, i) { + super(s, o, i), this.classes.push(Security.primaryClass); + } + } + const gg = Security; + class SecurityVisitor extends Mixin(nm, rm) { + constructor(s) { + super(s), (this.element = new gg()); + } + ArrayElement(s) { + return ( + s.forEach((s) => { + if (Fu(s)) { + const o = this.toRefractedElement( + ['document', 'objects', 'SecurityRequirement'], + s + ); + this.element.push(o); + } else this.element.push(cloneDeep(s)); + }), + this.copyMetaAndAttributes(s, this.element), + Ju + ); + } + } + const yg = SecurityVisitor; + class ComponentsVisitor extends Mixin(im, rm) { + constructor(s) { + super(s), + (this.element = new Jp()), + (this.specPath = Tl(['document', 'objects', 'Components'])), + (this.canSupportSpecificationExtensions = !0); + } + } + const _g = ComponentsVisitor; + class TagVisitor extends Mixin(im, rm) { + constructor(s) { + super(s), + (this.element = new Qf()), + (this.specPath = Tl(['document', 'objects', 'Tag'])), + (this.canSupportSpecificationExtensions = !0); + } + } + const xg = TagVisitor; + class ReferenceVisitor extends Mixin(im, rm) { + constructor(s) { + super(s), + (this.element = new Dh()), + (this.specPath = Tl(['document', 'objects', 'Reference'])), + (this.canSupportSpecificationExtensions = !1); + } + ObjectElement(s) { + const o = im.prototype.ObjectElement.call(this, s); + return Ru(this.element.$ref) && this.element.classes.push('reference-element'), o; + } + } + const kg = ReferenceVisitor; + const qg = class $RefVisitor_$RefVisitor extends rm { + StringElement(s) { + const o = super.enter(s); + return this.element.classes.push('reference-value'), o; + } + }; + class ParameterVisitor extends Mixin(im, rm) { + constructor(s) { + super(s), + (this.element = new Ih()), + (this.specPath = Tl(['document', 'objects', 'Parameter'])), + (this.canSupportSpecificationExtensions = !0); + } + ObjectElement(s) { + const o = im.prototype.ObjectElement.call(this, s); + return ( + Fu(this.element.contentProp) && + this.element.contentProp.filter(eg).forEach((s, o) => { + s.setMetaProperty('media-type', serializers_value(o)); + }), + o + ); + } + } + const Vg = ParameterVisitor; + class SchemaVisitor_SchemaVisitor extends Mixin(jm, rm) { + constructor(s) { + super(s), + (this.alternator = [ + { + predicate: isReferenceLikeElement, + specPath: ['document', 'objects', 'Reference'] + }, + { predicate: es_T, specPath: ['document', 'objects', 'Schema'] } + ]); + } + ObjectElement(s) { + const o = jm.prototype.enter.call(this, s); + return ( + Wm(this.element) && this.element.setMetaProperty('referenced-element', 'schema'), o + ); + } + } + const Ug = SchemaVisitor_SchemaVisitor; + class HeaderVisitor extends Mixin(im, rm) { + constructor(s) { + super(s), + (this.element = new th()), + (this.specPath = Tl(['document', 'objects', 'Header'])), + (this.canSupportSpecificationExtensions = !0); + } + } + const zg = HeaderVisitor; + class header_SchemaVisitor_SchemaVisitor extends Mixin(jm, rm) { + constructor(s) { + super(s), + (this.alternator = [ + { + predicate: isReferenceLikeElement, + specPath: ['document', 'objects', 'Reference'] + }, + { predicate: es_T, specPath: ['document', 'objects', 'Schema'] } + ]); + } + ObjectElement(s) { + const o = jm.prototype.enter.call(this, s); + return ( + Wm(this.element) && this.element.setMetaProperty('referenced-element', 'schema'), o + ); + } + } + const Wg = header_SchemaVisitor_SchemaVisitor; + class HeaderExamples extends Cu.Sh { + static primaryClass = 'header-examples'; + constructor(s, o, i) { + super(s, o, i), + this.classes.push(HeaderExamples.primaryClass), + this.classes.push('examples'); + } + } + const Kg = HeaderExamples; + const Yg = class header_ExamplesVisitor_ExamplesVisitor extends sg { + constructor(s) { + super(s), (this.element = new Kg()); + } + }; + class ContentVisitor extends Mixin(vm, rm) { + constructor(s) { + super(s), + (this.element = new Cu.Sh()), + this.element.classes.push('content'), + (this.specPath = Tl(['document', 'objects', 'MediaType'])); + } + } + const Xg = ContentVisitor; + class HeaderContent extends Cu.Sh { + static primaryClass = 'header-content'; + constructor(s, o, i) { + super(s, o, i), + this.classes.push(HeaderContent.primaryClass), + this.classes.push('content'); + } + } + const Zg = HeaderContent; + const ey = class ContentVisitor_ContentVisitor extends Xg { + constructor(s) { + super(s), (this.element = new Zg()); + } + }; + class schema_SchemaVisitor extends Mixin(im, rm) { + constructor(s) { + super(s), + (this.element = new Wf()), + (this.specPath = Tl(['document', 'objects', 'Schema'])), + (this.canSupportSpecificationExtensions = !0); + } + } + const ty = schema_SchemaVisitor, + { allOf: ry } = jf.visitors.document.objects.JSONSchema.fixedFields; + const ny = class AllOfVisitor_AllOfVisitor extends ry { + ArrayElement(s) { + const o = ry.prototype.ArrayElement.call(this, s); + return ( + this.element.filter(Wm).forEach((s) => { + s.setMetaProperty('referenced-element', 'schema'); + }), + o + ); + } + }, + { anyOf: sy } = jf.visitors.document.objects.JSONSchema.fixedFields; + const oy = class AnyOfVisitor_AnyOfVisitor extends sy { + ArrayElement(s) { + const o = sy.prototype.ArrayElement.call(this, s); + return ( + this.element.filter(Wm).forEach((s) => { + s.setMetaProperty('referenced-element', 'schema'); + }), + o + ); + } + }, + { oneOf: iy } = jf.visitors.document.objects.JSONSchema.fixedFields; + const ay = class OneOfVisitor_OneOfVisitor extends iy { + ArrayElement(s) { + const o = iy.prototype.ArrayElement.call(this, s); + return ( + this.element.filter(Wm).forEach((s) => { + s.setMetaProperty('referenced-element', 'schema'); + }), + o + ); + } + }, + { items: ly } = jf.visitors.document.objects.JSONSchema.fixedFields; + const cy = class ItemsVisitor_ItemsVisitor extends ly { + ObjectElement(s) { + const o = ly.prototype.ObjectElement.call(this, s); + return ( + Wm(this.element) && this.element.setMetaProperty('referenced-element', 'schema'), o + ); + } + ArrayElement(s) { + return this.enter(s); + } + }, + { properties: uy } = jf.visitors.document.objects.JSONSchema.fixedFields; + const py = class PropertiesVisitor_PropertiesVisitor extends uy { + ObjectElement(s) { + const o = uy.prototype.ObjectElement.call(this, s); + return ( + this.element.filter(Wm).forEach((s) => { + s.setMetaProperty('referenced-element', 'schema'); + }), + o + ); + } + }, + { type: hy } = jf.visitors.document.objects.JSONSchema.fixedFields; + const dy = class TypeVisitor_TypeVisitor extends hy { + ArrayElement(s) { + return this.enter(s); + } + }, + { JSONSchemaOrJSONReferenceVisitor: fy } = jf.visitors; + const my = class SchemaOrReferenceVisitor_SchemaOrReferenceVisitor extends fy { + ObjectElement(s) { + const o = fy.prototype.enter.call(this, s); + return ( + Wm(this.element) && this.element.setMetaProperty('referenced-element', 'schema'), o + ); + } + }; + class DiscriminatorVisitor extends Mixin(im, rm) { + constructor(s) { + super(s), + (this.element = new Yp()), + (this.specPath = Tl(['document', 'objects', 'Discriminator'])), + (this.canSupportSpecificationExtensions = !1); + } + } + const gy = DiscriminatorVisitor; + class DiscriminatorMapping extends Cu.Sh { + static primaryClass = 'discriminator-mapping'; + constructor(s, o, i) { + super(s, o, i), this.classes.push(DiscriminatorMapping.primaryClass); + } + } + const yy = DiscriminatorMapping; + class MappingVisitor extends Mixin(vm, rm) { + constructor(s) { + super(s), (this.element = new yy()), (this.specPath = Tl(['value'])); + } + } + const vy = MappingVisitor; + class XmlVisitor extends Mixin(im, rm) { + constructor(s) { + super(s), + (this.element = new em()), + (this.specPath = Tl(['document', 'objects', 'XML'])), + (this.canSupportSpecificationExtensions = !0); + } + } + const by = XmlVisitor; + class ParameterExamples extends Cu.Sh { + static primaryClass = 'parameter-examples'; + constructor(s, o, i) { + super(s, o, i), + this.classes.push(ParameterExamples.primaryClass), + this.classes.push('examples'); + } + } + const _y = ParameterExamples; + const Ey = class parameter_ExamplesVisitor_ExamplesVisitor extends sg { + constructor(s) { + super(s), (this.element = new _y()); + } + }; + class ParameterContent extends Cu.Sh { + static primaryClass = 'parameter-content'; + constructor(s, o, i) { + super(s, o, i), + this.classes.push(ParameterContent.primaryClass), + this.classes.push('content'); + } + } + const wy = ParameterContent; + const Sy = class parameter_ContentVisitor_ContentVisitor extends Xg { + constructor(s) { + super(s), (this.element = new wy()); + } + }; + class ComponentsSchemas extends Cu.Sh { + static primaryClass = 'components-schemas'; + constructor(s, o, i) { + super(s, o, i), this.classes.push(ComponentsSchemas.primaryClass); + } + } + const xy = ComponentsSchemas; + class SchemasVisitor extends Mixin(vm, rm) { + constructor(s) { + super(s), + (this.element = new xy()), + (this.specPath = (s) => + isReferenceLikeElement(s) + ? ['document', 'objects', 'Reference'] + : ['document', 'objects', 'Schema']); + } + ObjectElement(s) { + const o = vm.prototype.ObjectElement.call(this, s); + return ( + this.element.filter(Wm).forEach((s) => { + s.setMetaProperty('referenced-element', 'schema'); + }), + o + ); + } + } + const ky = SchemasVisitor; + class ComponentsResponses extends Cu.Sh { + static primaryClass = 'components-responses'; + constructor(s, o, i) { + super(s, o, i), this.classes.push(ComponentsResponses.primaryClass); + } + } + const Cy = ComponentsResponses; + class ResponsesVisitor extends Mixin(vm, rm) { + constructor(s) { + super(s), + (this.element = new Cy()), + (this.specPath = (s) => + isReferenceLikeElement(s) + ? ['document', 'objects', 'Reference'] + : ['document', 'objects', 'Response']); + } + ObjectElement(s) { + const o = vm.prototype.ObjectElement.call(this, s); + return ( + this.element.filter(Wm).forEach((s) => { + s.setMetaProperty('referenced-element', 'response'); + }), + this.element.filter(Hm).forEach((s, o) => { + s.setMetaProperty('http-status-code', serializers_value(o)); + }), + o + ); + } + } + const Oy = ResponsesVisitor; + class ComponentsParameters extends Cu.Sh { + static primaryClass = 'components-parameters'; + constructor(s, o, i) { + super(s, o, i), + this.classes.push(ComponentsParameters.primaryClass), + this.classes.push('parameters'); + } + } + const Ay = ComponentsParameters; + class ParametersVisitor_ParametersVisitor extends Mixin(vm, rm) { + constructor(s) { + super(s), + (this.element = new Ay()), + (this.specPath = (s) => + isReferenceLikeElement(s) + ? ['document', 'objects', 'Reference'] + : ['document', 'objects', 'Parameter']); + } + ObjectElement(s) { + const o = vm.prototype.ObjectElement.call(this, s); + return ( + this.element.filter(Wm).forEach((s) => { + s.setMetaProperty('referenced-element', 'parameter'); + }), + o + ); + } + } + const jy = ParametersVisitor_ParametersVisitor; + class ComponentsExamples extends Cu.Sh { + static primaryClass = 'components-examples'; + constructor(s, o, i) { + super(s, o, i), + this.classes.push(ComponentsExamples.primaryClass), + this.classes.push('examples'); + } + } + const Iy = ComponentsExamples; + class components_ExamplesVisitor_ExamplesVisitor extends Mixin(vm, rm) { + constructor(s) { + super(s), + (this.element = new Iy()), + (this.specPath = (s) => + isReferenceLikeElement(s) + ? ['document', 'objects', 'Reference'] + : ['document', 'objects', 'Example']); + } + ObjectElement(s) { + const o = vm.prototype.ObjectElement.call(this, s); + return ( + this.element.filter(Wm).forEach((s) => { + s.setMetaProperty('referenced-element', 'example'); + }), + o + ); + } + } + const Py = components_ExamplesVisitor_ExamplesVisitor; + class ComponentsRequestBodies extends Cu.Sh { + static primaryClass = 'components-request-bodies'; + constructor(s, o, i) { + super(s, o, i), this.classes.push(ComponentsRequestBodies.primaryClass); + } + } + const My = ComponentsRequestBodies; + class RequestBodiesVisitor extends Mixin(vm, rm) { + constructor(s) { + super(s), + (this.element = new My()), + (this.specPath = (s) => + isReferenceLikeElement(s) + ? ['document', 'objects', 'Reference'] + : ['document', 'objects', 'RequestBody']); + } + ObjectElement(s) { + const o = vm.prototype.ObjectElement.call(this, s); + return ( + this.element.filter(Wm).forEach((s) => { + s.setMetaProperty('referenced-element', 'requestBody'); + }), + o + ); + } + } + const Ty = RequestBodiesVisitor; + class ComponentsHeaders extends Cu.Sh { + static primaryClass = 'components-headers'; + constructor(s, o, i) { + super(s, o, i), this.classes.push(ComponentsHeaders.primaryClass); + } + } + const Ny = ComponentsHeaders; + class HeadersVisitor extends Mixin(vm, rm) { + constructor(s) { + super(s), + (this.element = new Ny()), + (this.specPath = (s) => + isReferenceLikeElement(s) + ? ['document', 'objects', 'Reference'] + : ['document', 'objects', 'Header']); + } + ObjectElement(s) { + const o = vm.prototype.ObjectElement.call(this, s); + return ( + this.element.filter(Wm).forEach((s) => { + s.setMetaProperty('referenced-element', 'header'); + }), + this.element.filter(Rm).forEach((s, o) => { + s.setMetaProperty('header-name', serializers_value(o)); + }), + o + ); + } + } + const Ry = HeadersVisitor; + class ComponentsSecuritySchemes extends Cu.Sh { + static primaryClass = 'components-security-schemes'; + constructor(s, o, i) { + super(s, o, i), this.classes.push(ComponentsSecuritySchemes.primaryClass); + } + } + const Dy = ComponentsSecuritySchemes; + class SecuritySchemesVisitor extends Mixin(vm, rm) { + constructor(s) { + super(s), + (this.element = new Dy()), + (this.specPath = (s) => + isReferenceLikeElement(s) + ? ['document', 'objects', 'Reference'] + : ['document', 'objects', 'SecurityScheme']); + } + ObjectElement(s) { + const o = vm.prototype.ObjectElement.call(this, s); + return ( + this.element.filter(Wm).forEach((s) => { + s.setMetaProperty('referenced-element', 'securityScheme'); + }), + o + ); + } + } + const Ly = SecuritySchemesVisitor; + class ComponentsLinks extends Cu.Sh { + static primaryClass = 'components-links'; + constructor(s, o, i) { + super(s, o, i), this.classes.push(ComponentsLinks.primaryClass); + } + } + const By = ComponentsLinks; + class LinksVisitor_LinksVisitor extends Mixin(vm, rm) { + constructor(s) { + super(s), + (this.element = new By()), + (this.specPath = (s) => + isReferenceLikeElement(s) + ? ['document', 'objects', 'Reference'] + : ['document', 'objects', 'Link']); + } + ObjectElement(s) { + const o = vm.prototype.ObjectElement.call(this, s); + return ( + this.element.filter(Wm).forEach((s) => { + s.setMetaProperty('referenced-element', 'link'); + }), + o + ); + } + } + const Fy = LinksVisitor_LinksVisitor; + class ComponentsCallbacks extends Cu.Sh { + static primaryClass = 'components-callbacks'; + constructor(s, o, i) { + super(s, o, i), this.classes.push(ComponentsCallbacks.primaryClass); + } + } + const qy = ComponentsCallbacks; + class CallbacksVisitor extends Mixin(vm, rm) { + constructor(s) { + super(s), + (this.element = new qy()), + (this.specPath = (s) => + isReferenceLikeElement(s) + ? ['document', 'objects', 'Reference'] + : ['document', 'objects', 'Callback']); + } + ObjectElement(s) { + const o = vm.prototype.ObjectElement.call(this, s); + return ( + this.element.filter(Wm).forEach((s) => { + s.setMetaProperty('referenced-element', 'callback'); + }), + o + ); + } + } + const $y = CallbacksVisitor; + class ExampleVisitor extends Mixin(im, rm) { + constructor(s) { + super(s), + (this.element = new Zp()), + (this.specPath = Tl(['document', 'objects', 'Example'])), + (this.canSupportSpecificationExtensions = !0); + } + ObjectElement(s) { + const o = im.prototype.ObjectElement.call(this, s); + return ( + Ru(this.element.externalValue) && this.element.classes.push('reference-element'), o + ); + } + } + const Vy = ExampleVisitor; + const Uy = class ExternalValueVisitor extends rm { + StringElement(s) { + const o = super.enter(s); + return this.element.classes.push('reference-value'), o; + } + }; + class ExternalDocumentationVisitor extends Mixin(im, rm) { + constructor(s) { + super(s), + (this.element = new Qp()), + (this.specPath = Tl(['document', 'objects', 'ExternalDocumentation'])), + (this.canSupportSpecificationExtensions = !0); + } + } + const zy = ExternalDocumentationVisitor; + class encoding_EncodingVisitor extends Mixin(im, rm) { + constructor(s) { + super(s), + (this.element = new Xp()), + (this.specPath = Tl(['document', 'objects', 'Encoding'])), + (this.canSupportSpecificationExtensions = !0); + } + ObjectElement(s) { + const o = im.prototype.ObjectElement.call(this, s); + return ( + Fu(this.element.headers) && + this.element.headers.filter(Rm).forEach((s, o) => { + s.setMetaProperty('header-name', serializers_value(o)); + }), + o + ); + } + } + const Wy = encoding_EncodingVisitor; + class EncodingHeaders extends Cu.Sh { + static primaryClass = 'encoding-headers'; + constructor(s, o, i) { + super(s, o, i), this.classes.push(EncodingHeaders.primaryClass); + } + } + const Ky = EncodingHeaders; + class HeadersVisitor_HeadersVisitor extends Mixin(vm, rm) { + constructor(s) { + super(s), + (this.element = new Ky()), + (this.specPath = (s) => + isReferenceLikeElement(s) + ? ['document', 'objects', 'Reference'] + : ['document', 'objects', 'Header']); + } + ObjectElement(s) { + const o = vm.prototype.ObjectElement.call(this, s); + return ( + this.element.filter(Wm).forEach((s) => { + s.setMetaProperty('referenced-element', 'header'); + }), + this.element.forEach((s, o) => { + if (!Rm(s)) return; + const i = serializers_value(o); + s.setMetaProperty('headerName', i); + }), + o + ); + } + } + const Hy = HeadersVisitor_HeadersVisitor; + class PathsVisitor extends Mixin(ym, rm) { + constructor(s) { + super(s), + (this.element = new Rh()), + (this.specPath = Tl(['document', 'objects', 'PathItem'])), + (this.canSupportSpecificationExtensions = !0), + (this.fieldPatternPredicate = es_T); + } + ObjectElement(s) { + const o = ym.prototype.ObjectElement.call(this, s); + return ( + this.element.filter(Um).forEach((s, o) => { + o.classes.push('openapi-path-template'), + o.classes.push('path-template'), + s.setMetaProperty('path', cloneDeep(o)); + }), + o + ); + } + } + const Jy = PathsVisitor; + class RequestBodyVisitor extends Mixin(im, rm) { + constructor(s) { + super(s), + (this.element = new Lh()), + (this.specPath = Tl(['document', 'objects', 'RequestBody'])); + } + ObjectElement(s) { + const o = im.prototype.ObjectElement.call(this, s); + return ( + Fu(this.element.contentProp) && + this.element.contentProp.filter(eg).forEach((s, o) => { + s.setMetaProperty('media-type', serializers_value(o)); + }), + o + ); + } + } + const Gy = RequestBodyVisitor; + class RequestBodyContent extends Cu.Sh { + static primaryClass = 'request-body-content'; + constructor(s, o, i) { + super(s, o, i), + this.classes.push(RequestBodyContent.primaryClass), + this.classes.push('content'); + } + } + const Yy = RequestBodyContent; + const Xy = class request_body_ContentVisitor_ContentVisitor extends Xg { + constructor(s) { + super(s), (this.element = new Yy()); + } + }; + class CallbackVisitor extends Mixin(ym, rm) { + constructor(s) { + super(s), + (this.element = new Hp()), + (this.specPath = Tl(['document', 'objects', 'PathItem'])), + (this.canSupportSpecificationExtensions = !0), + (this.fieldPatternPredicate = (s) => /{(?[^}]{1,2083})}/.test(String(s))); + } + ObjectElement(s) { + const o = vm.prototype.ObjectElement.call(this, s); + return ( + this.element.filter(Um).forEach((s, o) => { + s.setMetaProperty('runtime-expression', serializers_value(o)); + }), + o + ); + } + } + const Zy = CallbackVisitor; + class ResponseVisitor extends Mixin(im, rm) { + constructor(s) { + super(s), + (this.element = new Fh()), + (this.specPath = Tl(['document', 'objects', 'Response'])); + } + ObjectElement(s) { + const o = im.prototype.ObjectElement.call(this, s); + return ( + Fu(this.element.contentProp) && + this.element.contentProp.filter(eg).forEach((s, o) => { + s.setMetaProperty('media-type', serializers_value(o)); + }), + Fu(this.element.headers) && + this.element.headers.filter(Rm).forEach((s, o) => { + s.setMetaProperty('header-name', serializers_value(o)); + }), + o + ); + } + } + const Qy = ResponseVisitor; + class ResponseHeaders extends Cu.Sh { + static primaryClass = 'response-headers'; + constructor(s, o, i) { + super(s, o, i), this.classes.push(ResponseHeaders.primaryClass); + } + } + const ev = ResponseHeaders; + class response_HeadersVisitor_HeadersVisitor extends Mixin(vm, rm) { + constructor(s) { + super(s), + (this.element = new ev()), + (this.specPath = (s) => + isReferenceLikeElement(s) + ? ['document', 'objects', 'Reference'] + : ['document', 'objects', 'Header']); + } + ObjectElement(s) { + const o = vm.prototype.ObjectElement.call(this, s); + return ( + this.element.filter(Wm).forEach((s) => { + s.setMetaProperty('referenced-element', 'header'); + }), + this.element.forEach((s, o) => { + if (!Rm(s)) return; + const i = serializers_value(o); + s.setMetaProperty('header-name', i); + }), + o + ); + } + } + const tv = response_HeadersVisitor_HeadersVisitor; + class ResponseContent extends Cu.Sh { + static primaryClass = 'response-content'; + constructor(s, o, i) { + super(s, o, i), + this.classes.push(ResponseContent.primaryClass), + this.classes.push('content'); + } + } + const rv = ResponseContent; + const nv = class response_ContentVisitor_ContentVisitor extends Xg { + constructor(s) { + super(s), (this.element = new rv()); + } + }; + class ResponseLinks extends Cu.Sh { + static primaryClass = 'response-links'; + constructor(s, o, i) { + super(s, o, i), this.classes.push(ResponseLinks.primaryClass); + } + } + const sv = ResponseLinks; + class response_LinksVisitor_LinksVisitor extends Mixin(vm, rm) { + constructor(s) { + super(s), + (this.element = new sv()), + (this.specPath = (s) => + isReferenceLikeElement(s) + ? ['document', 'objects', 'Reference'] + : ['document', 'objects', 'Link']); + } + ObjectElement(s) { + const o = vm.prototype.ObjectElement.call(this, s); + return ( + this.element.filter(Wm).forEach((s) => { + s.setMetaProperty('referenced-element', 'link'); + }), + o + ); + } + } + const ov = response_LinksVisitor_LinksVisitor; + function _isNumber(s) { + return '[object Number]' === Object.prototype.toString.call(s); + } + var iv = _curry2(function range(s, o) { + if (!_isNumber(s) || !_isNumber(o)) + throw new TypeError('Both arguments to range must be numbers'); + for ( + var i = Array(s < o ? o - s : 0), u = s < 0 ? o + Math.abs(s) : o - s, _ = 0; + _ < u; + + ) + (i[_] = _ + s), (_ += 1); + return i; + }); + const av = iv; + function hasOrAdd(s, o, i) { + var u, + _ = typeof s; + switch (_) { + case 'string': + case 'number': + return 0 === s && 1 / s == -1 / 0 + ? !!i._items['-0'] || (o && (i._items['-0'] = !0), !1) + : null !== i._nativeSet + ? o + ? ((u = i._nativeSet.size), i._nativeSet.add(s), i._nativeSet.size === u) + : i._nativeSet.has(s) + : _ in i._items + ? s in i._items[_] || (o && (i._items[_][s] = !0), !1) + : (o && ((i._items[_] = {}), (i._items[_][s] = !0)), !1); + case 'boolean': + if (_ in i._items) { + var w = s ? 1 : 0; + return !!i._items[_][w] || (o && (i._items[_][w] = !0), !1); + } + return o && (i._items[_] = s ? [!1, !0] : [!0, !1]), !1; + case 'function': + return null !== i._nativeSet + ? o + ? ((u = i._nativeSet.size), i._nativeSet.add(s), i._nativeSet.size === u) + : i._nativeSet.has(s) + : _ in i._items + ? !!_includes(s, i._items[_]) || (o && i._items[_].push(s), !1) + : (o && (i._items[_] = [s]), !1); + case 'undefined': + return !!i._items[_] || (o && (i._items[_] = !0), !1); + case 'object': + if (null === s) return !!i._items.null || (o && (i._items.null = !0), !1); + default: + return (_ = Object.prototype.toString.call(s)) in i._items + ? !!_includes(s, i._items[_]) || (o && i._items[_].push(s), !1) + : (o && (i._items[_] = [s]), !1); + } + } + const lv = (function () { + function _Set() { + (this._nativeSet = 'function' == typeof Set ? new Set() : null), (this._items = {}); + } + return ( + (_Set.prototype.add = function (s) { + return !hasOrAdd(s, !0, this); + }), + (_Set.prototype.has = function (s) { + return hasOrAdd(s, !1, this); + }), + _Set + ); + })(); + var cv = _curry2(function difference(s, o) { + for (var i = [], u = 0, _ = s.length, w = o.length, x = new lv(), C = 0; C < w; C += 1) + x.add(o[C]); + for (; u < _; ) x.add(s[u]) && (i[i.length] = s[u]), (u += 1); + return i; + }); + const uv = cv; + class MixedFieldsVisitor extends Mixin(im, ym) { + specPathFixedFields; + specPathPatternedFields; + constructor({ specPathFixedFields: s, specPathPatternedFields: o, ...i }) { + super({ ...i }), (this.specPathFixedFields = s), (this.specPathPatternedFields = o); + } + ObjectElement(s) { + const { specPath: o, ignoredFields: i } = this; + try { + this.specPath = this.specPathFixedFields; + const o = this.retrieveFixedFields(this.specPath(s)); + (this.ignoredFields = [...i, ...uv(s.keys(), o)]), + im.prototype.ObjectElement.call(this, s), + (this.specPath = this.specPathPatternedFields), + (this.ignoredFields = o), + ym.prototype.ObjectElement.call(this, s); + } catch (s) { + throw ((this.specPath = o), s); + } + return Ju; + } + } + const pv = MixedFieldsVisitor; + class responses_ResponsesVisitor extends Mixin(pv, rm) { + constructor(s) { + super(s), + (this.element = new Kh()), + (this.specPathFixedFields = Tl(['document', 'objects', 'Responses'])), + (this.canSupportSpecificationExtensions = !0), + (this.specPathPatternedFields = (s) => + isReferenceLikeElement(s) + ? ['document', 'objects', 'Reference'] + : ['document', 'objects', 'Response']), + (this.fieldPatternPredicate = (s) => + new RegExp(`^(1XX|2XX|3XX|4XX|5XX|${av(100, 600).join('|')})$`).test(String(s))); + } + ObjectElement(s) { + const o = pv.prototype.ObjectElement.call(this, s); + return ( + this.element.filter(Wm).forEach((s) => { + s.setMetaProperty('referenced-element', 'response'); + }), + this.element.filter(Hm).forEach((s, o) => { + const i = cloneDeep(o); + this.fieldPatternPredicate(serializers_value(i)) && + s.setMetaProperty('http-status-code', i); + }), + o + ); + } + } + const hv = responses_ResponsesVisitor; + class DefaultVisitor extends Mixin(jm, rm) { + constructor(s) { + super(s), + (this.alternator = [ + { + predicate: isReferenceLikeElement, + specPath: ['document', 'objects', 'Reference'] + }, + { predicate: es_T, specPath: ['document', 'objects', 'Response'] } + ]); + } + ObjectElement(s) { + const o = jm.prototype.enter.call(this, s); + return ( + Wm(this.element) + ? this.element.setMetaProperty('referenced-element', 'response') + : Hm(this.element) && this.element.setMetaProperty('http-status-code', 'default'), + o + ); + } + } + const dv = DefaultVisitor; + class OperationVisitor extends Mixin(im, rm) { + constructor(s) { + super(s), + (this.element = new jh()), + (this.specPath = Tl(['document', 'objects', 'Operation'])); + } + } + const fv = OperationVisitor; + class OperationTags extends Cu.wE { + static primaryClass = 'operation-tags'; + constructor(s, o, i) { + super(s, o, i), this.classes.push(OperationTags.primaryClass); + } + } + const mv = OperationTags; + const gv = class TagsVisitor extends rm { + constructor(s) { + super(s), (this.element = new mv()); + } + ArrayElement(s) { + return (this.element = this.element.concat(cloneDeep(s))), Ju; + } + }; + class OperationParameters extends Cu.wE { + static primaryClass = 'operation-parameters'; + constructor(s, o, i) { + super(s, o, i), + this.classes.push(OperationParameters.primaryClass), + this.classes.push('parameters'); + } + } + const yv = OperationParameters; + class open_api_3_0_ParametersVisitor_ParametersVisitor extends Mixin(nm, rm) { + constructor(s) { + super(s), (this.element = new Cu.wE()), this.element.classes.push('parameters'); + } + ArrayElement(s) { + return ( + s.forEach((s) => { + const o = isReferenceLikeElement(s) + ? ['document', 'objects', 'Reference'] + : ['document', 'objects', 'Parameter'], + i = this.toRefractedElement(o, s); + Wm(i) && i.setMetaProperty('referenced-element', 'parameter'), this.element.push(i); + }), + this.copyMetaAndAttributes(s, this.element), + Ju + ); + } + } + const vv = open_api_3_0_ParametersVisitor_ParametersVisitor; + const bv = class operation_ParametersVisitor_ParametersVisitor extends vv { + constructor(s) { + super(s), (this.element = new yv()); + } + }; + const _v = class RequestBodyVisitor_RequestBodyVisitor extends jm { + constructor(s) { + super(s), + (this.alternator = [ + { + predicate: isReferenceLikeElement, + specPath: ['document', 'objects', 'Reference'] + }, + { predicate: es_T, specPath: ['document', 'objects', 'RequestBody'] } + ]); + } + ObjectElement(s) { + const o = jm.prototype.enter.call(this, s); + return ( + Wm(this.element) && this.element.setMetaProperty('referenced-element', 'requestBody'), + o + ); + } + }; + class OperationCallbacks extends Cu.Sh { + static primaryClass = 'operation-callbacks'; + constructor(s, o, i) { + super(s, o, i), this.classes.push(OperationCallbacks.primaryClass); + } + } + const Ev = OperationCallbacks; + class CallbacksVisitor_CallbacksVisitor extends Mixin(vm, rm) { + specPath; + constructor(s) { + super(s), + (this.element = new Ev()), + (this.specPath = (s) => + isReferenceLikeElement(s) + ? ['document', 'objects', 'Reference'] + : ['document', 'objects', 'Callback']); + } + ObjectElement(s) { + const o = vm.prototype.ObjectElement.call(this, s); + return ( + this.element.filter(Wm).forEach((s) => { + s.setMetaProperty('referenced-element', 'callback'); + }), + o + ); + } + } + const wv = CallbacksVisitor_CallbacksVisitor; + class OperationSecurity extends Cu.wE { + static primaryClass = 'operation-security'; + constructor(s, o, i) { + super(s, o, i), + this.classes.push(OperationSecurity.primaryClass), + this.classes.push('security'); + } + } + const Sv = OperationSecurity; + class SecurityVisitor_SecurityVisitor extends Mixin(nm, rm) { + constructor(s) { + super(s), (this.element = new Sv()); + } + ArrayElement(s) { + return ( + s.forEach((s) => { + const o = Fu(s) ? ['document', 'objects', 'SecurityRequirement'] : ['value'], + i = this.toRefractedElement(o, s); + this.element.push(i); + }), + this.copyMetaAndAttributes(s, this.element), + Ju + ); + } + } + const xv = SecurityVisitor_SecurityVisitor; + class OperationServers extends Cu.wE { + static primaryClass = 'operation-servers'; + constructor(s, o, i) { + super(s, o, i), + this.classes.push(OperationServers.primaryClass), + this.classes.push('servers'); + } + } + const kv = OperationServers; + const Cv = class ServersVisitor_ServersVisitor extends xm { + constructor(s) { + super(s), (this.element = new kv()); + } + }; + class PathItemVisitor extends Mixin(im, rm) { + constructor(s) { + super(s), + (this.element = new Ph()), + (this.specPath = Tl(['document', 'objects', 'PathItem'])); + } + ObjectElement(s) { + const o = im.prototype.ObjectElement.call(this, s); + return ( + this.element.filter($m).forEach((s, o) => { + const i = cloneDeep(o); + (i.content = serializers_value(i).toUpperCase()), + s.setMetaProperty('http-method', i); + }), + Ru(this.element.$ref) && this.element.classes.push('reference-element'), + o + ); + } + } + const Ov = PathItemVisitor; + const Av = class path_item_$RefVisitor_$RefVisitor extends rm { + StringElement(s) { + const o = super.enter(s); + return this.element.classes.push('reference-value'), o; + } + }; + class PathItemServers extends Cu.wE { + static primaryClass = 'path-item-servers'; + constructor(s, o, i) { + super(s, o, i), + this.classes.push(PathItemServers.primaryClass), + this.classes.push('servers'); + } + } + const jv = PathItemServers; + const Iv = class path_item_ServersVisitor_ServersVisitor extends xm { + constructor(s) { + super(s), (this.element = new jv()); + } + }; + class PathItemParameters extends Cu.wE { + static primaryClass = 'path-item-parameters'; + constructor(s, o, i) { + super(s, o, i), + this.classes.push(PathItemParameters.primaryClass), + this.classes.push('parameters'); + } + } + const Pv = PathItemParameters; + const Mv = class path_item_ParametersVisitor_ParametersVisitor extends vv { + constructor(s) { + super(s), (this.element = new Pv()); + } + }; + class SecuritySchemeVisitor extends Mixin(im, rm) { + constructor(s) { + super(s), + (this.element = new Jf()), + (this.specPath = Tl(['document', 'objects', 'SecurityScheme'])), + (this.canSupportSpecificationExtensions = !0); + } + } + const Tv = SecuritySchemeVisitor; + class OAuthFlowsVisitor extends Mixin(im, rm) { + constructor(s) { + super(s), + (this.element = new _h()), + (this.specPath = Tl(['document', 'objects', 'OAuthFlows'])), + (this.canSupportSpecificationExtensions = !0); + } + } + const Nv = OAuthFlowsVisitor; + class OAuthFlowVisitor extends Mixin(im, rm) { + constructor(s) { + super(s), + (this.element = new vh()), + (this.specPath = Tl(['document', 'objects', 'OAuthFlow'])), + (this.canSupportSpecificationExtensions = !0); + } + } + const Rv = OAuthFlowVisitor; + class OAuthFlowScopes extends Cu.Sh { + static primaryClass = 'oauth-flow-scopes'; + constructor(s, o, i) { + super(s, o, i), this.classes.push(OAuthFlowScopes.primaryClass); + } + } + const Dv = OAuthFlowScopes; + class ScopesVisitor extends Mixin(vm, rm) { + constructor(s) { + super(s), (this.element = new Dv()), (this.specPath = Tl(['value'])); + } + } + const Lv = ScopesVisitor; + class Tags extends Cu.wE { + static primaryClass = 'tags'; + constructor(s, o, i) { + super(s, o, i), this.classes.push(Tags.primaryClass); + } + } + const Bv = Tags; + class TagsVisitor_TagsVisitor extends Mixin(nm, rm) { + constructor(s) { + super(s), (this.element = new Bv()); + } + ArrayElement(s) { + return ( + s.forEach((s) => { + const o = om(s) ? ['document', 'objects', 'Tag'] : ['value'], + i = this.toRefractedElement(o, s); + this.element.push(i); + }), + this.copyMetaAndAttributes(s, this.element), + Ju + ); + } + } + const Fv = TagsVisitor_TagsVisitor, + { fixedFields: qv } = jf.visitors.document.objects.JSONSchema, + $v = { + visitors: { + value: rm, + document: { + objects: { + OpenApi: { + $visitor: am, + fixedFields: { + openapi: lm, + info: { $ref: '#/visitors/document/objects/Info' }, + servers: xm, + paths: { $ref: '#/visitors/document/objects/Paths' }, + components: { $ref: '#/visitors/document/objects/Components' }, + security: yg, + tags: Fv, + externalDocs: { $ref: '#/visitors/document/objects/ExternalDocumentation' } + } + }, + Info: { + $visitor: um, + fixedFields: { + title: { $ref: '#/visitors/value' }, + description: { $ref: '#/visitors/value' }, + termsOfService: { $ref: '#/visitors/value' }, + contact: { $ref: '#/visitors/document/objects/Contact' }, + license: { $ref: '#/visitors/document/objects/License' }, + version: pm + } + }, + Contact: { + $visitor: hm, + fixedFields: { + name: { $ref: '#/visitors/value' }, + url: { $ref: '#/visitors/value' }, + email: { $ref: '#/visitors/value' } + } + }, + License: { + $visitor: dm, + fixedFields: { + name: { $ref: '#/visitors/value' }, + url: { $ref: '#/visitors/value' } + } + }, + Server: { + $visitor: Em, + fixedFields: { + url: wm, + description: { $ref: '#/visitors/value' }, + variables: Om + } + }, + ServerVariable: { + $visitor: km, + fixedFields: { + enum: { $ref: '#/visitors/value' }, + default: { $ref: '#/visitors/value' }, + description: { $ref: '#/visitors/value' } + } + }, + Components: { + $visitor: _g, + fixedFields: { + schemas: ky, + responses: Oy, + parameters: jy, + examples: Py, + requestBodies: Ty, + headers: Ry, + securitySchemes: Ly, + links: Fy, + callbacks: $y + } + }, + Paths: { $visitor: Jy }, + PathItem: { + $visitor: Ov, + fixedFields: { + $ref: Av, + summary: { $ref: '#/visitors/value' }, + description: { $ref: '#/visitors/value' }, + get: { $ref: '#/visitors/document/objects/Operation' }, + put: { $ref: '#/visitors/document/objects/Operation' }, + post: { $ref: '#/visitors/document/objects/Operation' }, + delete: { $ref: '#/visitors/document/objects/Operation' }, + options: { $ref: '#/visitors/document/objects/Operation' }, + head: { $ref: '#/visitors/document/objects/Operation' }, + patch: { $ref: '#/visitors/document/objects/Operation' }, + trace: { $ref: '#/visitors/document/objects/Operation' }, + servers: Iv, + parameters: Mv + } + }, + Operation: { + $visitor: fv, + fixedFields: { + tags: gv, + summary: { $ref: '#/visitors/value' }, + description: { $ref: '#/visitors/value' }, + externalDocs: { $ref: '#/visitors/document/objects/ExternalDocumentation' }, + operationId: { $ref: '#/visitors/value' }, + parameters: bv, + requestBody: _v, + responses: { $ref: '#/visitors/document/objects/Responses' }, + callbacks: wv, + deprecated: { $ref: '#/visitors/value' }, + security: xv, + servers: Cv + } + }, + ExternalDocumentation: { + $visitor: zy, + fixedFields: { + description: { $ref: '#/visitors/value' }, + url: { $ref: '#/visitors/value' } + } + }, + Parameter: { + $visitor: Vg, + fixedFields: { + name: { $ref: '#/visitors/value' }, + in: { $ref: '#/visitors/value' }, + description: { $ref: '#/visitors/value' }, + required: { $ref: '#/visitors/value' }, + deprecated: { $ref: '#/visitors/value' }, + allowEmptyValue: { $ref: '#/visitors/value' }, + style: { $ref: '#/visitors/value' }, + explode: { $ref: '#/visitors/value' }, + allowReserved: { $ref: '#/visitors/value' }, + schema: Ug, + example: { $ref: '#/visitors/value' }, + examples: Ey, + content: Sy + } + }, + RequestBody: { + $visitor: Gy, + fixedFields: { + description: { $ref: '#/visitors/value' }, + content: Xy, + required: { $ref: '#/visitors/value' } + } + }, + MediaType: { + $visitor: Am, + fixedFields: { + schema: ng, + example: { $ref: '#/visitors/value' }, + examples: lg, + encoding: fg + } + }, + Encoding: { + $visitor: Wy, + fixedFields: { + contentType: { $ref: '#/visitors/value' }, + headers: Hy, + style: { $ref: '#/visitors/value' }, + explode: { $ref: '#/visitors/value' }, + allowReserved: { $ref: '#/visitors/value' } + } + }, + Responses: { $visitor: hv, fixedFields: { default: dv } }, + Response: { + $visitor: Qy, + fixedFields: { + description: { $ref: '#/visitors/value' }, + headers: tv, + content: nv, + links: ov + } + }, + Callback: { $visitor: Zy }, + Example: { + $visitor: Vy, + fixedFields: { + summary: { $ref: '#/visitors/value' }, + description: { $ref: '#/visitors/value' }, + value: { $ref: '#/visitors/value' }, + externalValue: Uy + } + }, + Link: { + $visitor: fm, + fixedFields: { + operationRef: mm, + operationId: gm, + parameters: _m, + requestBody: { $ref: '#/visitors/value' }, + description: { $ref: '#/visitors/value' }, + server: { $ref: '#/visitors/document/objects/Server' } + } + }, + Header: { + $visitor: zg, + fixedFields: { + description: { $ref: '#/visitors/value' }, + required: { $ref: '#/visitors/value' }, + deprecated: { $ref: '#/visitors/value' }, + allowEmptyValue: { $ref: '#/visitors/value' }, + style: { $ref: '#/visitors/value' }, + explode: { $ref: '#/visitors/value' }, + allowReserved: { $ref: '#/visitors/value' }, + schema: Wg, + example: { $ref: '#/visitors/value' }, + examples: Yg, + content: ey + } + }, + Tag: { + $visitor: xg, + fixedFields: { + name: { $ref: '#/visitors/value' }, + description: { $ref: '#/visitors/value' }, + externalDocs: { $ref: '#/visitors/document/objects/ExternalDocumentation' } + } + }, + Reference: { $visitor: kg, fixedFields: { $ref: qg } }, + JSONSchema: { $ref: '#/visitors/document/objects/Schema' }, + JSONReference: { $ref: '#/visitors/document/objects/Reference' }, + Schema: { + $visitor: ty, + fixedFields: { + title: qv.title, + multipleOf: qv.multipleOf, + maximum: qv.maximum, + exclusiveMaximum: qv.exclusiveMaximum, + minimum: qv.minimum, + exclusiveMinimum: qv.exclusiveMinimum, + maxLength: qv.maxLength, + minLength: qv.minLength, + pattern: qv.pattern, + maxItems: qv.maxItems, + minItems: qv.minItems, + uniqueItems: qv.uniqueItems, + maxProperties: qv.maxProperties, + minProperties: qv.minProperties, + required: qv.required, + enum: qv.enum, + type: dy, + allOf: ny, + anyOf: oy, + oneOf: ay, + not: my, + items: cy, + properties: py, + additionalProperties: my, + description: qv.description, + format: qv.format, + default: qv.default, + nullable: { $ref: '#/visitors/value' }, + discriminator: { $ref: '#/visitors/document/objects/Discriminator' }, + writeOnly: { $ref: '#/visitors/value' }, + xml: { $ref: '#/visitors/document/objects/XML' }, + externalDocs: { $ref: '#/visitors/document/objects/ExternalDocumentation' }, + example: { $ref: '#/visitors/value' }, + deprecated: { $ref: '#/visitors/value' } + } + }, + Discriminator: { + $visitor: gy, + fixedFields: { propertyName: { $ref: '#/visitors/value' }, mapping: vy } + }, + XML: { + $visitor: by, + fixedFields: { + name: { $ref: '#/visitors/value' }, + namespace: { $ref: '#/visitors/value' }, + prefix: { $ref: '#/visitors/value' }, + attribute: { $ref: '#/visitors/value' }, + wrapped: { $ref: '#/visitors/value' } + } + }, + SecurityScheme: { + $visitor: Tv, + fixedFields: { + type: { $ref: '#/visitors/value' }, + description: { $ref: '#/visitors/value' }, + name: { $ref: '#/visitors/value' }, + in: { $ref: '#/visitors/value' }, + scheme: { $ref: '#/visitors/value' }, + bearerFormat: { $ref: '#/visitors/value' }, + flows: { $ref: '#/visitors/document/objects/OAuthFlows' }, + openIdConnectUrl: { $ref: '#/visitors/value' } + } + }, + OAuthFlows: { + $visitor: Nv, + fixedFields: { + implicit: { $ref: '#/visitors/document/objects/OAuthFlow' }, + password: { $ref: '#/visitors/document/objects/OAuthFlow' }, + clientCredentials: { $ref: '#/visitors/document/objects/OAuthFlow' }, + authorizationCode: { $ref: '#/visitors/document/objects/OAuthFlow' } + } + }, + OAuthFlow: { + $visitor: Rv, + fixedFields: { + authorizationUrl: { $ref: '#/visitors/value' }, + tokenUrl: { $ref: '#/visitors/value' }, + refreshUrl: { $ref: '#/visitors/value' }, + scopes: Lv + } + }, + SecurityRequirement: { $visitor: mg } + }, + extension: { $visitor: cm } + } + } + }, + es_traversal_visitor_getNodeType = (s) => { + if (Nu(s)) return `${s.element.charAt(0).toUpperCase() + s.element.slice(1)}Element`; + }, + Vv = { + CallbackElement: ['content'], + ComponentsElement: ['content'], + ContactElement: ['content'], + DiscriminatorElement: ['content'], + Encoding: ['content'], + Example: ['content'], + ExternalDocumentationElement: ['content'], + HeaderElement: ['content'], + InfoElement: ['content'], + LicenseElement: ['content'], + MediaTypeElement: ['content'], + OAuthFlowElement: ['content'], + OAuthFlowsElement: ['content'], + OpenApi3_0Element: ['content'], + OperationElement: ['content'], + ParameterElement: ['content'], + PathItemElement: ['content'], + PathsElement: ['content'], + ReferenceElement: ['content'], + RequestBodyElement: ['content'], + ResponseElement: ['content'], + ResponsesElement: ['content'], + SchemaElement: ['content'], + SecurityRequirementElement: ['content'], + SecuritySchemeElement: ['content'], + ServerElement: ['content'], + ServerVariableElement: ['content'], + TagElement: ['content'], + ...Qu + }, + Uv = { + namespace: (s) => { + const { base: o } = s; + return ( + o.register('callback', Hp), + o.register('components', Jp), + o.register('contact', Gp), + o.register('discriminator', Yp), + o.register('encoding', Xp), + o.register('example', Zp), + o.register('externalDocumentation', Qp), + o.register('header', th), + o.register('info', rh), + o.register('license', uh), + o.register('link', dh), + o.register('mediaType', fh), + o.register('oAuthFlow', vh), + o.register('oAuthFlows', _h), + o.register('openapi', wh), + o.register('openApi3_0', Oh), + o.register('operation', jh), + o.register('parameter', Ih), + o.register('pathItem', Ph), + o.register('paths', Rh), + o.register('reference', Dh), + o.register('requestBody', Lh), + o.register('response', Fh), + o.register('responses', Kh), + o.register('schema', Wf), + o.register('securityRequirement', Hf), + o.register('securityScheme', Jf), + o.register('server', Gf), + o.register('serverVariable', Xf), + o.register('tag', Qf), + o.register('xml', em), + o + ); + } + }, + zv = Uv, + es_refractor_toolbox = () => { + const s = createNamespace(zv); + return { + predicates: { + ...pe, + isElement: Nu, + isStringElement: Ru, + isArrayElement: qu, + isObjectElement: Fu, + isMemberElement: $u, + includesClasses, + hasElementSourceMap + }, + namespace: s + }; + }, + es_refractor_refract = ( + s, + { + specPath: o = ['visitors', 'document', 'objects', 'OpenApi', '$visitor'], + plugins: i = [] + } = {} + ) => { + const u = (0, Cu.e)(s), + _ = dereference($v), + w = new (cp(o, _))({ specObj: _ }); + return ( + visitor_visit(u, w), + dispatchPluginsSync(w.element, i, { + toolboxCreator: es_refractor_toolbox, + visitorOptions: { keyMap: Vv, nodeTypeGetter: es_traversal_visitor_getNodeType } + }) + ); + }, + es_refractor_createRefractor = + (s) => + (o, i = {}) => + es_refractor_refract(o, { specPath: s, ...i }); + (Hp.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Callback', + '$visitor' + ])), + (Jp.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Components', + '$visitor' + ])), + (Gp.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Contact', + '$visitor' + ])), + (Zp.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Example', + '$visitor' + ])), + (Yp.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Discriminator', + '$visitor' + ])), + (Xp.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Encoding', + '$visitor' + ])), + (Qp.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'ExternalDocumentation', + '$visitor' + ])), + (th.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Header', + '$visitor' + ])), + (rh.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Info', + '$visitor' + ])), + (uh.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'License', + '$visitor' + ])), + (dh.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Link', + '$visitor' + ])), + (fh.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'MediaType', + '$visitor' + ])), + (vh.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'OAuthFlow', + '$visitor' + ])), + (_h.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'OAuthFlows', + '$visitor' + ])), + (wh.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'OpenApi', + 'fixedFields', + 'openapi' + ])), + (Oh.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'OpenApi', + '$visitor' + ])), + (jh.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Operation', + '$visitor' + ])), + (Ih.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Parameter', + '$visitor' + ])), + (Ph.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'PathItem', + '$visitor' + ])), + (Rh.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Paths', + '$visitor' + ])), + (Dh.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Reference', + '$visitor' + ])), + (Lh.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'RequestBody', + '$visitor' + ])), + (Fh.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Response', + '$visitor' + ])), + (Kh.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Responses', + '$visitor' + ])), + (Wf.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Schema', + '$visitor' + ])), + (Hf.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'SecurityRequirement', + '$visitor' + ])), + (Jf.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'SecurityScheme', + '$visitor' + ])), + (Gf.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Server', + '$visitor' + ])), + (Xf.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'ServerVariable', + '$visitor' + ])), + (Qf.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Tag', + '$visitor' + ])), + (em.refract = es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'XML', + '$visitor' + ])); + const Wv = class Callback_Callback extends Hp {}; + const Kv = class Components_Components extends Jp { + get pathItems() { + return this.get('pathItems'); + } + set pathItems(s) { + this.set('pathItems', s); + } + }; + const Hv = class Contact_Contact extends Gp {}; + const Jv = class Discriminator_Discriminator extends Yp {}; + const Gv = class Encoding_Encoding extends Xp {}; + const Yv = class Example_Example extends Zp {}; + const Xv = class ExternalDocumentation_ExternalDocumentation extends Qp {}; + const Zv = class Header_Header extends th { + get schema() { + return this.get('schema'); + } + set schema(s) { + this.set('schema', s); + } + }; + const Qv = class Info_Info extends rh { + get license() { + return this.get('license'); + } + set license(s) { + this.set('license', s); + } + get summary() { + return this.get('summary'); + } + set summary(s) { + this.set('summary', s); + } + }; + class JsonSchemaDialect extends Cu.Om { + static default = new JsonSchemaDialect('https://spec.openapis.org/oas/3.1/dialect/base'); + constructor(s, o, i) { + super(s, o, i), (this.element = 'jsonSchemaDialect'); + } + } + const eb = JsonSchemaDialect; + const tb = class License_License extends uh { + get identifier() { + return this.get('identifier'); + } + set identifier(s) { + this.set('identifier', s); + } + }; + const nb = class Link_Link extends dh {}; + const pb = class MediaType_MediaType extends fh { + get schema() { + return this.get('schema'); + } + set schema(s) { + this.set('schema', s); + } + }; + const mb = class OAuthFlow_OAuthFlow extends vh {}; + const yb = class OAuthFlows_OAuthFlows extends _h {}; + const _b = class Openapi_Openapi extends wh {}; + class OpenApi3_1 extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'openApi3_1'), this.classes.push('api'); + } + get openapi() { + return this.get('openapi'); + } + set openapi(s) { + this.set('openapi', s); + } + get info() { + return this.get('info'); + } + set info(s) { + this.set('info', s); + } + get jsonSchemaDialect() { + return this.get('jsonSchemaDialect'); + } + set jsonSchemaDialect(s) { + this.set('jsonSchemaDialect', s); + } + get servers() { + return this.get('servers'); + } + set servers(s) { + this.set('servers', s); + } + get paths() { + return this.get('paths'); + } + set paths(s) { + this.set('paths', s); + } + get components() { + return this.get('components'); + } + set components(s) { + this.set('components', s); + } + get security() { + return this.get('security'); + } + set security(s) { + this.set('security', s); + } + get tags() { + return this.get('tags'); + } + set tags(s) { + this.set('tags', s); + } + get externalDocs() { + return this.get('externalDocs'); + } + set externalDocs(s) { + this.set('externalDocs', s); + } + get webhooks() { + return this.get('webhooks'); + } + set webhooks(s) { + this.set('webhooks', s); + } + } + const wb = OpenApi3_1; + const Sb = class Operation_Operation extends jh { + get requestBody() { + return this.get('requestBody'); + } + set requestBody(s) { + this.set('requestBody', s); + } + }; + const Ob = class Parameter_Parameter extends Ih { + get schema() { + return this.get('schema'); + } + set schema(s) { + this.set('schema', s); + } + }; + const Ab = class PathItem_PathItem extends Ph { + get GET() { + return this.get('get'); + } + set GET(s) { + this.set('GET', s); + } + get PUT() { + return this.get('put'); + } + set PUT(s) { + this.set('PUT', s); + } + get POST() { + return this.get('post'); + } + set POST(s) { + this.set('POST', s); + } + get DELETE() { + return this.get('delete'); + } + set DELETE(s) { + this.set('DELETE', s); + } + get OPTIONS() { + return this.get('options'); + } + set OPTIONS(s) { + this.set('OPTIONS', s); + } + get HEAD() { + return this.get('head'); + } + set HEAD(s) { + this.set('HEAD', s); + } + get PATCH() { + return this.get('patch'); + } + set PATCH(s) { + this.set('PATCH', s); + } + get TRACE() { + return this.get('trace'); + } + set TRACE(s) { + this.set('TRACE', s); + } + }; + const Ib = class Paths_Paths extends Rh {}; + class Reference_Reference extends Dh {} + Object.defineProperty(Reference_Reference.prototype, 'description', { + get() { + return this.get('description'); + }, + set(s) { + this.set('description', s); + }, + enumerable: !0 + }), + Object.defineProperty(Reference_Reference.prototype, 'summary', { + get() { + return this.get('summary'); + }, + set(s) { + this.set('summary', s); + }, + enumerable: !0 + }); + const Pb = Reference_Reference; + const Mb = class RequestBody_RequestBody extends Lh {}; + const Rb = class elements_Response_Response extends Fh {}; + const Lb = class Responses_Responses extends Kh {}; + class elements_Schema_Schema extends Cu.Sh { + constructor(s, o, i) { + super(s, o, i), (this.element = 'schema'); + } + get $schema() { + return this.get('$schema'); + } + set $schema(s) { + this.set('$schema', s); + } + get $vocabulary() { + return this.get('$vocabulary'); + } + set $vocabulary(s) { + this.set('$vocabulary', s); + } + get $id() { + return this.get('$id'); + } + set $id(s) { + this.set('$id', s); + } + get $anchor() { + return this.get('$anchor'); + } + set $anchor(s) { + this.set('$anchor', s); + } + get $dynamicAnchor() { + return this.get('$dynamicAnchor'); + } + set $dynamicAnchor(s) { + this.set('$dynamicAnchor', s); + } + get $dynamicRef() { + return this.get('$dynamicRef'); + } + set $dynamicRef(s) { + this.set('$dynamicRef', s); + } + get $ref() { + return this.get('$ref'); + } + set $ref(s) { + this.set('$ref', s); + } + get $defs() { + return this.get('$defs'); + } + set $defs(s) { + this.set('$defs', s); + } + get $comment() { + return this.get('$comment'); + } + set $comment(s) { + this.set('$comment', s); + } + get allOf() { + return this.get('allOf'); + } + set allOf(s) { + this.set('allOf', s); + } + get anyOf() { + return this.get('anyOf'); + } + set anyOf(s) { + this.set('anyOf', s); + } + get oneOf() { + return this.get('oneOf'); + } + set oneOf(s) { + this.set('oneOf', s); + } + get not() { + return this.get('not'); + } + set not(s) { + this.set('not', s); + } + get if() { + return this.get('if'); + } + set if(s) { + this.set('if', s); + } + get then() { + return this.get('then'); + } + set then(s) { + this.set('then', s); + } + get else() { + return this.get('else'); + } + set else(s) { + this.set('else', s); + } + get dependentSchemas() { + return this.get('dependentSchemas'); + } + set dependentSchemas(s) { + this.set('dependentSchemas', s); + } + get prefixItems() { + return this.get('prefixItems'); + } + set prefixItems(s) { + this.set('prefixItems', s); + } + get items() { + return this.get('items'); + } + set items(s) { + this.set('items', s); + } + get containsProp() { + return this.get('contains'); + } + set containsProp(s) { + this.set('contains', s); + } + get properties() { + return this.get('properties'); + } + set properties(s) { + this.set('properties', s); + } + get patternProperties() { + return this.get('patternProperties'); + } + set patternProperties(s) { + this.set('patternProperties', s); + } + get additionalProperties() { + return this.get('additionalProperties'); + } + set additionalProperties(s) { + this.set('additionalProperties', s); + } + get propertyNames() { + return this.get('propertyNames'); + } + set propertyNames(s) { + this.set('propertyNames', s); + } + get unevaluatedItems() { + return this.get('unevaluatedItems'); + } + set unevaluatedItems(s) { + this.set('unevaluatedItems', s); + } + get unevaluatedProperties() { + return this.get('unevaluatedProperties'); + } + set unevaluatedProperties(s) { + this.set('unevaluatedProperties', s); + } + get type() { + return this.get('type'); + } + set type(s) { + this.set('type', s); + } + get enum() { + return this.get('enum'); + } + set enum(s) { + this.set('enum', s); + } + get const() { + return this.get('const'); + } + set const(s) { + this.set('const', s); + } + get multipleOf() { + return this.get('multipleOf'); + } + set multipleOf(s) { + this.set('multipleOf', s); + } + get maximum() { + return this.get('maximum'); + } + set maximum(s) { + this.set('maximum', s); + } + get exclusiveMaximum() { + return this.get('exclusiveMaximum'); + } + set exclusiveMaximum(s) { + this.set('exclusiveMaximum', s); + } + get minimum() { + return this.get('minimum'); + } + set minimum(s) { + this.set('minimum', s); + } + get exclusiveMinimum() { + return this.get('exclusiveMinimum'); + } + set exclusiveMinimum(s) { + this.set('exclusiveMinimum', s); + } + get maxLength() { + return this.get('maxLength'); + } + set maxLength(s) { + this.set('maxLength', s); + } + get minLength() { + return this.get('minLength'); + } + set minLength(s) { + this.set('minLength', s); + } + get pattern() { + return this.get('pattern'); + } + set pattern(s) { + this.set('pattern', s); + } + get maxItems() { + return this.get('maxItems'); + } + set maxItems(s) { + this.set('maxItems', s); + } + get minItems() { + return this.get('minItems'); + } + set minItems(s) { + this.set('minItems', s); + } + get uniqueItems() { + return this.get('uniqueItems'); + } + set uniqueItems(s) { + this.set('uniqueItems', s); + } + get maxContains() { + return this.get('maxContains'); + } + set maxContains(s) { + this.set('maxContains', s); + } + get minContains() { + return this.get('minContains'); + } + set minContains(s) { + this.set('minContains', s); + } + get maxProperties() { + return this.get('maxProperties'); + } + set maxProperties(s) { + this.set('maxProperties', s); + } + get minProperties() { + return this.get('minProperties'); + } + set minProperties(s) { + this.set('minProperties', s); + } + get required() { + return this.get('required'); + } + set required(s) { + this.set('required', s); + } + get dependentRequired() { + return this.get('dependentRequired'); + } + set dependentRequired(s) { + this.set('dependentRequired', s); + } + get title() { + return this.get('title'); + } + set title(s) { + this.set('title', s); + } + get description() { + return this.get('description'); + } + set description(s) { + this.set('description', s); + } + get default() { + return this.get('default'); + } + set default(s) { + this.set('default', s); + } + get deprecated() { + return this.get('deprecated'); + } + set deprecated(s) { + this.set('deprecated', s); + } + get readOnly() { + return this.get('readOnly'); + } + set readOnly(s) { + this.set('readOnly', s); + } + get writeOnly() { + return this.get('writeOnly'); + } + set writeOnly(s) { + this.set('writeOnly', s); + } + get examples() { + return this.get('examples'); + } + set examples(s) { + this.set('examples', s); + } + get format() { + return this.get('format'); + } + set format(s) { + this.set('format', s); + } + get contentEncoding() { + return this.get('contentEncoding'); + } + set contentEncoding(s) { + this.set('contentEncoding', s); + } + get contentMediaType() { + return this.get('contentMediaType'); + } + set contentMediaType(s) { + this.set('contentMediaType', s); + } + get contentSchema() { + return this.get('contentSchema'); + } + set contentSchema(s) { + this.set('contentSchema', s); + } + get discriminator() { + return this.get('discriminator'); + } + set discriminator(s) { + this.set('discriminator', s); + } + get xml() { + return this.get('xml'); + } + set xml(s) { + this.set('xml', s); + } + get externalDocs() { + return this.get('externalDocs'); + } + set externalDocs(s) { + this.set('externalDocs', s); + } + get example() { + return this.get('example'); + } + set example(s) { + this.set('example', s); + } + } + const qb = elements_Schema_Schema; + const zb = class SecurityRequirement_SecurityRequirement extends Hf {}; + const Qb = class SecurityScheme_SecurityScheme extends Jf {}; + const e_ = class Server_Server extends Gf {}; + const t_ = class ServerVariable_ServerVariable extends Xf {}; + const r_ = class Tag_Tag extends Qf {}; + const n_ = class Xml_Xml extends em {}; + class OpenApi3_1Visitor extends Mixin(im, rm) { + constructor(s) { + super(s), + (this.element = new wb()), + (this.specPath = Tl(['document', 'objects', 'OpenApi'])), + (this.canSupportSpecificationExtensions = !0), + (this.openApiSemanticElement = this.element); + } + ObjectElement(s) { + return (this.openApiGenericElement = s), im.prototype.ObjectElement.call(this, s); + } + } + const s_ = OpenApi3_1Visitor, + { + visitors: { + document: { + objects: { + Info: { $visitor: o_ } + } + } + } + } = $v; + const i_ = class info_InfoVisitor extends o_ { + constructor(s) { + super(s), (this.element = new Qv()); + } + }, + { + visitors: { + document: { + objects: { + Contact: { $visitor: a_ } + } + } + } + } = $v; + const l_ = class contact_ContactVisitor extends a_ { + constructor(s) { + super(s), (this.element = new Hv()); + } + }, + { + visitors: { + document: { + objects: { + License: { $visitor: c_ } + } + } + } + } = $v; + const u_ = class license_LicenseVisitor extends c_ { + constructor(s) { + super(s), (this.element = new tb()); + } + }, + { + visitors: { + document: { + objects: { + Link: { $visitor: p_ } + } + } + } + } = $v; + const h_ = class link_LinkVisitor extends p_ { + constructor(s) { + super(s), (this.element = new nb()); + } + }; + class JsonSchemaDialectVisitor extends Mixin(nm, rm) { + StringElement(s) { + const o = new eb(serializers_value(s)); + return this.copyMetaAndAttributes(s, o), (this.element = o), Ju; + } + } + const d_ = JsonSchemaDialectVisitor, + { + visitors: { + document: { + objects: { + Server: { $visitor: f_ } + } + } + } + } = $v; + const m_ = class server_ServerVisitor extends f_ { + constructor(s) { + super(s), (this.element = new e_()); + } + }, + { + visitors: { + document: { + objects: { + ServerVariable: { $visitor: g_ } + } + } + } + } = $v; + const y_ = class server_variable_ServerVariableVisitor extends g_ { + constructor(s) { + super(s), (this.element = new t_()); + } + }, + { + visitors: { + document: { + objects: { + MediaType: { $visitor: v_ } + } + } + } + } = $v; + const b_ = class media_type_MediaTypeVisitor extends v_ { + constructor(s) { + super(s), (this.element = new pb()); + } + }, + { + visitors: { + document: { + objects: { + SecurityRequirement: { $visitor: E_ } + } + } + } + } = $v; + const w_ = class security_requirement_SecurityRequirementVisitor extends E_ { + constructor(s) { + super(s), (this.element = new zb()); + } + }, + { + visitors: { + document: { + objects: { + Components: { $visitor: S_ } + } + } + } + } = $v; + const x_ = class components_ComponentsVisitor extends S_ { + constructor(s) { + super(s), (this.element = new Kv()); + } + }, + { + visitors: { + document: { + objects: { + Tag: { $visitor: k_ } + } + } + } + } = $v; + const C_ = class tag_TagVisitor extends k_ { + constructor(s) { + super(s), (this.element = new r_()); + } + }, + { + visitors: { + document: { + objects: { + Reference: { $visitor: O_ } + } + } + } + } = $v; + const A_ = class reference_ReferenceVisitor extends O_ { + constructor(s) { + super(s), (this.element = new Pb()); + } + }, + { + visitors: { + document: { + objects: { + Parameter: { $visitor: j_ } + } + } + } + } = $v; + const I_ = class parameter_ParameterVisitor extends j_ { + constructor(s) { + super(s), (this.element = new Ob()); + } + }, + { + visitors: { + document: { + objects: { + Header: { $visitor: P_ } + } + } + } + } = $v; + const M_ = class header_HeaderVisitor extends P_ { + constructor(s) { + super(s), (this.element = new Zv()); + } + }, + T_ = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Wv || (s(u) && o('callback', u) && i('object', u)) + ), + N_ = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Kv || (s(u) && o('components', u) && i('object', u)) + ), + R_ = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Hv || (s(u) && o('contact', u) && i('object', u)) + ), + D_ = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Yv || (s(u) && o('example', u) && i('object', u)) + ), + L_ = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Xv || (s(u) && o('externalDocumentation', u) && i('object', u)) + ), + B_ = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Zv || (s(u) && o('header', u) && i('object', u)) + ), + F_ = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Qv || (s(u) && o('info', u) && i('object', u)) + ), + q_ = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof eb || (s(u) && o('jsonSchemaDialect', u) && i('string', u)) + ), + $_ = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof tb || (s(u) && o('license', u) && i('object', u)) + ), + V_ = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof nb || (s(u) && o('link', u) && i('object', u)) + ), + U_ = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof _b || (s(u) && o('openapi', u) && i('string', u)) + ), + z_ = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i, hasClass: u }) => + (_) => + _ instanceof wb || (s(_) && o('openApi3_1', _) && i('object', _) && u('api', _)) + ), + W_ = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Sb || (s(u) && o('operation', u) && i('object', u)) + ), + K_ = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Ob || (s(u) && o('parameter', u) && i('object', u)) + ), + H_ = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Ab || (s(u) && o('pathItem', u) && i('object', u)) + ), + isPathItemElementExternal = (s) => { + if (!H_(s)) return !1; + if (!Ru(s.$ref)) return !1; + const o = serializers_value(s.$ref); + return 'string' == typeof o && o.length > 0 && !o.startsWith('#'); + }, + J_ = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Ib || (s(u) && o('paths', u) && i('object', u)) + ), + G_ = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Pb || (s(u) && o('reference', u) && i('object', u)) + ), + isReferenceElementExternal = (s) => { + if (!G_(s)) return !1; + if (!Ru(s.$ref)) return !1; + const o = serializers_value(s.$ref); + return 'string' == typeof o && o.length > 0 && !o.startsWith('#'); + }, + Y_ = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Mb || (s(u) && o('requestBody', u) && i('object', u)) + ), + X_ = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Rb || (s(u) && o('response', u) && i('object', u)) + ), + Z_ = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Lb || (s(u) && o('responses', u) && i('object', u)) + ), + Q_ = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof qb || (s(u) && o('schema', u) && i('object', u)) + ), + predicates_isBooleanJsonSchemaElement = (s) => + Bu(s) && s.classes.includes('boolean-json-schema'), + eE = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof zb || (s(u) && o('securityRequirement', u) && i('object', u)) + ), + tE = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof Qb || (s(u) && o('securityScheme', u) && i('object', u)) + ), + rE = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof e_ || (s(u) && o('server', u) && i('object', u)) + ), + nE = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof t_ || (s(u) && o('serverVariable', u) && i('object', u)) + ), + sE = helpers( + ({ hasBasicElementProps: s, isElementType: o, primitiveEq: i }) => + (u) => + u instanceof pb || (s(u) && o('mediaType', u) && i('object', u)) + ); + const oE = class ParentSchemaAwareVisitor_ParentSchemaAwareVisitor { + parent; + constructor({ parent: s }) { + this.parent = s; + } + }; + class open_api_3_1_schema_SchemaVisitor extends Mixin(im, oE, rm) { + constructor(s) { + super(s), + (this.element = new qb()), + (this.specPath = Tl(['document', 'objects', 'Schema'])), + (this.canSupportSpecificationExtensions = !0), + (this.jsonSchemaDefaultDialect = eb.default), + this.passingOptionsNames.push('parent'); + } + ObjectElement(s) { + this.handle$schema(s), this.handle$id(s), (this.parent = this.element); + const o = im.prototype.ObjectElement.call(this, s); + return ( + Ru(this.element.$ref) && + (this.element.classes.push('reference-element'), + this.element.setMetaProperty('referenced-element', 'schema')), + o + ); + } + BooleanElement(s) { + const o = super.enter(s); + return this.element.classes.push('boolean-json-schema'), o; + } + getJsonSchemaDialect() { + let s; + return ( + (s = + void 0 !== this.openApiSemanticElement && + q_(this.openApiSemanticElement.jsonSchemaDialect) + ? serializers_value(this.openApiSemanticElement.jsonSchemaDialect) + : void 0 !== this.openApiGenericElement && + Ru(this.openApiGenericElement.get('jsonSchemaDialect')) + ? serializers_value(this.openApiGenericElement.get('jsonSchemaDialect')) + : serializers_value(this.jsonSchemaDefaultDialect)), + s + ); + } + handle$schema(s) { + if (Rl(this.parent) && !Ru(s.get('$schema'))) + this.element.setMetaProperty('inherited$schema', this.getJsonSchemaDialect()); + else if (Q_(this.parent) && !Ru(s.get('$schema'))) { + const s = Na( + serializers_value(this.parent.meta.get('inherited$schema')), + serializers_value(this.parent.$schema) + ); + this.element.setMetaProperty('inherited$schema', s); + } + } + handle$id(s) { + const o = + void 0 !== this.parent + ? cloneDeep(this.parent.getMetaProperty('inherited$id', [])) + : new Cu.wE(), + i = serializers_value(s.get('$id')); + Vd(i) && o.push(i), this.element.setMetaProperty('inherited$id', o); + } + } + const iE = open_api_3_1_schema_SchemaVisitor; + const aE = class $vocabularyVisitor extends rm { + ObjectElement(s) { + const o = super.enter(s); + return this.element.classes.push('json-schema-$vocabulary'), o; + } + }; + const lE = class $refVisitor extends rm { + StringElement(s) { + const o = super.enter(s); + return this.element.classes.push('reference-value'), o; + } + }; + class $defsVisitor extends Mixin(vm, oE, rm) { + constructor(s) { + super(s), + (this.element = new Cu.Sh()), + this.element.classes.push('json-schema-$defs'), + (this.specPath = Tl(['document', 'objects', 'Schema'])), + this.passingOptionsNames.push('parent'); + } + } + const cE = $defsVisitor; + class schema_AllOfVisitor_AllOfVisitor extends Mixin(nm, oE, rm) { + constructor(s) { + super(s), + (this.element = new Cu.wE()), + this.element.classes.push('json-schema-allOf'), + this.passingOptionsNames.push('parent'); + } + ArrayElement(s) { + return ( + s.forEach((s) => { + if (Fu(s)) { + const o = this.toRefractedElement(['document', 'objects', 'Schema'], s); + this.element.push(o); + } else { + const o = cloneDeep(s); + this.element.push(o); + } + }), + this.copyMetaAndAttributes(s, this.element), + Ju + ); + } + } + const uE = schema_AllOfVisitor_AllOfVisitor; + class schema_AnyOfVisitor_AnyOfVisitor extends Mixin(nm, oE, rm) { + constructor(s) { + super(s), + (this.element = new Cu.wE()), + this.element.classes.push('json-schema-anyOf'), + this.passingOptionsNames.push('parent'); + } + ArrayElement(s) { + return ( + s.forEach((s) => { + if (Fu(s)) { + const o = this.toRefractedElement(['document', 'objects', 'Schema'], s); + this.element.push(o); + } else { + const o = cloneDeep(s); + this.element.push(o); + } + }), + this.copyMetaAndAttributes(s, this.element), + Ju + ); + } + } + const pE = schema_AnyOfVisitor_AnyOfVisitor; + class schema_OneOfVisitor_OneOfVisitor extends Mixin(nm, oE, rm) { + constructor(s) { + super(s), + (this.element = new Cu.wE()), + this.element.classes.push('json-schema-oneOf'), + this.passingOptionsNames.push('parent'); + } + ArrayElement(s) { + return ( + s.forEach((s) => { + if (Fu(s)) { + const o = this.toRefractedElement(['document', 'objects', 'Schema'], s); + this.element.push(o); + } else { + const o = cloneDeep(s); + this.element.push(o); + } + }), + this.copyMetaAndAttributes(s, this.element), + Ju + ); + } + } + const hE = schema_OneOfVisitor_OneOfVisitor; + class DependentSchemasVisitor extends Mixin(vm, oE, rm) { + constructor(s) { + super(s), + (this.element = new Cu.Sh()), + this.element.classes.push('json-schema-dependentSchemas'), + (this.specPath = Tl(['document', 'objects', 'Schema'])), + this.passingOptionsNames.push('parent'); + } + } + const dE = DependentSchemasVisitor; + class PrefixItemsVisitor extends Mixin(nm, oE, rm) { + constructor(s) { + super(s), + (this.element = new Cu.wE()), + this.element.classes.push('json-schema-prefixItems'), + this.passingOptionsNames.push('parent'); + } + ArrayElement(s) { + return ( + s.forEach((s) => { + if (Fu(s)) { + const o = this.toRefractedElement(['document', 'objects', 'Schema'], s); + this.element.push(o); + } else { + const o = cloneDeep(s); + this.element.push(o); + } + }), + this.copyMetaAndAttributes(s, this.element), + Ju + ); + } + } + const fE = PrefixItemsVisitor; + class schema_PropertiesVisitor_PropertiesVisitor extends Mixin(vm, oE, rm) { + constructor(s) { + super(s), + (this.element = new Cu.Sh()), + this.element.classes.push('json-schema-properties'), + (this.specPath = Tl(['document', 'objects', 'Schema'])), + this.passingOptionsNames.push('parent'); + } + } + const mE = schema_PropertiesVisitor_PropertiesVisitor; + class PatternPropertiesVisitor_PatternPropertiesVisitor extends Mixin(vm, oE, rm) { + constructor(s) { + super(s), + (this.element = new Cu.Sh()), + this.element.classes.push('json-schema-patternProperties'), + (this.specPath = Tl(['document', 'objects', 'Schema'])), + this.passingOptionsNames.push('parent'); + } + } + const gE = PatternPropertiesVisitor_PatternPropertiesVisitor; + const yE = class schema_TypeVisitor_TypeVisitor extends rm { + StringElement(s) { + const o = super.enter(s); + return this.element.classes.push('json-schema-type'), o; + } + ArrayElement(s) { + const o = super.enter(s); + return this.element.classes.push('json-schema-type'), o; + } + }; + const vE = class EnumVisitor_EnumVisitor extends rm { + ArrayElement(s) { + const o = super.enter(s); + return this.element.classes.push('json-schema-enum'), o; + } + }; + const bE = class DependentRequiredVisitor extends rm { + ObjectElement(s) { + const o = super.enter(s); + return this.element.classes.push('json-schema-dependentRequired'), o; + } + }; + const _E = class schema_ExamplesVisitor_ExamplesVisitor extends rm { + ArrayElement(s) { + const o = super.enter(s); + return this.element.classes.push('json-schema-examples'), o; + } + }, + { + visitors: { + document: { + objects: { + Discriminator: { $visitor: EE } + } + } + } + } = $v; + const wE = class distriminator_DiscriminatorVisitor extends EE { + constructor(s) { + super(s), (this.element = new Jv()), (this.canSupportSpecificationExtensions = !0); + } + }, + { + visitors: { + document: { + objects: { + XML: { $visitor: SE } + } + } + } + } = $v; + const xE = class xml_XmlVisitor extends SE { + constructor(s) { + super(s), (this.element = new n_()); + } + }; + class SchemasVisitor_SchemasVisitor extends Mixin(vm, rm) { + constructor(s) { + super(s), + (this.element = new xy()), + (this.specPath = Tl(['document', 'objects', 'Schema'])); + } + } + const kE = SchemasVisitor_SchemasVisitor; + class ComponentsPathItems extends Cu.Sh { + static primaryClass = 'components-path-items'; + constructor(s, o, i) { + super(s, o, i), this.classes.push(ComponentsPathItems.primaryClass); + } + } + const CE = ComponentsPathItems; + class PathItemsVisitor extends Mixin(vm, rm) { + constructor(s) { + super(s), + (this.element = new CE()), + (this.specPath = (s) => + isReferenceLikeElement(s) + ? ['document', 'objects', 'Reference'] + : ['document', 'objects', 'PathItem']); + } + ObjectElement(s) { + const o = vm.prototype.ObjectElement.call(this, s); + return ( + this.element.filter(G_).forEach((s) => { + s.setMetaProperty('referenced-element', 'pathItem'); + }), + o + ); + } + } + const OE = PathItemsVisitor, + { + visitors: { + document: { + objects: { + Example: { $visitor: AE } + } + } + } + } = $v; + const jE = class example_ExampleVisitor extends AE { + constructor(s) { + super(s), (this.element = new Yv()); + } + }, + { + visitors: { + document: { + objects: { + ExternalDocumentation: { $visitor: IE } + } + } + } + } = $v; + const PE = class external_documentation_ExternalDocumentationVisitor extends IE { + constructor(s) { + super(s), (this.element = new Xv()); + } + }, + { + visitors: { + document: { + objects: { + Encoding: { $visitor: ME } + } + } + } + } = $v; + const TE = class open_api_3_1_encoding_EncodingVisitor extends ME { + constructor(s) { + super(s), (this.element = new Gv()); + } + }, + { + visitors: { + document: { + objects: { + Paths: { $visitor: NE } + } + } + } + } = $v; + const RE = class paths_PathsVisitor extends NE { + constructor(s) { + super(s), (this.element = new Ib()); + } + }, + { + visitors: { + document: { + objects: { + RequestBody: { $visitor: DE } + } + } + } + } = $v; + const LE = class request_body_RequestBodyVisitor extends DE { + constructor(s) { + super(s), (this.element = new Mb()); + } + }, + { + visitors: { + document: { + objects: { + Callback: { $visitor: BE } + } + } + } + } = $v; + const FE = class callback_CallbackVisitor extends BE { + constructor(s) { + super(s), + (this.element = new Wv()), + (this.specPath = (s) => + isReferenceLikeElement(s) + ? ['document', 'objects', 'Reference'] + : ['document', 'objects', 'PathItem']); + } + ObjectElement(s) { + const o = BE.prototype.ObjectElement.call(this, s); + return ( + this.element.filter(G_).forEach((s) => { + s.setMetaProperty('referenced-element', 'pathItem'); + }), + o + ); + } + }, + { + visitors: { + document: { + objects: { + Response: { $visitor: qE } + } + } + } + } = $v; + const $E = class response_ResponseVisitor extends qE { + constructor(s) { + super(s), (this.element = new Rb()); + } + }, + { + visitors: { + document: { + objects: { + Responses: { $visitor: VE } + } + } + } + } = $v; + const UE = class open_api_3_1_responses_ResponsesVisitor extends VE { + constructor(s) { + super(s), (this.element = new Lb()); + } + }, + { + visitors: { + document: { + objects: { + Operation: { $visitor: zE } + } + } + } + } = $v; + const WE = class operation_OperationVisitor extends zE { + constructor(s) { + super(s), (this.element = new Sb()); + } + }, + { + visitors: { + document: { + objects: { + PathItem: { $visitor: KE } + } + } + } + } = $v; + const HE = class path_item_PathItemVisitor extends KE { + constructor(s) { + super(s), (this.element = new Ab()); + } + }, + { + visitors: { + document: { + objects: { + SecurityScheme: { $visitor: JE } + } + } + } + } = $v; + const GE = class security_scheme_SecuritySchemeVisitor extends JE { + constructor(s) { + super(s), (this.element = new Qb()); + } + }, + { + visitors: { + document: { + objects: { + OAuthFlows: { $visitor: YE } + } + } + } + } = $v; + const XE = class oauth_flows_OAuthFlowsVisitor extends YE { + constructor(s) { + super(s), (this.element = new yb()); + } + }, + { + visitors: { + document: { + objects: { + OAuthFlow: { $visitor: ZE } + } + } + } + } = $v; + const QE = class oauth_flow_OAuthFlowVisitor extends ZE { + constructor(s) { + super(s), (this.element = new mb()); + } + }; + class Webhooks extends Cu.Sh { + static primaryClass = 'webhooks'; + constructor(s, o, i) { + super(s, o, i), this.classes.push(Webhooks.primaryClass); + } + } + const ew = Webhooks; + class WebhooksVisitor extends Mixin(vm, rm) { + constructor(s) { + super(s), + (this.element = new ew()), + (this.specPath = (s) => + isReferenceLikeElement(s) + ? ['document', 'objects', 'Reference'] + : ['document', 'objects', 'PathItem']); + } + ObjectElement(s) { + const o = vm.prototype.ObjectElement.call(this, s); + return ( + this.element.filter(G_).forEach((s) => { + s.setMetaProperty('referenced-element', 'pathItem'); + }), + this.element.filter(H_).forEach((s, o) => { + s.setMetaProperty('webhook-name', serializers_value(o)); + }), + o + ); + } + } + const tw = WebhooksVisitor, + rw = { + visitors: { + value: $v.visitors.value, + document: { + objects: { + OpenApi: { + $visitor: s_, + fixedFields: { + openapi: $v.visitors.document.objects.OpenApi.fixedFields.openapi, + info: { $ref: '#/visitors/document/objects/Info' }, + jsonSchemaDialect: d_, + servers: $v.visitors.document.objects.OpenApi.fixedFields.servers, + paths: { $ref: '#/visitors/document/objects/Paths' }, + webhooks: tw, + components: { $ref: '#/visitors/document/objects/Components' }, + security: $v.visitors.document.objects.OpenApi.fixedFields.security, + tags: $v.visitors.document.objects.OpenApi.fixedFields.tags, + externalDocs: { $ref: '#/visitors/document/objects/ExternalDocumentation' } + } + }, + Info: { + $visitor: i_, + fixedFields: { + title: $v.visitors.document.objects.Info.fixedFields.title, + description: $v.visitors.document.objects.Info.fixedFields.description, + summary: { $ref: '#/visitors/value' }, + termsOfService: $v.visitors.document.objects.Info.fixedFields.termsOfService, + contact: { $ref: '#/visitors/document/objects/Contact' }, + license: { $ref: '#/visitors/document/objects/License' }, + version: $v.visitors.document.objects.Info.fixedFields.version + } + }, + Contact: { + $visitor: l_, + fixedFields: { + name: $v.visitors.document.objects.Contact.fixedFields.name, + url: $v.visitors.document.objects.Contact.fixedFields.url, + email: $v.visitors.document.objects.Contact.fixedFields.email + } + }, + License: { + $visitor: u_, + fixedFields: { + name: $v.visitors.document.objects.License.fixedFields.name, + identifier: { $ref: '#/visitors/value' }, + url: $v.visitors.document.objects.License.fixedFields.url + } + }, + Server: { + $visitor: m_, + fixedFields: { + url: $v.visitors.document.objects.Server.fixedFields.url, + description: $v.visitors.document.objects.Server.fixedFields.description, + variables: $v.visitors.document.objects.Server.fixedFields.variables + } + }, + ServerVariable: { + $visitor: y_, + fixedFields: { + enum: $v.visitors.document.objects.ServerVariable.fixedFields.enum, + default: $v.visitors.document.objects.ServerVariable.fixedFields.default, + description: + $v.visitors.document.objects.ServerVariable.fixedFields.description + } + }, + Components: { + $visitor: x_, + fixedFields: { + schemas: kE, + responses: $v.visitors.document.objects.Components.fixedFields.responses, + parameters: $v.visitors.document.objects.Components.fixedFields.parameters, + examples: $v.visitors.document.objects.Components.fixedFields.examples, + requestBodies: + $v.visitors.document.objects.Components.fixedFields.requestBodies, + headers: $v.visitors.document.objects.Components.fixedFields.headers, + securitySchemes: + $v.visitors.document.objects.Components.fixedFields.securitySchemes, + links: $v.visitors.document.objects.Components.fixedFields.links, + callbacks: $v.visitors.document.objects.Components.fixedFields.callbacks, + pathItems: OE + } + }, + Paths: { $visitor: RE }, + PathItem: { + $visitor: HE, + fixedFields: { + $ref: $v.visitors.document.objects.PathItem.fixedFields.$ref, + summary: $v.visitors.document.objects.PathItem.fixedFields.summary, + description: $v.visitors.document.objects.PathItem.fixedFields.description, + get: { $ref: '#/visitors/document/objects/Operation' }, + put: { $ref: '#/visitors/document/objects/Operation' }, + post: { $ref: '#/visitors/document/objects/Operation' }, + delete: { $ref: '#/visitors/document/objects/Operation' }, + options: { $ref: '#/visitors/document/objects/Operation' }, + head: { $ref: '#/visitors/document/objects/Operation' }, + patch: { $ref: '#/visitors/document/objects/Operation' }, + trace: { $ref: '#/visitors/document/objects/Operation' }, + servers: $v.visitors.document.objects.PathItem.fixedFields.servers, + parameters: $v.visitors.document.objects.PathItem.fixedFields.parameters + } + }, + Operation: { + $visitor: WE, + fixedFields: { + tags: $v.visitors.document.objects.Operation.fixedFields.tags, + summary: $v.visitors.document.objects.Operation.fixedFields.summary, + description: $v.visitors.document.objects.Operation.fixedFields.description, + externalDocs: { $ref: '#/visitors/document/objects/ExternalDocumentation' }, + operationId: $v.visitors.document.objects.Operation.fixedFields.operationId, + parameters: $v.visitors.document.objects.Operation.fixedFields.parameters, + requestBody: $v.visitors.document.objects.Operation.fixedFields.requestBody, + responses: { $ref: '#/visitors/document/objects/Responses' }, + callbacks: $v.visitors.document.objects.Operation.fixedFields.callbacks, + deprecated: $v.visitors.document.objects.Operation.fixedFields.deprecated, + security: $v.visitors.document.objects.Operation.fixedFields.security, + servers: $v.visitors.document.objects.Operation.fixedFields.servers + } + }, + ExternalDocumentation: { + $visitor: PE, + fixedFields: { + description: + $v.visitors.document.objects.ExternalDocumentation.fixedFields.description, + url: $v.visitors.document.objects.ExternalDocumentation.fixedFields.url + } + }, + Parameter: { + $visitor: I_, + fixedFields: { + name: $v.visitors.document.objects.Parameter.fixedFields.name, + in: $v.visitors.document.objects.Parameter.fixedFields.in, + description: $v.visitors.document.objects.Parameter.fixedFields.description, + required: $v.visitors.document.objects.Parameter.fixedFields.required, + deprecated: $v.visitors.document.objects.Parameter.fixedFields.deprecated, + allowEmptyValue: + $v.visitors.document.objects.Parameter.fixedFields.allowEmptyValue, + style: $v.visitors.document.objects.Parameter.fixedFields.style, + explode: $v.visitors.document.objects.Parameter.fixedFields.explode, + allowReserved: + $v.visitors.document.objects.Parameter.fixedFields.allowReserved, + schema: { $ref: '#/visitors/document/objects/Schema' }, + example: $v.visitors.document.objects.Parameter.fixedFields.example, + examples: $v.visitors.document.objects.Parameter.fixedFields.examples, + content: $v.visitors.document.objects.Parameter.fixedFields.content + } + }, + RequestBody: { + $visitor: LE, + fixedFields: { + description: $v.visitors.document.objects.RequestBody.fixedFields.description, + content: $v.visitors.document.objects.RequestBody.fixedFields.content, + required: $v.visitors.document.objects.RequestBody.fixedFields.required + } + }, + MediaType: { + $visitor: b_, + fixedFields: { + schema: { $ref: '#/visitors/document/objects/Schema' }, + example: $v.visitors.document.objects.MediaType.fixedFields.example, + examples: $v.visitors.document.objects.MediaType.fixedFields.examples, + encoding: $v.visitors.document.objects.MediaType.fixedFields.encoding + } + }, + Encoding: { + $visitor: TE, + fixedFields: { + contentType: $v.visitors.document.objects.Encoding.fixedFields.contentType, + headers: $v.visitors.document.objects.Encoding.fixedFields.headers, + style: $v.visitors.document.objects.Encoding.fixedFields.style, + explode: $v.visitors.document.objects.Encoding.fixedFields.explode, + allowReserved: $v.visitors.document.objects.Encoding.fixedFields.allowReserved + } + }, + Responses: { + $visitor: UE, + fixedFields: { + default: $v.visitors.document.objects.Responses.fixedFields.default + } + }, + Response: { + $visitor: $E, + fixedFields: { + description: $v.visitors.document.objects.Response.fixedFields.description, + headers: $v.visitors.document.objects.Response.fixedFields.headers, + content: $v.visitors.document.objects.Response.fixedFields.content, + links: $v.visitors.document.objects.Response.fixedFields.links + } + }, + Callback: { $visitor: FE }, + Example: { + $visitor: jE, + fixedFields: { + summary: $v.visitors.document.objects.Example.fixedFields.summary, + description: $v.visitors.document.objects.Example.fixedFields.description, + value: $v.visitors.document.objects.Example.fixedFields.value, + externalValue: $v.visitors.document.objects.Example.fixedFields.externalValue + } + }, + Link: { + $visitor: h_, + fixedFields: { + operationRef: $v.visitors.document.objects.Link.fixedFields.operationRef, + operationId: $v.visitors.document.objects.Link.fixedFields.operationId, + parameters: $v.visitors.document.objects.Link.fixedFields.parameters, + requestBody: $v.visitors.document.objects.Link.fixedFields.requestBody, + description: $v.visitors.document.objects.Link.fixedFields.description, + server: { $ref: '#/visitors/document/objects/Server' } + } + }, + Header: { + $visitor: M_, + fixedFields: { + description: $v.visitors.document.objects.Header.fixedFields.description, + required: $v.visitors.document.objects.Header.fixedFields.required, + deprecated: $v.visitors.document.objects.Header.fixedFields.deprecated, + allowEmptyValue: + $v.visitors.document.objects.Header.fixedFields.allowEmptyValue, + style: $v.visitors.document.objects.Header.fixedFields.style, + explode: $v.visitors.document.objects.Header.fixedFields.explode, + allowReserved: $v.visitors.document.objects.Header.fixedFields.allowReserved, + schema: { $ref: '#/visitors/document/objects/Schema' }, + example: $v.visitors.document.objects.Header.fixedFields.example, + examples: $v.visitors.document.objects.Header.fixedFields.examples, + content: $v.visitors.document.objects.Header.fixedFields.content + } + }, + Tag: { + $visitor: C_, + fixedFields: { + name: $v.visitors.document.objects.Tag.fixedFields.name, + description: $v.visitors.document.objects.Tag.fixedFields.description, + externalDocs: { $ref: '#/visitors/document/objects/ExternalDocumentation' } + } + }, + Reference: { + $visitor: A_, + fixedFields: { + $ref: $v.visitors.document.objects.Reference.fixedFields.$ref, + summary: { $ref: '#/visitors/value' }, + description: { $ref: '#/visitors/value' } + } + }, + Schema: { + $visitor: iE, + fixedFields: { + $schema: { $ref: '#/visitors/value' }, + $vocabulary: aE, + $id: { $ref: '#/visitors/value' }, + $anchor: { $ref: '#/visitors/value' }, + $dynamicAnchor: { $ref: '#/visitors/value' }, + $dynamicRef: { $ref: '#/visitors/value' }, + $ref: lE, + $defs: cE, + $comment: { $ref: '#/visitors/value' }, + allOf: uE, + anyOf: pE, + oneOf: hE, + not: { $ref: '#/visitors/document/objects/Schema' }, + if: { $ref: '#/visitors/document/objects/Schema' }, + then: { $ref: '#/visitors/document/objects/Schema' }, + else: { $ref: '#/visitors/document/objects/Schema' }, + dependentSchemas: dE, + prefixItems: fE, + items: { $ref: '#/visitors/document/objects/Schema' }, + contains: { $ref: '#/visitors/document/objects/Schema' }, + properties: mE, + patternProperties: gE, + additionalProperties: { $ref: '#/visitors/document/objects/Schema' }, + propertyNames: { $ref: '#/visitors/document/objects/Schema' }, + unevaluatedItems: { $ref: '#/visitors/document/objects/Schema' }, + unevaluatedProperties: { $ref: '#/visitors/document/objects/Schema' }, + type: yE, + enum: vE, + const: { $ref: '#/visitors/value' }, + multipleOf: { $ref: '#/visitors/value' }, + maximum: { $ref: '#/visitors/value' }, + exclusiveMaximum: { $ref: '#/visitors/value' }, + minimum: { $ref: '#/visitors/value' }, + exclusiveMinimum: { $ref: '#/visitors/value' }, + maxLength: { $ref: '#/visitors/value' }, + minLength: { $ref: '#/visitors/value' }, + pattern: { $ref: '#/visitors/value' }, + maxItems: { $ref: '#/visitors/value' }, + minItems: { $ref: '#/visitors/value' }, + uniqueItems: { $ref: '#/visitors/value' }, + maxContains: { $ref: '#/visitors/value' }, + minContains: { $ref: '#/visitors/value' }, + maxProperties: { $ref: '#/visitors/value' }, + minProperties: { $ref: '#/visitors/value' }, + required: { $ref: '#/visitors/value' }, + dependentRequired: bE, + title: { $ref: '#/visitors/value' }, + description: { $ref: '#/visitors/value' }, + default: { $ref: '#/visitors/value' }, + deprecated: { $ref: '#/visitors/value' }, + readOnly: { $ref: '#/visitors/value' }, + writeOnly: { $ref: '#/visitors/value' }, + examples: _E, + format: { $ref: '#/visitors/value' }, + contentEncoding: { $ref: '#/visitors/value' }, + contentMediaType: { $ref: '#/visitors/value' }, + contentSchema: { $ref: '#/visitors/document/objects/Schema' }, + discriminator: { $ref: '#/visitors/document/objects/Discriminator' }, + xml: { $ref: '#/visitors/document/objects/XML' }, + externalDocs: { $ref: '#/visitors/document/objects/ExternalDocumentation' }, + example: { $ref: '#/visitors/value' } + } + }, + Discriminator: { + $visitor: wE, + fixedFields: { + propertyName: + $v.visitors.document.objects.Discriminator.fixedFields.propertyName, + mapping: $v.visitors.document.objects.Discriminator.fixedFields.mapping + } + }, + XML: { + $visitor: xE, + fixedFields: { + name: $v.visitors.document.objects.XML.fixedFields.name, + namespace: $v.visitors.document.objects.XML.fixedFields.namespace, + prefix: $v.visitors.document.objects.XML.fixedFields.prefix, + attribute: $v.visitors.document.objects.XML.fixedFields.attribute, + wrapped: $v.visitors.document.objects.XML.fixedFields.wrapped + } + }, + SecurityScheme: { + $visitor: GE, + fixedFields: { + type: $v.visitors.document.objects.SecurityScheme.fixedFields.type, + description: + $v.visitors.document.objects.SecurityScheme.fixedFields.description, + name: $v.visitors.document.objects.SecurityScheme.fixedFields.name, + in: $v.visitors.document.objects.SecurityScheme.fixedFields.in, + scheme: $v.visitors.document.objects.SecurityScheme.fixedFields.scheme, + bearerFormat: + $v.visitors.document.objects.SecurityScheme.fixedFields.bearerFormat, + flows: { $ref: '#/visitors/document/objects/OAuthFlows' }, + openIdConnectUrl: + $v.visitors.document.objects.SecurityScheme.fixedFields.openIdConnectUrl + } + }, + OAuthFlows: { + $visitor: XE, + fixedFields: { + implicit: { $ref: '#/visitors/document/objects/OAuthFlow' }, + password: { $ref: '#/visitors/document/objects/OAuthFlow' }, + clientCredentials: { $ref: '#/visitors/document/objects/OAuthFlow' }, + authorizationCode: { $ref: '#/visitors/document/objects/OAuthFlow' } + } + }, + OAuthFlow: { + $visitor: QE, + fixedFields: { + authorizationUrl: + $v.visitors.document.objects.OAuthFlow.fixedFields.authorizationUrl, + tokenUrl: $v.visitors.document.objects.OAuthFlow.fixedFields.tokenUrl, + refreshUrl: $v.visitors.document.objects.OAuthFlow.fixedFields.refreshUrl, + scopes: $v.visitors.document.objects.OAuthFlow.fixedFields.scopes + } + }, + SecurityRequirement: { $visitor: w_ } + }, + extension: { $visitor: $v.visitors.document.extension.$visitor } + } + } + }, + apidom_ns_openapi_3_1_es_traversal_visitor_getNodeType = (s) => { + if (Nu(s)) return `${s.element.charAt(0).toUpperCase() + s.element.slice(1)}Element`; + }, + nw = { + CallbackElement: ['content'], + ComponentsElement: ['content'], + ContactElement: ['content'], + DiscriminatorElement: ['content'], + Encoding: ['content'], + Example: ['content'], + ExternalDocumentationElement: ['content'], + HeaderElement: ['content'], + InfoElement: ['content'], + LicenseElement: ['content'], + MediaTypeElement: ['content'], + OAuthFlowElement: ['content'], + OAuthFlowsElement: ['content'], + OpenApi3_1Element: ['content'], + OperationElement: ['content'], + ParameterElement: ['content'], + PathItemElement: ['content'], + PathsElement: ['content'], + ReferenceElement: ['content'], + RequestBodyElement: ['content'], + ResponseElement: ['content'], + ResponsesElement: ['content'], + SchemaElement: ['content'], + SecurityRequirementElement: ['content'], + SecuritySchemeElement: ['content'], + ServerElement: ['content'], + ServerVariableElement: ['content'], + TagElement: ['content'], + ...Qu + }, + sw = { + namespace: (s) => { + const { base: o } = s; + return ( + o.register('callback', Wv), + o.register('components', Kv), + o.register('contact', Hv), + o.register('discriminator', Jv), + o.register('encoding', Gv), + o.register('example', Yv), + o.register('externalDocumentation', Xv), + o.register('header', Zv), + o.register('info', Qv), + o.register('jsonSchemaDialect', eb), + o.register('license', tb), + o.register('link', nb), + o.register('mediaType', pb), + o.register('oAuthFlow', mb), + o.register('oAuthFlows', yb), + o.register('openapi', _b), + o.register('openApi3_1', wb), + o.register('operation', Sb), + o.register('parameter', Ob), + o.register('pathItem', Ab), + o.register('paths', Ib), + o.register('reference', Pb), + o.register('requestBody', Mb), + o.register('response', Rb), + o.register('responses', Lb), + o.register('schema', qb), + o.register('securityRequirement', zb), + o.register('securityScheme', Qb), + o.register('server', e_), + o.register('serverVariable', t_), + o.register('tag', r_), + o.register('xml', n_), + o + ); + } + }, + ow = sw, + ancestorLineageToJSONPointer = (s) => { + const o = s.reduce((o, i, u) => { + if ($u(i)) { + const s = String(serializers_value(i.key)); + o.push(s); + } else if (qu(s[u - 2])) { + const _ = String(s[u - 2].content.indexOf(i)); + o.push(_); + } + return o; + }, []); + return es_compile(o); + }, + apidom_ns_openapi_3_1_es_refractor_toolbox = () => { + const s = createNamespace(ow); + return { + predicates: { + ...de, + isElement: Nu, + isStringElement: Ru, + isArrayElement: qu, + isObjectElement: Fu, + isMemberElement: $u, + isServersElement: rg, + includesClasses, + hasElementSourceMap + }, + ancestorLineageToJSONPointer, + namespace: s + }; + }, + apidom_ns_openapi_3_1_es_refractor_refract = ( + s, + { + specPath: o = ['visitors', 'document', 'objects', 'OpenApi', '$visitor'], + plugins: i = [] + } = {} + ) => { + const u = (0, Cu.e)(s), + _ = dereference(rw), + w = new (cp(o, _))({ specObj: _ }); + return ( + visitor_visit(u, w), + dispatchPluginsSync(w.element, i, { + toolboxCreator: apidom_ns_openapi_3_1_es_refractor_toolbox, + visitorOptions: { + keyMap: nw, + nodeTypeGetter: apidom_ns_openapi_3_1_es_traversal_visitor_getNodeType + } + }) + ); + }, + apidom_ns_openapi_3_1_es_refractor_createRefractor = + (s) => + (o, i = {}) => + apidom_ns_openapi_3_1_es_refractor_refract(o, { specPath: s, ...i }); + (Wv.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Callback', + '$visitor' + ])), + (Kv.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Components', + '$visitor' + ])), + (Hv.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Contact', + '$visitor' + ])), + (Yv.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Example', + '$visitor' + ])), + (Jv.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Discriminator', + '$visitor' + ])), + (Gv.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Encoding', + '$visitor' + ])), + (Xv.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'ExternalDocumentation', + '$visitor' + ])), + (Zv.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Header', + '$visitor' + ])), + (Qv.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Info', + '$visitor' + ])), + (eb.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'OpenApi', + 'fixedFields', + 'jsonSchemaDialect' + ])), + (tb.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'License', + '$visitor' + ])), + (nb.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Link', + '$visitor' + ])), + (pb.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'MediaType', + '$visitor' + ])), + (mb.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'OAuthFlow', + '$visitor' + ])), + (yb.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'OAuthFlows', + '$visitor' + ])), + (_b.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'OpenApi', + 'fixedFields', + 'openapi' + ])), + (wb.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'OpenApi', + '$visitor' + ])), + (Sb.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Operation', + '$visitor' + ])), + (Ob.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Parameter', + '$visitor' + ])), + (Ab.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'PathItem', + '$visitor' + ])), + (Ib.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Paths', + '$visitor' + ])), + (Pb.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Reference', + '$visitor' + ])), + (Mb.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'RequestBody', + '$visitor' + ])), + (Rb.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Response', + '$visitor' + ])), + (Lb.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Responses', + '$visitor' + ])), + (qb.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Schema', + '$visitor' + ])), + (zb.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'SecurityRequirement', + '$visitor' + ])), + (Qb.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'SecurityScheme', + '$visitor' + ])), + (e_.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Server', + '$visitor' + ])), + (t_.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'ServerVariable', + '$visitor' + ])), + (r_.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'Tag', + '$visitor' + ])), + (n_.refract = apidom_ns_openapi_3_1_es_refractor_createRefractor([ + 'visitors', + 'document', + 'objects', + 'XML', + '$visitor' + ])); + const iw = class NotImplementedError extends Hh {}; + const aw = class MediaTypes extends Array { + unknownMediaType = 'application/octet-stream'; + filterByFormat() { + throw new iw('filterByFormat method in MediaTypes class is not yet implemented.'); + } + findBy() { + throw new iw('findBy method in MediaTypes class is not yet implemented.'); + } + latest() { + throw new iw('latest method in MediaTypes class is not yet implemented.'); + } + }; + class OpenAPIMediaTypes extends aw { + filterByFormat(s = 'generic') { + const o = 'generic' === s ? 'openapi;version' : s; + return this.filter((s) => s.includes(o)); + } + findBy(s = '3.1.0', o = 'generic') { + const i = + 'generic' === o + ? `vnd.oai.openapi;version=${s}` + : `vnd.oai.openapi+${o};version=${s}`; + return this.find((s) => s.includes(i)) || this.unknownMediaType; + } + latest(s = 'generic') { + return Fa(this.filterByFormat(s)); + } + } + const lw = new OpenAPIMediaTypes( + 'application/vnd.oai.openapi;version=3.1.0', + 'application/vnd.oai.openapi+json;version=3.1.0', + 'application/vnd.oai.openapi+yaml;version=3.1.0' + ); + const cw = class es_Reference_Reference { + uri; + depth; + value; + refSet; + errors; + constructor({ uri: s, depth: o = 0, refSet: i, value: u }) { + (this.uri = s), + (this.value = u), + (this.depth = o), + (this.refSet = i), + (this.errors = []); + } + }; + const uw = class ReferenceSet { + rootRef; + refs; + circular; + constructor({ refs: s = [], circular: o = !1 } = {}) { + (this.refs = []), (this.circular = o), s.forEach(this.add.bind(this)); + } + get size() { + return this.refs.length; + } + add(s) { + return ( + this.has(s) || + (this.refs.push(s), + (this.rootRef = void 0 === this.rootRef ? s : this.rootRef), + (s.refSet = this)), + this + ); + } + merge(s) { + for (const o of s.values()) this.add(o); + return this; + } + has(s) { + const o = Yl(s) ? s : s.uri; + return Dl(this.find((s) => s.uri === o)); + } + find(s) { + return this.refs.find(s); + } + *values() { + yield* this.refs; + } + clean() { + this.refs.forEach((s) => { + s.refSet = void 0; + }), + (this.rootRef = void 0), + (this.refs.length = 0); + } + }, + pw = { + parse: { mediaType: 'text/plain', parsers: [], parserOpts: {} }, + resolve: { + baseURI: '', + resolvers: [], + resolverOpts: {}, + strategies: [], + strategyOpts: {}, + internal: !0, + external: !0, + maxDepth: 1 / 0 + }, + dereference: { + strategies: [], + strategyOpts: {}, + refSet: null, + maxDepth: 1 / 0, + circular: 'ignore', + circularReplacer: Ip, + immutable: !0 + }, + bundle: { strategies: [], refSet: null, maxDepth: 1 / 0 } + }; + const hw = _curry2(function lens(s, o) { + return function (i) { + return function (u) { + return kl( + function (s) { + return o(s, u); + }, + i(s(u)) + ); + }; + }; + }); + var dw = _curry3(function assocPath(s, o, i) { + if (0 === s.length) return o; + var u = s[0]; + if (s.length > 1) { + var _ = !ld(i) && _has(u, i) && 'object' == typeof i[u] ? i[u] : Yo(s[1]) ? [] : {}; + o = assocPath(Array.prototype.slice.call(s, 1), o, _); + } + return (function _assoc(s, o, i) { + if (Yo(s) && aa(i)) { + var u = [].concat(i); + return (u[s] = o), u; + } + var _ = {}; + for (var w in i) _[w] = i[w]; + return (_[s] = o), _; + })(u, o, i); + }); + const fw = dw; + var Identity = function (s) { + return { + value: s, + map: function (o) { + return Identity(o(s)); + } + }; + }, + mw = _curry3(function over(s, o, i) { + return s(function (s) { + return Identity(o(s)); + })(i).value; + }); + const gw = mw, + yw = hw(cp(['resolve', 'baseURI']), fw(['resolve', 'baseURI'])), + baseURIDefault = (s) => (qp(s) ? url_cwd() : s), + util_merge = (s, o) => { + const i = lp(s, o); + return gw(yw, baseURIDefault, i); + }; + const vw = class File_File { + uri; + mediaType; + data; + parseResult; + constructor({ uri: s, mediaType: o = 'text/plain', data: i, parseResult: u }) { + (this.uri = s), (this.mediaType = o), (this.data = i), (this.parseResult = u); + } + get extension() { + return Yl(this.uri) + ? ((s) => { + const o = s.lastIndexOf('.'); + return o >= 0 ? s.substring(o).toLowerCase() : ''; + })(this.uri) + : ''; + } + toString() { + if ('string' == typeof this.data) return this.data; + if ( + this.data instanceof ArrayBuffer || + ['ArrayBuffer'].includes(ea(this.data)) || + ArrayBuffer.isView(this.data) + ) { + return new TextDecoder('utf-8').decode(this.data); + } + return String(this.data); + } + }; + const bw = class PluginError extends Ho { + plugin; + constructor(s, o) { + super(s, { cause: o.cause }), (this.plugin = o.plugin); + } + }, + plugins_filter = async (s, o, i) => { + const u = await Promise.all(i.map(_p([s], o))); + return i.filter((s, o) => u[o]); + }, + run = async (s, o, i) => { + let u; + for (const _ of i) + try { + const i = await _[s].call(_, ...o); + return { plugin: _, result: i }; + } catch (s) { + u = new bw('Error while running plugin', { cause: s, plugin: _ }); + } + return Promise.reject(u); + }; + const _w = class DereferenceError extends Ho {}; + const Ew = class UnmatchedDereferenceStrategyError extends _w {}, + dereferenceApiDOM = async (s, o) => { + let i = s, + u = !1; + if (!Ku(s)) { + const o = cloneShallow(s); + o.classes.push('result'), (i = new Mu([o])), (u = !0); + } + const _ = new vw({ + uri: o.resolve.baseURI, + parseResult: i, + mediaType: o.parse.mediaType + }), + w = await plugins_filter('canDereference', [_, o], o.dereference.strategies); + if (gp(w)) throw new Ew(_.uri); + try { + const { result: s } = await run('dereference', [_, o], w); + return u ? s.get(0) : s; + } catch (s) { + throw new _w(`Error while dereferencing file "${_.uri}"`, { cause: s }); + } + }; + const ww = class ParseError extends Ho {}; + const Sw = class ParserError extends ww {}; + const xw = class Parser { + name; + allowEmpty; + sourceMap; + fileExtensions; + mediaTypes; + constructor({ + name: s, + allowEmpty: o = !0, + sourceMap: i = !1, + fileExtensions: u = [], + mediaTypes: _ = [] + }) { + (this.name = s), + (this.allowEmpty = o), + (this.sourceMap = i), + (this.fileExtensions = u), + (this.mediaTypes = _); + } + }; + const kw = class BinaryParser extends xw { + constructor(s) { + super({ ...(null != s ? s : {}), name: 'binary' }); + } + canParse(s) { + return 0 === this.fileExtensions.length || this.fileExtensions.includes(s.extension); + } + parse(s) { + try { + const o = unescape(encodeURIComponent(s.toString())), + i = btoa(o), + u = new Mu(); + if (0 !== i.length) { + const s = new Cu.Om(i); + s.classes.push('result'), u.push(s); + } + return u; + } catch (o) { + throw new Sw(`Error parsing "${s.uri}"`, { cause: o }); + } + } + }; + const Cw = class ResolveStrategy { + name; + constructor({ name: s }) { + this.name = s; + } + }; + const Ow = class OpenAPI3_1ResolveStrategy extends Cw { + constructor(s) { + super({ ...(null != s ? s : {}), name: 'openapi-3-1' }); + } + canResolve(s, o) { + const i = o.dereference.strategies.find((s) => 'openapi-3-1' === s.name); + return void 0 !== i && i.canDereference(s, o); + } + async resolve(s, o) { + const i = o.dereference.strategies.find((s) => 'openapi-3-1' === s.name); + if (void 0 === i) throw new Ew('"openapi-3-1" dereference strategy is not available.'); + const u = new uw(), + _ = util_merge(o, { resolve: { internal: !1 }, dereference: { refSet: u } }); + return await i.dereference(s, _), u; + } + }; + const Aw = class Resolver { + name; + constructor({ name: s }) { + this.name = s; + } + }; + const jw = class HTTPResolver extends Aw { + timeout; + redirects; + withCredentials; + constructor(s) { + const { + name: o = 'http-resolver', + timeout: i = 5e3, + redirects: u = 5, + withCredentials: _ = !1 + } = null != s ? s : {}; + super({ name: o }), + (this.timeout = i), + (this.redirects = u), + (this.withCredentials = _); + } + canRead(s) { + return isHttpUrl(s.uri); + } + }; + const Iw = class ResolveError extends Ho {}; + const Pw = class ResolverError extends Iw {}, + { AbortController: Mw, AbortSignal: Tw } = globalThis; + void 0 === globalThis.AbortController && (globalThis.AbortController = Mw), + void 0 === globalThis.AbortSignal && (globalThis.AbortSignal = Tw); + const Nw = class HTTPResolverSwaggerClient extends jw { + swaggerHTTPClient = http_http; + swaggerHTTPClientConfig; + constructor({ + swaggerHTTPClient: s = http_http, + swaggerHTTPClientConfig: o = {}, + ...i + } = {}) { + super({ ...i, name: 'http-swagger-client' }), + (this.swaggerHTTPClient = s), + (this.swaggerHTTPClientConfig = o); + } + getHttpClient() { + return this.swaggerHTTPClient; + } + async read(s) { + const o = this.getHttpClient(), + i = new AbortController(), + { signal: u } = i, + _ = setTimeout(() => { + i.abort(); + }, this.timeout), + w = + this.getHttpClient().withCredentials || this.withCredentials + ? 'include' + : 'same-origin', + x = 0 === this.redirects ? 'error' : 'follow', + C = this.redirects > 0 ? this.redirects : void 0; + try { + return ( + await o({ + url: s.uri, + signal: u, + userFetch: async (s, o) => { + let i = await fetch(s, o); + try { + i.headers.delete('Content-Type'); + } catch { + (i = new Response(i.body, { ...i, headers: new Headers(i.headers) })), + i.headers.delete('Content-Type'); + } + return i; + }, + credentials: w, + redirect: x, + follow: C, + ...this.swaggerHTTPClientConfig + }) + ).text.arrayBuffer(); + } catch (o) { + throw new Pw(`Error downloading "${s.uri}"`, { cause: o }); + } finally { + clearTimeout(_); + } + } + }, + from = (s, o = wp) => { + if (Yl(s)) + try { + return o.fromRefract(JSON.parse(s)); + } catch {} + return ku(s) && md('element', s) ? o.fromRefract(s) : o.toElement(s); + }; + const Rw = class JSONParser extends xw { + constructor(s = {}) { + super({ name: 'json-swagger-client', mediaTypes: ['application/json'], ...s }); + } + async canParse(s) { + const o = 0 === this.fileExtensions.length || this.fileExtensions.includes(s.extension), + i = this.mediaTypes.includes(s.mediaType); + if (!o) return !1; + if (i) return !0; + if (!i) + try { + return JSON.parse(s.toString()), !0; + } catch (s) { + return !1; + } + return !1; + } + async parse(s) { + if (this.sourceMap) + throw new Sw("json-swagger-client parser plugin doesn't support sourceMaps option"); + const o = new Mu(), + i = s.toString(); + if (this.allowEmpty && '' === i.trim()) return o; + try { + const s = from(JSON.parse(i)); + return s.classes.push('result'), o.push(s), o; + } catch (o) { + throw new Sw(`Error parsing "${s.uri}"`, { cause: o }); + } + } + }; + const Dw = class YAMLParser extends xw { + constructor(s = {}) { + super({ + name: 'yaml-1-2-swagger-client', + mediaTypes: ['text/yaml', 'application/yaml'], + ...s + }); + } + async canParse(s) { + const o = 0 === this.fileExtensions.length || this.fileExtensions.includes(s.extension), + i = this.mediaTypes.includes(s.mediaType); + if (!o) return !1; + if (i) return !0; + if (!i) + try { + return mn.load(s.toString(), { schema: nn }), !0; + } catch (s) { + return !1; + } + return !1; + } + async parse(s) { + if (this.sourceMap) + throw new Sw( + "yaml-1-2-swagger-client parser plugin doesn't support sourceMaps option" + ); + const o = new Mu(), + i = s.toString(); + try { + const s = mn.load(i, { schema: nn }); + if (this.allowEmpty && void 0 === s) return o; + const u = from(s); + return u.classes.push('result'), o.push(u), o; + } catch (o) { + throw new Sw(`Error parsing "${s.uri}"`, { cause: o }); + } + } + }; + const Lw = class OpenAPIJSON3_1Parser extends xw { + detectionRegExp = /"openapi"\s*:\s*"(?3\.1\.(?:[1-9]\d*|0))"/; + constructor(s = {}) { + super({ + name: 'openapi-json-3-1-swagger-client', + mediaTypes: new OpenAPIMediaTypes( + ...lw.filterByFormat('generic'), + ...lw.filterByFormat('json') + ), + ...s + }); + } + async canParse(s) { + const o = 0 === this.fileExtensions.length || this.fileExtensions.includes(s.extension), + i = this.mediaTypes.includes(s.mediaType); + if (!o) return !1; + if (i) return !0; + if (!i) + try { + const o = s.toString(); + return JSON.parse(o), this.detectionRegExp.test(o); + } catch (s) { + return !1; + } + return !1; + } + async parse(s) { + if (this.sourceMap) + throw new Sw( + "openapi-json-3-1-swagger-client parser plugin doesn't support sourceMaps option" + ); + const o = new Mu(), + i = s.toString(); + if (this.allowEmpty && '' === i.trim()) return o; + try { + const s = JSON.parse(i), + u = wb.refract(s, this.refractorOpts); + return u.classes.push('result'), o.push(u), o; + } catch (o) { + throw new Sw(`Error parsing "${s.uri}"`, { cause: o }); + } + } + }; + const Bw = class OpenAPIYAML31Parser extends xw { + detectionRegExp = + /(?^(["']?)openapi\2\s*:\s*(["']?)(?3\.1\.(?:[1-9]\d*|0))\3(?:\s+|$))|(?"openapi"\s*:\s*"(?3\.1\.(?:[1-9]\d*|0))")/m; + constructor(s = {}) { + super({ + name: 'openapi-yaml-3-1-swagger-client', + mediaTypes: new OpenAPIMediaTypes( + ...lw.filterByFormat('generic'), + ...lw.filterByFormat('yaml') + ), + ...s + }); + } + async canParse(s) { + const o = 0 === this.fileExtensions.length || this.fileExtensions.includes(s.extension), + i = this.mediaTypes.includes(s.mediaType); + if (!o) return !1; + if (i) return !0; + if (!i) + try { + const o = s.toString(); + return mn.load(o), this.detectionRegExp.test(o); + } catch (s) { + return !1; + } + return !1; + } + async parse(s) { + if (this.sourceMap) + throw new Sw( + "openapi-yaml-3-1-swagger-client parser plugin doesn't support sourceMaps option" + ); + const o = new Mu(), + i = s.toString(); + try { + const s = mn.load(i, { schema: nn }); + if (this.allowEmpty && void 0 === s) return o; + const u = wb.refract(s, this.refractorOpts); + return u.classes.push('result'), o.push(u), o; + } catch (o) { + throw new Sw(`Error parsing "${s.uri}"`, { cause: o }); + } + } + }; + const Fw = _curry3(function propEq(s, o, i) { + return ra(s, Da(o, i)); + }); + const qw = class DereferenceStrategy { + name; + constructor({ name: s }) { + this.name = s; + } + }; + var $w = _curry2(function none(s, o) { + return ju(_complement(s), o); + }); + const Vw = $w; + var Uw = __webpack_require__(8068); + const zw = class ElementIdentityError extends Jo { + value; + constructor(s, o) { + super(s, o), void 0 !== o && (this.value = o.value); + } + }; + class IdentityManager { + uuid; + identityMap; + constructor({ length: s = 6 } = {}) { + (this.uuid = new Uw({ length: s })), (this.identityMap = new WeakMap()); + } + identify(s) { + if (!Nu(s)) + throw new zw( + 'Cannot not identify the element. `element` is neither structurally compatible nor a subclass of an Element class.', + { value: s } + ); + if (s.meta.hasKey('id') && Ru(s.meta.get('id')) && !s.meta.get('id').equals('')) + return s.id; + if (this.identityMap.has(s)) return this.identityMap.get(s); + const o = new Cu.Om(this.generateId()); + return this.identityMap.set(s, o), o; + } + forget(s) { + return !!this.identityMap.has(s) && (this.identityMap.delete(s), !0); + } + generateId() { + return this.uuid.randomUUID(); + } + } + new IdentityManager(); + const Ww = _curry3(function pathOr(s, o, i) { + return Na(s, _path(o, i)); + }), + traversal_find = (s, o) => { + const i = new PredicateVisitor({ predicate: s, returnOnTrue: Ju }); + return visitor_visit(o, i), Ww(void 0, [0], i.result); + }; + const Kw = class JsonSchema$anchorError extends Ho {}; + const Hw = class EvaluationJsonSchema$anchorError extends Kw {}; + const Jw = class InvalidJsonSchema$anchorError extends Kw { + constructor(s) { + super(`Invalid JSON Schema $anchor "${s}".`); + } + }, + isAnchor = (s) => /^[A-Za-z_][A-Za-z_0-9.-]*$/.test(s), + uriToAnchor = (s) => { + const o = getHash(s); + return Up('#', o); + }, + $anchor_evaluate = (s, o) => { + const i = ((s) => { + if (!isAnchor(s)) throw new Jw(s); + return s; + })(s), + u = traversal_find((s) => Q_(s) && serializers_value(s.$anchor) === i, o); + if (Rl(u)) throw new Hw(`Evaluation failed on token: "${i}"`); + return u; + }, + traversal_filter = (s, o) => { + const i = new PredicateVisitor({ predicate: s }); + return visitor_visit(o, i), new Cu.G6(i.result); + }; + const Gw = class JsonSchemaUriError extends Ho {}; + const Yw = class EvaluationJsonSchemaUriError extends Gw {}, + resolveSchema$refField = (s, o) => { + if (void 0 === o.$ref) return; + const i = getHash(serializers_value(o.$ref)), + u = serializers_value(o.meta.get('inherited$id')), + _ = Ca((s, o) => resolve(s, sanitize(stripHash(o))), s, [ + ...u, + serializers_value(o.$ref) + ]); + return `${_}${'#' === i ? '' : i}`; + }, + refractToSchemaElement = (s) => { + if (refractToSchemaElement.cache.has(s)) return refractToSchemaElement.cache.get(s); + const o = qb.refract(s); + return refractToSchemaElement.cache.set(s, o), o; + }; + refractToSchemaElement.cache = new WeakMap(); + const maybeRefractToSchemaElement = (s) => + isPrimitiveElement(s) ? refractToSchemaElement(s) : s, + uri_evaluate = (s, o) => { + const { cache: i } = uri_evaluate, + u = stripHash(s), + isSchemaElementWith$id = (s) => Q_(s) && void 0 !== s.$id; + if (!i.has(o)) { + const s = traversal_filter(isSchemaElementWith$id, o); + i.set(o, Array.from(s)); + } + const _ = i.get(o).find((s) => { + const o = ((s, o) => { + if (void 0 === o.$id) return; + const i = serializers_value(o.meta.get('inherited$id')); + return Ca((s, o) => resolve(s, sanitize(stripHash(o))), s, [ + ...i, + serializers_value(o.$id) + ]); + })(u, s); + return o === u; + }); + if (Rl(_)) throw new Yw(`Evaluation failed on URI: "${s}"`); + let w, x; + return ( + isAnchor(uriToAnchor(s)) + ? ((w = $anchor_evaluate), (x = uriToAnchor(s))) + : ((w = es_evaluate), (x = uriToPointer(s))), + w(x, _) + ); + }; + uri_evaluate.cache = new WeakMap(); + const Xw = class MaximumDereferenceDepthError extends _w {}; + const Zw = class MaximumResolveDepthError extends Iw {}; + const Qw = class UnmatchedResolverError extends Pw {}, + _swagger_api_apidom_reference_es_parse = async (s, o) => { + const i = new vw({ uri: sanitize(stripHash(s)), mediaType: o.parse.mediaType }), + u = await (async (s, o) => { + const i = o.resolve.resolvers.map((s) => { + const i = Object.create(s); + return Object.assign(i, o.resolve.resolverOpts); + }), + u = await plugins_filter('canRead', [s, o], i); + if (gp(u)) throw new Qw(s.uri); + try { + const { result: o } = await run('read', [s], u); + return o; + } catch (o) { + throw new Iw(`Error while reading file "${s.uri}"`, { cause: o }); + } + })(i, o); + return (async (s, o) => { + const i = o.parse.parsers.map((s) => { + const i = Object.create(s); + return Object.assign(i, o.parse.parserOpts); + }), + u = await plugins_filter('canParse', [s, o], i); + if (gp(u)) throw new Qw(s.uri); + try { + const { plugin: i, result: _ } = await run('parse', [s, o], u); + return !i.allowEmpty && _.isEmpty + ? Promise.reject(new ww(`Error while parsing file "${s.uri}". File is empty.`)) + : _; + } catch (o) { + throw new ww(`Error while parsing file "${s.uri}"`, { cause: o }); + } + })(new vw({ ...i, data: u }), o); + }; + class AncestorLineage extends Array { + includesCycle(s) { + return this.filter((o) => o.has(s)).length > 1; + } + includes(s, o) { + return s instanceof Set ? super.includes(s, o) : this.some((o) => o.has(s)); + } + findItem(s) { + for (const o of this) for (const i of o) if (Nu(i) && s(i)) return i; + } + } + const eS = visitor_visit[Symbol.for('nodejs.util.promisify.custom')], + tS = new IdentityManager(), + mutationReplacer = (s, o, i, u) => { + $u(u) ? (u.value = s) : Array.isArray(u) && (u[i] = s); + }; + class OpenAPI3_1DereferenceVisitor { + indirections; + namespace; + reference; + options; + ancestors; + refractCache; + constructor({ + reference: s, + namespace: o, + options: i, + indirections: u = [], + ancestors: _ = new AncestorLineage(), + refractCache: w = new Map() + }) { + (this.indirections = u), + (this.namespace = o), + (this.reference = s), + (this.options = i), + (this.ancestors = new AncestorLineage(..._)), + (this.refractCache = w); + } + toBaseURI(s) { + return resolve(this.reference.uri, sanitize(stripHash(s))); + } + async toReference(s) { + if (this.reference.depth >= this.options.resolve.maxDepth) + throw new Zw( + `Maximum resolution depth of ${this.options.resolve.maxDepth} has been exceeded by file "${this.reference.uri}"` + ); + const o = this.toBaseURI(s), + { refSet: i } = this.reference; + if (i.has(o)) return i.find(Fw(o, 'uri')); + const u = await _swagger_api_apidom_reference_es_parse(unsanitize(o), { + ...this.options, + parse: { ...this.options.parse, mediaType: 'text/plain' } + }), + _ = new cw({ uri: o, value: cloneDeep(u), depth: this.reference.depth + 1 }); + if ((i.add(_), this.options.dereference.immutable)) { + const s = new cw({ + uri: `immutable://${o}`, + value: u, + depth: this.reference.depth + 1 + }); + i.add(s); + } + return _; + } + toAncestorLineage(s) { + const o = new Set(s.filter(Nu)); + return [new AncestorLineage(...this.ancestors, o), o]; + } + async ReferenceElement(s, o, i, u, _, w) { + if (this.indirections.includes(s)) return !1; + const [x, C] = this.toAncestorLineage([..._, i]), + j = this.toBaseURI(serializers_value(s.$ref)), + L = stripHash(this.reference.uri) === j, + B = !L; + if (!this.options.resolve.internal && L) return !1; + if (!this.options.resolve.external && B) return !1; + const $ = await this.toReference(serializers_value(s.$ref)), + V = resolve(j, serializers_value(s.$ref)); + this.indirections.push(s); + const U = uriToPointer(V); + let z = es_evaluate(U, $.value.result); + if (((z.id = tS.identify(z)), isPrimitiveElement(z))) { + const o = serializers_value(s.meta.get('referenced-element')), + i = `${o}-${serializers_value(tS.identify(z))}`; + if (this.refractCache.has(i)) z = this.refractCache.get(i); + else if (isReferenceLikeElement(z)) + (z = Pb.refract(z)), + z.setMetaProperty('referenced-element', o), + this.refractCache.set(i, z); + else { + (z = this.namespace.getElementClass(o).refract(z)), this.refractCache.set(i, z); + } + } + if (s === z) throw new Ho('Recursive Reference Object detected'); + if (this.indirections.length > this.options.dereference.maxDepth) + throw new Xw( + `Maximum dereference depth of "${this.options.dereference.maxDepth}" has been exceeded in file "${this.reference.uri}"` + ); + if (x.includes(z)) { + if ((($.refSet.circular = !0), 'error' === this.options.dereference.circular)) + throw new Ho('Circular reference detected'); + if ('replace' === this.options.dereference.circular) { + var Y, Z; + const o = new Cu.sI(z.id, { + type: 'reference', + uri: $.uri, + $ref: serializers_value(s.$ref) + }), + u = ( + null !== + (Y = + null === (Z = this.options.dereference.strategyOpts['openapi-3-1']) || + void 0 === Z + ? void 0 + : Z.circularReplacer) && void 0 !== Y + ? Y + : this.options.dereference.circularReplacer + )(o); + return w.replaceWith(u, mutationReplacer), !i && u; + } + } + const ee = stripHash($.refSet.rootRef.uri) !== $.uri, + ie = ['error', 'replace'].includes(this.options.dereference.circular); + if ((B || ee || G_(z) || ie) && !x.includesCycle(z)) { + C.add(s); + const o = new OpenAPI3_1DereferenceVisitor({ + reference: $, + namespace: this.namespace, + indirections: [...this.indirections], + options: this.options, + refractCache: this.refractCache, + ancestors: x + }); + (z = await eS(z, o, { + keyMap: nw, + nodeTypeGetter: apidom_ns_openapi_3_1_es_traversal_visitor_getNodeType + })), + C.delete(s); + } + this.indirections.pop(); + const ae = cloneShallow(z); + return ( + ae.setMetaProperty('id', tS.generateId()), + ae.setMetaProperty('ref-fields', { + $ref: serializers_value(s.$ref), + description: serializers_value(s.description), + summary: serializers_value(s.summary) + }), + ae.setMetaProperty('ref-origin', $.uri), + ae.setMetaProperty('ref-referencing-element-id', cloneDeep(tS.identify(s))), + Fu(z) && + Fu(ae) && + (s.hasKey('description') && + 'description' in z && + (ae.remove('description'), ae.set('description', s.get('description'))), + s.hasKey('summary') && + 'summary' in z && + (ae.remove('summary'), ae.set('summary', s.get('summary')))), + w.replaceWith(ae, mutationReplacer), + !i && ae + ); + } + async PathItemElement(s, o, i, u, _, w) { + if (!Ru(s.$ref)) return; + if (this.indirections.includes(s)) return !1; + const [x, C] = this.toAncestorLineage([..._, i]), + j = this.toBaseURI(serializers_value(s.$ref)), + L = stripHash(this.reference.uri) === j, + B = !L; + if (!this.options.resolve.internal && L) return; + if (!this.options.resolve.external && B) return; + const $ = await this.toReference(serializers_value(s.$ref)), + V = resolve(j, serializers_value(s.$ref)); + this.indirections.push(s); + const U = uriToPointer(V); + let z = es_evaluate(U, $.value.result); + if (((z.id = tS.identify(z)), isPrimitiveElement(z))) { + const s = `path-item-${serializers_value(tS.identify(z))}`; + this.refractCache.has(s) + ? (z = this.refractCache.get(s)) + : ((z = Ab.refract(z)), this.refractCache.set(s, z)); + } + if (s === z) throw new Ho('Recursive Path Item Object reference detected'); + if (this.indirections.length > this.options.dereference.maxDepth) + throw new Xw( + `Maximum dereference depth of "${this.options.dereference.maxDepth}" has been exceeded in file "${this.reference.uri}"` + ); + if (x.includes(z)) { + if ((($.refSet.circular = !0), 'error' === this.options.dereference.circular)) + throw new Ho('Circular reference detected'); + if ('replace' === this.options.dereference.circular) { + var Y, Z; + const o = new Cu.sI(z.id, { + type: 'path-item', + uri: $.uri, + $ref: serializers_value(s.$ref) + }), + u = ( + null !== + (Y = + null === (Z = this.options.dereference.strategyOpts['openapi-3-1']) || + void 0 === Z + ? void 0 + : Z.circularReplacer) && void 0 !== Y + ? Y + : this.options.dereference.circularReplacer + )(o); + return w.replaceWith(u, mutationReplacer), !i && u; + } + } + const ee = stripHash($.refSet.rootRef.uri) !== $.uri, + ie = ['error', 'replace'].includes(this.options.dereference.circular); + if ((B || ee || (H_(z) && Ru(z.$ref)) || ie) && !x.includesCycle(z)) { + C.add(s); + const o = new OpenAPI3_1DereferenceVisitor({ + reference: $, + namespace: this.namespace, + indirections: [...this.indirections], + options: this.options, + refractCache: this.refractCache, + ancestors: x + }); + (z = await eS(z, o, { + keyMap: nw, + nodeTypeGetter: apidom_ns_openapi_3_1_es_traversal_visitor_getNodeType + })), + C.delete(s); + } + if ((this.indirections.pop(), H_(z))) { + const o = new Ab([...z.content], cloneDeep(z.meta), cloneDeep(z.attributes)); + o.setMetaProperty('id', tS.generateId()), + s.forEach((s, i, u) => { + o.remove(serializers_value(i)), o.content.push(u); + }), + o.remove('$ref'), + o.setMetaProperty('ref-fields', { $ref: serializers_value(s.$ref) }), + o.setMetaProperty('ref-origin', $.uri), + o.setMetaProperty('ref-referencing-element-id', cloneDeep(tS.identify(s))), + (z = o); + } + return w.replaceWith(z, mutationReplacer), i ? void 0 : z; + } + async LinkElement(s, o, i, u, _, w) { + if (!Ru(s.operationRef) && !Ru(s.operationId)) return; + if (Ru(s.operationRef) && Ru(s.operationId)) + throw new Ho( + 'LinkElement operationRef and operationId fields are mutually exclusive.' + ); + let x; + if (Ru(s.operationRef)) { + var C; + const o = uriToPointer(serializers_value(s.operationRef)), + u = this.toBaseURI(serializers_value(s.operationRef)), + _ = stripHash(this.reference.uri) === u, + j = !_; + if (!this.options.resolve.internal && _) return; + if (!this.options.resolve.external && j) return; + const L = await this.toReference(serializers_value(s.operationRef)); + if (((x = es_evaluate(o, L.value.result)), isPrimitiveElement(x))) { + const s = `operation-${serializers_value(tS.identify(x))}`; + this.refractCache.has(s) + ? (x = this.refractCache.get(s)) + : ((x = Sb.refract(x)), this.refractCache.set(s, x)); + } + (x = cloneShallow(x)), x.setMetaProperty('ref-origin', L.uri); + const B = cloneShallow(s); + return ( + null === (C = B.operationRef) || void 0 === C || C.meta.set('operation', x), + w.replaceWith(B, mutationReplacer), + i ? void 0 : B + ); + } + if (Ru(s.operationId)) { + var j; + const o = serializers_value(s.operationId), + u = await this.toReference(unsanitize(this.reference.uri)); + if ( + ((x = traversal_find( + (s) => W_(s) && Nu(s.operationId) && s.operationId.equals(o), + u.value.result + )), + Rl(x)) + ) + throw new Ho(`OperationElement(operationId=${o}) not found.`); + const _ = cloneShallow(s); + return ( + null === (j = _.operationId) || void 0 === j || j.meta.set('operation', x), + w.replaceWith(_, mutationReplacer), + i ? void 0 : _ + ); + } + } + async ExampleElement(s, o, i, u, _, w) { + if (!Ru(s.externalValue)) return; + if (s.hasKey('value') && Ru(s.externalValue)) + throw new Ho('ExampleElement value and externalValue fields are mutually exclusive.'); + const x = this.toBaseURI(serializers_value(s.externalValue)), + C = stripHash(this.reference.uri) === x, + j = !C; + if (!this.options.resolve.internal && C) return; + if (!this.options.resolve.external && j) return; + const L = await this.toReference(serializers_value(s.externalValue)), + B = cloneShallow(L.value.result); + B.setMetaProperty('ref-origin', L.uri); + const $ = cloneShallow(s); + return ($.value = B), w.replaceWith($, mutationReplacer), i ? void 0 : $; + } + async SchemaElement(s, o, i, u, _, w) { + if (!Ru(s.$ref)) return; + if (this.indirections.includes(s)) return !1; + const [x, C] = this.toAncestorLineage([..._, i]); + let j = await this.toReference(unsanitize(this.reference.uri)), + { uri: L } = j; + const B = resolveSchema$refField(L, s), + $ = stripHash(B), + V = new vw({ uri: $ }), + U = Vw((s) => s.canRead(V), this.options.resolve.resolvers), + z = !U; + let Y, + Z = stripHash(this.reference.uri) === B, + ee = !Z; + this.indirections.push(s); + try { + if (U || z) { + L = this.toBaseURI(B); + const s = B, + o = maybeRefractToSchemaElement(j.value.result); + if ( + ((Y = uri_evaluate(s, o)), + (Y = maybeRefractToSchemaElement(Y)), + (Y.id = tS.identify(Y)), + !this.options.resolve.internal && Z) + ) + return; + if (!this.options.resolve.external && ee) return; + } else { + if ( + ((L = this.toBaseURI(B)), + (Z = stripHash(this.reference.uri) === L), + (ee = !Z), + !this.options.resolve.internal && Z) + ) + return; + if (!this.options.resolve.external && ee) return; + j = await this.toReference(unsanitize(B)); + const s = uriToPointer(B), + o = maybeRefractToSchemaElement(j.value.result); + (Y = es_evaluate(s, o)), + (Y = maybeRefractToSchemaElement(Y)), + (Y.id = tS.identify(Y)); + } + } catch (s) { + if (!(z && s instanceof Yw)) throw s; + if (isAnchor(uriToAnchor(B))) { + if ( + ((Z = stripHash(this.reference.uri) === L), + (ee = !Z), + !this.options.resolve.internal && Z) + ) + return; + if (!this.options.resolve.external && ee) return; + j = await this.toReference(unsanitize(B)); + const s = uriToAnchor(B), + o = maybeRefractToSchemaElement(j.value.result); + (Y = $anchor_evaluate(s, o)), + (Y = maybeRefractToSchemaElement(Y)), + (Y.id = tS.identify(Y)); + } else { + if ( + ((L = this.toBaseURI(B)), + (Z = stripHash(this.reference.uri) === L), + (ee = !Z), + !this.options.resolve.internal && Z) + ) + return; + if (!this.options.resolve.external && ee) return; + j = await this.toReference(unsanitize(B)); + const s = uriToPointer(B), + o = maybeRefractToSchemaElement(j.value.result); + (Y = es_evaluate(s, o)), + (Y = maybeRefractToSchemaElement(Y)), + (Y.id = tS.identify(Y)); + } + } + if (s === Y) throw new Ho('Recursive Schema Object reference detected'); + if (this.indirections.length > this.options.dereference.maxDepth) + throw new Xw( + `Maximum dereference depth of "${this.options.dereference.maxDepth}" has been exceeded in file "${this.reference.uri}"` + ); + if (x.includes(Y)) { + if (((j.refSet.circular = !0), 'error' === this.options.dereference.circular)) + throw new Ho('Circular reference detected'); + if ('replace' === this.options.dereference.circular) { + var ie, ae; + const o = new Cu.sI(Y.id, { + type: 'json-schema', + uri: j.uri, + $ref: serializers_value(s.$ref) + }), + u = ( + null !== + (ie = + null === (ae = this.options.dereference.strategyOpts['openapi-3-1']) || + void 0 === ae + ? void 0 + : ae.circularReplacer) && void 0 !== ie + ? ie + : this.options.dereference.circularReplacer + )(o); + return w.replaceWith(u, mutationReplacer), !i && u; + } + } + const le = stripHash(j.refSet.rootRef.uri) !== j.uri, + ce = ['error', 'replace'].includes(this.options.dereference.circular); + if ((ee || le || (Q_(Y) && Ru(Y.$ref)) || ce) && !x.includesCycle(Y)) { + C.add(s); + const o = new OpenAPI3_1DereferenceVisitor({ + reference: j, + namespace: this.namespace, + indirections: [...this.indirections], + options: this.options, + refractCache: this.refractCache, + ancestors: x + }); + (Y = await eS(Y, o, { + keyMap: nw, + nodeTypeGetter: apidom_ns_openapi_3_1_es_traversal_visitor_getNodeType + })), + C.delete(s); + } + if ((this.indirections.pop(), predicates_isBooleanJsonSchemaElement(Y))) { + const o = cloneDeep(Y); + return ( + o.setMetaProperty('id', tS.generateId()), + o.setMetaProperty('ref-fields', { $ref: serializers_value(s.$ref) }), + o.setMetaProperty('ref-origin', j.uri), + o.setMetaProperty('ref-referencing-element-id', cloneDeep(tS.identify(s))), + w.replaceWith(o, mutationReplacer), + !i && o + ); + } + if (Q_(Y)) { + const o = new qb([...Y.content], cloneDeep(Y.meta), cloneDeep(Y.attributes)); + o.setMetaProperty('id', tS.generateId()), + s.forEach((s, i, u) => { + o.remove(serializers_value(i)), o.content.push(u); + }), + o.remove('$ref'), + o.setMetaProperty('ref-fields', { $ref: serializers_value(s.$ref) }), + o.setMetaProperty('ref-origin', j.uri), + o.setMetaProperty('ref-referencing-element-id', cloneDeep(tS.identify(s))), + (Y = o); + } + return w.replaceWith(Y, mutationReplacer), i ? void 0 : Y; + } + } + const rS = OpenAPI3_1DereferenceVisitor, + nS = visitor_visit[Symbol.for('nodejs.util.promisify.custom')]; + const sS = class OpenAPI3_1DereferenceStrategy extends qw { + constructor(s) { + super({ ...(null != s ? s : {}), name: 'openapi-3-1' }); + } + canDereference(s) { + var o; + return 'text/plain' !== s.mediaType + ? lw.includes(s.mediaType) + : z_(null === (o = s.parseResult) || void 0 === o ? void 0 : o.result); + } + async dereference(s, o) { + var i; + const u = createNamespace(ow), + _ = null !== (i = o.dereference.refSet) && void 0 !== i ? i : new uw(), + w = new uw(); + let x, + C = _; + _.has(s.uri) + ? (x = _.find(Fw(s.uri, 'uri'))) + : ((x = new cw({ uri: s.uri, value: s.parseResult })), _.add(x)), + o.dereference.immutable && + (_.refs + .map((s) => new cw({ ...s, value: cloneDeep(s.value) })) + .forEach((s) => w.add(s)), + (x = w.find((o) => o.uri === s.uri)), + (C = w)); + const j = new rS({ reference: x, namespace: u, options: o }), + L = await nS(C.rootRef.value, j, { + keyMap: nw, + nodeTypeGetter: apidom_ns_openapi_3_1_es_traversal_visitor_getNodeType + }); + return ( + o.dereference.immutable && + w.refs + .filter((s) => s.uri.startsWith('immutable://')) + .map((s) => new cw({ ...s, uri: s.uri.replace(/^immutable:\/\//, '') })) + .forEach((s) => _.add(s)), + null === o.dereference.refSet && _.clean(), + w.clean(), + L + ); + } + }, + to_path = (s) => { + const o = ((s) => s.slice(2))(s); + return o.reduce((s, i, u) => { + if ($u(i)) { + const o = String(serializers_value(i.key)); + s.push(o); + } else if (qu(o[u - 2])) { + const _ = o[u - 2].content.indexOf(i); + s.push(_); + } + return s; + }, []); + }; + const oS = class ModelPropertyMacroVisitor { + modelPropertyMacro; + options; + SchemaElement = { + leave: (s, o, i, u, _) => { + void 0 !== s.properties && + Fu(s.properties) && + s.properties.forEach((o) => { + if (Fu(o)) + try { + const s = this.modelPropertyMacro(serializers_value(o)); + o.set('default', s); + } catch (o) { + var u, w; + const x = new Error(o, { cause: o }); + (x.fullPath = [...to_path([..._, i, s]), 'properties']), + null === (u = this.options.dereference.dereferenceOpts) || + void 0 === u || + null === (u = u.errors) || + void 0 === u || + null === (w = u.push) || + void 0 === w || + w.call(u, x); + } + }); + } + }; + constructor({ modelPropertyMacro: s, options: o }) { + (this.modelPropertyMacro = s), (this.options = o); + } + }; + const iS = class all_of_AllOfVisitor { + options; + SchemaElement = { + leave(s, o, i, u, _) { + if (void 0 === s.allOf) return; + if (!qu(s.allOf)) { + var w, x; + const o = new TypeError('allOf must be an array'); + return ( + (o.fullPath = [...to_path([..._, i, s]), 'allOf']), + void ( + null === (w = this.options.dereference.dereferenceOpts) || + void 0 === w || + null === (w = w.errors) || + void 0 === w || + null === (x = w.push) || + void 0 === x || + x.call(w, o) + ) + ); + } + if (s.allOf.isEmpty) return void s.remove('allOf'); + if (!s.allOf.content.every(Q_)) { + var C, j; + const o = new TypeError('Elements in allOf must be objects'); + return ( + (o.fullPath = [...to_path([..._, i, s]), 'allOf']), + void ( + null === (C = this.options.dereference.dereferenceOpts) || + void 0 === C || + null === (C = C.errors) || + void 0 === C || + null === (j = C.push) || + void 0 === j || + j.call(C, o) + ) + ); + } + for (; s.hasKey('allOf'); ) { + const { allOf: o } = s; + s.remove('allOf'); + const i = deepmerge.all([...o.content, s]); + if ((s.hasKey('$$ref') || i.remove('$$ref'), s.hasKey('example'))) { + const o = i.getMember('example'); + o && (o.value = s.get('example')); + } + if (s.hasKey('examples')) { + const o = i.getMember('examples'); + o && (o.value = s.get('examples')); + } + s.content = i.content; + } + } + }; + constructor({ options: s }) { + this.options = s; + } + }; + const aS = class ParameterMacroVisitor { + parameterMacro; + options; + #e; + OperationElement = { + enter: (s) => { + this.#e = s; + }, + leave: () => { + this.#e = void 0; + } + }; + ParameterElement = { + leave: (s, o, i, u, _) => { + const w = this.#e ? serializers_value(this.#e) : null, + x = serializers_value(s); + try { + const o = this.parameterMacro(w, x); + s.set('default', o); + } catch (s) { + var C, j; + const o = new Error(s, { cause: s }); + (o.fullPath = to_path([..._, i])), + null === (C = this.options.dereference.dereferenceOpts) || + void 0 === C || + null === (C = C.errors) || + void 0 === C || + null === (j = C.push) || + void 0 === j || + j.call(C, o); + } + } + }; + constructor({ parameterMacro: s, options: o }) { + (this.parameterMacro = s), (this.options = o); + } + }, + get_root_cause = (s) => { + if (null == s.cause) return s; + let { cause: o } = s; + for (; null != o.cause; ) o = o.cause; + return o; + }; + const lS = class SchemaRefError extends Jo {}, + { wrapError: cS } = ru, + uS = visitor_visit[Symbol.for('nodejs.util.promisify.custom')], + pS = new IdentityManager(), + dereference_mutationReplacer = (s, o, i, u) => { + $u(u) ? (u.value = s) : Array.isArray(u) && (u[i] = s); + }; + class OpenAPI3_1SwaggerClientDereferenceVisitor extends rS { + useCircularStructures; + allowMetaPatches; + basePath; + constructor({ + allowMetaPatches: s = !0, + useCircularStructures: o = !1, + basePath: i = null, + ...u + }) { + super(u), + (this.allowMetaPatches = s), + (this.useCircularStructures = o), + (this.basePath = i); + } + async ReferenceElement(s, o, i, u, _, w) { + try { + if (this.indirections.includes(s)) return !1; + const [o, u] = this.toAncestorLineage([..._, i]), + L = this.toBaseURI(serializers_value(s.$ref)), + B = stripHash(this.reference.uri) === L, + $ = !B; + if (!this.options.resolve.internal && B) return !1; + if (!this.options.resolve.external && $) return !1; + const V = await this.toReference(serializers_value(s.$ref)), + U = resolve(L, serializers_value(s.$ref)); + this.indirections.push(s); + const z = uriToPointer(U); + let Y = es_evaluate(z, V.value.result); + if (((Y.id = pS.identify(Y)), isPrimitiveElement(Y))) { + const o = serializers_value(s.meta.get('referenced-element')), + i = `${o}-${serializers_value(pS.identify(Y))}`; + if (this.refractCache.has(i)) Y = this.refractCache.get(i); + else if (isReferenceLikeElement(Y)) + (Y = Pb.refract(Y)), + Y.setMetaProperty('referenced-element', o), + this.refractCache.set(i, Y); + else { + (Y = this.namespace.getElementClass(o).refract(Y)), this.refractCache.set(i, Y); + } + } + if (s === Y) throw new Ho('Recursive Reference Object detected'); + if (this.indirections.length > this.options.dereference.maxDepth) + throw new Xw( + `Maximum dereference depth of "${this.options.dereference.maxDepth}" has been exceeded in file "${this.reference.uri}"` + ); + if (o.includes(Y)) { + if (((V.refSet.circular = !0), 'error' === this.options.dereference.circular)) + throw new Ho('Circular reference detected'); + if ('replace' === this.options.dereference.circular) { + var x, C; + const o = new Cu.sI(Y.id, { + type: 'reference', + uri: V.uri, + $ref: serializers_value(s.$ref), + baseURI: U, + referencingElement: s + }), + u = ( + null !== + (x = + null === (C = this.options.dereference.strategyOpts['openapi-3-1']) || + void 0 === C + ? void 0 + : C.circularReplacer) && void 0 !== x + ? x + : this.options.dereference.circularReplacer + )(o); + return w.replaceWith(o, dereference_mutationReplacer), !i && u; + } + } + const Z = stripHash(V.refSet.rootRef.uri) !== V.uri, + ee = ['error', 'replace'].includes(this.options.dereference.circular); + if (($ || Z || G_(Y) || ee) && !o.includesCycle(Y)) { + var j; + u.add(s); + const w = new OpenAPI3_1SwaggerClientDereferenceVisitor({ + reference: V, + namespace: this.namespace, + indirections: [...this.indirections], + options: this.options, + refractCache: this.refractCache, + ancestors: o, + allowMetaPatches: this.allowMetaPatches, + useCircularStructures: this.useCircularStructures, + basePath: + null !== (j = this.basePath) && void 0 !== j + ? j + : [...to_path([..._, i, s]), '$ref'] + }); + (Y = await uS(Y, w, { + keyMap: nw, + nodeTypeGetter: apidom_ns_openapi_3_1_es_traversal_visitor_getNodeType + })), + u.delete(s); + } + this.indirections.pop(); + const ie = cloneShallow(Y); + if ( + (ie.setMetaProperty('ref-fields', { + $ref: serializers_value(s.$ref), + description: serializers_value(s.description), + summary: serializers_value(s.summary) + }), + ie.setMetaProperty('ref-origin', V.uri), + ie.setMetaProperty('ref-referencing-element-id', cloneDeep(pS.identify(s))), + Fu(Y) && + (s.hasKey('description') && + 'description' in Y && + (ie.remove('description'), ie.set('description', s.get('description'))), + s.hasKey('summary') && + 'summary' in Y && + (ie.remove('summary'), ie.set('summary', s.get('summary')))), + this.allowMetaPatches && Fu(ie) && !ie.hasKey('$$ref')) + ) { + const s = resolve(L, U); + ie.set('$$ref', s); + } + return w.replaceWith(ie, dereference_mutationReplacer), !i && ie; + } catch (o) { + var L, B, $; + const u = get_root_cause(o), + w = cS(u, { + baseDoc: this.reference.uri, + $ref: serializers_value(s.$ref), + pointer: uriToPointer(serializers_value(s.$ref)), + fullPath: + null !== (L = this.basePath) && void 0 !== L + ? L + : [...to_path([..._, i, s]), '$ref'] + }); + return void ( + null === (B = this.options.dereference.dereferenceOpts) || + void 0 === B || + null === (B = B.errors) || + void 0 === B || + null === ($ = B.push) || + void 0 === $ || + $.call(B, w) + ); + } + } + async PathItemElement(s, o, i, u, _, w) { + try { + if (!Ru(s.$ref)) return; + if (this.indirections.includes(s)) return !1; + if (includesClasses(['cycle'], s.$ref)) return !1; + const [o, u] = this.toAncestorLineage([..._, i]), + L = this.toBaseURI(serializers_value(s.$ref)), + B = stripHash(this.reference.uri) === L, + $ = !B; + if (!this.options.resolve.internal && B) return; + if (!this.options.resolve.external && $) return; + const V = await this.toReference(serializers_value(s.$ref)), + U = resolve(L, serializers_value(s.$ref)); + this.indirections.push(s); + const z = uriToPointer(U); + let Y = es_evaluate(z, V.value.result); + if (((Y.id = pS.identify(Y)), isPrimitiveElement(Y))) { + const s = `path-item-${serializers_value(pS.identify(Y))}`; + this.refractCache.has(s) + ? (Y = this.refractCache.get(s)) + : ((Y = Ab.refract(Y)), this.refractCache.set(s, Y)); + } + if (s === Y) throw new Ho('Recursive Path Item Object reference detected'); + if (this.indirections.length > this.options.dereference.maxDepth) + throw new Xw( + `Maximum dereference depth of "${this.options.dereference.maxDepth}" has been exceeded in file "${this.reference.uri}"` + ); + if (o.includes(Y)) { + if (((V.refSet.circular = !0), 'error' === this.options.dereference.circular)) + throw new Ho('Circular reference detected'); + if ('replace' === this.options.dereference.circular) { + var x, C; + const o = new Cu.sI(Y.id, { + type: 'path-item', + uri: V.uri, + $ref: serializers_value(s.$ref), + baseURI: U, + referencingElement: s + }), + u = ( + null !== + (x = + null === (C = this.options.dereference.strategyOpts['openapi-3-1']) || + void 0 === C + ? void 0 + : C.circularReplacer) && void 0 !== x + ? x + : this.options.dereference.circularReplacer + )(o); + return w.replaceWith(o, dereference_mutationReplacer), !i && u; + } + } + const Z = stripHash(V.refSet.rootRef.uri) !== V.uri, + ee = ['error', 'replace'].includes(this.options.dereference.circular); + if (($ || Z || (H_(Y) && Ru(Y.$ref)) || ee) && !o.includesCycle(Y)) { + var j; + u.add(s); + const w = new OpenAPI3_1SwaggerClientDereferenceVisitor({ + reference: V, + namespace: this.namespace, + indirections: [...this.indirections], + options: this.options, + ancestors: o, + allowMetaPatches: this.allowMetaPatches, + useCircularStructures: this.useCircularStructures, + basePath: + null !== (j = this.basePath) && void 0 !== j + ? j + : [...to_path([..._, i, s]), '$ref'] + }); + (Y = await uS(Y, w, { + keyMap: nw, + nodeTypeGetter: apidom_ns_openapi_3_1_es_traversal_visitor_getNodeType + })), + u.delete(s); + } + if ((this.indirections.pop(), H_(Y))) { + const o = new Ab([...Y.content], cloneDeep(Y.meta), cloneDeep(Y.attributes)); + if ( + (s.forEach((s, i, u) => { + o.remove(serializers_value(i)), o.content.push(u); + }), + o.remove('$ref'), + o.setMetaProperty('ref-fields', { $ref: serializers_value(s.$ref) }), + o.setMetaProperty('ref-origin', V.uri), + o.setMetaProperty('ref-referencing-element-id', cloneDeep(pS.identify(s))), + this.allowMetaPatches && void 0 === o.get('$$ref')) + ) { + const s = resolve(L, U); + o.set('$$ref', s); + } + Y = o; + } + return w.replaceWith(Y, dereference_mutationReplacer), i ? void 0 : Y; + } catch (o) { + var L, B, $; + const u = get_root_cause(o), + w = cS(u, { + baseDoc: this.reference.uri, + $ref: serializers_value(s.$ref), + pointer: uriToPointer(serializers_value(s.$ref)), + fullPath: + null !== (L = this.basePath) && void 0 !== L + ? L + : [...to_path([..._, i, s]), '$ref'] + }); + return void ( + null === (B = this.options.dereference.dereferenceOpts) || + void 0 === B || + null === (B = B.errors) || + void 0 === B || + null === ($ = B.push) || + void 0 === $ || + $.call(B, w) + ); + } + } + async SchemaElement(s, o, i, u, _, w) { + try { + if (!Ru(s.$ref)) return; + if (this.indirections.includes(s)) return !1; + const [o, u] = this.toAncestorLineage([..._, i]); + let L = await this.toReference(unsanitize(this.reference.uri)), + { uri: B } = L; + const $ = resolveSchema$refField(B, s), + V = stripHash($), + U = new vw({ uri: V }), + z = !this.options.resolve.resolvers.some((s) => s.canRead(U)), + Y = !z; + let Z, + ee = stripHash(this.reference.uri) === $, + ie = !ee; + this.indirections.push(s); + try { + if (z || Y) { + B = this.toBaseURI($); + const s = $, + o = maybeRefractToSchemaElement(L.value.result); + if ( + ((Z = uri_evaluate(s, o)), + (Z = maybeRefractToSchemaElement(Z)), + (Z.id = pS.identify(Z)), + !this.options.resolve.internal && ee) + ) + return; + if (!this.options.resolve.external && ie) return; + } else { + if ( + ((B = this.toBaseURI($)), + (ee = stripHash(this.reference.uri) === B), + (ie = !ee), + !this.options.resolve.internal && ee) + ) + return; + if (!this.options.resolve.external && ie) return; + L = await this.toReference(unsanitize($)); + const s = uriToPointer($), + o = maybeRefractToSchemaElement(L.value.result); + (Z = es_evaluate(s, o)), + (Z = maybeRefractToSchemaElement(Z)), + (Z.id = pS.identify(Z)); + } + } catch (s) { + if (!(Y && s instanceof Yw)) throw s; + if (isAnchor(uriToAnchor($))) { + if ( + ((ee = stripHash(this.reference.uri) === B), + (ie = !ee), + !this.options.resolve.internal && ee) + ) + return; + if (!this.options.resolve.external && ie) return; + L = await this.toReference(unsanitize($)); + const s = uriToAnchor($), + o = maybeRefractToSchemaElement(L.value.result); + (Z = $anchor_evaluate(s, o)), + (Z = maybeRefractToSchemaElement(Z)), + (Z.id = pS.identify(Z)); + } else { + if ( + ((B = this.toBaseURI(serializers_value($))), + (ee = stripHash(this.reference.uri) === B), + (ie = !ee), + !this.options.resolve.internal && ee) + ) + return; + if (!this.options.resolve.external && ie) return; + L = await this.toReference(unsanitize($)); + const s = uriToPointer($), + o = maybeRefractToSchemaElement(L.value.result); + (Z = es_evaluate(s, o)), + (Z = maybeRefractToSchemaElement(Z)), + (Z.id = pS.identify(Z)); + } + } + if (s === Z) throw new Ho('Recursive Schema Object reference detected'); + if (this.indirections.length > this.options.dereference.maxDepth) + throw new Xw( + `Maximum dereference depth of "${this.options.dereference.maxDepth}" has been exceeded in file "${this.reference.uri}"` + ); + if (o.includes(Z)) { + if (((L.refSet.circular = !0), 'error' === this.options.dereference.circular)) + throw new Ho('Circular reference detected'); + if ('replace' === this.options.dereference.circular) { + var x, C; + const o = new Cu.sI(Z.id, { + type: 'json-schema', + uri: L.uri, + $ref: serializers_value(s.$ref), + baseURI: resolve(B, $), + referencingElement: s + }), + u = ( + null !== + (x = + null === (C = this.options.dereference.strategyOpts['openapi-3-1']) || + void 0 === C + ? void 0 + : C.circularReplacer) && void 0 !== x + ? x + : this.options.dereference.circularReplacer + )(o); + return w.replaceWith(u, dereference_mutationReplacer), !i && u; + } + } + const ae = stripHash(L.refSet.rootRef.uri) !== L.uri, + le = ['error', 'replace'].includes(this.options.dereference.circular); + if ((ie || ae || (Q_(Z) && Ru(Z.$ref)) || le) && !o.includesCycle(Z)) { + var j; + u.add(s); + const w = new OpenAPI3_1SwaggerClientDereferenceVisitor({ + reference: L, + namespace: this.namespace, + indirections: [...this.indirections], + options: this.options, + useCircularStructures: this.useCircularStructures, + allowMetaPatches: this.allowMetaPatches, + ancestors: o, + basePath: + null !== (j = this.basePath) && void 0 !== j + ? j + : [...to_path([..._, i, s]), '$ref'] + }); + (Z = await uS(Z, w, { + keyMap: nw, + nodeTypeGetter: apidom_ns_openapi_3_1_es_traversal_visitor_getNodeType + })), + u.delete(s); + } + if ((this.indirections.pop(), predicates_isBooleanJsonSchemaElement(Z))) { + const o = cloneDeep(Z); + return ( + o.setMetaProperty('ref-fields', { $ref: serializers_value(s.$ref) }), + o.setMetaProperty('ref-origin', L.uri), + o.setMetaProperty('ref-referencing-element-id', cloneDeep(pS.identify(s))), + w.replaceWith(o, dereference_mutationReplacer), + !i && o + ); + } + if (Q_(Z)) { + const o = new qb([...Z.content], cloneDeep(Z.meta), cloneDeep(Z.attributes)); + if ( + (s.forEach((s, i, u) => { + o.remove(serializers_value(i)), o.content.push(u); + }), + o.remove('$ref'), + o.setMetaProperty('ref-fields', { $ref: serializers_value(s.$ref) }), + o.setMetaProperty('ref-origin', L.uri), + o.setMetaProperty('ref-referencing-element-id', cloneDeep(pS.identify(s))), + this.allowMetaPatches && void 0 === o.get('$$ref')) + ) { + const s = resolve(B, $); + o.set('$$ref', s); + } + Z = o; + } + return w.replaceWith(Z, dereference_mutationReplacer), i ? void 0 : Z; + } catch (o) { + var L, B, $; + const u = get_root_cause(o), + w = new lS(`Could not resolve reference: ${u.message}`, { + baseDoc: this.reference.uri, + $ref: serializers_value(s.$ref), + fullPath: + null !== (L = this.basePath) && void 0 !== L + ? L + : [...to_path([..._, i, s]), '$ref'], + cause: u + }); + return void ( + null === (B = this.options.dereference.dereferenceOpts) || + void 0 === B || + null === (B = B.errors) || + void 0 === B || + null === ($ = B.push) || + void 0 === $ || + $.call(B, w) + ); + } + } + async LinkElement() {} + async ExampleElement(s, o, i, u, _, w) { + try { + return await super.ExampleElement(s, o, i, u, _, w); + } catch (o) { + var x, C, j; + const u = get_root_cause(o), + w = cS(u, { + baseDoc: this.reference.uri, + externalValue: serializers_value(s.externalValue), + fullPath: + null !== (x = this.basePath) && void 0 !== x + ? x + : [...to_path([..._, i, s]), 'externalValue'] + }); + return void ( + null === (C = this.options.dereference.dereferenceOpts) || + void 0 === C || + null === (C = C.errors) || + void 0 === C || + null === (j = C.push) || + void 0 === j || + j.call(C, w) + ); + } + } + } + const hS = OpenAPI3_1SwaggerClientDereferenceVisitor, + dS = mergeAll[Symbol.for('nodejs.util.promisify.custom')]; + const fS = class RootVisitor { + constructor({ parameterMacro: s, modelPropertyMacro: o, mode: i, options: u, ..._ }) { + const w = []; + w.push(new hS({ ..._, options: u })), + 'function' == typeof o && w.push(new oS({ modelPropertyMacro: o, options: u })), + 'strict' !== i && w.push(new iS({ options: u })), + 'function' == typeof s && w.push(new aS({ parameterMacro: s, options: u })); + const x = dS(w, { + nodeTypeGetter: apidom_ns_openapi_3_1_es_traversal_visitor_getNodeType + }); + Object.assign(this, x); + } + }, + mS = visitor_visit[Symbol.for('nodejs.util.promisify.custom')]; + const gS = class OpenAPI3_1SwaggerClientDereferenceStrategy extends sS { + allowMetaPatches; + parameterMacro; + modelPropertyMacro; + mode; + ancestors; + constructor({ + allowMetaPatches: s = !1, + parameterMacro: o = null, + modelPropertyMacro: i = null, + mode: u = 'non-strict', + ancestors: _ = [], + ...w + } = {}) { + super({ ...w }), + (this.name = 'openapi-3-1-swagger-client'), + (this.allowMetaPatches = s), + (this.parameterMacro = o), + (this.modelPropertyMacro = i), + (this.mode = u), + (this.ancestors = [..._]); + } + async dereference(s, o) { + var i; + const u = createNamespace(ow), + _ = null !== (i = o.dereference.refSet) && void 0 !== i ? i : new uw(), + w = new uw(); + let x, + C = _; + _.has(s.uri) + ? (x = _.find((o) => o.uri === s.uri)) + : ((x = new cw({ uri: s.uri, value: s.parseResult })), _.add(x)), + o.dereference.immutable && + (_.refs + .map((s) => new cw({ ...s, value: cloneDeep(s.value) })) + .forEach((s) => w.add(s)), + (x = w.find((o) => o.uri === s.uri)), + (C = w)); + const j = new fS({ + reference: x, + namespace: u, + options: o, + allowMetaPatches: this.allowMetaPatches, + ancestors: this.ancestors, + modelPropertyMacro: this.modelPropertyMacro, + mode: this.mode, + parameterMacro: this.parameterMacro + }), + L = await mS(C.rootRef.value, j, { + keyMap: nw, + nodeTypeGetter: apidom_ns_openapi_3_1_es_traversal_visitor_getNodeType + }); + return ( + o.dereference.immutable && + w.refs + .filter((s) => s.uri.startsWith('immutable://')) + .map((s) => new cw({ ...s, uri: s.uri.replace(/^immutable:\/\//, '') })) + .forEach((s) => _.add(s)), + null === o.dereference.refSet && _.clean(), + w.clean(), + L + ); + } + }, + circularReplacer = (s) => { + const o = serializers_value(s.meta.get('baseURI')), + i = s.meta.get('referencingElement'); + return new Cu.Sh({ $ref: o }, cloneDeep(i.meta), cloneDeep(i.attributes)); + }, + resolveOpenAPI31Strategy = async (s) => { + const { + spec: o, + timeout: i, + redirects: u, + requestInterceptor: _, + responseInterceptor: w, + pathDiscriminator: x = [], + allowMetaPatches: C = !1, + useCircularStructures: j = !1, + skipNormalization: L = !1, + parameterMacro: B = null, + modelPropertyMacro: $ = null, + mode: V = 'non-strict', + strategies: U + } = s; + try { + const { cache: z } = resolveOpenAPI31Strategy, + Y = U.find((s) => s.match(o)), + Z = isHttpUrl(url_cwd()) ? url_cwd() : Nc, + ee = options_retrievalURI(s), + ie = resolve(Z, ee); + let ae; + z.has(o) + ? (ae = z.get(o)) + : ((ae = wb.refract(o)), ae.classes.push('result'), z.set(o, ae)); + const le = new Mu([ae]), + ce = es_compile(x), + pe = '' === ce ? '' : `#${ce}`, + de = es_evaluate(ce, ae), + fe = new cw({ uri: ie, value: le }), + ye = new uw({ refs: [fe] }); + '' !== ce && (ye.rootRef = void 0); + const be = [new Set([de])], + _e = [], + we = await (async (s, o = {}) => { + const i = util_merge(pw, o); + return dereferenceApiDOM(s, i); + })(de, { + resolve: { + baseURI: `${ie}${pe}`, + resolvers: [new Nw({ timeout: i || 1e4, redirects: u || 10 })], + resolverOpts: { + swaggerHTTPClientConfig: { requestInterceptor: _, responseInterceptor: w } + }, + strategies: [new Ow()] + }, + parse: { + mediaType: lw.latest(), + parsers: [ + new Lw({ allowEmpty: !1, sourceMap: !1 }), + new Bw({ allowEmpty: !1, sourceMap: !1 }), + new Rw({ allowEmpty: !1, sourceMap: !1 }), + new Dw({ allowEmpty: !1, sourceMap: !1 }), + new kw({ allowEmpty: !1, sourceMap: !1 }) + ] + }, + dereference: { + maxDepth: 100, + strategies: [ + new gS({ + allowMetaPatches: C, + useCircularStructures: j, + parameterMacro: B, + modelPropertyMacro: $, + mode: V, + ancestors: be + }) + ], + refSet: ye, + dereferenceOpts: { errors: _e }, + immutable: !1, + circular: j ? 'ignore' : 'replace', + circularReplacer: j ? pw.dereference.circularReplacer : circularReplacer + } + }), + Se = ((s, o, i) => new xp({ element: i }).transclude(s, o))(de, we, ae), + xe = L ? Se : Y.normalize(Se); + return { spec: serializers_value(xe), errors: _e }; + } catch (s) { + if (s instanceof Wp || s instanceof Kp) return { spec: null, errors: [] }; + throw s; + } + }; + resolveOpenAPI31Strategy.cache = new WeakMap(); + const yS = resolveOpenAPI31Strategy; + function _clone(s, o, i) { + if ( + (i || (i = new vS()), + (function _isPrimitive(s) { + var o = typeof s; + return null == s || ('object' != o && 'function' != o); + })(s)) + ) + return s; + var u = function copy(u) { + var _ = i.get(s); + if (_) return _; + for (var w in (i.set(s, u), s)) + Object.prototype.hasOwnProperty.call(s, w) && (u[w] = o ? _clone(s[w], !0, i) : s[w]); + return u; + }; + switch (ea(s)) { + case 'Object': + return u(Object.create(Object.getPrototypeOf(s))); + case 'Array': + return u(Array(s.length)); + case 'Date': + return new Date(s.valueOf()); + case 'RegExp': + return _cloneRegExp(s); + case 'Int8Array': + case 'Uint8Array': + case 'Uint8ClampedArray': + case 'Int16Array': + case 'Uint16Array': + case 'Int32Array': + case 'Uint32Array': + case 'Float32Array': + case 'Float64Array': + case 'BigInt64Array': + case 'BigUint64Array': + return s.slice(); + default: + return s; + } + } + var vS = (function () { + function _ObjectMap() { + (this.map = {}), (this.length = 0); + } + return ( + (_ObjectMap.prototype.set = function (s, o) { + var i = this.hash(s), + u = this.map[i]; + u || (this.map[i] = u = []), u.push([s, o]), (this.length += 1); + }), + (_ObjectMap.prototype.hash = function (s) { + var o = []; + for (var i in s) o.push(Object.prototype.toString.call(s[i])); + return o.join(); + }), + (_ObjectMap.prototype.get = function (s) { + if (this.length <= 180) + for (var o in this.map) + for (var i = this.map[o], u = 0; u < i.length; u += 1) { + if ((w = i[u])[0] === s) return w[1]; + } + else { + var _ = this.hash(s); + if ((i = this.map[_])) + for (u = 0; u < i.length; u += 1) { + var w; + if ((w = i[u])[0] === s) return w[1]; + } + } + }), + _ObjectMap + ); + })(), + bS = (function () { + function XReduceBy(s, o, i, u) { + (this.valueFn = s), + (this.valueAcc = o), + (this.keyFn = i), + (this.xf = u), + (this.inputs = {}); + } + return ( + (XReduceBy.prototype['@@transducer/init'] = _xfBase_init), + (XReduceBy.prototype['@@transducer/result'] = function (s) { + var o; + for (o in this.inputs) + if ( + _has(o, this.inputs) && + (s = this.xf['@@transducer/step'](s, this.inputs[o]))['@@transducer/reduced'] + ) { + s = s['@@transducer/value']; + break; + } + return (this.inputs = null), this.xf['@@transducer/result'](s); + }), + (XReduceBy.prototype['@@transducer/step'] = function (s, o) { + var i = this.keyFn(o); + return ( + (this.inputs[i] = this.inputs[i] || [i, _clone(this.valueAcc, !1)]), + (this.inputs[i][1] = this.valueFn(this.inputs[i][1], o)), + s + ); + }), + XReduceBy + ); + })(); + function _xreduceBy(s, o, i) { + return function (u) { + return new bS(s, o, i, u); + }; + } + var _S = _curryN( + 4, + [], + _dispatchable([], _xreduceBy, function reduceBy(s, o, i, u) { + var _ = _xwrap(function (u, _) { + var w = i(_), + x = s(_has(w, u) ? u[w] : _clone(o, !1), _); + return x && x['@@transducer/reduced'] ? _reduced(u) : ((u[w] = x), u); + }); + return wa(_, {}, u); + }) + ); + const ES = _curry2( + _checkForMethod( + 'groupBy', + _S(function (s, o) { + return s.push(o), s; + }, []) + ) + ); + const wS = class NormalizeStorage { + internalStore; + constructor(s, o, i) { + (this.storageElement = s), (this.storageField = o), (this.storageSubField = i); + } + get store() { + if (!this.internalStore) { + let s = this.storageElement.get(this.storageField); + Fu(s) || ((s = new Cu.Sh()), this.storageElement.set(this.storageField, s)); + let o = s.get(this.storageSubField); + qu(o) || ((o = new Cu.wE()), s.set(this.storageSubField, o)), + (this.internalStore = o); + } + return this.internalStore; + } + append(s) { + this.includes(s) || this.store.push(s); + } + includes(s) { + return this.store.includes(s); + } + }, + removeSpaces = (s) => s.replace(/\s/g, ''), + normalize_operation_ids_replaceSpecialCharsWithUnderscore = (s) => s.replace(/\W/gi, '_'), + normalizeOperationId = (s, o, i) => { + const u = removeSpaces(s); + return u.length > 0 + ? normalize_operation_ids_replaceSpecialCharsWithUnderscore(u) + : ((s, o) => + `${normalize_operation_ids_replaceSpecialCharsWithUnderscore(removeSpaces(o.toLowerCase()))}${normalize_operation_ids_replaceSpecialCharsWithUnderscore(removeSpaces(s))}`)( + o, + i + ); + }, + normalize_operation_ids = + ({ + storageField: s = 'x-normalized', + operationIdNormalizer: o = normalizeOperationId + } = {}) => + (i) => { + const { predicates: u, ancestorLineageToJSONPointer: _, namespace: w } = i, + x = [], + C = [], + j = []; + let L; + return { + visitor: { + OpenApi3_1Element: { + enter(o) { + L = new wS(o, s, 'operation-ids'); + }, + leave() { + const s = ES((s) => serializers_value(s.operationId), C); + Object.entries(s).forEach(([s, o]) => { + Array.isArray(o) && + (o.length <= 1 || + o.forEach((o, i) => { + const u = `${s}${i + 1}`; + o.operationId = new w.elements.String(u); + })); + }), + j.forEach((s) => { + if (void 0 === s.operationId) return; + const o = String(serializers_value(s.operationId)), + i = C.find( + (s) => serializers_value(s.meta.get('originalOperationId')) === o + ); + void 0 !== i && + ((s.operationId = cloneDeep.safe(i.operationId)), + s.meta.set('originalOperationId', o), + s.set('__originalOperationId', o)); + }), + (C.length = 0), + (j.length = 0), + (L = void 0); + } + }, + PathItemElement: { + enter(s) { + const o = Na('path', serializers_value(s.meta.get('path'))); + x.push(o); + }, + leave() { + x.pop(); + } + }, + OperationElement: { + enter(s, i, u, j, B) { + if (void 0 === s.operationId) return; + const $ = _([...B, u, s]); + if (L.includes($)) return; + const V = String(serializers_value(s.operationId)), + U = Fa(x), + z = Na('method', serializers_value(s.meta.get('http-method'))), + Y = o(V, U, z); + V !== Y && + ((s.operationId = new w.elements.String(Y)), + s.set('__originalOperationId', V), + s.meta.set('originalOperationId', V), + C.push(s), + L.append($)); + } + }, + LinkElement: { + leave(s) { + u.isLinkElement(s) && void 0 !== s.operationId && j.push(s); + } + } + } + }; + }; + var SS = (function () { + function XUniqWith(s, o) { + (this.xf = o), (this.pred = s), (this.items = []); + } + return ( + (XUniqWith.prototype['@@transducer/init'] = _xfBase_init), + (XUniqWith.prototype['@@transducer/result'] = _xfBase_result), + (XUniqWith.prototype['@@transducer/step'] = function (s, o) { + return _includesWith(this.pred, o, this.items) + ? s + : (this.items.push(o), this.xf['@@transducer/step'](s, o)); + }), + XUniqWith + ); + })(); + function _xuniqWith(s) { + return function (o) { + return new SS(s, o); + }; + } + var xS = _curry2( + _dispatchable([], _xuniqWith, function (s, o) { + for (var i, u = 0, _ = o.length, w = []; u < _; ) + _includesWith(s, (i = o[u]), w) || (w[w.length] = i), (u += 1); + return w; + }) + ); + const kS = xS, + normalize_parameters = + ({ storageField: s = 'x-normalized' } = {}) => + (o) => { + const { predicates: i, ancestorLineageToJSONPointer: u } = o, + parameterEquals = (s, o) => + !!i.isParameterElement(s) && + !!i.isParameterElement(o) && + !!i.isStringElement(s.name) && + !!i.isStringElement(s.in) && + !!i.isStringElement(o.name) && + !!i.isStringElement(o.in) && + serializers_value(s.name) === serializers_value(o.name) && + serializers_value(s.in) === serializers_value(o.in), + _ = []; + let w; + return { + visitor: { + OpenApi3_1Element: { + enter(o) { + w = new wS(o, s, 'parameters'); + }, + leave() { + w = void 0; + } + }, + PathItemElement: { + enter(s, o, u, w, x) { + if (x.some(i.isComponentsElement)) return; + const { parameters: C } = s; + i.isArrayElement(C) ? _.push([...C.content]) : _.push([]); + }, + leave() { + _.pop(); + } + }, + OperationElement: { + leave(s, o, i, x, C) { + const j = Fa(_); + if (!Array.isArray(j) || 0 === j.length) return; + const L = u([...C, i, s]); + if (w.includes(L)) return; + const B = Ww([], ['parameters', 'content'], s), + $ = kS(parameterEquals, [...B, ...j]); + (s.parameters = new yv($)), w.append(L); + } + } + } + }; + }, + normalize_security_requirements = + ({ storageField: s = 'x-normalized' } = {}) => + (o) => { + const { predicates: i, ancestorLineageToJSONPointer: u } = o; + let _, w; + return { + visitor: { + OpenApi3_1Element: { + enter(o) { + (w = new wS(o, s, 'security-requirements')), + i.isArrayElement(o.security) && (_ = o.security); + }, + leave() { + (w = void 0), (_ = void 0); + } + }, + OperationElement: { + leave(s, o, x, C, j) { + if (j.some(i.isComponentsElement)) return; + const L = u([...j, x, s]); + if (w.includes(L)) return; + var B; + void 0 === s.security && + void 0 !== _ && + ((s.security = new Sv( + null === (B = _) || void 0 === B ? void 0 : B.content + )), + w.append(L)); + } + } + } + }; + }, + normalize_parameter_examples = + ({ storageField: s = 'x-normalized' } = {}) => + (o) => { + const { predicates: i, ancestorLineageToJSONPointer: u } = o; + let _; + return { + visitor: { + OpenApi3_1Element: { + enter(o) { + _ = new wS(o, s, 'parameter-examples'); + }, + leave() { + _ = void 0; + } + }, + ParameterElement: { + leave(s, o, w, x, C) { + var j, L; + if (C.some(i.isComponentsElement)) return; + if (void 0 === s.schema || !i.isSchemaElement(s.schema)) return; + if ( + void 0 === (null === (j = s.schema) || void 0 === j ? void 0 : j.example) && + void 0 === (null === (L = s.schema) || void 0 === L ? void 0 : L.examples) + ) + return; + const B = u([...C, w, s]); + if (!_.includes(B)) { + if (void 0 !== s.examples && i.isObjectElement(s.examples)) { + const o = s.examples.map((s) => cloneDeep.safe(s.value)); + return ( + void 0 !== s.schema.examples && + (s.schema.set('examples', o), _.append(B)), + void ( + void 0 !== s.schema.example && + (s.schema.set('example', o[0]), _.append(B)) + ) + ); + } + void 0 !== s.example && + (void 0 !== s.schema.examples && + (s.schema.set('examples', [cloneDeep(s.example)]), _.append(B)), + void 0 !== s.schema.example && + (s.schema.set('example', cloneDeep(s.example)), _.append(B))); + } + } + } + } + }; + }, + normalize_header_examples = + ({ storageField: s = 'x-normalized' } = {}) => + (o) => { + const { predicates: i, ancestorLineageToJSONPointer: u } = o; + let _; + return { + visitor: { + OpenApi3_1Element: { + enter(o) { + _ = new wS(o, s, 'header-examples'); + }, + leave() { + _ = void 0; + } + }, + HeaderElement: { + leave(s, o, w, x, C) { + var j, L; + if (C.some(i.isComponentsElement)) return; + if (void 0 === s.schema || !i.isSchemaElement(s.schema)) return; + if ( + void 0 === (null === (j = s.schema) || void 0 === j ? void 0 : j.example) && + void 0 === (null === (L = s.schema) || void 0 === L ? void 0 : L.examples) + ) + return; + const B = u([...C, w, s]); + if (!_.includes(B)) { + if (void 0 !== s.examples && i.isObjectElement(s.examples)) { + const o = s.examples.map((s) => cloneDeep.safe(s.value)); + return ( + void 0 !== s.schema.examples && + (s.schema.set('examples', o), _.append(B)), + void ( + void 0 !== s.schema.example && + (s.schema.set('example', o[0]), _.append(B)) + ) + ); + } + void 0 !== s.example && + (void 0 !== s.schema.examples && + (s.schema.set('examples', [cloneDeep(s.example)]), _.append(B)), + void 0 !== s.schema.example && + (s.schema.set('example', cloneDeep(s.example)), _.append(B))); + } + } + } + } + }; + }, + openapi_3_1_apidom_normalize = (s) => { + if (!Fu(s)) return s; + const o = [ + normalize_operation_ids({ + operationIdNormalizer: (s, o, i) => + opId({ operationId: s }, o, i, { v2OperationIdCompatibilityMode: !1 }) + }), + normalize_parameters(), + normalize_security_requirements(), + normalize_parameter_examples(), + normalize_header_examples() + ]; + return dispatchPluginsSync(s, o, { + toolboxCreator: apidom_ns_openapi_3_1_es_refractor_toolbox, + visitorOptions: { + keyMap: nw, + nodeTypeGetter: apidom_ns_openapi_3_1_es_traversal_visitor_getNodeType + } + }); + }, + CS = { + name: 'openapi-3-1-apidom', + match: (s) => isOpenAPI31(s), + normalize(s) { + if (!Nu(s) && ku(s) && !s.$$normalized) { + const i = ((o = openapi_3_1_apidom_normalize), + (s) => { + const i = wb.refract(s); + i.classes.push('result'); + const u = o(i), + _ = serializers_value(u); + return yS.cache.set(_, u), serializers_value(u); + })(s); + return (i.$$normalized = !0), i; + } + var o; + return Nu(s) ? openapi_3_1_apidom_normalize(s) : s; + }, + resolve: async (s) => yS(s) + }, + OS = CS, + makeResolve = (s) => async (o) => + (async (s) => { + const { spec: o, requestInterceptor: i, responseInterceptor: u } = s, + _ = options_retrievalURI(s), + w = options_httpClient(s), + x = + o || + (await makeFetchJSON(w, { requestInterceptor: i, responseInterceptor: u })(_)), + C = { ...s, spec: x }; + return s.strategies.find((s) => s.match(x)).resolve(C); + })({ ...s, ...o }), + AS = makeResolve({ strategies: [fu, hu, uu] }); + var jS = __webpack_require__(69883); + const IS = function fnparser() { + const s = TS, + o = MS, + i = this, + u = 'parser.js: Parser(): '; + (i.ast = void 0), (i.stats = void 0), (i.trace = void 0), (i.callbacks = []); + let _, + w, + x, + C, + j, + L, + B, + $ = 0, + V = 0, + U = 0, + z = 0, + Y = 0, + Z = new (function systemData() { + (this.state = s.ACTIVE), + (this.phraseLength = 0), + (this.refresh = () => { + (this.state = s.ACTIVE), (this.phraseLength = 0); + }); + })(); + i.parse = (ee, ie, ae, le) => { + const ce = `${u}parse(): `; + ($ = 0), + (V = 0), + (U = 0), + (z = 0), + (Y = 0), + (_ = void 0), + (w = void 0), + (x = void 0), + (C = void 0), + Z.refresh(), + (j = void 0), + (L = void 0), + (B = void 0), + (C = o.stringToChars(ae)), + (_ = ee.rules), + (w = ee.udts); + const pe = ie.toLowerCase(); + let de; + for (const s in _) + if (_.hasOwnProperty(s) && pe === _[s].lower) { + de = _[s].index; + break; + } + if (void 0 === de) + throw new Error(`${ce}start rule name '${startRule}' not recognized`); + (() => { + const s = `${u}initializeCallbacks(): `; + let o, x; + for (j = [], L = [], o = 0; o < _.length; o += 1) j[o] = void 0; + for (o = 0; o < w.length; o += 1) L[o] = void 0; + const C = []; + for (o = 0; o < _.length; o += 1) C.push(_[o].lower); + for (o = 0; o < w.length; o += 1) C.push(w[o].lower); + for (const u in i.callbacks) + if (i.callbacks.hasOwnProperty(u)) { + if (((o = C.indexOf(u.toLowerCase())), o < 0)) + throw new Error(`${s}syntax callback '${u}' not a rule or udt name`); + if ( + ((x = i.callbacks[u] ? i.callbacks[u] : void 0), + 'function' != typeof x && void 0 !== x) + ) + throw new Error( + `${s}syntax callback[${u}] must be function reference or falsy)` + ); + o < _.length ? (j[o] = x) : (L[o - _.length] = x); + } + })(), + i.trace && i.trace.init(_, w, C), + i.stats && i.stats.init(_, w), + i.ast && i.ast.init(_, w, C), + (B = le), + (x = [{ type: s.RNM, index: de }]), + opExecute(0, 0), + (x = void 0); + let fe = !1; + switch (Z.state) { + case s.ACTIVE: + throw new Error(`${ce}final state should never be 'ACTIVE'`); + case s.NOMATCH: + fe = !1; + break; + case s.EMPTY: + case s.MATCH: + fe = Z.phraseLength === C.length; + break; + default: + throw new Error('unrecognized state'); + } + return { + success: fe, + state: Z.state, + stateName: s.idName(Z.state), + length: C.length, + matched: Z.phraseLength, + maxMatched: Y, + maxTreeDepth: U, + nodeHits: z + }; + }; + const validateRnmCallbackResult = (o, i, _, w) => { + if (i.phraseLength > _) { + let s = `${u}opRNM(${o.name}): callback function error: `; + throw ( + ((s += `sysData.phraseLength: ${i.phraseLength}`), + (s += ` must be <= remaining chars: ${_}`), + new Error(s)) + ); + } + switch (i.state) { + case s.ACTIVE: + if (!w) + throw new Error( + `${u}opRNM(${o.name}): callback function return error. ACTIVE state not allowed.` + ); + break; + case s.EMPTY: + i.phraseLength = 0; + break; + case s.MATCH: + 0 === i.phraseLength && (i.state = s.EMPTY); + break; + case s.NOMATCH: + i.phraseLength = 0; + break; + default: + throw new Error( + `${u}opRNM(${o.name}): callback function return error. Unrecognized return state: ${i.state}` + ); + } + }, + opUDT = (o, j) => { + let V, U, z; + const Y = x[o], + ee = w[Y.index]; + (Z.UdtIndex = ee.index), + $ || + ((z = i.ast && i.ast.udtDefined(Y.index)), + z && + ((U = _.length + Y.index), (V = i.ast.getLength()), i.ast.down(U, ee.name))); + const ie = C.length - j; + L[Y.index](Z, C, j, B), + ((o, i, _) => { + if (i.phraseLength > _) { + let s = `${u}opUDT(${o.name}): callback function error: `; + throw ( + ((s += `sysData.phraseLength: ${i.phraseLength}`), + (s += ` must be <= remaining chars: ${_}`), + new Error(s)) + ); + } + switch (i.state) { + case s.ACTIVE: + throw new Error(`${u}opUDT(${o.name}) ACTIVE state return not allowed.`); + case s.EMPTY: + if (!o.empty) throw new Error(`${u}opUDT(${o.name}) may not return EMPTY.`); + i.phraseLength = 0; + break; + case s.MATCH: + if (0 === i.phraseLength) { + if (!o.empty) + throw new Error(`${u}opUDT(${o.name}) may not return EMPTY.`); + i.state = s.EMPTY; + } + break; + case s.NOMATCH: + i.phraseLength = 0; + break; + default: + throw new Error( + `${u}opUDT(${o.name}): callback function return error. Unrecognized return state: ${i.state}` + ); + } + })(ee, Z, ie), + $ || + (z && + (Z.state === s.NOMATCH + ? i.ast.setLength(V) + : i.ast.up(U, ee.name, j, Z.phraseLength))); + }, + opExecute = (o, w) => { + const L = `${u}opExecute(): `, + ee = x[o]; + switch ( + ((z += 1), + V > U && (U = V), + (V += 1), + Z.refresh(), + i.trace && i.trace.down(ee, w), + ee.type) + ) { + case s.ALT: + ((o, i) => { + const u = x[o]; + for ( + let o = 0; + o < u.children.length && + (opExecute(u.children[o], i), Z.state === s.NOMATCH); + o += 1 + ); + })(o, w); + break; + case s.CAT: + ((o, u) => { + let _, w, C, j; + const L = x[o]; + i.ast && (w = i.ast.getLength()), (_ = !0), (C = u), (j = 0); + for (let o = 0; o < L.children.length; o += 1) { + if ((opExecute(L.children[o], C), Z.state === s.NOMATCH)) { + _ = !1; + break; + } + (C += Z.phraseLength), (j += Z.phraseLength); + } + _ + ? ((Z.state = 0 === j ? s.EMPTY : s.MATCH), (Z.phraseLength = j)) + : ((Z.state = s.NOMATCH), + (Z.phraseLength = 0), + i.ast && i.ast.setLength(w)); + })(o, w); + break; + case s.REP: + ((o, u) => { + let _, w, j, L; + const B = x[o]; + if (0 === B.max) return (Z.state = s.EMPTY), void (Z.phraseLength = 0); + for ( + w = u, j = 0, L = 0, i.ast && (_ = i.ast.getLength()); + !(w >= C.length) && + (opExecute(o + 1, w), Z.state !== s.NOMATCH) && + Z.state !== s.EMPTY && + ((L += 1), (j += Z.phraseLength), (w += Z.phraseLength), L !== B.max); + + ); + Z.state === s.EMPTY || L >= B.min + ? ((Z.state = 0 === j ? s.EMPTY : s.MATCH), (Z.phraseLength = j)) + : ((Z.state = s.NOMATCH), + (Z.phraseLength = 0), + i.ast && i.ast.setLength(_)); + })(o, w); + break; + case s.RNM: + ((o, u) => { + let w, L, V; + const U = x[o], + z = _[U.index], + Y = j[z.index]; + if ( + ($ || + ((L = i.ast && i.ast.ruleDefined(U.index)), + L && ((w = i.ast.getLength()), i.ast.down(U.index, _[U.index].name))), + Y) + ) { + const o = C.length - u; + Y(Z, C, u, B), + validateRnmCallbackResult(z, Z, o, !0), + Z.state === s.ACTIVE && + ((V = x), + (x = z.opcodes), + opExecute(0, u), + (x = V), + Y(Z, C, u, B), + validateRnmCallbackResult(z, Z, o, !1)); + } else (V = x), (x = z.opcodes), opExecute(0, u, Z), (x = V); + $ || + (L && + (Z.state === s.NOMATCH + ? i.ast.setLength(w) + : i.ast.up(U.index, z.name, u, Z.phraseLength))); + })(o, w); + break; + case s.TRG: + ((o, i) => { + const u = x[o]; + (Z.state = s.NOMATCH), + i < C.length && + u.min <= C[i] && + C[i] <= u.max && + ((Z.state = s.MATCH), (Z.phraseLength = 1)); + })(o, w); + break; + case s.TBS: + ((o, i) => { + const u = x[o], + _ = u.string.length; + if (((Z.state = s.NOMATCH), i + _ <= C.length)) { + for (let s = 0; s < _; s += 1) if (C[i + s] !== u.string[s]) return; + (Z.state = s.MATCH), (Z.phraseLength = _); + } + })(o, w); + break; + case s.TLS: + ((o, i) => { + let u; + const _ = x[o]; + Z.state = s.NOMATCH; + const w = _.string.length; + if (0 !== w) { + if (i + w <= C.length) { + for (let s = 0; s < w; s += 1) + if ( + ((u = C[i + s]), u >= 65 && u <= 90 && (u += 32), u !== _.string[s]) + ) + return; + (Z.state = s.MATCH), (Z.phraseLength = w); + } + } else Z.state = s.EMPTY; + })(o, w); + break; + case s.UDT: + opUDT(o, w); + break; + case s.AND: + ((o, i) => { + switch ( + (($ += 1), opExecute(o + 1, i), ($ -= 1), (Z.phraseLength = 0), Z.state) + ) { + case s.EMPTY: + case s.MATCH: + Z.state = s.EMPTY; + break; + case s.NOMATCH: + Z.state = s.NOMATCH; + break; + default: + throw new Error(`opAND: invalid state ${Z.state}`); + } + })(o, w); + break; + case s.NOT: + ((o, i) => { + switch ( + (($ += 1), opExecute(o + 1, i), ($ -= 1), (Z.phraseLength = 0), Z.state) + ) { + case s.EMPTY: + case s.MATCH: + Z.state = s.NOMATCH; + break; + case s.NOMATCH: + Z.state = s.EMPTY; + break; + default: + throw new Error(`opNOT: invalid state ${Z.state}`); + } + })(o, w); + break; + default: + throw new Error(`${L}unrecognized operator`); + } + $ || (w + Z.phraseLength > Y && (Y = w + Z.phraseLength)), + i.stats && i.stats.collect(ee, Z), + i.trace && i.trace.up(ee, Z.state, w, Z.phraseLength), + (V -= 1); + }; + }, + PS = function fnast() { + const s = TS, + o = MS, + i = this; + let u, + _, + w, + x = 0; + const C = [], + j = [], + L = []; + function indent(s) { + let o = ''; + for (; s-- > 0; ) o += ' '; + return o; + } + (i.callbacks = []), + (i.init = (s, o, B) => { + let $; + (j.length = 0), (L.length = 0), (x = 0), (u = s), (_ = o), (w = B); + const V = []; + for ($ = 0; $ < u.length; $ += 1) V.push(u[$].lower); + for ($ = 0; $ < _.length; $ += 1) V.push(_[$].lower); + for (x = u.length + _.length, $ = 0; $ < x; $ += 1) C[$] = void 0; + for (const s in i.callbacks) + if (i.callbacks.hasOwnProperty(s)) { + const o = s.toLowerCase(); + if ((($ = V.indexOf(o)), $ < 0)) + throw new Error( + `parser.js: Ast()): init: node '${s}' not a rule or udt name` + ); + C[$] = i.callbacks[s]; + } + }), + (i.ruleDefined = (s) => !!C[s]), + (i.udtDefined = (s) => !!C[u.length + s]), + (i.down = (o, i) => { + const u = L.length; + return ( + j.push(u), + L.push({ + name: i, + thisIndex: u, + thatIndex: void 0, + state: s.SEM_PRE, + callbackIndex: o, + phraseIndex: void 0, + phraseLength: void 0, + stack: j.length + }), + u + ); + }), + (i.up = (o, i, u, _) => { + const w = L.length, + x = j.pop(); + return ( + L.push({ + name: i, + thisIndex: w, + thatIndex: x, + state: s.SEM_POST, + callbackIndex: o, + phraseIndex: u, + phraseLength: _, + stack: j.length + }), + (L[x].thatIndex = w), + (L[x].phraseIndex = u), + (L[x].phraseLength = _), + w + ); + }), + (i.translate = (o) => { + let i, u; + for (let _ = 0; _ < L.length; _ += 1) + (u = L[_]), + (i = C[u.callbackIndex]), + i && + (u.state === s.SEM_PRE + ? i(s.SEM_PRE, w, u.phraseIndex, u.phraseLength, o) + : i && i(s.SEM_POST, w, u.phraseIndex, u.phraseLength, o)); + }), + (i.setLength = (s) => { + (L.length = s), (j.length = s > 0 ? L[s - 1].stack : 0); + }), + (i.getLength = () => L.length), + (i.toXml = () => { + let i = '', + u = 0; + return ( + (i += '\n'), + (i += `\n`), + (i += '\x3c!-- input string --\x3e\n'), + (i += indent(u + 2)), + (i += o.charsToString(w)), + (i += '\n'), + L.forEach((_) => { + _.state === s.SEM_PRE + ? ((u += 1), + (i += indent(u)), + (i += `\n`), + (i += indent(u + 2)), + (i += o.charsToString(w, _.phraseIndex, _.phraseLength)), + (i += '\n')) + : ((i += indent(u)), + (i += `\x3c!-- name="${_.name}" --\x3e\n`), + (u -= 1)); + }), + (i += '\n'), + i + ); + }); + }, + MS = { + stringToChars: (s) => [...s].map((s) => s.codePointAt(0)), + charsToString: (s, o, i) => { + let u = s; + for (; !(void 0 === o || o < 0); ) { + if (void 0 === i) { + u = s.slice(o); + break; + } + if (i <= 0) return ''; + u = s.slice(o, o + i); + break; + } + return String.fromCodePoint(...u); + } + }, + TS = { + ALT: 1, + CAT: 2, + REP: 3, + RNM: 4, + TRG: 5, + TBS: 6, + TLS: 7, + UDT: 11, + AND: 12, + NOT: 13, + ACTIVE: 100, + MATCH: 101, + EMPTY: 102, + NOMATCH: 103, + SEM_PRE: 200, + SEM_POST: 201, + SEM_OK: 300, + idName: (s) => { + switch (s) { + case TS.ALT: + return 'ALT'; + case TS.CAT: + return 'CAT'; + case TS.REP: + return 'REP'; + case TS.RNM: + return 'RNM'; + case TS.TRG: + return 'TRG'; + case TS.TBS: + return 'TBS'; + case TS.TLS: + return 'TLS'; + case TS.UDT: + return 'UDT'; + case TS.AND: + return 'AND'; + case TS.NOT: + return 'NOT'; + case TS.ACTIVE: + return 'ACTIVE'; + case TS.EMPTY: + return 'EMPTY'; + case TS.MATCH: + return 'MATCH'; + case TS.NOMATCH: + return 'NOMATCH'; + case TS.SEM_PRE: + return 'SEM_PRE'; + case TS.SEM_POST: + return 'SEM_POST'; + case TS.SEM_OK: + return 'SEM_OK'; + default: + return 'UNRECOGNIZED STATE'; + } + } + }; + const server_url_template = (s, o, i, u, _) => { + if (s === TS.SEM_PRE) { + if (!1 === Array.isArray(_)) throw new Error("parser's user data must be an array"); + _.push(['server-url-template', MS.charsToString(o, i, u)]); + } + return TS.SEM_OK; + }, + callbacks_server_variable = (s, o, i, u, _) => { + if (s === TS.SEM_PRE) { + if (!1 === Array.isArray(_)) throw new Error("parser's user data must be an array"); + _.push(['server-variable', MS.charsToString(o, i, u)]); + } + return TS.SEM_OK; + }, + server_variable_name = (s, o, i, u, _) => { + if (s === TS.SEM_PRE) { + if (!1 === Array.isArray(_)) throw new Error("parser's user data must be an array"); + _.push(['server-variable-name', MS.charsToString(o, i, u)]); + } + return TS.SEM_OK; + }, + callbacks_literals = (s, o, i, u, _) => { + if (s === TS.SEM_PRE) { + if (!1 === Array.isArray(_)) throw new Error("parser's user data must be an array"); + _.push(['literals', MS.charsToString(o, i, u)]); + } + return TS.SEM_OK; + }, + NS = new (function grammar() { + (this.grammarObject = 'grammarObject'), + (this.rules = []), + (this.rules[0] = { + name: 'server-url-template', + lower: 'server-url-template', + index: 0, + isBkr: !1 + }), + (this.rules[1] = { + name: 'server-variable', + lower: 'server-variable', + index: 1, + isBkr: !1 + }), + (this.rules[2] = { + name: 'server-variable-name', + lower: 'server-variable-name', + index: 2, + isBkr: !1 + }), + (this.rules[3] = { name: 'literals', lower: 'literals', index: 3, isBkr: !1 }), + (this.rules[4] = { name: 'ALPHA', lower: 'alpha', index: 4, isBkr: !1 }), + (this.rules[5] = { name: 'DIGIT', lower: 'digit', index: 5, isBkr: !1 }), + (this.rules[6] = { name: 'HEXDIG', lower: 'hexdig', index: 6, isBkr: !1 }), + (this.rules[7] = { name: 'pct-encoded', lower: 'pct-encoded', index: 7, isBkr: !1 }), + (this.rules[8] = { name: 'unreserved', lower: 'unreserved', index: 8, isBkr: !1 }), + (this.rules[9] = { name: 'sub-delims', lower: 'sub-delims', index: 9, isBkr: !1 }), + (this.rules[10] = { name: 'ucschar', lower: 'ucschar', index: 10, isBkr: !1 }), + (this.rules[11] = { name: 'iprivate', lower: 'iprivate', index: 11, isBkr: !1 }), + (this.udts = []), + (this.rules[0].opcodes = []), + (this.rules[0].opcodes[0] = { type: 3, min: 1, max: 1 / 0 }), + (this.rules[0].opcodes[1] = { type: 1, children: [2, 3] }), + (this.rules[0].opcodes[2] = { type: 4, index: 3 }), + (this.rules[0].opcodes[3] = { type: 4, index: 1 }), + (this.rules[1].opcodes = []), + (this.rules[1].opcodes[0] = { type: 2, children: [1, 2, 3] }), + (this.rules[1].opcodes[1] = { type: 7, string: [123] }), + (this.rules[1].opcodes[2] = { type: 4, index: 2 }), + (this.rules[1].opcodes[3] = { type: 7, string: [125] }), + (this.rules[2].opcodes = []), + (this.rules[2].opcodes[0] = { type: 3, min: 1, max: 1 / 0 }), + (this.rules[2].opcodes[1] = { type: 1, children: [2, 3, 4, 5, 6] }), + (this.rules[2].opcodes[2] = { type: 4, index: 8 }), + (this.rules[2].opcodes[3] = { type: 4, index: 7 }), + (this.rules[2].opcodes[4] = { type: 4, index: 9 }), + (this.rules[2].opcodes[5] = { type: 7, string: [58] }), + (this.rules[2].opcodes[6] = { type: 7, string: [64] }), + (this.rules[3].opcodes = []), + (this.rules[3].opcodes[0] = { type: 3, min: 1, max: 1 / 0 }), + (this.rules[3].opcodes[1] = { + type: 1, + children: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] + }), + (this.rules[3].opcodes[2] = { type: 6, string: [33] }), + (this.rules[3].opcodes[3] = { type: 5, min: 35, max: 36 }), + (this.rules[3].opcodes[4] = { type: 6, string: [38] }), + (this.rules[3].opcodes[5] = { type: 5, min: 40, max: 59 }), + (this.rules[3].opcodes[6] = { type: 6, string: [61] }), + (this.rules[3].opcodes[7] = { type: 5, min: 63, max: 91 }), + (this.rules[3].opcodes[8] = { type: 6, string: [93] }), + (this.rules[3].opcodes[9] = { type: 6, string: [95] }), + (this.rules[3].opcodes[10] = { type: 5, min: 97, max: 122 }), + (this.rules[3].opcodes[11] = { type: 6, string: [126] }), + (this.rules[3].opcodes[12] = { type: 4, index: 10 }), + (this.rules[3].opcodes[13] = { type: 4, index: 11 }), + (this.rules[3].opcodes[14] = { type: 4, index: 7 }), + (this.rules[4].opcodes = []), + (this.rules[4].opcodes[0] = { type: 1, children: [1, 2] }), + (this.rules[4].opcodes[1] = { type: 5, min: 65, max: 90 }), + (this.rules[4].opcodes[2] = { type: 5, min: 97, max: 122 }), + (this.rules[5].opcodes = []), + (this.rules[5].opcodes[0] = { type: 5, min: 48, max: 57 }), + (this.rules[6].opcodes = []), + (this.rules[6].opcodes[0] = { type: 1, children: [1, 2, 3, 4, 5, 6, 7] }), + (this.rules[6].opcodes[1] = { type: 4, index: 5 }), + (this.rules[6].opcodes[2] = { type: 7, string: [97] }), + (this.rules[6].opcodes[3] = { type: 7, string: [98] }), + (this.rules[6].opcodes[4] = { type: 7, string: [99] }), + (this.rules[6].opcodes[5] = { type: 7, string: [100] }), + (this.rules[6].opcodes[6] = { type: 7, string: [101] }), + (this.rules[6].opcodes[7] = { type: 7, string: [102] }), + (this.rules[7].opcodes = []), + (this.rules[7].opcodes[0] = { type: 2, children: [1, 2, 3] }), + (this.rules[7].opcodes[1] = { type: 7, string: [37] }), + (this.rules[7].opcodes[2] = { type: 4, index: 6 }), + (this.rules[7].opcodes[3] = { type: 4, index: 6 }), + (this.rules[8].opcodes = []), + (this.rules[8].opcodes[0] = { type: 1, children: [1, 2, 3, 4, 5, 6] }), + (this.rules[8].opcodes[1] = { type: 4, index: 4 }), + (this.rules[8].opcodes[2] = { type: 4, index: 5 }), + (this.rules[8].opcodes[3] = { type: 7, string: [45] }), + (this.rules[8].opcodes[4] = { type: 7, string: [46] }), + (this.rules[8].opcodes[5] = { type: 7, string: [95] }), + (this.rules[8].opcodes[6] = { type: 7, string: [126] }), + (this.rules[9].opcodes = []), + (this.rules[9].opcodes[0] = { + type: 1, + children: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] + }), + (this.rules[9].opcodes[1] = { type: 7, string: [33] }), + (this.rules[9].opcodes[2] = { type: 7, string: [36] }), + (this.rules[9].opcodes[3] = { type: 7, string: [38] }), + (this.rules[9].opcodes[4] = { type: 7, string: [39] }), + (this.rules[9].opcodes[5] = { type: 7, string: [40] }), + (this.rules[9].opcodes[6] = { type: 7, string: [41] }), + (this.rules[9].opcodes[7] = { type: 7, string: [42] }), + (this.rules[9].opcodes[8] = { type: 7, string: [43] }), + (this.rules[9].opcodes[9] = { type: 7, string: [44] }), + (this.rules[9].opcodes[10] = { type: 7, string: [59] }), + (this.rules[9].opcodes[11] = { type: 7, string: [61] }), + (this.rules[10].opcodes = []), + (this.rules[10].opcodes[0] = { + type: 1, + children: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17] + }), + (this.rules[10].opcodes[1] = { type: 5, min: 160, max: 55295 }), + (this.rules[10].opcodes[2] = { type: 5, min: 63744, max: 64975 }), + (this.rules[10].opcodes[3] = { type: 5, min: 65008, max: 65519 }), + (this.rules[10].opcodes[4] = { type: 5, min: 65536, max: 131069 }), + (this.rules[10].opcodes[5] = { type: 5, min: 131072, max: 196605 }), + (this.rules[10].opcodes[6] = { type: 5, min: 196608, max: 262141 }), + (this.rules[10].opcodes[7] = { type: 5, min: 262144, max: 327677 }), + (this.rules[10].opcodes[8] = { type: 5, min: 327680, max: 393213 }), + (this.rules[10].opcodes[9] = { type: 5, min: 393216, max: 458749 }), + (this.rules[10].opcodes[10] = { type: 5, min: 458752, max: 524285 }), + (this.rules[10].opcodes[11] = { type: 5, min: 524288, max: 589821 }), + (this.rules[10].opcodes[12] = { type: 5, min: 589824, max: 655357 }), + (this.rules[10].opcodes[13] = { type: 5, min: 655360, max: 720893 }), + (this.rules[10].opcodes[14] = { type: 5, min: 720896, max: 786429 }), + (this.rules[10].opcodes[15] = { type: 5, min: 786432, max: 851965 }), + (this.rules[10].opcodes[16] = { type: 5, min: 851968, max: 917501 }), + (this.rules[10].opcodes[17] = { type: 5, min: 921600, max: 983037 }), + (this.rules[11].opcodes = []), + (this.rules[11].opcodes[0] = { type: 1, children: [1, 2, 3] }), + (this.rules[11].opcodes[1] = { type: 5, min: 57344, max: 63743 }), + (this.rules[11].opcodes[2] = { type: 5, min: 983040, max: 1048573 }), + (this.rules[11].opcodes[3] = { type: 5, min: 1048576, max: 1114109 }), + (this.toString = function toString() { + let s = ''; + return ( + (s += '; OpenAPI Server URL templating ABNF syntax\n'), + (s += 'server-url-template = 1*( literals / server-variable )\n'), + (s += 'server-variable = "{" server-variable-name "}"\n'), + (s += + 'server-variable-name = 1*( unreserved / pct-encoded / sub-delims / ":" / "@" )\n'), + (s += + 'literals = 1*( %x21 / %x23-24 / %x26 / %x28-3B / %x3D / %x3F-5B\n'), + (s += + ' / %x5D / %x5F / %x61-7A / %x7E / ucschar / iprivate\n'), + (s += ' / pct-encoded)\n'), + (s += ' ; any Unicode character except: CTL, SP,\n'), + (s += + ' ; DQUOTE, "\'", "%" (aside from pct-encoded),\n'), + (s += ' ; "<", ">", "\\", "^", "`", "{", "|", "}"\n'), + (s += '\n'), + (s += '; Characters definitions (from RFC 6570)\n'), + (s += 'ALPHA = %x41-5A / %x61-7A ; A-Z / a-z\n'), + (s += 'DIGIT = %x30-39 ; 0-9\n'), + (s += 'HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"\n'), + (s += ' ; case-insensitive\n'), + (s += '\n'), + (s += 'pct-encoded = "%" HEXDIG HEXDIG\n'), + (s += 'unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"\n'), + (s += 'sub-delims = "!" / "$" / "&" / "\'" / "(" / ")"\n'), + (s += ' / "*" / "+" / "," / ";" / "="\n'), + (s += '\n'), + (s += 'ucschar = %xA0-D7FF / %xF900-FDCF / %xFDF0-FFEF\n'), + (s += ' / %x10000-1FFFD / %x20000-2FFFD / %x30000-3FFFD\n'), + (s += ' / %x40000-4FFFD / %x50000-5FFFD / %x60000-6FFFD\n'), + (s += ' / %x70000-7FFFD / %x80000-8FFFD / %x90000-9FFFD\n'), + (s += ' / %xA0000-AFFFD / %xB0000-BFFFD / %xC0000-CFFFD\n'), + (s += ' / %xD0000-DFFFD / %xE1000-EFFFD\n'), + (s += '\n'), + (s += 'iprivate = %xE000-F8FF / %xF0000-FFFFD / %x100000-10FFFD\n'), + '; OpenAPI Server URL templating ABNF syntax\nserver-url-template = 1*( literals / server-variable )\nserver-variable = "{" server-variable-name "}"\nserver-variable-name = 1*( unreserved / pct-encoded / sub-delims / ":" / "@" )\nliterals = 1*( %x21 / %x23-24 / %x26 / %x28-3B / %x3D / %x3F-5B\n / %x5D / %x5F / %x61-7A / %x7E / ucschar / iprivate\n / pct-encoded)\n ; any Unicode character except: CTL, SP,\n ; DQUOTE, "\'", "%" (aside from pct-encoded),\n ; "<", ">", "\\", "^", "`", "{", "|", "}"\n\n; Characters definitions (from RFC 6570)\nALPHA = %x41-5A / %x61-7A ; A-Z / a-z\nDIGIT = %x30-39 ; 0-9\nHEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"\n ; case-insensitive\n\npct-encoded = "%" HEXDIG HEXDIG\nunreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"\nsub-delims = "!" / "$" / "&" / "\'" / "(" / ")"\n / "*" / "+" / "," / ";" / "="\n\nucschar = %xA0-D7FF / %xF900-FDCF / %xFDF0-FFEF\n / %x10000-1FFFD / %x20000-2FFFD / %x30000-3FFFD\n / %x40000-4FFFD / %x50000-5FFFD / %x60000-6FFFD\n / %x70000-7FFFD / %x80000-8FFFD / %x90000-9FFFD\n / %xA0000-AFFFD / %xB0000-BFFFD / %xC0000-CFFFD\n / %xD0000-DFFFD / %xE1000-EFFFD\n\niprivate = %xE000-F8FF / %xF0000-FFFFD / %x100000-10FFFD\n' + ); + }); + })(), + openapi_server_url_templating_es_parse = (s) => { + const o = new IS(); + (o.ast = new PS()), + (o.ast.callbacks['server-url-template'] = server_url_template), + (o.ast.callbacks['server-variable'] = callbacks_server_variable), + (o.ast.callbacks['server-variable-name'] = server_variable_name), + (o.ast.callbacks.literals = callbacks_literals); + return { result: o.parse(NS, 'server-url-template', s), ast: o.ast }; + }, + openapi_server_url_templating_es_test = (s, { strict: o = !1 } = {}) => { + try { + const i = openapi_server_url_templating_es_parse(s); + if (!i.result.success) return !1; + const u = []; + i.ast.translate(u); + const _ = u.some(([s]) => 'server-variable' === s); + if (!o && !_) + try { + return new URL(s, 'https://vladimirgorej.com'), !0; + } catch { + return !1; + } + return !o || _; + } catch { + return !1; + } + }, + encodeServerVariable = (s) => + ((s) => { + try { + return 'string' == typeof s && decodeURIComponent(s) !== s; + } catch { + return !1; + } + })(s) + ? s + : encodeURIComponent(s).replace(/%5B/g, '[').replace(/%5D/g, ']'), + RS = ['literals', 'server-variable-name'], + es_substitute = (s, o, i = {}) => { + const u = { ...{ encoder: encodeServerVariable }, ...i }, + _ = openapi_server_url_templating_es_parse(s); + if (!_.result.success) return s; + const w = []; + _.ast.translate(w); + const x = w + .filter(([s]) => RS.includes(s)) + .map(([s, i]) => + 'server-variable-name' === s + ? Object.hasOwn(o, i) + ? u.encoder(o[i], i) + : `{${i}}` + : i + ); + return x.join(''); + }; + const callbacks_slash = (s, o, i, u, _) => ( + s === TS.SEM_PRE ? _.push(['slash', MS.charsToString(o, i, u)]) : TS.SEM_POST, TS.SEM_OK + ), + path_template = (s, o, i, u, _) => { + if (s === TS.SEM_PRE) { + if (!1 === Array.isArray(_)) throw new Error("parser's user data must be an array"); + _.push(['path-template', MS.charsToString(o, i, u)]); + } + return TS.SEM_OK; + }, + callbacks_path = (s, o, i, u, _) => ( + s === TS.SEM_PRE ? _.push(['path', MS.charsToString(o, i, u)]) : TS.SEM_POST, TS.SEM_OK + ), + path_literal = (s, o, i, u, _) => ( + s === TS.SEM_PRE ? _.push(['path-literal', MS.charsToString(o, i, u)]) : TS.SEM_POST, + TS.SEM_OK + ), + callbacks_query = (s, o, i, u, _) => ( + s === TS.SEM_PRE ? _.push(['query', MS.charsToString(o, i, u)]) : TS.SEM_POST, TS.SEM_OK + ), + query_marker = (s, o, i, u, _) => ( + s === TS.SEM_PRE ? _.push(['query-marker', MS.charsToString(o, i, u)]) : TS.SEM_POST, + TS.SEM_OK + ), + callbacks_fragment = (s, o, i, u, _) => ( + s === TS.SEM_PRE ? _.push(['fragment', MS.charsToString(o, i, u)]) : TS.SEM_POST, + TS.SEM_OK + ), + fragment_marker = (s, o, i, u, _) => ( + s === TS.SEM_PRE ? _.push(['fragment-marker', MS.charsToString(o, i, u)]) : TS.SEM_POST, + TS.SEM_OK + ), + template_expression = (s, o, i, u, _) => ( + s === TS.SEM_PRE + ? _.push(['template-expression', MS.charsToString(o, i, u)]) + : TS.SEM_POST, + TS.SEM_OK + ), + template_expression_param_name = (s, o, i, u, _) => ( + s === TS.SEM_PRE + ? _.push(['template-expression-param-name', MS.charsToString(o, i, u)]) + : TS.SEM_POST, + TS.SEM_OK + ), + DS = new (function path_templating_grammar() { + (this.grammarObject = 'grammarObject'), + (this.rules = []), + (this.rules[0] = { + name: 'path-template', + lower: 'path-template', + index: 0, + isBkr: !1 + }), + (this.rules[1] = { name: 'path', lower: 'path', index: 1, isBkr: !1 }), + (this.rules[2] = { + name: 'path-segment', + lower: 'path-segment', + index: 2, + isBkr: !1 + }), + (this.rules[3] = { name: 'query', lower: 'query', index: 3, isBkr: !1 }), + (this.rules[4] = { + name: 'query-literal', + lower: 'query-literal', + index: 4, + isBkr: !1 + }), + (this.rules[5] = { + name: 'query-marker', + lower: 'query-marker', + index: 5, + isBkr: !1 + }), + (this.rules[6] = { name: 'fragment', lower: 'fragment', index: 6, isBkr: !1 }), + (this.rules[7] = { + name: 'fragment-literal', + lower: 'fragment-literal', + index: 7, + isBkr: !1 + }), + (this.rules[8] = { + name: 'fragment-marker', + lower: 'fragment-marker', + index: 8, + isBkr: !1 + }), + (this.rules[9] = { name: 'slash', lower: 'slash', index: 9, isBkr: !1 }), + (this.rules[10] = { + name: 'path-literal', + lower: 'path-literal', + index: 10, + isBkr: !1 + }), + (this.rules[11] = { + name: 'template-expression', + lower: 'template-expression', + index: 11, + isBkr: !1 + }), + (this.rules[12] = { + name: 'template-expression-param-name', + lower: 'template-expression-param-name', + index: 12, + isBkr: !1 + }), + (this.rules[13] = { name: 'unreserved', lower: 'unreserved', index: 13, isBkr: !1 }), + (this.rules[14] = { + name: 'pct-encoded', + lower: 'pct-encoded', + index: 14, + isBkr: !1 + }), + (this.rules[15] = { name: 'sub-delims', lower: 'sub-delims', index: 15, isBkr: !1 }), + (this.rules[16] = { name: 'ALPHA', lower: 'alpha', index: 16, isBkr: !1 }), + (this.rules[17] = { name: 'DIGIT', lower: 'digit', index: 17, isBkr: !1 }), + (this.rules[18] = { name: 'HEXDIG', lower: 'hexdig', index: 18, isBkr: !1 }), + (this.udts = []), + (this.rules[0].opcodes = []), + (this.rules[0].opcodes[0] = { type: 2, children: [1, 2, 6] }), + (this.rules[0].opcodes[1] = { type: 4, index: 1 }), + (this.rules[0].opcodes[2] = { type: 3, min: 0, max: 1 }), + (this.rules[0].opcodes[3] = { type: 2, children: [4, 5] }), + (this.rules[0].opcodes[4] = { type: 4, index: 5 }), + (this.rules[0].opcodes[5] = { type: 4, index: 3 }), + (this.rules[0].opcodes[6] = { type: 3, min: 0, max: 1 }), + (this.rules[0].opcodes[7] = { type: 2, children: [8, 9] }), + (this.rules[0].opcodes[8] = { type: 4, index: 8 }), + (this.rules[0].opcodes[9] = { type: 4, index: 6 }), + (this.rules[1].opcodes = []), + (this.rules[1].opcodes[0] = { type: 2, children: [1, 2, 6] }), + (this.rules[1].opcodes[1] = { type: 4, index: 9 }), + (this.rules[1].opcodes[2] = { type: 3, min: 0, max: 1 / 0 }), + (this.rules[1].opcodes[3] = { type: 2, children: [4, 5] }), + (this.rules[1].opcodes[4] = { type: 4, index: 2 }), + (this.rules[1].opcodes[5] = { type: 4, index: 9 }), + (this.rules[1].opcodes[6] = { type: 3, min: 0, max: 1 }), + (this.rules[1].opcodes[7] = { type: 4, index: 2 }), + (this.rules[2].opcodes = []), + (this.rules[2].opcodes[0] = { type: 3, min: 1, max: 1 / 0 }), + (this.rules[2].opcodes[1] = { type: 1, children: [2, 3] }), + (this.rules[2].opcodes[2] = { type: 4, index: 10 }), + (this.rules[2].opcodes[3] = { type: 4, index: 11 }), + (this.rules[3].opcodes = []), + (this.rules[3].opcodes[0] = { type: 3, min: 0, max: 1 / 0 }), + (this.rules[3].opcodes[1] = { type: 4, index: 4 }), + (this.rules[4].opcodes = []), + (this.rules[4].opcodes[0] = { type: 3, min: 1, max: 1 / 0 }), + (this.rules[4].opcodes[1] = { type: 1, children: [2, 3, 4, 5, 6, 7, 8, 9, 10] }), + (this.rules[4].opcodes[2] = { type: 4, index: 13 }), + (this.rules[4].opcodes[3] = { type: 4, index: 14 }), + (this.rules[4].opcodes[4] = { type: 4, index: 15 }), + (this.rules[4].opcodes[5] = { type: 7, string: [58] }), + (this.rules[4].opcodes[6] = { type: 7, string: [64] }), + (this.rules[4].opcodes[7] = { type: 7, string: [47] }), + (this.rules[4].opcodes[8] = { type: 7, string: [63] }), + (this.rules[4].opcodes[9] = { type: 7, string: [38] }), + (this.rules[4].opcodes[10] = { type: 7, string: [61] }), + (this.rules[5].opcodes = []), + (this.rules[5].opcodes[0] = { type: 7, string: [63] }), + (this.rules[6].opcodes = []), + (this.rules[6].opcodes[0] = { type: 3, min: 0, max: 1 / 0 }), + (this.rules[6].opcodes[1] = { type: 4, index: 7 }), + (this.rules[7].opcodes = []), + (this.rules[7].opcodes[0] = { type: 3, min: 1, max: 1 / 0 }), + (this.rules[7].opcodes[1] = { type: 1, children: [2, 3, 4, 5, 6, 7, 8] }), + (this.rules[7].opcodes[2] = { type: 4, index: 13 }), + (this.rules[7].opcodes[3] = { type: 4, index: 14 }), + (this.rules[7].opcodes[4] = { type: 4, index: 15 }), + (this.rules[7].opcodes[5] = { type: 7, string: [58] }), + (this.rules[7].opcodes[6] = { type: 7, string: [64] }), + (this.rules[7].opcodes[7] = { type: 7, string: [47] }), + (this.rules[7].opcodes[8] = { type: 7, string: [63] }), + (this.rules[8].opcodes = []), + (this.rules[8].opcodes[0] = { type: 7, string: [35] }), + (this.rules[9].opcodes = []), + (this.rules[9].opcodes[0] = { type: 7, string: [47] }), + (this.rules[10].opcodes = []), + (this.rules[10].opcodes[0] = { type: 3, min: 1, max: 1 / 0 }), + (this.rules[10].opcodes[1] = { type: 1, children: [2, 3, 4, 5, 6] }), + (this.rules[10].opcodes[2] = { type: 4, index: 13 }), + (this.rules[10].opcodes[3] = { type: 4, index: 14 }), + (this.rules[10].opcodes[4] = { type: 4, index: 15 }), + (this.rules[10].opcodes[5] = { type: 7, string: [58] }), + (this.rules[10].opcodes[6] = { type: 7, string: [64] }), + (this.rules[11].opcodes = []), + (this.rules[11].opcodes[0] = { type: 2, children: [1, 2, 3] }), + (this.rules[11].opcodes[1] = { type: 7, string: [123] }), + (this.rules[11].opcodes[2] = { type: 4, index: 12 }), + (this.rules[11].opcodes[3] = { type: 7, string: [125] }), + (this.rules[12].opcodes = []), + (this.rules[12].opcodes[0] = { type: 3, min: 1, max: 1 / 0 }), + (this.rules[12].opcodes[1] = { type: 1, children: [2, 3, 4, 5, 6] }), + (this.rules[12].opcodes[2] = { type: 4, index: 13 }), + (this.rules[12].opcodes[3] = { type: 4, index: 14 }), + (this.rules[12].opcodes[4] = { type: 4, index: 15 }), + (this.rules[12].opcodes[5] = { type: 7, string: [58] }), + (this.rules[12].opcodes[6] = { type: 7, string: [64] }), + (this.rules[13].opcodes = []), + (this.rules[13].opcodes[0] = { type: 1, children: [1, 2, 3, 4, 5, 6] }), + (this.rules[13].opcodes[1] = { type: 4, index: 16 }), + (this.rules[13].opcodes[2] = { type: 4, index: 17 }), + (this.rules[13].opcodes[3] = { type: 7, string: [45] }), + (this.rules[13].opcodes[4] = { type: 7, string: [46] }), + (this.rules[13].opcodes[5] = { type: 7, string: [95] }), + (this.rules[13].opcodes[6] = { type: 7, string: [126] }), + (this.rules[14].opcodes = []), + (this.rules[14].opcodes[0] = { type: 2, children: [1, 2, 3] }), + (this.rules[14].opcodes[1] = { type: 7, string: [37] }), + (this.rules[14].opcodes[2] = { type: 4, index: 18 }), + (this.rules[14].opcodes[3] = { type: 4, index: 18 }), + (this.rules[15].opcodes = []), + (this.rules[15].opcodes[0] = { + type: 1, + children: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] + }), + (this.rules[15].opcodes[1] = { type: 7, string: [33] }), + (this.rules[15].opcodes[2] = { type: 7, string: [36] }), + (this.rules[15].opcodes[3] = { type: 7, string: [38] }), + (this.rules[15].opcodes[4] = { type: 7, string: [39] }), + (this.rules[15].opcodes[5] = { type: 7, string: [40] }), + (this.rules[15].opcodes[6] = { type: 7, string: [41] }), + (this.rules[15].opcodes[7] = { type: 7, string: [42] }), + (this.rules[15].opcodes[8] = { type: 7, string: [43] }), + (this.rules[15].opcodes[9] = { type: 7, string: [44] }), + (this.rules[15].opcodes[10] = { type: 7, string: [59] }), + (this.rules[15].opcodes[11] = { type: 7, string: [61] }), + (this.rules[16].opcodes = []), + (this.rules[16].opcodes[0] = { type: 1, children: [1, 2] }), + (this.rules[16].opcodes[1] = { type: 5, min: 65, max: 90 }), + (this.rules[16].opcodes[2] = { type: 5, min: 97, max: 122 }), + (this.rules[17].opcodes = []), + (this.rules[17].opcodes[0] = { type: 5, min: 48, max: 57 }), + (this.rules[18].opcodes = []), + (this.rules[18].opcodes[0] = { type: 1, children: [1, 2, 3, 4, 5, 6, 7] }), + (this.rules[18].opcodes[1] = { type: 4, index: 17 }), + (this.rules[18].opcodes[2] = { type: 7, string: [97] }), + (this.rules[18].opcodes[3] = { type: 7, string: [98] }), + (this.rules[18].opcodes[4] = { type: 7, string: [99] }), + (this.rules[18].opcodes[5] = { type: 7, string: [100] }), + (this.rules[18].opcodes[6] = { type: 7, string: [101] }), + (this.rules[18].opcodes[7] = { type: 7, string: [102] }), + (this.toString = function toString() { + let s = ''; + return ( + (s += '; OpenAPI Path Templating ABNF syntax\n'), + (s += + 'path-template = path [ query-marker query ] [ fragment-marker fragment ]\n'), + (s += + 'path = slash *( path-segment slash ) [ path-segment ]\n'), + (s += + 'path-segment = 1*( path-literal / template-expression )\n'), + (s += 'query = *( query-literal )\n'), + (s += + 'query-literal = 1*( unreserved / pct-encoded / sub-delims / ":" / "@" / "/" / "?" / "&" / "=" )\n'), + (s += 'query-marker = "?"\n'), + (s += 'fragment = *( fragment-literal )\n'), + (s += + 'fragment-literal = 1*( unreserved / pct-encoded / sub-delims / ":" / "@" / "/" / "?" )\n'), + (s += 'fragment-marker = "#"\n'), + (s += 'slash = "/"\n'), + (s += + 'path-literal = 1*( unreserved / pct-encoded / sub-delims / ":" / "@" )\n'), + (s += + 'template-expression = "{" template-expression-param-name "}"\n'), + (s += + 'template-expression-param-name = 1*( unreserved / pct-encoded / sub-delims / ":" / "@" )\n'), + (s += '\n'), + (s += '; Characters definitions (from RFC 3986)\n'), + (s += 'unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"\n'), + (s += 'pct-encoded = "%" HEXDIG HEXDIG\n'), + (s += 'sub-delims = "!" / "$" / "&" / "\'" / "(" / ")"\n'), + (s += ' / "*" / "+" / "," / ";" / "="\n'), + (s += 'ALPHA = %x41-5A / %x61-7A ; A-Z / a-z\n'), + (s += 'DIGIT = %x30-39 ; 0-9\n'), + (s += 'HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"\n'), + '; OpenAPI Path Templating ABNF syntax\npath-template = path [ query-marker query ] [ fragment-marker fragment ]\npath = slash *( path-segment slash ) [ path-segment ]\npath-segment = 1*( path-literal / template-expression )\nquery = *( query-literal )\nquery-literal = 1*( unreserved / pct-encoded / sub-delims / ":" / "@" / "/" / "?" / "&" / "=" )\nquery-marker = "?"\nfragment = *( fragment-literal )\nfragment-literal = 1*( unreserved / pct-encoded / sub-delims / ":" / "@" / "/" / "?" )\nfragment-marker = "#"\nslash = "/"\npath-literal = 1*( unreserved / pct-encoded / sub-delims / ":" / "@" )\ntemplate-expression = "{" template-expression-param-name "}"\ntemplate-expression-param-name = 1*( unreserved / pct-encoded / sub-delims / ":" / "@" )\n\n; Characters definitions (from RFC 3986)\nunreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"\npct-encoded = "%" HEXDIG HEXDIG\nsub-delims = "!" / "$" / "&" / "\'" / "(" / ")"\n / "*" / "+" / "," / ";" / "="\nALPHA = %x41-5A / %x61-7A ; A-Z / a-z\nDIGIT = %x30-39 ; 0-9\nHEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"\n' + ); + }); + })(), + openapi_path_templating_es_parse = (s) => { + const o = new IS(); + (o.ast = new PS()), + (o.ast.callbacks['path-template'] = path_template), + (o.ast.callbacks.path = callbacks_path), + (o.ast.callbacks.query = callbacks_query), + (o.ast.callbacks['query-marker'] = query_marker), + (o.ast.callbacks.fragment = callbacks_fragment), + (o.ast.callbacks['fragment-marker'] = fragment_marker), + (o.ast.callbacks.slash = callbacks_slash), + (o.ast.callbacks['path-literal'] = path_literal), + (o.ast.callbacks['template-expression'] = template_expression), + (o.ast.callbacks['template-expression-param-name'] = template_expression_param_name); + return { result: o.parse(DS, 'path-template', s), ast: o.ast }; + }, + encodePathComponent = (s) => + ((s) => { + try { + return 'string' == typeof s && decodeURIComponent(s) !== s; + } catch { + return !1; + } + })(s) + ? s + : encodeURIComponent(s).replace(/%5B/g, '[').replace(/%5D/g, ']'), + LS = [ + 'slash', + 'path-literal', + 'query-marker', + 'query-literal', + 'template-expression-param-name' + ], + openapi_path_templating_es_resolve = (s, o, i = {}) => { + const u = { ...{ encoder: encodePathComponent }, ...i }, + _ = openapi_path_templating_es_parse(s); + if (!_.result.success) return s; + const w = []; + _.ast.translate(w); + const x = w + .filter(([s]) => LS.includes(s)) + .map(([s, i]) => + 'template-expression-param-name' === s + ? Object.hasOwn(o, i) + ? u.encoder(o[i], i) + : `{${i}}` + : i + ); + return x.join(''); + }, + BS = { + body: function bodyBuilder({ req: s, value: o }) { + void 0 !== o && (s.body = o); + }, + header: function headerBuilder({ req: s, parameter: o, value: i }) { + (s.headers = s.headers || {}), void 0 !== i && (s.headers[o.name] = i); + }, + query: function queryBuilder({ req: s, value: o, parameter: i }) { + (s.query = s.query || {}), !1 === o && 'boolean' === i.type && (o = 'false'); + 0 === o && ['number', 'integer'].indexOf(i.type) > -1 && (o = '0'); + if (o) s.query[i.name] = { collectionFormat: i.collectionFormat, value: o }; + else if (i.allowEmptyValue && void 0 !== o) { + const o = i.name; + (s.query[o] = s.query[o] || {}), (s.query[o].allowEmptyValue = !0); + } + }, + path: function pathBuilder({ req: s, value: o, parameter: i, baseURL: u }) { + if (void 0 !== o) { + const _ = s.url.replace(u, ''), + w = openapi_path_templating_es_resolve(_, { [i.name]: o }); + s.url = u + w; + } + }, + formData: function formDataBuilder({ req: s, value: o, parameter: i }) { + !1 === o && 'boolean' === i.type && (o = 'false'); + 0 === o && ['number', 'integer'].indexOf(i.type) > -1 && (o = '0'); + if (o) + (s.form = s.form || {}), + (s.form[i.name] = { collectionFormat: i.collectionFormat, value: o }); + else if (i.allowEmptyValue && void 0 !== o) { + s.form = s.form || {}; + const o = i.name; + (s.form[o] = s.form[o] || {}), (s.form[o].allowEmptyValue = !0); + } + } + }; + function serialize(s, o) { + return o.includes('application/json') + ? 'string' == typeof s + ? s + : (Array.isArray(s) && + (s = s.map((s) => { + try { + return JSON.parse(s); + } catch (o) { + return s; + } + })), + JSON.stringify(s)) + : String(s); + } + function parameter_builders_path({ req: s, value: o, parameter: i, baseURL: u }) { + const { name: _, style: w, explode: x, content: C } = i; + if (void 0 === o) return; + const j = s.url.replace(u, ''); + let L; + if (C) { + const s = Object.keys(C)[0]; + L = openapi_path_templating_es_resolve( + j, + { [_]: o }, + { encoder: (o) => encodeCharacters(serialize(o, s)) } + ); + } else + L = openapi_path_templating_es_resolve( + j, + { [_]: o }, + { + encoder: (s) => + stylize({ + key: i.name, + value: s, + style: w || 'simple', + explode: x || !1, + escape: 'reserved' + }) + } + ); + s.url = u + L; + } + function parameter_builders_query({ req: s, value: o, parameter: i }) { + if (((s.query = s.query || {}), void 0 !== o && i.content)) { + const u = serialize(o, Object.keys(i.content)[0]); + if (u) s.query[i.name] = u; + else if (i.allowEmptyValue) { + const o = i.name; + (s.query[o] = s.query[o] || {}), (s.query[o].allowEmptyValue = !0); + } + } else if ((!1 === o && (o = 'false'), 0 === o && (o = '0'), o)) { + const { style: u, explode: _, allowReserved: w } = i; + s.query[i.name] = { + value: o, + serializationOption: { style: u, explode: _, allowReserved: w } + }; + } else if (i.allowEmptyValue && void 0 !== o) { + const o = i.name; + (s.query[o] = s.query[o] || {}), (s.query[o].allowEmptyValue = !0); + } + } + const FS = ['accept', 'authorization', 'content-type']; + function parameter_builders_header({ req: s, parameter: o, value: i }) { + if (((s.headers = s.headers || {}), !(FS.indexOf(o.name.toLowerCase()) > -1))) + if (void 0 !== i && o.content) { + const u = Object.keys(o.content)[0]; + s.headers[o.name] = serialize(i, u); + } else + void 0 === i || + (Array.isArray(i) && 0 === i.length) || + (s.headers[o.name] = stylize({ + key: o.name, + value: i, + style: o.style || 'simple', + explode: void 0 !== o.explode && o.explode, + escape: !1 + })); + } + function parameter_builders_cookie({ req: s, parameter: o, value: i }) { + s.headers = s.headers || {}; + const u = typeof i; + if (void 0 !== i && o.content) { + const u = Object.keys(o.content)[0]; + s.headers.Cookie = `${o.name}=${serialize(i, u)}`; + } else if (void 0 !== i && (!Array.isArray(i) || 0 !== i.length)) { + const _ = 'object' === u && !Array.isArray(i) && o.explode ? '' : `${o.name}=`; + s.headers.Cookie = + _ + + stylize({ + key: o.name, + value: i, + escape: !1, + style: o.style || 'form', + explode: void 0 !== o.explode && o.explode + }); + } + } + const qS = + 'undefined' != typeof globalThis + ? globalThis + : 'undefined' != typeof self + ? self + : window, + { btoa: $S } = qS, + VS = $S; + function buildRequest(s, o) { + const { + operation: i, + requestBody: u, + securities: _, + spec: w, + attachContentTypeForEmptyPayload: x + } = s; + let { requestContentType: C } = s; + o = (function applySecurities({ + request: s, + securities: o = {}, + operation: i = {}, + spec: u + }) { + var _; + const w = { ...s }, + { authorized: x = {} } = o, + C = i.security || u.security || [], + j = x && !!Object.keys(x).length, + L = + (null == u || null === (_ = u.components) || void 0 === _ + ? void 0 + : _.securitySchemes) || {}; + if ( + ((w.headers = w.headers || {}), + (w.query = w.query || {}), + !Object.keys(o).length || + !j || + !C || + (Array.isArray(i.security) && !i.security.length)) + ) + return s; + return ( + C.forEach((s) => { + Object.keys(s).forEach((s) => { + const o = x[s], + i = L[s]; + if (!o) return; + const u = o.value || o, + { type: _ } = i; + if (o) + if ('apiKey' === _) + 'query' === i.in && (w.query[i.name] = u), + 'header' === i.in && (w.headers[i.name] = u), + 'cookie' === i.in && (w.cookies[i.name] = u); + else if ('http' === _) { + if (/^basic$/i.test(i.scheme)) { + const s = u.username || '', + o = u.password || '', + i = VS(`${s}:${o}`); + w.headers.Authorization = `Basic ${i}`; + } + /^bearer$/i.test(i.scheme) && (w.headers.Authorization = `Bearer ${u}`); + } else if ('oauth2' === _ || 'openIdConnect' === _) { + const s = o.token || {}, + u = s[i['x-tokenName'] || 'access_token']; + let _ = s.token_type; + (_ && 'bearer' !== _.toLowerCase()) || (_ = 'Bearer'), + (w.headers.Authorization = `${_} ${u}`); + } + }); + }), + w + ); + })({ request: o, securities: _, operation: i, spec: w }); + const j = i.requestBody || {}, + L = Object.keys(j.content || {}), + B = C && L.indexOf(C) > -1; + if (u || x) { + if (C && B) o.headers['Content-Type'] = C; + else if (!C) { + const s = L[0]; + s && ((o.headers['Content-Type'] = s), (C = s)); + } + } else C && B && (o.headers['Content-Type'] = C); + if (!s.responseContentType && i.responses) { + const s = Object.entries(i.responses) + .filter(([s, o]) => { + const i = parseInt(s, 10); + return i >= 200 && i < 300 && ku(o.content); + }) + .reduce((s, [, o]) => s.concat(Object.keys(o.content)), []); + s.length > 0 && (o.headers.accept = s.join(', ')); + } + if (u) + if (C) { + if (L.indexOf(C) > -1) + if ('application/x-www-form-urlencoded' === C || 'multipart/form-data' === C) + if ('object' == typeof u) { + var $, V; + const s = + null !== + ($ = null === (V = j.content[C]) || void 0 === V ? void 0 : V.encoding) && + void 0 !== $ + ? $ + : {}; + (o.form = {}), + Object.keys(u).forEach((i) => { + let _; + try { + _ = JSON.parse(u[i]); + } catch { + _ = u[i]; + } + o.form[i] = { value: _, encoding: s[i] || {} }; + }); + } else if ('string' == typeof u) { + var U, z; + const s = + null !== + (U = null === (z = j.content[C]) || void 0 === z ? void 0 : z.encoding) && + void 0 !== U + ? U + : {}; + try { + o.form = {}; + const i = JSON.parse(u); + Object.entries(i).forEach(([i, u]) => { + o.form[i] = { value: u, encoding: s[i] || {} }; + }); + } catch { + o.form = u; + } + } else o.form = u; + else o.body = u; + } else o.body = u; + return o; + } + function build_request_buildRequest(s, o) { + const { + spec: i, + operation: u, + securities: _, + requestContentType: w, + responseContentType: x, + attachContentTypeForEmptyPayload: C + } = s; + if ( + ((o = (function build_request_applySecurities({ + request: s, + securities: o = {}, + operation: i = {}, + spec: u + }) { + const _ = { ...s }, + { authorized: w = {}, specSecurity: x = [] } = o, + C = i.security || x, + j = w && !!Object.keys(w).length, + L = u.securityDefinitions; + if ( + ((_.headers = _.headers || {}), + (_.query = _.query || {}), + !Object.keys(o).length || + !j || + !C || + (Array.isArray(i.security) && !i.security.length)) + ) + return s; + return ( + C.forEach((s) => { + Object.keys(s).forEach((s) => { + const o = w[s]; + if (!o) return; + const { token: i } = o, + u = o.value || o, + x = L[s], + { type: C } = x, + j = x['x-tokenName'] || 'access_token', + B = i && i[j]; + let $ = i && i.token_type; + if (o) + if ('apiKey' === C) { + const s = 'query' === x.in ? 'query' : 'headers'; + (_[s] = _[s] || {}), (_[s][x.name] = u); + } else if ('basic' === C) + if (u.header) _.headers.authorization = u.header; + else { + const s = u.username || '', + o = u.password || ''; + (u.base64 = VS(`${s}:${o}`)), + (_.headers.authorization = `Basic ${u.base64}`); + } + else + 'oauth2' === C && + B && + (($ = $ && 'bearer' !== $.toLowerCase() ? $ : 'Bearer'), + (_.headers.authorization = `${$} ${B}`)); + }); + }), + _ + ); + })({ request: o, securities: _, operation: u, spec: i })), + o.body || o.form || C) + ) + w + ? (o.headers['Content-Type'] = w) + : Array.isArray(u.consumes) + ? ([o.headers['Content-Type']] = u.consumes) + : Array.isArray(i.consumes) + ? ([o.headers['Content-Type']] = i.consumes) + : u.parameters && u.parameters.filter((s) => 'file' === s.type).length + ? (o.headers['Content-Type'] = 'multipart/form-data') + : u.parameters && + u.parameters.filter((s) => 'formData' === s.in).length && + (o.headers['Content-Type'] = 'application/x-www-form-urlencoded'); + else if (w) { + const s = u.parameters && u.parameters.filter((s) => 'body' === s.in).length > 0, + i = u.parameters && u.parameters.filter((s) => 'formData' === s.in).length > 0; + (s || i) && (o.headers['Content-Type'] = w); + } + return ( + !x && + Array.isArray(u.produces) && + u.produces.length > 0 && + (o.headers.accept = u.produces.join(', ')), + o + ); + } + function idFromPathMethodLegacy(s, o) { + return `${o.toLowerCase()}-${s}`; + } + const arrayOrEmpty = (s) => (Array.isArray(s) ? s : []), + parseURIReference = (s) => { + try { + return new URL(s); + } catch { + const o = new URL(s, Nc), + i = String(s).startsWith('/') ? o.pathname : o.pathname.substring(1); + return { + hash: o.hash, + host: '', + hostname: '', + href: '', + origin: '', + password: '', + pathname: i, + port: '', + protocol: '', + search: o.search, + searchParams: o.searchParams + }; + } + }; + class OperationNotFoundError extends Jo {} + const US = { buildRequest: execute_buildRequest }; + function execute_execute({ + http: s, + fetch: o, + spec: i, + operationId: u, + pathName: _, + method: w, + parameters: x, + securities: C, + ...j + }) { + const L = s || o || http_http; + _ && w && !u && (u = idFromPathMethodLegacy(_, w)); + const B = US.buildRequest({ + spec: i, + operationId: u, + parameters: x, + securities: C, + http: L, + ...j + }); + return ( + B.body && (ku(B.body) || Array.isArray(B.body)) && (B.body = JSON.stringify(B.body)), + L(B) + ); + } + function execute_buildRequest(s) { + var o; + const { + spec: i, + operationId: u, + responseContentType: _, + scheme: w, + requestInterceptor: x, + responseInterceptor: C, + contextUrl: j, + userFetch: L, + server: B, + serverVariables: $, + http: V, + signal: U, + serverVariableEncoder: z + } = s; + let { parameters: Y, parameterBuilders: Z, baseURL: ee } = s; + const ie = isOpenAPI3(i); + Z || (Z = ie ? fe : BS); + let ae = { + url: '', + credentials: V && V.withCredentials ? 'include' : 'same-origin', + headers: {}, + cookies: {} + }; + U && (ae.signal = U), + x && (ae.requestInterceptor = x), + C && (ae.responseInterceptor = C), + L && (ae.userFetch = L); + const le = (function getOperationRaw(s, o) { + return s && s.paths + ? (function findOperation(s, o) { + return ( + (function eachOperation(s, o, i) { + if (!s || 'object' != typeof s || !s.paths || 'object' != typeof s.paths) + return null; + const { paths: u } = s; + for (const _ in u) + for (const w in u[_]) { + if ('PARAMETERS' === w.toUpperCase()) continue; + const x = u[_][w]; + if (!x || 'object' != typeof x) continue; + const C = { spec: s, pathName: _, method: w.toUpperCase(), operation: x }, + j = o(C); + if (i && j) return C; + } + })(s, o, !0) || null + ); + })(s, ({ pathName: s, method: i, operation: u }) => { + if (!u || 'object' != typeof u) return !1; + const _ = u.operationId; + return [opId(u, s, i), idFromPathMethodLegacy(s, i), _].some((s) => s && s === o); + }) + : null; + })(i, u); + if (!le) throw new OperationNotFoundError(`Operation ${u} not found`); + const { operation: ce = {}, method: pe, pathName: de } = le; + if ( + ((ee = + null !== (o = ee) && void 0 !== o + ? o + : (function baseUrl(s) { + const o = isOpenAPI3(s.spec); + return o + ? (function oas3BaseUrl({ + spec: s, + pathName: o, + method: i, + server: u, + contextUrl: _, + serverVariables: w = {}, + serverVariableEncoder: x + }) { + var C, j; + let L, + B = [], + $ = ''; + const V = + null == s || + null === (C = s.paths) || + void 0 === C || + null === (C = C[o]) || + void 0 === C || + null === (C = C[(i || '').toLowerCase()]) || + void 0 === C + ? void 0 + : C.servers, + U = + null == s || + null === (j = s.paths) || + void 0 === j || + null === (j = j[o]) || + void 0 === j + ? void 0 + : j.servers, + z = null == s ? void 0 : s.servers; + (B = isNonEmptyServerList(V) + ? V + : isNonEmptyServerList(U) + ? U + : isNonEmptyServerList(z) + ? z + : [Rc]), + u && ((L = B.find((s) => s.url === u)), L && ($ = u)); + $ || (([L] = B), ($ = L.url)); + if (openapi_server_url_templating_es_test($, { strict: !0 })) { + const s = Object.entries({ ...L.variables }).reduce( + (s, [o, i]) => ((s[o] = i.default), s), + {} + ); + $ = es_substitute( + $, + { ...s, ...w }, + { encoder: 'function' == typeof x ? x : Ip } + ); + } + return (function buildOas3UrlWithContext(s = '', o = '') { + const i = parseURIReference(s && o ? resolve(o, s) : s), + u = parseURIReference(o), + _ = stripNonAlpha(i.protocol) || stripNonAlpha(u.protocol), + w = i.host || u.host, + x = i.pathname; + let C; + C = _ && w ? `${_}://${w + x}` : x; + return '/' === C[C.length - 1] ? C.slice(0, -1) : C; + })($, _); + })(s) + : (function swagger2BaseUrl({ spec: s, scheme: o, contextUrl: i = '' }) { + const u = parseURIReference(i), + _ = Array.isArray(s.schemes) ? s.schemes[0] : null, + w = o || _ || stripNonAlpha(u.protocol) || 'http', + x = s.host || u.host || '', + C = s.basePath || ''; + let j; + j = w && x ? `${w}://${x + C}` : C; + return '/' === j[j.length - 1] ? j.slice(0, -1) : j; + })(s); + })({ + spec: i, + scheme: w, + contextUrl: j, + server: B, + serverVariables: $, + pathName: de, + method: pe, + serverVariableEncoder: z + })), + (ae.url += ee), + !u) + ) + return delete ae.cookies, ae; + (ae.url += de), (ae.method = `${pe}`.toUpperCase()), (Y = Y || {}); + const ye = i.paths[de] || {}; + _ && (ae.headers.accept = _); + const be = ((s) => { + const o = {}; + s.forEach((s) => { + o[s.in] || (o[s.in] = {}), (o[s.in][s.name] = s); + }); + const i = []; + return ( + Object.keys(o).forEach((s) => { + Object.keys(o[s]).forEach((u) => { + i.push(o[s][u]); + }); + }), + i + ); + })([].concat(arrayOrEmpty(ce.parameters)).concat(arrayOrEmpty(ye.parameters))); + be.forEach((s) => { + const o = Z[s.in]; + let u; + if ( + ('body' === s.in && s.schema && s.schema.properties && (u = Y), + (u = s && s.name && Y[s.name]), + void 0 === u + ? (u = s && s.name && Y[`${s.in}.${s.name}`]) + : ((s, o) => o.filter((o) => o.name === s))(s.name, be).length > 1 && + console.warn( + `Parameter '${s.name}' is ambiguous because the defined spec has more than one parameter with the name: '${s.name}' and the passed-in parameter values did not define an 'in' value.` + ), + null !== u) + ) { + if ( + (void 0 !== s.default && void 0 === u && (u = s.default), + void 0 === u && s.required && !s.allowEmptyValue) + ) + throw new Error(`Required parameter ${s.name} is not provided`); + if (ie && s.schema && 'object' === s.schema.type && 'string' == typeof u) + try { + u = JSON.parse(u); + } catch (s) { + throw new Error('Could not parse object parameter value string as JSON'); + } + o && o({ req: ae, parameter: s, value: u, operation: ce, spec: i, baseURL: ee }); + } + }); + const _e = { ...s, operation: ce }; + if ( + ((ae = ie ? buildRequest(_e, ae) : build_request_buildRequest(_e, ae)), + ae.cookies && Object.keys(ae.cookies).length) + ) { + const s = Object.keys(ae.cookies).reduce((s, o) => { + const i = ae.cookies[o]; + return s + (s ? '&' : '') + jS.serialize(o, i); + }, ''); + ae.headers.Cookie = s; + } + return ae.cookies && delete ae.cookies, serializeRequest(ae); + } + const stripNonAlpha = (s) => (s ? s.replace(/\W/g, '') : null); + const isNonEmptyServerList = (s) => Array.isArray(s) && s.length > 0; + const makeResolveSubtree = + (s) => + async (o, i, u = {}) => + (async (s, o, i = {}) => { + const { + returnEntireTree: u, + baseDoc: _, + requestInterceptor: w, + responseInterceptor: x, + parameterMacro: C, + modelPropertyMacro: j, + useCircularStructures: L, + strategies: B + } = i, + $ = { + spec: s, + pathDiscriminator: o, + baseDoc: _, + requestInterceptor: w, + responseInterceptor: x, + parameterMacro: C, + modelPropertyMacro: j, + useCircularStructures: L, + strategies: B + }, + V = B.find((o) => o.match(s)).normalize(s), + U = await AS({ + spec: V, + ...$, + allowMetaPatches: !0, + skipNormalization: !isOpenAPI31(s) + }); + return ( + !u && + Array.isArray(o) && + o.length && + (U.spec = o.reduce((s, o) => (null == s ? void 0 : s[o]), U.spec) || null), + U + ); + })(o, i, { ...s, ...u }), + zS = + (makeResolveSubtree({ strategies: [fu, hu, uu] }), + (s, o) => + (...i) => { + s(...i); + const u = o.getConfigs().withCredentials; + o.fn.fetch.withCredentials = u; + }); + function swagger_client({ configs: s, getConfigs: o }) { + return { + fn: { + fetch: + ((i = http_http), + (u = s.preFetch), + (_ = s.postFetch), + (_ = _ || ((s) => s)), + (u = u || ((s) => s)), + (s) => ( + 'string' == typeof s && (s = { url: s }), + (s = serializeRequest(s)), + (s = u(s)), + _(i(s)) + )), + buildRequest: execute_buildRequest, + execute: execute_execute, + resolve: makeResolve({ strategies: [OS, fu, hu, uu] }), + resolveSubtree: async (s, i, u = {}) => { + const _ = o(), + w = { + modelPropertyMacro: _.modelPropertyMacro, + parameterMacro: _.parameterMacro, + requestInterceptor: _.requestInterceptor, + responseInterceptor: _.responseInterceptor, + strategies: [OS, fu, hu, uu] + }; + return makeResolveSubtree(w)(s, i, u); + }, + serializeRes: serializeResponse, + opId + }, + statePlugins: { configs: { wrapActions: { loaded: zS } } } + }; + var i, u, _; + } + function util() { + return { fn: { shallowEqualKeys } }; + } + var WS = __webpack_require__(40961), + KS = __webpack_require__(78418), + HS = Pe, + JS = Symbol.for('react-redux-context'), + GS = 'undefined' != typeof globalThis ? globalThis : {}; + function getContext() { + if (!HS.createContext) return {}; + const s = GS[JS] ?? (GS[JS] = new Map()); + let o = s.get(HS.createContext); + return o || ((o = HS.createContext(null)), s.set(HS.createContext, o)), o; + } + var YS = getContext(), + notInitialized = () => { + throw new Error('uSES not initialized!'); + }; + var XS = Symbol.for('react.element'), + ZS = Symbol.for('react.portal'), + QS = Symbol.for('react.fragment'), + ex = Symbol.for('react.strict_mode'), + tx = Symbol.for('react.profiler'), + rx = Symbol.for('react.provider'), + nx = Symbol.for('react.context'), + sx = Symbol.for('react.server_context'), + ox = Symbol.for('react.forward_ref'), + ix = Symbol.for('react.suspense'), + ax = Symbol.for('react.suspense_list'), + lx = Symbol.for('react.memo'), + cx = Symbol.for('react.lazy'), + ux = (Symbol.for('react.offscreen'), Symbol.for('react.client.reference'), ox), + px = lx; + function typeOf(s) { + if ('object' == typeof s && null !== s) { + const o = s.$$typeof; + switch (o) { + case XS: { + const i = s.type; + switch (i) { + case QS: + case tx: + case ex: + case ix: + case ax: + return i; + default: { + const s = i && i.$$typeof; + switch (s) { + case sx: + case nx: + case ox: + case cx: + case lx: + case rx: + return s; + default: + return o; + } + } + } + } + case ZS: + return o; + } + } + } + function pureFinalPropsSelectorFactory( + s, + o, + i, + u, + { areStatesEqual: _, areOwnPropsEqual: w, areStatePropsEqual: x } + ) { + let C, + j, + L, + B, + $, + V = !1; + function handleSubsequentCalls(V, U) { + const z = !w(U, j), + Y = !_(V, C, U, j); + return ( + (C = V), + (j = U), + z && Y + ? (function handleNewPropsAndNewState() { + return (L = s(C, j)), o.dependsOnOwnProps && (B = o(u, j)), ($ = i(L, B, j)), $; + })() + : z + ? (function handleNewProps() { + return ( + s.dependsOnOwnProps && (L = s(C, j)), + o.dependsOnOwnProps && (B = o(u, j)), + ($ = i(L, B, j)), + $ + ); + })() + : Y + ? (function handleNewState() { + const o = s(C, j), + u = !x(o, L); + return (L = o), u && ($ = i(L, B, j)), $; + })() + : $ + ); + } + return function pureFinalPropsSelector(_, w) { + return V + ? handleSubsequentCalls(_, w) + : (function handleFirstCall(_, w) { + return ( + (C = _), (j = w), (L = s(C, j)), (B = o(u, j)), ($ = i(L, B, j)), (V = !0), $ + ); + })(_, w); + }; + } + function wrapMapToPropsConstant(s) { + return function initConstantSelector(o) { + const i = s(o); + function constantSelector() { + return i; + } + return (constantSelector.dependsOnOwnProps = !1), constantSelector; + }; + } + function getDependsOnOwnProps(s) { + return s.dependsOnOwnProps ? Boolean(s.dependsOnOwnProps) : 1 !== s.length; + } + function wrapMapToPropsFunc(s, o) { + return function initProxySelector(o, { displayName: i }) { + const u = function mapToPropsProxy(s, o) { + return u.dependsOnOwnProps ? u.mapToProps(s, o) : u.mapToProps(s, void 0); + }; + return ( + (u.dependsOnOwnProps = !0), + (u.mapToProps = function detectFactoryAndVerify(o, i) { + (u.mapToProps = s), (u.dependsOnOwnProps = getDependsOnOwnProps(s)); + let _ = u(o, i); + return ( + 'function' == typeof _ && + ((u.mapToProps = _), + (u.dependsOnOwnProps = getDependsOnOwnProps(_)), + (_ = u(o, i))), + _ + ); + }), + u + ); + }; + } + function createInvalidArgFactory(s, o) { + return (i, u) => { + throw new Error( + `Invalid value of type ${typeof s} for ${o} argument when connecting component ${u.wrappedComponentName}.` + ); + }; + } + function defaultMergeProps(s, o, i) { + return { ...i, ...s, ...o }; + } + function defaultNoopBatch(s) { + s(); + } + var hx = { notify() {}, get: () => [] }; + function createSubscription(s, o) { + let i, + u = hx, + _ = 0, + w = !1; + function handleChangeWrapper() { + x.onStateChange && x.onStateChange(); + } + function trySubscribe() { + _++, + i || + ((i = o ? o.addNestedSub(handleChangeWrapper) : s.subscribe(handleChangeWrapper)), + (u = (function createListenerCollection() { + let s = null, + o = null; + return { + clear() { + (s = null), (o = null); + }, + notify() { + defaultNoopBatch(() => { + let o = s; + for (; o; ) o.callback(), (o = o.next); + }); + }, + get() { + const o = []; + let i = s; + for (; i; ) o.push(i), (i = i.next); + return o; + }, + subscribe(i) { + let u = !0; + const _ = (o = { callback: i, next: null, prev: o }); + return ( + _.prev ? (_.prev.next = _) : (s = _), + function unsubscribe() { + u && + null !== s && + ((u = !1), + _.next ? (_.next.prev = _.prev) : (o = _.prev), + _.prev ? (_.prev.next = _.next) : (s = _.next)); + } + ); + } + }; + })())); + } + function tryUnsubscribe() { + _--, i && 0 === _ && (i(), (i = void 0), u.clear(), (u = hx)); + } + const x = { + addNestedSub: function addNestedSub(s) { + trySubscribe(); + const o = u.subscribe(s); + let i = !1; + return () => { + i || ((i = !0), o(), tryUnsubscribe()); + }; + }, + notifyNestedSubs: function notifyNestedSubs() { + u.notify(); + }, + handleChangeWrapper, + isSubscribed: function isSubscribed() { + return w; + }, + trySubscribe: function trySubscribeSelf() { + w || ((w = !0), trySubscribe()); + }, + tryUnsubscribe: function tryUnsubscribeSelf() { + w && ((w = !1), tryUnsubscribe()); + }, + getListeners: () => u + }; + return x; + } + var dx = !( + 'undefined' == typeof window || + void 0 === window.document || + void 0 === window.document.createElement + ), + fx = 'undefined' != typeof navigator && 'ReactNative' === navigator.product, + mx = dx || fx ? HS.useLayoutEffect : HS.useEffect; + function is(s, o) { + return s === o ? 0 !== s || 0 !== o || 1 / s == 1 / o : s != s && o != o; + } + function shallowEqual(s, o) { + if (is(s, o)) return !0; + if ('object' != typeof s || null === s || 'object' != typeof o || null === o) return !1; + const i = Object.keys(s), + u = Object.keys(o); + if (i.length !== u.length) return !1; + for (let u = 0; u < i.length; u++) + if (!Object.prototype.hasOwnProperty.call(o, i[u]) || !is(s[i[u]], o[i[u]])) return !1; + return !0; + } + var gx = { + childContextTypes: !0, + contextType: !0, + contextTypes: !0, + defaultProps: !0, + displayName: !0, + getDefaultProps: !0, + getDerivedStateFromError: !0, + getDerivedStateFromProps: !0, + mixins: !0, + propTypes: !0, + type: !0 + }, + yx = { + name: !0, + length: !0, + prototype: !0, + caller: !0, + callee: !0, + arguments: !0, + arity: !0 + }, + vx = { + $$typeof: !0, + compare: !0, + defaultProps: !0, + displayName: !0, + propTypes: !0, + type: !0 + }, + bx = { + [ux]: { $$typeof: !0, render: !0, defaultProps: !0, displayName: !0, propTypes: !0 }, + [px]: vx + }; + function getStatics(s) { + return (function isMemo(s) { + return typeOf(s) === lx; + })(s) + ? vx + : bx[s.$$typeof] || gx; + } + var _x = Object.defineProperty, + Ex = Object.getOwnPropertyNames, + wx = Object.getOwnPropertySymbols, + Sx = Object.getOwnPropertyDescriptor, + xx = Object.getPrototypeOf, + kx = Object.prototype; + function hoistNonReactStatics(s, o) { + if ('string' != typeof o) { + if (kx) { + const i = xx(o); + i && i !== kx && hoistNonReactStatics(s, i); + } + let i = Ex(o); + wx && (i = i.concat(wx(o))); + const u = getStatics(s), + _ = getStatics(o); + for (let w = 0; w < i.length; ++w) { + const x = i[w]; + if (!(yx[x] || (_ && _[x]) || (u && u[x]))) { + const i = Sx(o, x); + try { + _x(s, x, i); + } catch (s) {} + } + } + } + return s; + } + var Cx = notInitialized, + Ox = [null, null]; + function captureWrapperProps(s, o, i, u, _, w) { + (s.current = u), (i.current = !1), _.current && ((_.current = null), w()); + } + function strictEqual(s, o) { + return s === o; + } + var Ax = function connect( + s, + o, + i, + { + pure: u, + areStatesEqual: _ = strictEqual, + areOwnPropsEqual: w = shallowEqual, + areStatePropsEqual: x = shallowEqual, + areMergedPropsEqual: C = shallowEqual, + forwardRef: j = !1, + context: L = YS + } = {} + ) { + const B = L, + $ = (function mapStateToPropsFactory(s) { + return s + ? 'function' == typeof s + ? wrapMapToPropsFunc(s) + : createInvalidArgFactory(s, 'mapStateToProps') + : wrapMapToPropsConstant(() => ({})); + })(s), + V = (function mapDispatchToPropsFactory(s) { + return s && 'object' == typeof s + ? wrapMapToPropsConstant((o) => + (function react_redux_bindActionCreators(s, o) { + const i = {}; + for (const u in s) { + const _ = s[u]; + 'function' == typeof _ && (i[u] = (...s) => o(_(...s))); + } + return i; + })(s, o) + ) + : s + ? 'function' == typeof s + ? wrapMapToPropsFunc(s) + : createInvalidArgFactory(s, 'mapDispatchToProps') + : wrapMapToPropsConstant((s) => ({ dispatch: s })); + })(o), + U = (function mergePropsFactory(s) { + return s + ? 'function' == typeof s + ? (function wrapMergePropsFunc(s) { + return function initMergePropsProxy( + o, + { displayName: i, areMergedPropsEqual: u } + ) { + let _, + w = !1; + return function mergePropsProxy(o, i, x) { + const C = s(o, i, x); + return w ? u(C, _) || (_ = C) : ((w = !0), (_ = C)), _; + }; + }; + })(s) + : createInvalidArgFactory(s, 'mergeProps') + : () => defaultMergeProps; + })(i), + z = Boolean(s); + return (s) => { + const o = s.displayName || s.name || 'Component', + i = `Connect(${o})`, + u = { + shouldHandleStateChanges: z, + displayName: i, + wrappedComponentName: o, + WrappedComponent: s, + initMapStateToProps: $, + initMapDispatchToProps: V, + initMergeProps: U, + areStatesEqual: _, + areStatePropsEqual: x, + areOwnPropsEqual: w, + areMergedPropsEqual: C + }; + function ConnectFunction(o) { + const [i, _, w] = HS.useMemo(() => { + const { reactReduxForwardedRef: s, ...i } = o; + return [o.context, s, i]; + }, [o]), + x = HS.useMemo(() => B, [i, B]), + C = HS.useContext(x), + j = Boolean(o.store) && Boolean(o.store.getState) && Boolean(o.store.dispatch), + L = Boolean(C) && Boolean(C.store); + const $ = j ? o.store : C.store, + V = L ? C.getServerState : $.getState, + U = HS.useMemo( + () => + (function finalPropsSelectorFactory( + s, + { initMapStateToProps: o, initMapDispatchToProps: i, initMergeProps: u, ..._ } + ) { + return pureFinalPropsSelectorFactory(o(s, _), i(s, _), u(s, _), s, _); + })($.dispatch, u), + [$] + ), + [Y, Z] = HS.useMemo(() => { + if (!z) return Ox; + const s = createSubscription($, j ? void 0 : C.subscription), + o = s.notifyNestedSubs.bind(s); + return [s, o]; + }, [$, j, C]), + ee = HS.useMemo(() => (j ? C : { ...C, subscription: Y }), [j, C, Y]), + ie = HS.useRef(void 0), + ae = HS.useRef(w), + le = HS.useRef(void 0), + ce = HS.useRef(!1), + pe = HS.useRef(!1), + de = HS.useRef(void 0); + mx( + () => ( + (pe.current = !0), + () => { + pe.current = !1; + } + ), + [] + ); + const fe = HS.useMemo( + () => () => (le.current && w === ae.current ? le.current : U($.getState(), w)), + [$, w] + ), + ye = HS.useMemo( + () => (s) => + Y + ? (function subscribeUpdates(s, o, i, u, _, w, x, C, j, L, B) { + if (!s) return () => {}; + let $ = !1, + V = null; + const checkForUpdates = () => { + if ($ || !C.current) return; + const s = o.getState(); + let i, U; + try { + i = u(s, _.current); + } catch (s) { + (U = s), (V = s); + } + U || (V = null), + i === w.current + ? x.current || L() + : ((w.current = i), (j.current = i), (x.current = !0), B()); + }; + return ( + (i.onStateChange = checkForUpdates), + i.trySubscribe(), + checkForUpdates(), + () => { + if ((($ = !0), i.tryUnsubscribe(), (i.onStateChange = null), V)) + throw V; + } + ); + })(z, $, Y, U, ae, ie, ce, pe, le, Z, s) + : () => {}, + [Y] + ); + let be; + !(function useIsomorphicLayoutEffectWithArgs(s, o, i) { + mx(() => s(...o), i); + })(captureWrapperProps, [ae, ie, ce, w, le, Z]); + try { + be = Cx(ye, fe, V ? () => U(V(), w) : fe); + } catch (s) { + throw ( + (de.current && + (s.message += `\nThe error may be correlated with this previous error:\n${de.current.stack}\n\n`), + s) + ); + } + mx(() => { + (de.current = void 0), (le.current = void 0), (ie.current = be); + }); + const _e = HS.useMemo(() => HS.createElement(s, { ...be, ref: _ }), [_, s, be]); + return HS.useMemo( + () => (z ? HS.createElement(x.Provider, { value: ee }, _e) : _e), + [x, _e, ee] + ); + } + const L = HS.memo(ConnectFunction); + if (((L.WrappedComponent = s), (L.displayName = ConnectFunction.displayName = i), j)) { + const o = HS.forwardRef(function forwardConnectRef(s, o) { + return HS.createElement(L, { ...s, reactReduxForwardedRef: o }); + }); + return (o.displayName = i), (o.WrappedComponent = s), hoistNonReactStatics(o, s); + } + return hoistNonReactStatics(L, s); + }; + }; + var jx = function Provider({ + store: s, + context: o, + children: i, + serverState: u, + stabilityCheck: _ = 'once', + identityFunctionCheck: w = 'once' + }) { + const x = HS.useMemo(() => { + const o = createSubscription(s); + return { + store: s, + subscription: o, + getServerState: u ? () => u : void 0, + stabilityCheck: _, + identityFunctionCheck: w + }; + }, [s, u, _, w]), + C = HS.useMemo(() => s.getState(), [s]); + mx(() => { + const { subscription: o } = x; + return ( + (o.onStateChange = o.notifyNestedSubs), + o.trySubscribe(), + C !== s.getState() && o.notifyNestedSubs(), + () => { + o.tryUnsubscribe(), (o.onStateChange = void 0); + } + ); + }, [x, C]); + const j = o || YS; + return HS.createElement(j.Provider, { value: x }, i); + }; + var Ix; + (Ix = KS.useSyncExternalStoreWithSelector), + ((s) => { + Cx = s; + })(Pe.useSyncExternalStore); + var Px = __webpack_require__(83488), + Mx = __webpack_require__.n(Px); + const withSystem = (s) => (o) => { + const { fn: i } = s(); + class WithSystem extends Pe.Component { + render() { + return Pe.createElement(o, Rn()({}, s(), this.props, this.context)); + } + } + return (WithSystem.displayName = `WithSystem(${i.getDisplayName(o)})`), WithSystem; + }, + withRoot = (s, o) => (i) => { + const { fn: u } = s(); + class WithRoot extends Pe.Component { + render() { + return Pe.createElement( + jx, + { store: o }, + Pe.createElement(i, Rn()({}, this.props, this.context)) + ); + } + } + return (WithRoot.displayName = `WithRoot(${u.getDisplayName(i)})`), WithRoot; + }, + withConnect = (s, o, i) => + compose( + i ? withRoot(s, i) : Mx(), + Ax((i, u) => { + const _ = { ...u, ...s() }, + w = o.prototype?.mapStateToProps || ((s) => ({ state: s })); + return w(i, _); + }), + withSystem(s) + )(o), + handleProps = (s, o, i, u) => { + for (const _ in o) { + const w = o[_]; + 'function' == typeof w && w(i[_], u[_], s()); + } + }, + withMappedContainer = (s, o, i) => (o, u) => { + const { fn: _ } = s(), + w = i(o, 'root'); + class WithMappedContainer extends Pe.Component { + constructor(o, i) { + super(o, i), handleProps(s, u, o, {}); + } + UNSAFE_componentWillReceiveProps(o) { + handleProps(s, u, o, this.props); + } + render() { + const s = Yt()(this.props, u ? Object.keys(u) : []); + return Pe.createElement(w, s); + } + } + return ( + (WithMappedContainer.displayName = `WithMappedContainer(${_.getDisplayName(w)})`), + WithMappedContainer + ); + }, + render = (s, o, i, u) => (_) => { + const w = i(s, o, u)('App', 'root'), + { createRoot: x } = WS; + x(_).render(Pe.createElement(w, null)); + }, + getComponent = + (s, o, i) => + (u, _, w = {}) => { + if ('string' != typeof u) + throw new TypeError('Need a string, to fetch a component. Was given a ' + typeof u); + const x = i(u); + return x + ? _ + ? 'root' === _ + ? withConnect(s, x, o()) + : withConnect(s, x) + : x + : (w.failSilently || s().log.warn('Could not find component:', u), null); + }, + getDisplayName = (s) => s.displayName || s.name || 'Component', + view = ({ getComponents: s, getStore: o, getSystem: i }) => { + const u = ((s) => jt(s, (...s) => JSON.stringify(s)))(getComponent(i, o, s)), + _ = ((s) => utils_memoizeN(s, (...s) => s))(withMappedContainer(i, 0, u)); + return { + rootInjects: { + getComponent: u, + makeMappedContainer: _, + render: render(i, o, getComponent, s) + }, + fn: { getDisplayName } + }; + }, + view_legacy = ({ React: s, getSystem: o, getStore: i, getComponents: u }) => { + const _ = {}, + w = parseInt(s?.version, 10); + return ( + w >= 16 && + w < 18 && + (_.render = ((s, o, i, u) => (_) => { + const w = i(s, o, u)('App', 'root'); + WS.render(Pe.createElement(w, null), _); + })(o, i, getComponent, u)), + { rootInjects: _ } + ); + }; + function downloadUrlPlugin(s) { + let { fn: o } = s; + const i = { + download: + (s) => + ({ errActions: i, specSelectors: u, specActions: _, getConfigs: w }) => { + let { fetch: x } = o; + const C = w(); + function next(o) { + if (o instanceof Error || o.status >= 400) + return ( + _.updateLoadingStatus('failed'), + i.newThrownErr( + Object.assign(new Error((o.message || o.statusText) + ' ' + s), { + source: 'fetch' + }) + ), + void ( + !o.status && + o instanceof Error && + (function checkPossibleFailReasons() { + try { + let o; + if ( + ('URL' in at + ? (o = new URL(s)) + : ((o = document.createElement('a')), (o.href = s)), + 'https:' !== o.protocol && 'https:' === at.location.protocol) + ) { + const s = Object.assign( + new Error( + `Possible mixed-content issue? The page was loaded over https:// but a ${o.protocol}// URL was specified. Check that you are not attempting to load mixed content.` + ), + { source: 'fetch' } + ); + return void i.newThrownErr(s); + } + if (o.origin !== at.location.origin) { + const s = Object.assign( + new Error( + `Possible cross-origin (CORS) issue? The URL origin (${o.origin}) does not match the page (${at.location.origin}). Check the server returns the correct 'Access-Control-Allow-*' headers.` + ), + { source: 'fetch' } + ); + i.newThrownErr(s); + } + } catch (s) { + return; + } + })() + ) + ); + _.updateLoadingStatus('success'), + _.updateSpec(o.text), + u.url() !== s && _.updateUrl(s); + } + (s = s || u.url()), + _.updateLoadingStatus('loading'), + i.clear({ source: 'fetch' }), + x({ + url: s, + loadSpec: !0, + requestInterceptor: C.requestInterceptor || ((s) => s), + responseInterceptor: C.responseInterceptor || ((s) => s), + credentials: 'same-origin', + headers: { Accept: 'application/json,*/*' } + }).then(next, next); + }, + updateLoadingStatus: (s) => { + let o = [null, 'loading', 'failed', 'success', 'failedConfig']; + return ( + -1 === o.indexOf(s) && + console.error(`Error: ${s} is not one of ${JSON.stringify(o)}`), + { type: 'spec_update_loading_status', payload: s } + ); + } + }; + let u = { + loadingStatus: Ut( + (s) => s || (0, qe.Map)(), + (s) => s.get('loadingStatus') || null + ) + }; + return { + statePlugins: { + spec: { + actions: i, + reducers: { + spec_update_loading_status: (s, o) => + 'string' == typeof o.payload ? s.set('loadingStatus', o.payload) : s + }, + selectors: u + } + } + }; + } + function arrayLikeToArray_arrayLikeToArray(s, o) { + (null == o || o > s.length) && (o = s.length); + for (var i = 0, u = Array(o); i < o; i++) u[i] = s[i]; + return u; + } + function toConsumableArray_toConsumableArray(s) { + return ( + (function arrayWithoutHoles_arrayWithoutHoles(s) { + if (Array.isArray(s)) return arrayLikeToArray_arrayLikeToArray(s); + })(s) || + (function iterableToArray_iterableToArray(s) { + if ( + ('undefined' != typeof Symbol && null != s[Symbol.iterator]) || + null != s['@@iterator'] + ) + return Array.from(s); + })(s) || + (function unsupportedIterableToArray_unsupportedIterableToArray(s, o) { + if (s) { + if ('string' == typeof s) return arrayLikeToArray_arrayLikeToArray(s, o); + var i = {}.toString.call(s).slice(8, -1); + return ( + 'Object' === i && s.constructor && (i = s.constructor.name), + 'Map' === i || 'Set' === i + ? Array.from(s) + : 'Arguments' === i || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(i) + ? arrayLikeToArray_arrayLikeToArray(s, o) + : void 0 + ); + } + })(s) || + (function nonIterableSpread_nonIterableSpread() { + throw new TypeError( + 'Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.' + ); + })() + ); + } + function typeof_typeof(s) { + return ( + (typeof_typeof = + 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator + ? function (s) { + return typeof s; + } + : function (s) { + return s && + 'function' == typeof Symbol && + s.constructor === Symbol && + s !== Symbol.prototype + ? 'symbol' + : typeof s; + }), + typeof_typeof(s) + ); + } + function toPropertyKey(s) { + var o = (function toPrimitive(s, o) { + if ('object' != typeof_typeof(s) || !s) return s; + var i = s[Symbol.toPrimitive]; + if (void 0 !== i) { + var u = i.call(s, o || 'default'); + if ('object' != typeof_typeof(u)) return u; + throw new TypeError('@@toPrimitive must return a primitive value.'); + } + return ('string' === o ? String : Number)(s); + })(s, 'string'); + return 'symbol' == typeof_typeof(o) ? o : o + ''; + } + function defineProperty_defineProperty(s, o, i) { + return ( + (o = toPropertyKey(o)) in s + ? Object.defineProperty(s, o, { + value: i, + enumerable: !0, + configurable: !0, + writable: !0 + }) + : (s[o] = i), + s + ); + } + function extends_extends() { + return ( + (extends_extends = Object.assign + ? Object.assign.bind() + : function (s) { + for (var o = 1; o < arguments.length; o++) { + var i = arguments[o]; + for (var u in i) ({}).hasOwnProperty.call(i, u) && (s[u] = i[u]); + } + return s; + }), + extends_extends.apply(null, arguments) + ); + } + function create_element_ownKeys(s, o) { + var i = Object.keys(s); + if (Object.getOwnPropertySymbols) { + var u = Object.getOwnPropertySymbols(s); + o && + (u = u.filter(function (o) { + return Object.getOwnPropertyDescriptor(s, o).enumerable; + })), + i.push.apply(i, u); + } + return i; + } + function _objectSpread(s) { + for (var o = 1; o < arguments.length; o++) { + var i = null != arguments[o] ? arguments[o] : {}; + o % 2 + ? create_element_ownKeys(Object(i), !0).forEach(function (o) { + defineProperty_defineProperty(s, o, i[o]); + }) + : Object.getOwnPropertyDescriptors + ? Object.defineProperties(s, Object.getOwnPropertyDescriptors(i)) + : create_element_ownKeys(Object(i)).forEach(function (o) { + Object.defineProperty(s, o, Object.getOwnPropertyDescriptor(i, o)); + }); + } + return s; + } + var Tx = {}; + function createStyleObject(s) { + var o = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, + i = arguments.length > 2 ? arguments[2] : void 0; + return (function getClassNameCombinations(s) { + if (0 === s.length || 1 === s.length) return s; + var o = s.join('.'); + return ( + Tx[o] || + (Tx[o] = (function powerSetPermutations(s) { + var o = s.length; + return 0 === o || 1 === o + ? s + : 2 === o + ? [ + s[0], + s[1], + ''.concat(s[0], '.').concat(s[1]), + ''.concat(s[1], '.').concat(s[0]) + ] + : 3 === o + ? [ + s[0], + s[1], + s[2], + ''.concat(s[0], '.').concat(s[1]), + ''.concat(s[0], '.').concat(s[2]), + ''.concat(s[1], '.').concat(s[0]), + ''.concat(s[1], '.').concat(s[2]), + ''.concat(s[2], '.').concat(s[0]), + ''.concat(s[2], '.').concat(s[1]), + ''.concat(s[0], '.').concat(s[1], '.').concat(s[2]), + ''.concat(s[0], '.').concat(s[2], '.').concat(s[1]), + ''.concat(s[1], '.').concat(s[0], '.').concat(s[2]), + ''.concat(s[1], '.').concat(s[2], '.').concat(s[0]), + ''.concat(s[2], '.').concat(s[0], '.').concat(s[1]), + ''.concat(s[2], '.').concat(s[1], '.').concat(s[0]) + ] + : o >= 4 + ? [ + s[0], + s[1], + s[2], + s[3], + ''.concat(s[0], '.').concat(s[1]), + ''.concat(s[0], '.').concat(s[2]), + ''.concat(s[0], '.').concat(s[3]), + ''.concat(s[1], '.').concat(s[0]), + ''.concat(s[1], '.').concat(s[2]), + ''.concat(s[1], '.').concat(s[3]), + ''.concat(s[2], '.').concat(s[0]), + ''.concat(s[2], '.').concat(s[1]), + ''.concat(s[2], '.').concat(s[3]), + ''.concat(s[3], '.').concat(s[0]), + ''.concat(s[3], '.').concat(s[1]), + ''.concat(s[3], '.').concat(s[2]), + ''.concat(s[0], '.').concat(s[1], '.').concat(s[2]), + ''.concat(s[0], '.').concat(s[1], '.').concat(s[3]), + ''.concat(s[0], '.').concat(s[2], '.').concat(s[1]), + ''.concat(s[0], '.').concat(s[2], '.').concat(s[3]), + ''.concat(s[0], '.').concat(s[3], '.').concat(s[1]), + ''.concat(s[0], '.').concat(s[3], '.').concat(s[2]), + ''.concat(s[1], '.').concat(s[0], '.').concat(s[2]), + ''.concat(s[1], '.').concat(s[0], '.').concat(s[3]), + ''.concat(s[1], '.').concat(s[2], '.').concat(s[0]), + ''.concat(s[1], '.').concat(s[2], '.').concat(s[3]), + ''.concat(s[1], '.').concat(s[3], '.').concat(s[0]), + ''.concat(s[1], '.').concat(s[3], '.').concat(s[2]), + ''.concat(s[2], '.').concat(s[0], '.').concat(s[1]), + ''.concat(s[2], '.').concat(s[0], '.').concat(s[3]), + ''.concat(s[2], '.').concat(s[1], '.').concat(s[0]), + ''.concat(s[2], '.').concat(s[1], '.').concat(s[3]), + ''.concat(s[2], '.').concat(s[3], '.').concat(s[0]), + ''.concat(s[2], '.').concat(s[3], '.').concat(s[1]), + ''.concat(s[3], '.').concat(s[0], '.').concat(s[1]), + ''.concat(s[3], '.').concat(s[0], '.').concat(s[2]), + ''.concat(s[3], '.').concat(s[1], '.').concat(s[0]), + ''.concat(s[3], '.').concat(s[1], '.').concat(s[2]), + ''.concat(s[3], '.').concat(s[2], '.').concat(s[0]), + ''.concat(s[3], '.').concat(s[2], '.').concat(s[1]), + ''.concat(s[0], '.').concat(s[1], '.').concat(s[2], '.').concat(s[3]), + ''.concat(s[0], '.').concat(s[1], '.').concat(s[3], '.').concat(s[2]), + ''.concat(s[0], '.').concat(s[2], '.').concat(s[1], '.').concat(s[3]), + ''.concat(s[0], '.').concat(s[2], '.').concat(s[3], '.').concat(s[1]), + ''.concat(s[0], '.').concat(s[3], '.').concat(s[1], '.').concat(s[2]), + ''.concat(s[0], '.').concat(s[3], '.').concat(s[2], '.').concat(s[1]), + ''.concat(s[1], '.').concat(s[0], '.').concat(s[2], '.').concat(s[3]), + ''.concat(s[1], '.').concat(s[0], '.').concat(s[3], '.').concat(s[2]), + ''.concat(s[1], '.').concat(s[2], '.').concat(s[0], '.').concat(s[3]), + ''.concat(s[1], '.').concat(s[2], '.').concat(s[3], '.').concat(s[0]), + ''.concat(s[1], '.').concat(s[3], '.').concat(s[0], '.').concat(s[2]), + ''.concat(s[1], '.').concat(s[3], '.').concat(s[2], '.').concat(s[0]), + ''.concat(s[2], '.').concat(s[0], '.').concat(s[1], '.').concat(s[3]), + ''.concat(s[2], '.').concat(s[0], '.').concat(s[3], '.').concat(s[1]), + ''.concat(s[2], '.').concat(s[1], '.').concat(s[0], '.').concat(s[3]), + ''.concat(s[2], '.').concat(s[1], '.').concat(s[3], '.').concat(s[0]), + ''.concat(s[2], '.').concat(s[3], '.').concat(s[0], '.').concat(s[1]), + ''.concat(s[2], '.').concat(s[3], '.').concat(s[1], '.').concat(s[0]), + ''.concat(s[3], '.').concat(s[0], '.').concat(s[1], '.').concat(s[2]), + ''.concat(s[3], '.').concat(s[0], '.').concat(s[2], '.').concat(s[1]), + ''.concat(s[3], '.').concat(s[1], '.').concat(s[0], '.').concat(s[2]), + ''.concat(s[3], '.').concat(s[1], '.').concat(s[2], '.').concat(s[0]), + ''.concat(s[3], '.').concat(s[2], '.').concat(s[0], '.').concat(s[1]), + ''.concat(s[3], '.').concat(s[2], '.').concat(s[1], '.').concat(s[0]) + ] + : void 0; + })(s)), + Tx[o] + ); + })( + s.filter(function (s) { + return 'token' !== s; + }) + ).reduce(function (s, o) { + return _objectSpread(_objectSpread({}, s), i[o]); + }, o); + } + function createClassNameString(s) { + return s.join(' '); + } + function createElement(s) { + var o = s.node, + i = s.stylesheet, + u = s.style, + _ = void 0 === u ? {} : u, + w = s.useInlineStyles, + x = s.key, + C = o.properties, + j = o.type, + L = o.tagName, + B = o.value; + if ('text' === j) return B; + if (L) { + var $, + V = (function createChildren(s, o) { + var i = 0; + return function (u) { + return ( + (i += 1), + u.map(function (u, _) { + return createElement({ + node: u, + stylesheet: s, + useInlineStyles: o, + key: 'code-segment-'.concat(i, '-').concat(_) + }); + }) + ); + }; + })(i, w); + if (w) { + var U = Object.keys(i).reduce(function (s, o) { + return ( + o.split('.').forEach(function (o) { + s.includes(o) || s.push(o); + }), + s + ); + }, []), + z = C.className && C.className.includes('token') ? ['token'] : [], + Y = + C.className && + z.concat( + C.className.filter(function (s) { + return !U.includes(s); + }) + ); + $ = _objectSpread( + _objectSpread({}, C), + {}, + { + className: createClassNameString(Y) || void 0, + style: createStyleObject(C.className, Object.assign({}, C.style, _), i) + } + ); + } else + $ = _objectSpread( + _objectSpread({}, C), + {}, + { className: createClassNameString(C.className) } + ); + var Z = V(o.children); + return Pe.createElement(L, extends_extends({ key: x }, $), Z); + } + } + var Nx = [ + 'language', + 'children', + 'style', + 'customStyle', + 'codeTagProps', + 'useInlineStyles', + 'showLineNumbers', + 'showInlineLineNumbers', + 'startingLineNumber', + 'lineNumberContainerStyle', + 'lineNumberStyle', + 'wrapLines', + 'wrapLongLines', + 'lineProps', + 'renderer', + 'PreTag', + 'CodeTag', + 'code', + 'astGenerator' + ]; + function highlight_ownKeys(s, o) { + var i = Object.keys(s); + if (Object.getOwnPropertySymbols) { + var u = Object.getOwnPropertySymbols(s); + o && + (u = u.filter(function (o) { + return Object.getOwnPropertyDescriptor(s, o).enumerable; + })), + i.push.apply(i, u); + } + return i; + } + function highlight_objectSpread(s) { + for (var o = 1; o < arguments.length; o++) { + var i = null != arguments[o] ? arguments[o] : {}; + o % 2 + ? highlight_ownKeys(Object(i), !0).forEach(function (o) { + defineProperty_defineProperty(s, o, i[o]); + }) + : Object.getOwnPropertyDescriptors + ? Object.defineProperties(s, Object.getOwnPropertyDescriptors(i)) + : highlight_ownKeys(Object(i)).forEach(function (o) { + Object.defineProperty(s, o, Object.getOwnPropertyDescriptor(i, o)); + }); + } + return s; + } + var Rx = /\n/g; + function AllLineNumbers(s) { + var o = s.codeString, + i = s.codeStyle, + u = s.containerStyle, + _ = void 0 === u ? { float: 'left', paddingRight: '10px' } : u, + w = s.numberStyle, + x = void 0 === w ? {} : w, + C = s.startingLineNumber; + return Pe.createElement( + 'code', + { style: Object.assign({}, i, _) }, + (function getAllLineNumbers(s) { + var o = s.lines, + i = s.startingLineNumber, + u = s.style; + return o.map(function (s, o) { + var _ = o + i; + return Pe.createElement( + 'span', + { + key: 'line-'.concat(o), + className: 'react-syntax-highlighter-line-number', + style: 'function' == typeof u ? u(_) : u + }, + ''.concat(_, '\n') + ); + }); + })({ lines: o.replace(/\n$/, '').split('\n'), style: x, startingLineNumber: C }) + ); + } + function getInlineLineNumber(s, o) { + return { + type: 'element', + tagName: 'span', + properties: { + key: 'line-number--'.concat(s), + className: ['comment', 'linenumber', 'react-syntax-highlighter-line-number'], + style: o + }, + children: [{ type: 'text', value: s }] + }; + } + function assembleLineNumberStyles(s, o, i) { + var u, + _ = { + display: 'inline-block', + minWidth: ((u = i), ''.concat(u.toString().length, '.25em')), + paddingRight: '1em', + textAlign: 'right', + userSelect: 'none' + }, + w = 'function' == typeof s ? s(o) : s; + return highlight_objectSpread(highlight_objectSpread({}, _), w); + } + function createLineElement(s) { + var o = s.children, + i = s.lineNumber, + u = s.lineNumberStyle, + _ = s.largestLineNumber, + w = s.showInlineLineNumbers, + x = s.lineProps, + C = void 0 === x ? {} : x, + j = s.className, + L = void 0 === j ? [] : j, + B = s.showLineNumbers, + $ = s.wrapLongLines, + V = s.wrapLines, + U = + void 0 !== V && V + ? highlight_objectSpread({}, 'function' == typeof C ? C(i) : C) + : {}; + if ( + ((U.className = U.className + ? [].concat( + toConsumableArray_toConsumableArray(U.className.trim().split(/\s+/)), + toConsumableArray_toConsumableArray(L) + ) + : L), + i && w) + ) { + var z = assembleLineNumberStyles(u, i, _); + o.unshift(getInlineLineNumber(i, z)); + } + return ( + $ & B && (U.style = highlight_objectSpread({ display: 'flex' }, U.style)), + { type: 'element', tagName: 'span', properties: U, children: o } + ); + } + function flattenCodeTree(s) { + for ( + var o = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : [], + i = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : [], + u = 0; + u < s.length; + u++ + ) { + var _ = s[u]; + if ('text' === _.type) + i.push( + createLineElement({ + children: [_], + className: toConsumableArray_toConsumableArray(new Set(o)) + }) + ); + else if (_.children) { + var w = o.concat(_.properties.className); + flattenCodeTree(_.children, w).forEach(function (s) { + return i.push(s); + }); + } + } + return i; + } + function processLines(s, o, i, u, _, w, x, C, j) { + var L, + B = flattenCodeTree(s.value), + $ = [], + V = -1, + U = 0; + function createLine(s, w) { + var L = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : []; + return o || L.length > 0 + ? (function createWrappedLine(s, w) { + return createLineElement({ + children: s, + lineNumber: w, + lineNumberStyle: C, + largestLineNumber: x, + showInlineLineNumbers: _, + lineProps: i, + className: arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : [], + showLineNumbers: u, + wrapLongLines: j, + wrapLines: o + }); + })(s, w, L) + : (function createUnwrappedLine(s, o) { + if (u && o && _) { + var i = assembleLineNumberStyles(C, o, x); + s.unshift(getInlineLineNumber(o, i)); + } + return s; + })(s, w); + } + for ( + var z = function _loop() { + var s = B[U], + o = s.children[0].value, + i = (function getNewLines(s) { + return s.match(Rx); + })(o); + if (i) { + var _ = o.split('\n'); + _.forEach(function (o, i) { + var x = u && $.length + w, + C = { type: 'text', value: ''.concat(o, '\n') }; + if (0 === i) { + var j = createLine( + B.slice(V + 1, U).concat( + createLineElement({ children: [C], className: s.properties.className }) + ), + x + ); + $.push(j); + } else if (i === _.length - 1) { + var L = B[U + 1] && B[U + 1].children && B[U + 1].children[0], + z = { type: 'text', value: ''.concat(o) }; + if (L) { + var Y = createLineElement({ + children: [z], + className: s.properties.className + }); + B.splice(U + 1, 0, Y); + } else { + var Z = createLine([z], x, s.properties.className); + $.push(Z); + } + } else { + var ee = createLine([C], x, s.properties.className); + $.push(ee); + } + }), + (V = U); + } + U++; + }; + U < B.length; + + ) + z(); + if (V !== B.length - 1) { + var Y = B.slice(V + 1, B.length); + if (Y && Y.length) { + var Z = createLine(Y, u && $.length + w); + $.push(Z); + } + } + return o ? $ : (L = []).concat.apply(L, $); + } + function defaultRenderer(s) { + var o = s.rows, + i = s.stylesheet, + u = s.useInlineStyles; + return o.map(function (s, o) { + return createElement({ + node: s, + stylesheet: i, + useInlineStyles: u, + key: 'code-segement'.concat(o) + }); + }); + } + function isHighlightJs(s) { + return s && void 0 !== s.highlightAuto; + } + var Dx = __webpack_require__(43768), + Lx = (function highlight(s, o) { + return function SyntaxHighlighter(i) { + var u = i.language, + _ = i.children, + w = i.style, + x = void 0 === w ? o : w, + C = i.customStyle, + j = void 0 === C ? {} : C, + L = i.codeTagProps, + B = + void 0 === L + ? { + className: u ? 'language-'.concat(u) : void 0, + style: highlight_objectSpread( + highlight_objectSpread({}, x['code[class*="language-"]']), + x['code[class*="language-'.concat(u, '"]')] + ) + } + : L, + $ = i.useInlineStyles, + V = void 0 === $ || $, + U = i.showLineNumbers, + z = void 0 !== U && U, + Y = i.showInlineLineNumbers, + Z = void 0 === Y || Y, + ee = i.startingLineNumber, + ie = void 0 === ee ? 1 : ee, + ae = i.lineNumberContainerStyle, + le = i.lineNumberStyle, + ce = void 0 === le ? {} : le, + pe = i.wrapLines, + de = i.wrapLongLines, + fe = void 0 !== de && de, + ye = i.lineProps, + be = void 0 === ye ? {} : ye, + _e = i.renderer, + we = i.PreTag, + Se = void 0 === we ? 'pre' : we, + xe = i.CodeTag, + Te = void 0 === xe ? 'code' : xe, + Re = i.code, + qe = void 0 === Re ? (Array.isArray(_) ? _[0] : _) || '' : Re, + $e = i.astGenerator, + ze = (function _objectWithoutProperties(s, o) { + if (null == s) return {}; + var i, + u, + _ = (function _objectWithoutPropertiesLoose(s, o) { + if (null == s) return {}; + var i = {}; + for (var u in s) + if ({}.hasOwnProperty.call(s, u)) { + if (o.includes(u)) continue; + i[u] = s[u]; + } + return i; + })(s, o); + if (Object.getOwnPropertySymbols) { + var w = Object.getOwnPropertySymbols(s); + for (u = 0; u < w.length; u++) + (i = w[u]), + o.includes(i) || ({}.propertyIsEnumerable.call(s, i) && (_[i] = s[i])); + } + return _; + })(i, Nx); + $e = $e || s; + var We = z + ? Pe.createElement(AllLineNumbers, { + containerStyle: ae, + codeStyle: B.style || {}, + numberStyle: ce, + startingLineNumber: ie, + codeString: qe + }) + : null, + He = x.hljs || x['pre[class*="language-"]'] || { backgroundColor: '#fff' }, + Ye = isHighlightJs($e) ? 'hljs' : 'prismjs', + Xe = V + ? Object.assign({}, ze, { style: Object.assign({}, He, j) }) + : Object.assign({}, ze, { + className: ze.className ? ''.concat(Ye, ' ').concat(ze.className) : Ye, + style: Object.assign({}, j) + }); + if ( + ((B.style = highlight_objectSpread( + fe ? { whiteSpace: 'pre-wrap' } : { whiteSpace: 'pre' }, + B.style + )), + !$e) + ) + return Pe.createElement(Se, Xe, We, Pe.createElement(Te, B, qe)); + ((void 0 === pe && _e) || fe) && (pe = !0), (_e = _e || defaultRenderer); + var Qe = [{ type: 'text', value: qe }], + et = (function getCodeTree(s) { + var o = s.astGenerator, + i = s.language, + u = s.code, + _ = s.defaultCodeValue; + if (isHighlightJs(o)) { + var w = (function (s, o) { + return -1 !== s.listLanguages().indexOf(o); + })(o, i); + return 'text' === i + ? { value: _, language: 'text' } + : w + ? o.highlight(i, u) + : o.highlightAuto(u); + } + try { + return i && 'text' !== i ? { value: o.highlight(u, i) } : { value: _ }; + } catch (s) { + return { value: _ }; + } + })({ astGenerator: $e, language: u, code: qe, defaultCodeValue: Qe }); + null === et.language && (et.value = Qe); + var tt = et.value.length; + 1 === tt && + 'text' === et.value[0].type && + (tt = et.value[0].value.split('\n').length); + var rt = processLines(et, pe, be, z, Z, ie, tt + ie, ce, fe); + return Pe.createElement( + Se, + Xe, + Pe.createElement( + Te, + B, + !Z && We, + _e({ rows: rt, stylesheet: x, useInlineStyles: V }) + ) + ); + }; + })(Dx, {}); + Lx.registerLanguage = Dx.registerLanguage; + const Bx = Lx; + var Fx = __webpack_require__(95089); + const qx = __webpack_require__.n(Fx)(); + var $x = __webpack_require__(65772); + const Vx = __webpack_require__.n($x)(); + var Ux = __webpack_require__(17285); + const zx = __webpack_require__.n(Ux)(); + var Wx = __webpack_require__(35344); + const Kx = __webpack_require__.n(Wx)(); + var Hx = __webpack_require__(17533); + const Jx = __webpack_require__.n(Hx)(); + var Gx = __webpack_require__(73402); + const Yx = __webpack_require__.n(Gx)(); + var Xx = __webpack_require__(26571); + const Zx = __webpack_require__.n(Xx)(), + after_load = () => { + Bx.registerLanguage('json', Vx), + Bx.registerLanguage('js', qx), + Bx.registerLanguage('xml', zx), + Bx.registerLanguage('yaml', Jx), + Bx.registerLanguage('http', Yx), + Bx.registerLanguage('bash', Kx), + Bx.registerLanguage('powershell', Zx), + Bx.registerLanguage('javascript', qx); + }, + Qx = { + hljs: { + display: 'block', + overflowX: 'auto', + padding: '0.5em', + background: '#333', + color: 'white' + }, + 'hljs-name': { fontWeight: 'bold' }, + 'hljs-strong': { fontWeight: 'bold' }, + 'hljs-code': { fontStyle: 'italic', color: '#888' }, + 'hljs-emphasis': { fontStyle: 'italic' }, + 'hljs-tag': { color: '#62c8f3' }, + 'hljs-variable': { color: '#ade5fc' }, + 'hljs-template-variable': { color: '#ade5fc' }, + 'hljs-selector-id': { color: '#ade5fc' }, + 'hljs-selector-class': { color: '#ade5fc' }, + 'hljs-string': { color: '#a2fca2' }, + 'hljs-bullet': { color: '#d36363' }, + 'hljs-type': { color: '#ffa' }, + 'hljs-title': { color: '#ffa' }, + 'hljs-section': { color: '#ffa' }, + 'hljs-attribute': { color: '#ffa' }, + 'hljs-quote': { color: '#ffa' }, + 'hljs-built_in': { color: '#ffa' }, + 'hljs-builtin-name': { color: '#ffa' }, + 'hljs-number': { color: '#d36363' }, + 'hljs-symbol': { color: '#d36363' }, + 'hljs-keyword': { color: '#fcc28c' }, + 'hljs-selector-tag': { color: '#fcc28c' }, + 'hljs-literal': { color: '#fcc28c' }, + 'hljs-comment': { color: '#888' }, + 'hljs-deletion': { color: '#333', backgroundColor: '#fc9b9b' }, + 'hljs-regexp': { color: '#c6b4f0' }, + 'hljs-link': { color: '#c6b4f0' }, + 'hljs-meta': { color: '#fc9b9b' }, + 'hljs-addition': { backgroundColor: '#a2fca2', color: '#333' } + }, + tk = { + agate: Qx, + arta: { + hljs: { + display: 'block', + overflowX: 'auto', + padding: '0.5em', + background: '#222', + color: '#aaa' + }, + 'hljs-subst': { color: '#aaa' }, + 'hljs-section': { color: '#fff', fontWeight: 'bold' }, + 'hljs-comment': { color: '#444' }, + 'hljs-quote': { color: '#444' }, + 'hljs-meta': { color: '#444' }, + 'hljs-string': { color: '#ffcc33' }, + 'hljs-symbol': { color: '#ffcc33' }, + 'hljs-bullet': { color: '#ffcc33' }, + 'hljs-regexp': { color: '#ffcc33' }, + 'hljs-number': { color: '#00cc66' }, + 'hljs-addition': { color: '#00cc66' }, + 'hljs-built_in': { color: '#32aaee' }, + 'hljs-builtin-name': { color: '#32aaee' }, + 'hljs-literal': { color: '#32aaee' }, + 'hljs-type': { color: '#32aaee' }, + 'hljs-template-variable': { color: '#32aaee' }, + 'hljs-attribute': { color: '#32aaee' }, + 'hljs-link': { color: '#32aaee' }, + 'hljs-keyword': { color: '#6644aa' }, + 'hljs-selector-tag': { color: '#6644aa' }, + 'hljs-name': { color: '#6644aa' }, + 'hljs-selector-id': { color: '#6644aa' }, + 'hljs-selector-class': { color: '#6644aa' }, + 'hljs-title': { color: '#bb1166' }, + 'hljs-variable': { color: '#bb1166' }, + 'hljs-deletion': { color: '#bb1166' }, + 'hljs-template-tag': { color: '#bb1166' }, + 'hljs-doctag': { fontWeight: 'bold' }, + 'hljs-strong': { fontWeight: 'bold' }, + 'hljs-emphasis': { fontStyle: 'italic' } + }, + monokai: { + hljs: { + display: 'block', + overflowX: 'auto', + padding: '0.5em', + background: '#272822', + color: '#ddd' + }, + 'hljs-tag': { color: '#f92672' }, + 'hljs-keyword': { color: '#f92672', fontWeight: 'bold' }, + 'hljs-selector-tag': { color: '#f92672', fontWeight: 'bold' }, + 'hljs-literal': { color: '#f92672', fontWeight: 'bold' }, + 'hljs-strong': { color: '#f92672' }, + 'hljs-name': { color: '#f92672' }, + 'hljs-code': { color: '#66d9ef' }, + 'hljs-class .hljs-title': { color: 'white' }, + 'hljs-attribute': { color: '#bf79db' }, + 'hljs-symbol': { color: '#bf79db' }, + 'hljs-regexp': { color: '#bf79db' }, + 'hljs-link': { color: '#bf79db' }, + 'hljs-string': { color: '#a6e22e' }, + 'hljs-bullet': { color: '#a6e22e' }, + 'hljs-subst': { color: '#a6e22e' }, + 'hljs-title': { color: '#a6e22e', fontWeight: 'bold' }, + 'hljs-section': { color: '#a6e22e', fontWeight: 'bold' }, + 'hljs-emphasis': { color: '#a6e22e' }, + 'hljs-type': { color: '#a6e22e', fontWeight: 'bold' }, + 'hljs-built_in': { color: '#a6e22e' }, + 'hljs-builtin-name': { color: '#a6e22e' }, + 'hljs-selector-attr': { color: '#a6e22e' }, + 'hljs-selector-pseudo': { color: '#a6e22e' }, + 'hljs-addition': { color: '#a6e22e' }, + 'hljs-variable': { color: '#a6e22e' }, + 'hljs-template-tag': { color: '#a6e22e' }, + 'hljs-template-variable': { color: '#a6e22e' }, + 'hljs-comment': { color: '#75715e' }, + 'hljs-quote': { color: '#75715e' }, + 'hljs-deletion': { color: '#75715e' }, + 'hljs-meta': { color: '#75715e' }, + 'hljs-doctag': { fontWeight: 'bold' }, + 'hljs-selector-id': { fontWeight: 'bold' } + }, + nord: { + hljs: { + display: 'block', + overflowX: 'auto', + padding: '0.5em', + background: '#2E3440', + color: '#D8DEE9' + }, + 'hljs-subst': { color: '#D8DEE9' }, + 'hljs-selector-tag': { color: '#81A1C1' }, + 'hljs-selector-id': { color: '#8FBCBB', fontWeight: 'bold' }, + 'hljs-selector-class': { color: '#8FBCBB' }, + 'hljs-selector-attr': { color: '#8FBCBB' }, + 'hljs-selector-pseudo': { color: '#88C0D0' }, + 'hljs-addition': { backgroundColor: 'rgba(163, 190, 140, 0.5)' }, + 'hljs-deletion': { backgroundColor: 'rgba(191, 97, 106, 0.5)' }, + 'hljs-built_in': { color: '#8FBCBB' }, + 'hljs-type': { color: '#8FBCBB' }, + 'hljs-class': { color: '#8FBCBB' }, + 'hljs-function': { color: '#88C0D0' }, + 'hljs-function > .hljs-title': { color: '#88C0D0' }, + 'hljs-keyword': { color: '#81A1C1' }, + 'hljs-literal': { color: '#81A1C1' }, + 'hljs-symbol': { color: '#81A1C1' }, + 'hljs-number': { color: '#B48EAD' }, + 'hljs-regexp': { color: '#EBCB8B' }, + 'hljs-string': { color: '#A3BE8C' }, + 'hljs-title': { color: '#8FBCBB' }, + 'hljs-params': { color: '#D8DEE9' }, + 'hljs-bullet': { color: '#81A1C1' }, + 'hljs-code': { color: '#8FBCBB' }, + 'hljs-emphasis': { fontStyle: 'italic' }, + 'hljs-formula': { color: '#8FBCBB' }, + 'hljs-strong': { fontWeight: 'bold' }, + 'hljs-link:hover': { textDecoration: 'underline' }, + 'hljs-quote': { color: '#4C566A' }, + 'hljs-comment': { color: '#4C566A' }, + 'hljs-doctag': { color: '#8FBCBB' }, + 'hljs-meta': { color: '#5E81AC' }, + 'hljs-meta-keyword': { color: '#5E81AC' }, + 'hljs-meta-string': { color: '#A3BE8C' }, + 'hljs-attr': { color: '#8FBCBB' }, + 'hljs-attribute': { color: '#D8DEE9' }, + 'hljs-builtin-name': { color: '#81A1C1' }, + 'hljs-name': { color: '#81A1C1' }, + 'hljs-section': { color: '#88C0D0' }, + 'hljs-tag': { color: '#81A1C1' }, + 'hljs-variable': { color: '#D8DEE9' }, + 'hljs-template-variable': { color: '#D8DEE9' }, + 'hljs-template-tag': { color: '#5E81AC' }, + 'abnf .hljs-attribute': { color: '#88C0D0' }, + 'abnf .hljs-symbol': { color: '#EBCB8B' }, + 'apache .hljs-attribute': { color: '#88C0D0' }, + 'apache .hljs-section': { color: '#81A1C1' }, + 'arduino .hljs-built_in': { color: '#88C0D0' }, + 'aspectj .hljs-meta': { color: '#D08770' }, + 'aspectj > .hljs-title': { color: '#88C0D0' }, + 'bnf .hljs-attribute': { color: '#8FBCBB' }, + 'clojure .hljs-name': { color: '#88C0D0' }, + 'clojure .hljs-symbol': { color: '#EBCB8B' }, + 'coq .hljs-built_in': { color: '#88C0D0' }, + 'cpp .hljs-meta-string': { color: '#8FBCBB' }, + 'css .hljs-built_in': { color: '#88C0D0' }, + 'css .hljs-keyword': { color: '#D08770' }, + 'diff .hljs-meta': { color: '#8FBCBB' }, + 'ebnf .hljs-attribute': { color: '#8FBCBB' }, + 'glsl .hljs-built_in': { color: '#88C0D0' }, + 'groovy .hljs-meta:not(:first-child)': { color: '#D08770' }, + 'haxe .hljs-meta': { color: '#D08770' }, + 'java .hljs-meta': { color: '#D08770' }, + 'ldif .hljs-attribute': { color: '#8FBCBB' }, + 'lisp .hljs-name': { color: '#88C0D0' }, + 'lua .hljs-built_in': { color: '#88C0D0' }, + 'moonscript .hljs-built_in': { color: '#88C0D0' }, + 'nginx .hljs-attribute': { color: '#88C0D0' }, + 'nginx .hljs-section': { color: '#5E81AC' }, + 'pf .hljs-built_in': { color: '#88C0D0' }, + 'processing .hljs-built_in': { color: '#88C0D0' }, + 'scss .hljs-keyword': { color: '#81A1C1' }, + 'stylus .hljs-keyword': { color: '#81A1C1' }, + 'swift .hljs-meta': { color: '#D08770' }, + 'vim .hljs-built_in': { color: '#88C0D0', fontStyle: 'italic' }, + 'yaml .hljs-meta': { color: '#D08770' } + }, + obsidian: { + hljs: { + display: 'block', + overflowX: 'auto', + padding: '0.5em', + background: '#282b2e', + color: '#e0e2e4' + }, + 'hljs-keyword': { color: '#93c763', fontWeight: 'bold' }, + 'hljs-selector-tag': { color: '#93c763', fontWeight: 'bold' }, + 'hljs-literal': { color: '#93c763', fontWeight: 'bold' }, + 'hljs-selector-id': { color: '#93c763' }, + 'hljs-number': { color: '#ffcd22' }, + 'hljs-attribute': { color: '#668bb0' }, + 'hljs-code': { color: 'white' }, + 'hljs-class .hljs-title': { color: 'white' }, + 'hljs-section': { color: 'white', fontWeight: 'bold' }, + 'hljs-regexp': { color: '#d39745' }, + 'hljs-link': { color: '#d39745' }, + 'hljs-meta': { color: '#557182' }, + 'hljs-tag': { color: '#8cbbad' }, + 'hljs-name': { color: '#8cbbad', fontWeight: 'bold' }, + 'hljs-bullet': { color: '#8cbbad' }, + 'hljs-subst': { color: '#8cbbad' }, + 'hljs-emphasis': { color: '#8cbbad' }, + 'hljs-type': { color: '#8cbbad', fontWeight: 'bold' }, + 'hljs-built_in': { color: '#8cbbad' }, + 'hljs-selector-attr': { color: '#8cbbad' }, + 'hljs-selector-pseudo': { color: '#8cbbad' }, + 'hljs-addition': { color: '#8cbbad' }, + 'hljs-variable': { color: '#8cbbad' }, + 'hljs-template-tag': { color: '#8cbbad' }, + 'hljs-template-variable': { color: '#8cbbad' }, + 'hljs-string': { color: '#ec7600' }, + 'hljs-symbol': { color: '#ec7600' }, + 'hljs-comment': { color: '#818e96' }, + 'hljs-quote': { color: '#818e96' }, + 'hljs-deletion': { color: '#818e96' }, + 'hljs-selector-class': { color: '#A082BD' }, + 'hljs-doctag': { fontWeight: 'bold' }, + 'hljs-title': { fontWeight: 'bold' }, + 'hljs-strong': { fontWeight: 'bold' } + }, + 'tomorrow-night': { + 'hljs-comment': { color: '#969896' }, + 'hljs-quote': { color: '#969896' }, + 'hljs-variable': { color: '#cc6666' }, + 'hljs-template-variable': { color: '#cc6666' }, + 'hljs-tag': { color: '#cc6666' }, + 'hljs-name': { color: '#cc6666' }, + 'hljs-selector-id': { color: '#cc6666' }, + 'hljs-selector-class': { color: '#cc6666' }, + 'hljs-regexp': { color: '#cc6666' }, + 'hljs-deletion': { color: '#cc6666' }, + 'hljs-number': { color: '#de935f' }, + 'hljs-built_in': { color: '#de935f' }, + 'hljs-builtin-name': { color: '#de935f' }, + 'hljs-literal': { color: '#de935f' }, + 'hljs-type': { color: '#de935f' }, + 'hljs-params': { color: '#de935f' }, + 'hljs-meta': { color: '#de935f' }, + 'hljs-link': { color: '#de935f' }, + 'hljs-attribute': { color: '#f0c674' }, + 'hljs-string': { color: '#b5bd68' }, + 'hljs-symbol': { color: '#b5bd68' }, + 'hljs-bullet': { color: '#b5bd68' }, + 'hljs-addition': { color: '#b5bd68' }, + 'hljs-title': { color: '#81a2be' }, + 'hljs-section': { color: '#81a2be' }, + 'hljs-keyword': { color: '#b294bb' }, + 'hljs-selector-tag': { color: '#b294bb' }, + hljs: { + display: 'block', + overflowX: 'auto', + background: '#1d1f21', + color: '#c5c8c6', + padding: '0.5em' + }, + 'hljs-emphasis': { fontStyle: 'italic' }, + 'hljs-strong': { fontWeight: 'bold' } + }, + idea: { + hljs: { + display: 'block', + overflowX: 'auto', + padding: '0.5em', + color: '#000', + background: '#fff' + }, + 'hljs-subst': { fontWeight: 'normal', color: '#000' }, + 'hljs-title': { fontWeight: 'normal', color: '#000' }, + 'hljs-comment': { color: '#808080', fontStyle: 'italic' }, + 'hljs-quote': { color: '#808080', fontStyle: 'italic' }, + 'hljs-meta': { color: '#808000' }, + 'hljs-tag': { background: '#efefef' }, + 'hljs-section': { fontWeight: 'bold', color: '#000080' }, + 'hljs-name': { fontWeight: 'bold', color: '#000080' }, + 'hljs-literal': { fontWeight: 'bold', color: '#000080' }, + 'hljs-keyword': { fontWeight: 'bold', color: '#000080' }, + 'hljs-selector-tag': { fontWeight: 'bold', color: '#000080' }, + 'hljs-type': { fontWeight: 'bold', color: '#000080' }, + 'hljs-selector-id': { fontWeight: 'bold', color: '#000080' }, + 'hljs-selector-class': { fontWeight: 'bold', color: '#000080' }, + 'hljs-attribute': { fontWeight: 'bold', color: '#0000ff' }, + 'hljs-number': { fontWeight: 'normal', color: '#0000ff' }, + 'hljs-regexp': { fontWeight: 'normal', color: '#0000ff' }, + 'hljs-link': { fontWeight: 'normal', color: '#0000ff' }, + 'hljs-string': { color: '#008000', fontWeight: 'bold' }, + 'hljs-symbol': { color: '#000', background: '#d0eded', fontStyle: 'italic' }, + 'hljs-bullet': { color: '#000', background: '#d0eded', fontStyle: 'italic' }, + 'hljs-formula': { color: '#000', background: '#d0eded', fontStyle: 'italic' }, + 'hljs-doctag': { textDecoration: 'underline' }, + 'hljs-variable': { color: '#660e7a' }, + 'hljs-template-variable': { color: '#660e7a' }, + 'hljs-addition': { background: '#baeeba' }, + 'hljs-deletion': { background: '#ffc8bd' }, + 'hljs-emphasis': { fontStyle: 'italic' }, + 'hljs-strong': { fontWeight: 'bold' } + } + }, + rk = Qx, + components_SyntaxHighlighter = ({ + language: s, + className: o = '', + getConfigs: i, + syntaxHighlighting: u = {}, + children: _ = '' + }) => { + const w = i().syntaxHighlight.theme, + { styles: x, defaultStyle: C } = u, + j = x?.[w] ?? C; + return Pe.createElement(Bx, { language: s, className: o, style: j }, _); + }; + var nk = __webpack_require__(5419), + sk = __webpack_require__.n(nk); + const components_HighlightCode = ({ + fileName: s = 'response.txt', + className: o, + downloadable: i, + getComponent: u, + canCopy: _, + language: w, + children: x + }) => { + const C = (0, Pe.useRef)(null), + j = u('SyntaxHighlighter', !0), + handlePreventYScrollingBeyondElement = (s) => { + const { target: o, deltaY: i } = s, + { scrollHeight: u, offsetHeight: _, scrollTop: w } = o; + u > _ && ((0 === w && i < 0) || (_ + w >= u && i > 0)) && s.preventDefault(); + }; + return ( + (0, Pe.useEffect)(() => { + const s = Array.from(C.current.childNodes).filter( + (s) => !!s.nodeType && s.classList.contains('microlight') + ); + return ( + s.forEach((s) => + s.addEventListener('mousewheel', handlePreventYScrollingBeyondElement, { + passive: !1 + }) + ), + () => { + s.forEach((s) => + s.removeEventListener('mousewheel', handlePreventYScrollingBeyondElement) + ); + } + ); + }, [x, o, w]), + Pe.createElement( + 'div', + { className: 'highlight-code', ref: C }, + _ && + Pe.createElement( + 'div', + { className: 'copy-to-clipboard' }, + Pe.createElement( + Jn.CopyToClipboard, + { text: x }, + Pe.createElement('button', null) + ) + ), + i + ? Pe.createElement( + 'button', + { + className: 'download-contents', + onClick: () => { + sk()(x, s); + } + }, + 'Download' + ) + : null, + Pe.createElement( + j, + { + language: w, + className: Hn()(o, 'microlight'), + renderPlainText: ({ children: s, PlainTextViewer: i }) => + Pe.createElement(i, { className: o }, s) + }, + x + ) + ) + ); + }, + components_PlainTextViewer = ({ className: s = '', children: o }) => + Pe.createElement('pre', { className: Hn()('microlight', s) }, o), + wrap_components_SyntaxHighlighter = + (s, o) => + ({ renderPlainText: i, children: u, ..._ }) => { + const w = o.getConfigs().syntaxHighlight.activated, + x = o.getComponent('PlainTextViewer'); + return w || 'function' != typeof i + ? w + ? Pe.createElement(s, _, u) + : Pe.createElement(x, null, u) + : i({ children: u, PlainTextViewer: x }); + }, + SyntaxHighlightingPlugin1 = () => ({ + afterLoad: after_load, + rootInjects: { syntaxHighlighting: { styles: tk, defaultStyle: rk } }, + components: { + SyntaxHighlighter: components_SyntaxHighlighter, + HighlightCode: components_HighlightCode, + PlainTextViewer: components_PlainTextViewer + } + }), + SyntaxHighlightingPlugin2 = () => ({ + wrapComponents: { SyntaxHighlighter: wrap_components_SyntaxHighlighter } + }), + syntax_highlighting = () => [SyntaxHighlightingPlugin1, SyntaxHighlightingPlugin2], + versions_after_load = () => { + const { + GIT_DIRTY: s, + GIT_COMMIT: o, + PACKAGE_VERSION: i, + BUILD_TIME: u + } = { + PACKAGE_VERSION: '5.18.2', + GIT_COMMIT: 'g1dd1f7cc', + GIT_DIRTY: !0, + BUILD_TIME: 'Thu, 07 Nov 2024 14:01:17 GMT' + }; + (at.versions = at.versions || {}), + (at.versions.swaggerUI = { + version: i, + gitRevision: o, + gitDirty: s, + buildTimestamp: u + }); + }, + versions = () => ({ afterLoad: versions_after_load }); + var ok = __webpack_require__(47248), + lk = __webpack_require__.n(ok); + const uk = console.error, + withErrorBoundary = (s) => (o) => { + const { getComponent: i, fn: u } = s(), + _ = i('ErrorBoundary'), + w = u.getDisplayName(o); + class WithErrorBoundary extends Pe.Component { + render() { + return Pe.createElement( + _, + { targetName: w, getComponent: i, fn: u }, + Pe.createElement(o, Rn()({}, this.props, this.context)) + ); + } + } + var x; + return ( + (WithErrorBoundary.displayName = `WithErrorBoundary(${w})`), + (x = o).prototype && + x.prototype.isReactComponent && + (WithErrorBoundary.prototype.mapStateToProps = o.prototype.mapStateToProps), + WithErrorBoundary + ); + }, + fallback = ({ name: s }) => + Pe.createElement( + 'div', + { className: 'fallback' }, + '😱 ', + Pe.createElement( + 'i', + null, + 'Could not render ', + 't' === s ? 'this component' : s, + ', see the console.' + ) + ); + class ErrorBoundary extends Pe.Component { + static defaultProps = { + targetName: 'this component', + getComponent: () => fallback, + fn: { componentDidCatch: uk }, + children: null + }; + static getDerivedStateFromError(s) { + return { hasError: !0, error: s }; + } + constructor(...s) { + super(...s), (this.state = { hasError: !1, error: null }); + } + componentDidCatch(s, o) { + this.props.fn.componentDidCatch(s, o); + } + render() { + const { getComponent: s, targetName: o, children: i } = this.props; + if (this.state.hasError) { + const i = s('Fallback'); + return Pe.createElement(i, { name: o }); + } + return i; + } + } + const pk = ErrorBoundary, + safe_render = + ({ componentList: s = [], fullOverride: o = !1 } = {}) => + ({ getSystem: i }) => { + const u = o + ? s + : [ + 'App', + 'BaseLayout', + 'VersionPragmaFilter', + 'InfoContainer', + 'ServersContainer', + 'SchemesContainer', + 'AuthorizeBtnContainer', + 'FilterContainer', + 'Operations', + 'OperationContainer', + 'parameters', + 'responses', + 'OperationServers', + 'Models', + 'ModelWrapper', + ...s + ], + _ = lk()( + u, + Array(u.length).fill((s, { fn: o }) => o.withErrorBoundary(s)) + ); + return { + fn: { componentDidCatch: uk, withErrorBoundary: withErrorBoundary(i) }, + components: { ErrorBoundary: pk, Fallback: fallback }, + wrapComponents: _ + }; + }; + class App extends Pe.Component { + getLayout() { + const { getComponent: s, layoutSelectors: o } = this.props, + i = o.current(), + u = s(i, !0); + return u || (() => Pe.createElement('h1', null, ' No layout defined for "', i, '" ')); + } + render() { + const s = this.getLayout(); + return Pe.createElement(s, null); + } + } + const fk = App; + class AuthorizationPopup extends Pe.Component { + close = () => { + let { authActions: s } = this.props; + s.showDefinitions(!1); + }; + render() { + let { + authSelectors: s, + authActions: o, + getComponent: i, + errSelectors: u, + specSelectors: _, + fn: { AST: w = {} } + } = this.props, + x = s.shownDefinitions(); + const C = i('auths'), + j = i('CloseIcon'); + return Pe.createElement( + 'div', + { className: 'dialog-ux' }, + Pe.createElement('div', { className: 'backdrop-ux' }), + Pe.createElement( + 'div', + { className: 'modal-ux' }, + Pe.createElement( + 'div', + { className: 'modal-dialog-ux' }, + Pe.createElement( + 'div', + { className: 'modal-ux-inner' }, + Pe.createElement( + 'div', + { className: 'modal-ux-header' }, + Pe.createElement('h3', null, 'Available authorizations'), + Pe.createElement( + 'button', + { type: 'button', className: 'close-modal', onClick: this.close }, + Pe.createElement(j, null) + ) + ), + Pe.createElement( + 'div', + { className: 'modal-ux-content' }, + x.valueSeq().map((x, j) => + Pe.createElement(C, { + key: j, + AST: w, + definitions: x, + getComponent: i, + errSelectors: u, + authSelectors: s, + authActions: o, + specSelectors: _ + }) + ) + ) + ) + ) + ) + ); + } + } + class AuthorizeBtn extends Pe.Component { + render() { + let { isAuthorized: s, showPopup: o, onClick: i, getComponent: u } = this.props; + const _ = u('authorizationPopup', !0), + w = u('LockAuthIcon', !0), + x = u('UnlockAuthIcon', !0); + return Pe.createElement( + 'div', + { className: 'auth-wrapper' }, + Pe.createElement( + 'button', + { className: s ? 'btn authorize locked' : 'btn authorize unlocked', onClick: i }, + Pe.createElement('span', null, 'Authorize'), + s ? Pe.createElement(w, null) : Pe.createElement(x, null) + ), + o && Pe.createElement(_, null) + ); + } + } + class AuthorizeBtnContainer extends Pe.Component { + render() { + const { + authActions: s, + authSelectors: o, + specSelectors: i, + getComponent: u + } = this.props, + _ = i.securityDefinitions(), + w = o.definitionsToAuthorize(), + x = u('authorizeBtn'); + return _ + ? Pe.createElement(x, { + onClick: () => s.showDefinitions(w), + isAuthorized: !!o.authorized().size, + showPopup: !!o.shownDefinitions(), + getComponent: u + }) + : null; + } + } + class AuthorizeOperationBtn extends Pe.Component { + onClick = (s) => { + s.stopPropagation(); + let { onClick: o } = this.props; + o && o(); + }; + render() { + let { isAuthorized: s, getComponent: o } = this.props; + const i = o('LockAuthOperationIcon', !0), + u = o('UnlockAuthOperationIcon', !0); + return Pe.createElement( + 'button', + { + className: 'authorization__btn', + 'aria-label': s ? 'authorization button locked' : 'authorization button unlocked', + onClick: this.onClick + }, + s + ? Pe.createElement(i, { className: 'locked' }) + : Pe.createElement(u, { className: 'unlocked' }) + ); + } + } + class Auths extends Pe.Component { + constructor(s, o) { + super(s, o), (this.state = {}); + } + onAuthChange = (s) => { + let { name: o } = s; + this.setState({ [o]: s }); + }; + submitAuth = (s) => { + s.preventDefault(); + let { authActions: o } = this.props; + o.authorizeWithPersistOption(this.state); + }; + logoutClick = (s) => { + s.preventDefault(); + let { authActions: o, definitions: i } = this.props, + u = i.map((s, o) => o).toArray(); + this.setState(u.reduce((s, o) => ((s[o] = ''), s), {})), o.logoutWithPersistOption(u); + }; + close = (s) => { + s.preventDefault(); + let { authActions: o } = this.props; + o.showDefinitions(!1); + }; + render() { + let { definitions: s, getComponent: o, authSelectors: i, errSelectors: u } = this.props; + const _ = o('AuthItem'), + w = o('oauth2', !0), + x = o('Button'); + let C = i.authorized(), + j = s.filter((s, o) => !!C.get(o)), + L = s.filter((s) => 'oauth2' !== s.get('type')), + B = s.filter((s) => 'oauth2' === s.get('type')); + return Pe.createElement( + 'div', + { className: 'auth-container' }, + !!L.size && + Pe.createElement( + 'form', + { onSubmit: this.submitAuth }, + L.map((s, i) => + Pe.createElement(_, { + key: i, + schema: s, + name: i, + getComponent: o, + onAuthChange: this.onAuthChange, + authorized: C, + errSelectors: u + }) + ).toArray(), + Pe.createElement( + 'div', + { className: 'auth-btn-wrapper' }, + L.size === j.size + ? Pe.createElement( + x, + { + className: 'btn modal-btn auth', + onClick: this.logoutClick, + 'aria-label': 'Remove authorization' + }, + 'Logout' + ) + : Pe.createElement( + x, + { + type: 'submit', + className: 'btn modal-btn auth authorize', + 'aria-label': 'Apply credentials' + }, + 'Authorize' + ), + Pe.createElement( + x, + { className: 'btn modal-btn auth btn-done', onClick: this.close }, + 'Close' + ) + ) + ), + B && B.size + ? Pe.createElement( + 'div', + null, + Pe.createElement( + 'div', + { className: 'scope-def' }, + Pe.createElement( + 'p', + null, + 'Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes.' + ), + Pe.createElement( + 'p', + null, + 'API requires the following scopes. Select which ones you want to grant to Swagger UI.' + ) + ), + s + .filter((s) => 'oauth2' === s.get('type')) + .map((s, o) => + Pe.createElement( + 'div', + { key: o }, + Pe.createElement(w, { authorized: C, schema: s, name: o }) + ) + ) + .toArray() + ) + : null + ); + } + } + class auth_item_Auths extends Pe.Component { + render() { + let { + schema: s, + name: o, + getComponent: i, + onAuthChange: u, + authorized: _, + errSelectors: w + } = this.props; + const x = i('apiKeyAuth'), + C = i('basicAuth'); + let j; + const L = s.get('type'); + switch (L) { + case 'apiKey': + j = Pe.createElement(x, { + key: o, + schema: s, + name: o, + errSelectors: w, + authorized: _, + getComponent: i, + onChange: u + }); + break; + case 'basic': + j = Pe.createElement(C, { + key: o, + schema: s, + name: o, + errSelectors: w, + authorized: _, + getComponent: i, + onChange: u + }); + break; + default: + j = Pe.createElement('div', { key: o }, 'Unknown security definition type ', L); + } + return Pe.createElement('div', { key: `${o}-jump` }, j); + } + } + class AuthError extends Pe.Component { + render() { + let { error: s } = this.props, + o = s.get('level'), + i = s.get('message'), + u = s.get('source'); + return Pe.createElement( + 'div', + { className: 'errors' }, + Pe.createElement('b', null, u, ' ', o), + Pe.createElement('span', null, i) + ); + } + } + class ApiKeyAuth extends Pe.Component { + constructor(s, o) { + super(s, o); + let { name: i, schema: u } = this.props, + _ = this.getValue(); + this.state = { name: i, schema: u, value: _ }; + } + getValue() { + let { name: s, authorized: o } = this.props; + return o && o.getIn([s, 'value']); + } + onChange = (s) => { + let { onChange: o } = this.props, + i = s.target.value, + u = Object.assign({}, this.state, { value: i }); + this.setState(u), o(u); + }; + render() { + let { schema: s, getComponent: o, errSelectors: i, name: u } = this.props; + const _ = o('Input'), + w = o('Row'), + x = o('Col'), + C = o('authError'), + j = o('Markdown', !0), + L = o('JumpToPath', !0); + let B = this.getValue(), + $ = i.allErrors().filter((s) => s.get('authId') === u); + return Pe.createElement( + 'div', + null, + Pe.createElement( + 'h4', + null, + Pe.createElement('code', null, u || s.get('name')), + ' (apiKey)', + Pe.createElement(L, { path: ['securityDefinitions', u] }) + ), + B && Pe.createElement('h6', null, 'Authorized'), + Pe.createElement(w, null, Pe.createElement(j, { source: s.get('description') })), + Pe.createElement( + w, + null, + Pe.createElement('p', null, 'Name: ', Pe.createElement('code', null, s.get('name'))) + ), + Pe.createElement( + w, + null, + Pe.createElement('p', null, 'In: ', Pe.createElement('code', null, s.get('in'))) + ), + Pe.createElement( + w, + null, + Pe.createElement('label', { htmlFor: 'api_key_value' }, 'Value:'), + B + ? Pe.createElement('code', null, ' ****** ') + : Pe.createElement( + x, + null, + Pe.createElement(_, { + id: 'api_key_value', + type: 'text', + onChange: this.onChange, + autoFocus: !0 + }) + ) + ), + $.valueSeq().map((s, o) => Pe.createElement(C, { error: s, key: o })) + ); + } + } + class BasicAuth extends Pe.Component { + constructor(s, o) { + super(s, o); + let { schema: i, name: u } = this.props, + _ = this.getValue().username; + this.state = { name: u, schema: i, value: _ ? { username: _ } : {} }; + } + getValue() { + let { authorized: s, name: o } = this.props; + return (s && s.getIn([o, 'value'])) || {}; + } + onChange = (s) => { + let { onChange: o } = this.props, + { value: i, name: u } = s.target, + _ = this.state.value; + (_[u] = i), this.setState({ value: _ }), o(this.state); + }; + render() { + let { schema: s, getComponent: o, name: i, errSelectors: u } = this.props; + const _ = o('Input'), + w = o('Row'), + x = o('Col'), + C = o('authError'), + j = o('JumpToPath', !0), + L = o('Markdown', !0); + let B = this.getValue().username, + $ = u.allErrors().filter((s) => s.get('authId') === i); + return Pe.createElement( + 'div', + null, + Pe.createElement( + 'h4', + null, + 'Basic authorization', + Pe.createElement(j, { path: ['securityDefinitions', i] }) + ), + B && Pe.createElement('h6', null, 'Authorized'), + Pe.createElement(w, null, Pe.createElement(L, { source: s.get('description') })), + Pe.createElement( + w, + null, + Pe.createElement('label', { htmlFor: 'auth_username' }, 'Username:'), + B + ? Pe.createElement('code', null, ' ', B, ' ') + : Pe.createElement( + x, + null, + Pe.createElement(_, { + id: 'auth_username', + type: 'text', + required: 'required', + name: 'username', + onChange: this.onChange, + autoFocus: !0 + }) + ) + ), + Pe.createElement( + w, + null, + Pe.createElement('label', { htmlFor: 'auth_password' }, 'Password:'), + B + ? Pe.createElement('code', null, ' ****** ') + : Pe.createElement( + x, + null, + Pe.createElement(_, { + id: 'auth_password', + autoComplete: 'new-password', + name: 'password', + type: 'password', + onChange: this.onChange + }) + ) + ), + $.valueSeq().map((s, o) => Pe.createElement(C, { error: s, key: o })) + ); + } + } + function example_Example(s) { + const { example: o, showValue: i, getComponent: u } = s, + _ = u('Markdown', !0), + w = u('HighlightCode', !0); + return o + ? Pe.createElement( + 'div', + { className: 'example' }, + o.get('description') + ? Pe.createElement( + 'section', + { className: 'example__section' }, + Pe.createElement( + 'div', + { className: 'example__section-header' }, + 'Example Description' + ), + Pe.createElement( + 'p', + null, + Pe.createElement(_, { source: o.get('description') }) + ) + ) + : null, + i && o.has('value') + ? Pe.createElement( + 'section', + { className: 'example__section' }, + Pe.createElement( + 'div', + { className: 'example__section-header' }, + 'Example Value' + ), + Pe.createElement(w, null, stringify(o.get('value'))) + ) + : null + ) + : null; + } + class ExamplesSelect extends Pe.PureComponent { + static defaultProps = { + examples: $e().Map({}), + onSelect: (...s) => + console.log('DEBUG: ExamplesSelect was not given an onSelect callback', ...s), + currentExampleKey: null, + showLabels: !0 + }; + _onSelect = (s, { isSyntheticChange: o = !1 } = {}) => { + 'function' == typeof this.props.onSelect && + this.props.onSelect(s, { isSyntheticChange: o }); + }; + _onDomSelect = (s) => { + if ('function' == typeof this.props.onSelect) { + const o = s.target.selectedOptions[0].getAttribute('value'); + this._onSelect(o, { isSyntheticChange: !1 }); + } + }; + getCurrentExample = () => { + const { examples: s, currentExampleKey: o } = this.props, + i = s.get(o), + u = s.keySeq().first(), + _ = s.get(u); + return i || _ || Map({}); + }; + componentDidMount() { + const { onSelect: s, examples: o } = this.props; + if ('function' == typeof s) { + const s = o.first(), + i = o.keyOf(s); + this._onSelect(i, { isSyntheticChange: !0 }); + } + } + UNSAFE_componentWillReceiveProps(s) { + const { currentExampleKey: o, examples: i } = s; + if (i !== this.props.examples && !i.has(o)) { + const s = i.first(), + o = i.keyOf(s); + this._onSelect(o, { isSyntheticChange: !0 }); + } + } + render() { + const { + examples: s, + currentExampleKey: o, + isValueModified: i, + isModifiedValueAvailable: u, + showLabels: _ + } = this.props; + return Pe.createElement( + 'div', + { className: 'examples-select' }, + _ + ? Pe.createElement( + 'span', + { className: 'examples-select__section-label' }, + 'Examples: ' + ) + : null, + Pe.createElement( + 'select', + { + className: 'examples-select-element', + onChange: this._onDomSelect, + value: u && i ? '__MODIFIED__VALUE__' : o || '' + }, + u + ? Pe.createElement('option', { value: '__MODIFIED__VALUE__' }, '[Modified value]') + : null, + s + .map((s, o) => + Pe.createElement('option', { key: o, value: o }, s.get('summary') || o) + ) + .valueSeq() + ) + ); + } + } + const stringifyUnlessList = (s) => (qe.List.isList(s) ? s : stringify(s)); + class ExamplesSelectValueRetainer extends Pe.PureComponent { + static defaultProps = { + userHasEditedBody: !1, + examples: (0, qe.Map)({}), + currentNamespace: '__DEFAULT__NAMESPACE__', + setRetainRequestBodyValueFlag: () => {}, + onSelect: (...s) => + console.log('ExamplesSelectValueRetainer: no `onSelect` function was provided', ...s), + updateValue: (...s) => + console.log( + 'ExamplesSelectValueRetainer: no `updateValue` function was provided', + ...s + ) + }; + constructor(s) { + super(s); + const o = this._getCurrentExampleValue(); + this.state = { + [s.currentNamespace]: (0, qe.Map)({ + lastUserEditedValue: this.props.currentUserInputValue, + lastDownstreamValue: o, + isModifiedValueSelected: + this.props.userHasEditedBody || this.props.currentUserInputValue !== o + }) + }; + } + componentWillUnmount() { + this.props.setRetainRequestBodyValueFlag(!1); + } + _getStateForCurrentNamespace = () => { + const { currentNamespace: s } = this.props; + return (this.state[s] || (0, qe.Map)()).toObject(); + }; + _setStateForCurrentNamespace = (s) => { + const { currentNamespace: o } = this.props; + return this._setStateForNamespace(o, s); + }; + _setStateForNamespace = (s, o) => { + const i = (this.state[s] || (0, qe.Map)()).mergeDeep(o); + return this.setState({ [s]: i }); + }; + _isCurrentUserInputSameAsExampleValue = () => { + const { currentUserInputValue: s } = this.props; + return this._getCurrentExampleValue() === s; + }; + _getValueForExample = (s, o) => { + const { examples: i } = o || this.props; + return stringifyUnlessList((i || (0, qe.Map)({})).getIn([s, 'value'])); + }; + _getCurrentExampleValue = (s) => { + const { currentKey: o } = s || this.props; + return this._getValueForExample(o, s || this.props); + }; + _onExamplesSelect = (s, { isSyntheticChange: o } = {}, ...i) => { + const { + onSelect: u, + updateValue: _, + currentUserInputValue: w, + userHasEditedBody: x + } = this.props, + { lastUserEditedValue: C } = this._getStateForCurrentNamespace(), + j = this._getValueForExample(s); + if ('__MODIFIED__VALUE__' === s) + return ( + _(stringifyUnlessList(C)), + this._setStateForCurrentNamespace({ isModifiedValueSelected: !0 }) + ); + 'function' == typeof u && u(s, { isSyntheticChange: o }, ...i), + this._setStateForCurrentNamespace({ + lastDownstreamValue: j, + isModifiedValueSelected: (o && x) || (!!w && w !== j) + }), + o || ('function' == typeof _ && _(stringifyUnlessList(j))); + }; + UNSAFE_componentWillReceiveProps(s) { + const { currentUserInputValue: o, examples: i, onSelect: u, userHasEditedBody: _ } = s, + { lastUserEditedValue: w, lastDownstreamValue: x } = + this._getStateForCurrentNamespace(), + C = this._getValueForExample(s.currentKey, s), + j = i.filter((s) => s.get('value') === o || stringify(s.get('value')) === o); + if (j.size) { + let o; + (o = j.has(s.currentKey) ? s.currentKey : j.keySeq().first()), + u(o, { isSyntheticChange: !0 }); + } else + o !== this.props.currentUserInputValue && + o !== w && + o !== x && + (this.props.setRetainRequestBodyValueFlag(!0), + this._setStateForNamespace(s.currentNamespace, { + lastUserEditedValue: s.currentUserInputValue, + isModifiedValueSelected: _ || o !== C + })); + } + render() { + const { + currentUserInputValue: s, + examples: o, + currentKey: i, + getComponent: u, + userHasEditedBody: _ + } = this.props, + { + lastDownstreamValue: w, + lastUserEditedValue: x, + isModifiedValueSelected: C + } = this._getStateForCurrentNamespace(), + j = u('ExamplesSelect'); + return Pe.createElement(j, { + examples: o, + currentExampleKey: i, + onSelect: this._onExamplesSelect, + isModifiedValueAvailable: !!x && x !== w, + isValueModified: (void 0 !== s && C && s !== this._getCurrentExampleValue()) || _ + }); + } + } + function oauth2_authorize_authorize({ + auth: s, + authActions: o, + errActions: i, + configs: u, + authConfigs: _ = {}, + currentServer: w + }) { + let { schema: x, scopes: C, name: j, clientId: L } = s, + B = x.get('flow'), + $ = []; + switch (B) { + case 'password': + return void o.authorizePassword(s); + case 'application': + case 'clientCredentials': + case 'client_credentials': + return void o.authorizeApplication(s); + case 'accessCode': + case 'authorizationCode': + case 'authorization_code': + $.push('response_type=code'); + break; + case 'implicit': + $.push('response_type=token'); + } + 'string' == typeof L && $.push('client_id=' + encodeURIComponent(L)); + let V = u.oauth2RedirectUrl; + if (void 0 === V) + return void i.newAuthErr({ + authId: j, + source: 'validation', + level: 'error', + message: + 'oauth2RedirectUrl configuration is not passed. Oauth2 authorization cannot be performed.' + }); + $.push('redirect_uri=' + encodeURIComponent(V)); + let U = []; + if ( + (Array.isArray(C) ? (U = C) : $e().List.isList(C) && (U = C.toArray()), U.length > 0) + ) { + let s = _.scopeSeparator || ' '; + $.push('scope=' + encodeURIComponent(U.join(s))); + } + let z = utils_btoa(new Date()); + if ( + ($.push('state=' + encodeURIComponent(z)), + void 0 !== _.realm && $.push('realm=' + encodeURIComponent(_.realm)), + ('authorizationCode' === B || 'authorization_code' === B || 'accessCode' === B) && + _.usePkceWithAuthorizationCodeGrant) + ) { + const o = (function generateCodeVerifier() { + return b64toB64UrlEncoded(St()(32).toString('base64')); + })(), + i = (function createCodeChallenge(s) { + return b64toB64UrlEncoded(kt()('sha256').update(s).digest('base64')); + })(o); + $.push('code_challenge=' + i), + $.push('code_challenge_method=S256'), + (s.codeVerifier = o); + } + let { additionalQueryStringParams: Y } = _; + for (let s in Y) void 0 !== Y[s] && $.push([s, Y[s]].map(encodeURIComponent).join('=')); + const Z = x.get('authorizationUrl'); + let ee; + ee = w ? Mt()(sanitizeUrl(Z), w, !0).toString() : sanitizeUrl(Z); + let ie, + ae = [ee, $.join('&')].join(-1 === Z.indexOf('?') ? '?' : '&'); + (ie = + 'implicit' === B + ? o.preAuthorizeImplicit + : _.useBasicAuthenticationWithAccessCodeGrant + ? o.authorizeAccessCodeWithBasicAuthentication + : o.authorizeAccessCodeWithFormParams), + o.authPopup(ae, { + auth: s, + state: z, + redirectUrl: V, + callback: ie, + errCb: i.newAuthErr + }); + } + class Oauth2 extends Pe.Component { + constructor(s, o) { + super(s, o); + let { name: i, schema: u, authorized: _, authSelectors: w } = this.props, + x = _ && _.get(i), + C = w.getConfigs() || {}, + j = (x && x.get('username')) || '', + L = (x && x.get('clientId')) || C.clientId || '', + B = (x && x.get('clientSecret')) || C.clientSecret || '', + $ = (x && x.get('passwordType')) || 'basic', + V = (x && x.get('scopes')) || C.scopes || []; + 'string' == typeof V && (V = V.split(C.scopeSeparator || ' ')), + (this.state = { + appName: C.appName, + name: i, + schema: u, + scopes: V, + clientId: L, + clientSecret: B, + username: j, + password: '', + passwordType: $ + }); + } + close = (s) => { + s.preventDefault(); + let { authActions: o } = this.props; + o.showDefinitions(!1); + }; + authorize = () => { + let { + authActions: s, + errActions: o, + getConfigs: i, + authSelectors: u, + oas3Selectors: _ + } = this.props, + w = i(), + x = u.getConfigs(); + o.clear({ authId: name, type: 'auth', source: 'auth' }), + oauth2_authorize_authorize({ + auth: this.state, + currentServer: _.serverEffectiveValue(_.selectedServer()), + authActions: s, + errActions: o, + configs: w, + authConfigs: x + }); + }; + onScopeChange = (s) => { + let { target: o } = s, + { checked: i } = o, + u = o.dataset.value; + if (i && -1 === this.state.scopes.indexOf(u)) { + let s = this.state.scopes.concat([u]); + this.setState({ scopes: s }); + } else + !i && + this.state.scopes.indexOf(u) > -1 && + this.setState({ scopes: this.state.scopes.filter((s) => s !== u) }); + }; + onInputChange = (s) => { + let { + target: { + dataset: { name: o }, + value: i + } + } = s, + u = { [o]: i }; + this.setState(u); + }; + selectScopes = (s) => { + s.target.dataset.all + ? this.setState({ + scopes: Array.from( + ( + this.props.schema.get('allowedScopes') || this.props.schema.get('scopes') + ).keys() + ) + }) + : this.setState({ scopes: [] }); + }; + logout = (s) => { + s.preventDefault(); + let { authActions: o, errActions: i, name: u } = this.props; + i.clear({ authId: u, type: 'auth', source: 'auth' }), o.logoutWithPersistOption([u]); + }; + render() { + let { + schema: s, + getComponent: o, + authSelectors: i, + errSelectors: u, + name: _, + specSelectors: w + } = this.props; + const x = o('Input'), + C = o('Row'), + j = o('Col'), + L = o('Button'), + B = o('authError'), + $ = o('JumpToPath', !0), + V = o('Markdown', !0), + U = o('InitializedInput'), + { isOAS3: z } = w; + let Y = z() ? s.get('openIdConnectUrl') : null; + const Z = 'implicit', + ee = 'password', + ie = z() ? (Y ? 'authorization_code' : 'authorizationCode') : 'accessCode', + ae = z() ? (Y ? 'client_credentials' : 'clientCredentials') : 'application'; + let le = !!(i.getConfigs() || {}).usePkceWithAuthorizationCodeGrant, + ce = s.get('flow'), + pe = ce === ie && le ? ce + ' with PKCE' : ce, + de = s.get('allowedScopes') || s.get('scopes'), + fe = !!i.authorized().get(_), + ye = u.allErrors().filter((s) => s.get('authId') === _), + be = !ye.filter((s) => 'validation' === s.get('source')).size, + _e = s.get('description'); + return Pe.createElement( + 'div', + null, + Pe.createElement( + 'h4', + null, + _, + ' (OAuth2, ', + pe, + ') ', + Pe.createElement($, { path: ['securityDefinitions', _] }) + ), + this.state.appName + ? Pe.createElement('h5', null, 'Application: ', this.state.appName, ' ') + : null, + _e && Pe.createElement(V, { source: s.get('description') }), + fe && Pe.createElement('h6', null, 'Authorized'), + Y && + Pe.createElement( + 'p', + null, + 'OpenID Connect URL: ', + Pe.createElement('code', null, Y) + ), + (ce === Z || ce === ie) && + Pe.createElement( + 'p', + null, + 'Authorization URL: ', + Pe.createElement('code', null, s.get('authorizationUrl')) + ), + (ce === ee || ce === ie || ce === ae) && + Pe.createElement( + 'p', + null, + 'Token URL:', + Pe.createElement('code', null, ' ', s.get('tokenUrl')) + ), + Pe.createElement( + 'p', + { className: 'flow' }, + 'Flow: ', + Pe.createElement('code', null, pe) + ), + ce !== ee + ? null + : Pe.createElement( + C, + null, + Pe.createElement( + C, + null, + Pe.createElement('label', { htmlFor: 'oauth_username' }, 'username:'), + fe + ? Pe.createElement('code', null, ' ', this.state.username, ' ') + : Pe.createElement( + j, + { tablet: 10, desktop: 10 }, + Pe.createElement('input', { + id: 'oauth_username', + type: 'text', + 'data-name': 'username', + onChange: this.onInputChange, + autoFocus: !0 + }) + ) + ), + Pe.createElement( + C, + null, + Pe.createElement('label', { htmlFor: 'oauth_password' }, 'password:'), + fe + ? Pe.createElement('code', null, ' ****** ') + : Pe.createElement( + j, + { tablet: 10, desktop: 10 }, + Pe.createElement('input', { + id: 'oauth_password', + type: 'password', + 'data-name': 'password', + onChange: this.onInputChange + }) + ) + ), + Pe.createElement( + C, + null, + Pe.createElement( + 'label', + { htmlFor: 'password_type' }, + 'Client credentials location:' + ), + fe + ? Pe.createElement('code', null, ' ', this.state.passwordType, ' ') + : Pe.createElement( + j, + { tablet: 10, desktop: 10 }, + Pe.createElement( + 'select', + { + id: 'password_type', + 'data-name': 'passwordType', + onChange: this.onInputChange + }, + Pe.createElement( + 'option', + { value: 'basic' }, + 'Authorization header' + ), + Pe.createElement('option', { value: 'request-body' }, 'Request body') + ) + ) + ) + ), + (ce === ae || ce === Z || ce === ie || ce === ee) && + (!fe || (fe && this.state.clientId)) && + Pe.createElement( + C, + null, + Pe.createElement('label', { htmlFor: `client_id_${ce}` }, 'client_id:'), + fe + ? Pe.createElement('code', null, ' ****** ') + : Pe.createElement( + j, + { tablet: 10, desktop: 10 }, + Pe.createElement(U, { + id: `client_id_${ce}`, + type: 'text', + required: ce === ee, + initialValue: this.state.clientId, + 'data-name': 'clientId', + onChange: this.onInputChange + }) + ) + ), + (ce === ae || ce === ie || ce === ee) && + Pe.createElement( + C, + null, + Pe.createElement('label', { htmlFor: `client_secret_${ce}` }, 'client_secret:'), + fe + ? Pe.createElement('code', null, ' ****** ') + : Pe.createElement( + j, + { tablet: 10, desktop: 10 }, + Pe.createElement(U, { + id: `client_secret_${ce}`, + initialValue: this.state.clientSecret, + type: 'password', + 'data-name': 'clientSecret', + onChange: this.onInputChange + }) + ) + ), + !fe && de && de.size + ? Pe.createElement( + 'div', + { className: 'scopes' }, + Pe.createElement( + 'h2', + null, + 'Scopes:', + Pe.createElement( + 'a', + { onClick: this.selectScopes, 'data-all': !0 }, + 'select all' + ), + Pe.createElement('a', { onClick: this.selectScopes }, 'select none') + ), + de + .map((s, o) => + Pe.createElement( + C, + { key: o }, + Pe.createElement( + 'div', + { className: 'checkbox' }, + Pe.createElement(x, { + 'data-value': o, + id: `${o}-${ce}-checkbox-${this.state.name}`, + disabled: fe, + checked: this.state.scopes.includes(o), + type: 'checkbox', + onChange: this.onScopeChange + }), + Pe.createElement( + 'label', + { htmlFor: `${o}-${ce}-checkbox-${this.state.name}` }, + Pe.createElement('span', { className: 'item' }), + Pe.createElement( + 'div', + { className: 'text' }, + Pe.createElement('p', { className: 'name' }, o), + Pe.createElement('p', { className: 'description' }, s) + ) + ) + ) + ) + ) + .toArray() + ) + : null, + ye.valueSeq().map((s, o) => Pe.createElement(B, { error: s, key: o })), + Pe.createElement( + 'div', + { className: 'auth-btn-wrapper' }, + be && + (fe + ? Pe.createElement( + L, + { + className: 'btn modal-btn auth authorize', + onClick: this.logout, + 'aria-label': 'Remove authorization' + }, + 'Logout' + ) + : Pe.createElement( + L, + { + className: 'btn modal-btn auth authorize', + onClick: this.authorize, + 'aria-label': 'Apply given OAuth2 credentials' + }, + 'Authorize' + )), + Pe.createElement( + L, + { className: 'btn modal-btn auth btn-done', onClick: this.close }, + 'Close' + ) + ) + ); + } + } + class Clear extends Pe.Component { + onClick = () => { + let { specActions: s, path: o, method: i } = this.props; + s.clearResponse(o, i), s.clearRequest(o, i); + }; + render() { + return Pe.createElement( + 'button', + { className: 'btn btn-clear opblock-control__btn', onClick: this.onClick }, + 'Clear' + ); + } + } + const live_response_Headers = ({ headers: s }) => + Pe.createElement( + 'div', + null, + Pe.createElement('h5', null, 'Response headers'), + Pe.createElement('pre', { className: 'microlight' }, s) + ), + Duration = ({ duration: s }) => + Pe.createElement( + 'div', + null, + Pe.createElement('h5', null, 'Request duration'), + Pe.createElement('pre', { className: 'microlight' }, s, ' ms') + ); + class LiveResponse extends Pe.Component { + shouldComponentUpdate(s) { + return ( + this.props.response !== s.response || + this.props.path !== s.path || + this.props.method !== s.method || + this.props.displayRequestDuration !== s.displayRequestDuration + ); + } + render() { + const { + response: s, + getComponent: o, + getConfigs: i, + displayRequestDuration: u, + specSelectors: _, + path: w, + method: x + } = this.props, + { showMutatedRequest: C, requestSnippetsEnabled: j } = i(), + L = C ? _.mutatedRequestFor(w, x) : _.requestFor(w, x), + B = s.get('status'), + $ = L.get('url'), + V = s.get('headers').toJS(), + U = s.get('notDocumented'), + z = s.get('error'), + Y = s.get('text'), + Z = s.get('duration'), + ee = Object.keys(V), + ie = V['content-type'] || V['Content-Type'], + ae = o('responseBody'), + le = ee.map((s) => { + var o = Array.isArray(V[s]) ? V[s].join() : V[s]; + return Pe.createElement( + 'span', + { className: 'headerline', key: s }, + ' ', + s, + ': ', + o, + ' ' + ); + }), + ce = 0 !== le.length, + pe = o('Markdown', !0), + de = o('RequestSnippets', !0), + fe = o('curl', !0); + return Pe.createElement( + 'div', + null, + L && j ? Pe.createElement(de, { request: L }) : Pe.createElement(fe, { request: L }), + $ && + Pe.createElement( + 'div', + null, + Pe.createElement( + 'div', + { className: 'request-url' }, + Pe.createElement('h4', null, 'Request URL'), + Pe.createElement('pre', { className: 'microlight' }, $) + ) + ), + Pe.createElement('h4', null, 'Server response'), + Pe.createElement( + 'table', + { className: 'responses-table live-responses-table' }, + Pe.createElement( + 'thead', + null, + Pe.createElement( + 'tr', + { className: 'responses-header' }, + Pe.createElement('td', { className: 'col_header response-col_status' }, 'Code'), + Pe.createElement( + 'td', + { className: 'col_header response-col_description' }, + 'Details' + ) + ) + ), + Pe.createElement( + 'tbody', + null, + Pe.createElement( + 'tr', + { className: 'response' }, + Pe.createElement( + 'td', + { className: 'response-col_status' }, + B, + U + ? Pe.createElement( + 'div', + { className: 'response-undocumented' }, + Pe.createElement('i', null, ' Undocumented ') + ) + : null + ), + Pe.createElement( + 'td', + { className: 'response-col_description' }, + z + ? Pe.createElement(pe, { + source: `${'' !== s.get('name') ? `${s.get('name')}: ` : ''}${s.get('message')}` + }) + : null, + Y + ? Pe.createElement(ae, { + content: Y, + contentType: ie, + url: $, + headers: V, + getConfigs: i, + getComponent: o + }) + : null, + ce ? Pe.createElement(live_response_Headers, { headers: le }) : null, + u && Z ? Pe.createElement(Duration, { duration: Z }) : null + ) + ) + ) + ) + ); + } + } + class OnlineValidatorBadge extends Pe.Component { + constructor(s, o) { + super(s, o); + let { getConfigs: i } = s, + { validatorUrl: u } = i(); + this.state = { + url: this.getDefinitionUrl(), + validatorUrl: void 0 === u ? 'https://validator.swagger.io/validator' : u + }; + } + getDefinitionUrl = () => { + let { specSelectors: s } = this.props; + return new (Mt())(s.url(), at.location).toString(); + }; + UNSAFE_componentWillReceiveProps(s) { + let { getConfigs: o } = s, + { validatorUrl: i } = o(); + this.setState({ + url: this.getDefinitionUrl(), + validatorUrl: void 0 === i ? 'https://validator.swagger.io/validator' : i + }); + } + render() { + let { getConfigs: s } = this.props, + { spec: o } = s(), + i = sanitizeUrl(this.state.validatorUrl); + return 'object' == typeof o && Object.keys(o).length + ? null + : this.state.url && + requiresValidationURL(this.state.validatorUrl) && + requiresValidationURL(this.state.url) + ? Pe.createElement( + 'span', + { className: 'float-right' }, + Pe.createElement( + 'a', + { + target: '_blank', + rel: 'noopener noreferrer', + href: `${i}/debug?url=${encodeURIComponent(this.state.url)}` + }, + Pe.createElement(ValidatorImage, { + src: `${i}?url=${encodeURIComponent(this.state.url)}`, + alt: 'Online validator badge' + }) + ) + ) + : null; + } + } + class ValidatorImage extends Pe.Component { + constructor(s) { + super(s), (this.state = { loaded: !1, error: !1 }); + } + componentDidMount() { + const s = new Image(); + (s.onload = () => { + this.setState({ loaded: !0 }); + }), + (s.onerror = () => { + this.setState({ error: !0 }); + }), + (s.src = this.props.src); + } + UNSAFE_componentWillReceiveProps(s) { + if (s.src !== this.props.src) { + const o = new Image(); + (o.onload = () => { + this.setState({ loaded: !0 }); + }), + (o.onerror = () => { + this.setState({ error: !0 }); + }), + (o.src = s.src); + } + } + render() { + return this.state.error + ? Pe.createElement('img', { alt: 'Error' }) + : this.state.loaded + ? Pe.createElement('img', { src: this.props.src, alt: this.props.alt }) + : null; + } + } + class Operations extends Pe.Component { + render() { + let { specSelectors: s } = this.props; + const o = s.taggedOperations(); + return 0 === o.size + ? Pe.createElement('h3', null, ' No operations defined in spec!') + : Pe.createElement( + 'div', + null, + o.map(this.renderOperationTag).toArray(), + o.size < 1 + ? Pe.createElement('h3', null, ' No operations defined in spec! ') + : null + ); + } + renderOperationTag = (s, o) => { + const { + specSelectors: i, + getComponent: u, + oas3Selectors: _, + layoutSelectors: w, + layoutActions: x, + getConfigs: C + } = this.props, + j = i.validOperationMethods(), + L = u('OperationContainer', !0), + B = u('OperationTag'), + $ = s.get('operations'); + return Pe.createElement( + B, + { + key: 'operation-' + o, + tagObj: s, + tag: o, + oas3Selectors: _, + layoutSelectors: w, + layoutActions: x, + getConfigs: C, + getComponent: u, + specUrl: i.url() + }, + Pe.createElement( + 'div', + { className: 'operation-tag-content' }, + $.map((s) => { + const i = s.get('path'), + u = s.get('method'), + _ = $e().List(['paths', i, u]); + return -1 === j.indexOf(u) + ? null + : Pe.createElement(L, { + key: `${i}-${u}`, + specPath: _, + op: s, + path: i, + method: u, + tag: o + }); + }).toArray() + ) + ); + }; + } + function isAbsoluteUrl(s) { + return s.match(/^(?:[a-z]+:)?\/\//i); + } + function buildBaseUrl(s, o) { + return s + ? isAbsoluteUrl(s) + ? (function addProtocol(s) { + return s.match(/^\/\//i) ? `${window.location.protocol}${s}` : s; + })(s) + : new URL(s, o).href + : o; + } + function safeBuildUrl(s, o, { selectedServer: i = '' } = {}) { + try { + return (function buildUrl(s, o, { selectedServer: i = '' } = {}) { + if (!s) return; + if (isAbsoluteUrl(s)) return s; + const u = buildBaseUrl(i, o); + return isAbsoluteUrl(u) ? new URL(s, u).href : new URL(s, window.location.href).href; + })(s, o, { selectedServer: i }); + } catch { + return; + } + } + class OperationTag extends Pe.Component { + static defaultProps = { tagObj: $e().fromJS({}), tag: '' }; + render() { + const { + tagObj: s, + tag: o, + children: i, + oas3Selectors: u, + layoutSelectors: _, + layoutActions: w, + getConfigs: x, + getComponent: C, + specUrl: j + } = this.props; + let { docExpansion: L, deepLinking: B } = x(); + const $ = C('Collapse'), + V = C('Markdown', !0), + U = C('DeepLink'), + z = C('Link'), + Y = C('ArrowUpIcon'), + Z = C('ArrowDownIcon'); + let ee, + ie = s.getIn(['tagDetails', 'description'], null), + ae = s.getIn(['tagDetails', 'externalDocs', 'description']), + le = s.getIn(['tagDetails', 'externalDocs', 'url']); + ee = + isFunc(u) && isFunc(u.selectedServer) + ? safeBuildUrl(le, j, { selectedServer: u.selectedServer() }) + : le; + let ce = ['operations-tag', o], + pe = _.isShown(ce, 'full' === L || 'list' === L); + return Pe.createElement( + 'div', + { className: pe ? 'opblock-tag-section is-open' : 'opblock-tag-section' }, + Pe.createElement( + 'h3', + { + onClick: () => w.show(ce, !pe), + className: ie ? 'opblock-tag' : 'opblock-tag no-desc', + id: ce.map((s) => escapeDeepLinkPath(s)).join('-'), + 'data-tag': o, + 'data-is-open': pe + }, + Pe.createElement(U, { + enabled: B, + isShown: pe, + path: createDeepLinkPath(o), + text: o + }), + ie + ? Pe.createElement('small', null, Pe.createElement(V, { source: ie })) + : Pe.createElement('small', null), + ee + ? Pe.createElement( + 'div', + { className: 'info__externaldocs' }, + Pe.createElement( + 'small', + null, + Pe.createElement( + z, + { + href: sanitizeUrl(ee), + onClick: (s) => s.stopPropagation(), + target: '_blank' + }, + ae || ee + ) + ) + ) + : null, + Pe.createElement( + 'button', + { + 'aria-expanded': pe, + className: 'expand-operation', + title: pe ? 'Collapse operation' : 'Expand operation', + onClick: () => w.show(ce, !pe) + }, + pe + ? Pe.createElement(Y, { className: 'arrow' }) + : Pe.createElement(Z, { className: 'arrow' }) + ) + ), + Pe.createElement($, { isOpened: pe }, i) + ); + } + } + class operation_Operation extends Pe.PureComponent { + static defaultProps = { + operation: null, + response: null, + request: null, + specPath: (0, qe.List)(), + summary: '' + }; + render() { + let { + specPath: s, + response: o, + request: i, + toggleShown: u, + onTryoutClick: _, + onResetClick: w, + onCancelClick: x, + onExecute: C, + fn: j, + getComponent: L, + getConfigs: B, + specActions: $, + specSelectors: V, + authActions: U, + authSelectors: z, + oas3Actions: Y, + oas3Selectors: Z + } = this.props, + ee = this.props.operation, + { + deprecated: ie, + isShown: ae, + path: le, + method: ce, + op: pe, + tag: de, + operationId: fe, + allowTryItOut: ye, + displayRequestDuration: be, + tryItOutEnabled: _e, + executeInProgress: we + } = ee.toJS(), + { description: Se, externalDocs: xe, schemes: Te } = pe; + const Re = xe + ? safeBuildUrl(xe.url, V.url(), { selectedServer: Z.selectedServer() }) + : ''; + let qe = ee.getIn(['op']), + ze = qe.get('responses'), + We = (function getList(s, o) { + if (!$e().Iterable.isIterable(s)) return $e().List(); + let i = s.getIn(Array.isArray(o) ? o : [o]); + return $e().List.isList(i) ? i : $e().List(); + })(qe, ['parameters']), + He = V.operationScheme(le, ce), + Ye = ['operations', de, fe], + Xe = getExtensions(qe); + const Qe = L('responses'), + et = L('parameters'), + tt = L('execute'), + rt = L('clear'), + nt = L('Collapse'), + st = L('Markdown', !0), + ot = L('schemes'), + it = L('OperationServers'), + at = L('OperationExt'), + lt = L('OperationSummary'), + ct = L('Link'), + { showExtensions: ut } = B(); + if (ze && o && o.size > 0) { + let s = !ze.get(String(o.get('status'))) && !ze.get('default'); + o = o.set('notDocumented', s); + } + let pt = [le, ce]; + const ht = V.validationErrors([le, ce]); + return Pe.createElement( + 'div', + { + className: ie + ? 'opblock opblock-deprecated' + : ae + ? `opblock opblock-${ce} is-open` + : `opblock opblock-${ce}`, + id: escapeDeepLinkPath(Ye.join('-')) + }, + Pe.createElement(lt, { + operationProps: ee, + isShown: ae, + toggleShown: u, + getComponent: L, + authActions: U, + authSelectors: z, + specPath: s + }), + Pe.createElement( + nt, + { isOpened: ae }, + Pe.createElement( + 'div', + { className: 'opblock-body' }, + (qe && qe.size) || null === qe + ? null + : Pe.createElement(rolling_load, { + height: '32px', + width: '32px', + className: 'opblock-loading-animation' + }), + ie && + Pe.createElement( + 'h4', + { className: 'opblock-title_normal' }, + ' Warning: Deprecated' + ), + Se && + Pe.createElement( + 'div', + { className: 'opblock-description-wrapper' }, + Pe.createElement( + 'div', + { className: 'opblock-description' }, + Pe.createElement(st, { source: Se }) + ) + ), + Re + ? Pe.createElement( + 'div', + { className: 'opblock-external-docs-wrapper' }, + Pe.createElement( + 'h4', + { className: 'opblock-title_normal' }, + 'Find more details' + ), + Pe.createElement( + 'div', + { className: 'opblock-external-docs' }, + xe.description && + Pe.createElement( + 'span', + { className: 'opblock-external-docs__description' }, + Pe.createElement(st, { source: xe.description }) + ), + Pe.createElement( + ct, + { + target: '_blank', + className: 'opblock-external-docs__link', + href: sanitizeUrl(Re) + }, + Re + ) + ) + ) + : null, + qe && qe.size + ? Pe.createElement(et, { + parameters: We, + specPath: s.push('parameters'), + operation: qe, + onChangeKey: pt, + onTryoutClick: _, + onResetClick: w, + onCancelClick: x, + tryItOutEnabled: _e, + allowTryItOut: ye, + fn: j, + getComponent: L, + specActions: $, + specSelectors: V, + pathMethod: [le, ce], + getConfigs: B, + oas3Actions: Y, + oas3Selectors: Z + }) + : null, + _e + ? Pe.createElement(it, { + getComponent: L, + path: le, + method: ce, + operationServers: qe.get('servers'), + pathServers: V.paths().getIn([le, 'servers']), + getSelectedServer: Z.selectedServer, + setSelectedServer: Y.setSelectedServer, + setServerVariableValue: Y.setServerVariableValue, + getServerVariable: Z.serverVariableValue, + getEffectiveServerValue: Z.serverEffectiveValue + }) + : null, + _e && ye && Te && Te.size + ? Pe.createElement( + 'div', + { className: 'opblock-schemes' }, + Pe.createElement(ot, { + schemes: Te, + path: le, + method: ce, + specActions: $, + currentScheme: He + }) + ) + : null, + !_e || !ye || ht.length <= 0 + ? null + : Pe.createElement( + 'div', + { className: 'validation-errors errors-wrapper' }, + 'Please correct the following validation errors and try again.', + Pe.createElement( + 'ul', + null, + ht.map((s, o) => Pe.createElement('li', { key: o }, ' ', s, ' ')) + ) + ), + Pe.createElement( + 'div', + { className: _e && o && ye ? 'btn-group' : 'execute-wrapper' }, + _e && ye + ? Pe.createElement(tt, { + operation: qe, + specActions: $, + specSelectors: V, + oas3Selectors: Z, + oas3Actions: Y, + path: le, + method: ce, + onExecute: C, + disabled: we + }) + : null, + _e && o && ye + ? Pe.createElement(rt, { specActions: $, path: le, method: ce }) + : null + ), + we + ? Pe.createElement( + 'div', + { className: 'loading-container' }, + Pe.createElement('div', { className: 'loading' }) + ) + : null, + ze + ? Pe.createElement(Qe, { + responses: ze, + request: i, + tryItOutResponse: o, + getComponent: L, + getConfigs: B, + specSelectors: V, + oas3Actions: Y, + oas3Selectors: Z, + specActions: $, + produces: V.producesOptionsFor([le, ce]), + producesValue: V.currentProducesFor([le, ce]), + specPath: s.push('responses'), + path: le, + method: ce, + displayRequestDuration: be, + fn: j + }) + : null, + ut && Xe.size ? Pe.createElement(at, { extensions: Xe, getComponent: L }) : null + ) + ) + ); + } + } + class OperationContainer extends Pe.PureComponent { + constructor(s, o) { + super(s, o); + const { tryItOutEnabled: i } = s.getConfigs(); + this.state = { tryItOutEnabled: i, executeInProgress: !1 }; + } + static defaultProps = { + showSummary: !0, + response: null, + allowTryItOut: !0, + displayOperationId: !1, + displayRequestDuration: !1 + }; + mapStateToProps(s, o) { + const { op: i, layoutSelectors: u, getConfigs: _ } = o, + { + docExpansion: w, + deepLinking: x, + displayOperationId: C, + displayRequestDuration: j, + supportedSubmitMethods: L + } = _(), + B = u.showSummary(), + $ = + i.getIn(['operation', '__originalOperationId']) || + i.getIn(['operation', 'operationId']) || + opId(i.get('operation'), o.path, o.method) || + i.get('id'), + V = ['operations', o.tag, $], + U = + L.indexOf(o.method) >= 0 && + (void 0 === o.allowTryItOut + ? o.specSelectors.allowTryItOutFor(o.path, o.method) + : o.allowTryItOut), + z = i.getIn(['operation', 'security']) || o.specSelectors.security(); + return { + operationId: $, + isDeepLinkingEnabled: x, + showSummary: B, + displayOperationId: C, + displayRequestDuration: j, + allowTryItOut: U, + security: z, + isAuthorized: o.authSelectors.isAuthorized(z), + isShown: u.isShown(V, 'full' === w), + jumpToKey: `paths.${o.path}.${o.method}`, + response: o.specSelectors.responseFor(o.path, o.method), + request: o.specSelectors.requestFor(o.path, o.method) + }; + } + componentDidMount() { + const { isShown: s } = this.props, + o = this.getResolvedSubtree(); + s && void 0 === o && this.requestResolvedSubtree(); + } + UNSAFE_componentWillReceiveProps(s) { + const { response: o, isShown: i } = s, + u = this.getResolvedSubtree(); + o !== this.props.response && this.setState({ executeInProgress: !1 }), + i && void 0 === u && this.requestResolvedSubtree(); + } + toggleShown = () => { + let { layoutActions: s, tag: o, operationId: i, isShown: u } = this.props; + const _ = this.getResolvedSubtree(); + u || void 0 !== _ || this.requestResolvedSubtree(), s.show(['operations', o, i], !u); + }; + onCancelClick = () => { + this.setState({ tryItOutEnabled: !this.state.tryItOutEnabled }); + }; + onTryoutClick = () => { + this.setState({ tryItOutEnabled: !this.state.tryItOutEnabled }); + }; + onResetClick = (s) => { + const o = this.props.oas3Selectors.selectDefaultRequestBodyValue(...s); + this.props.oas3Actions.setRequestBodyValue({ value: o, pathMethod: s }); + }; + onExecute = () => { + this.setState({ executeInProgress: !0 }); + }; + getResolvedSubtree = () => { + const { specSelectors: s, path: o, method: i, specPath: u } = this.props; + return u ? s.specResolvedSubtree(u.toJS()) : s.specResolvedSubtree(['paths', o, i]); + }; + requestResolvedSubtree = () => { + const { specActions: s, path: o, method: i, specPath: u } = this.props; + return u + ? s.requestResolvedSubtree(u.toJS()) + : s.requestResolvedSubtree(['paths', o, i]); + }; + render() { + let { + op: s, + tag: o, + path: i, + method: u, + security: _, + isAuthorized: w, + operationId: x, + showSummary: C, + isShown: j, + jumpToKey: L, + allowTryItOut: B, + response: $, + request: V, + displayOperationId: U, + displayRequestDuration: z, + isDeepLinkingEnabled: Y, + specPath: Z, + specSelectors: ee, + specActions: ie, + getComponent: ae, + getConfigs: le, + layoutSelectors: ce, + layoutActions: pe, + authActions: de, + authSelectors: fe, + oas3Actions: ye, + oas3Selectors: be, + fn: _e + } = this.props; + const we = ae('operation'), + Se = this.getResolvedSubtree() || (0, qe.Map)(), + xe = (0, qe.fromJS)({ + op: Se, + tag: o, + path: i, + summary: s.getIn(['operation', 'summary']) || '', + deprecated: Se.get('deprecated') || s.getIn(['operation', 'deprecated']) || !1, + method: u, + security: _, + isAuthorized: w, + operationId: x, + originalOperationId: Se.getIn(['operation', '__originalOperationId']), + showSummary: C, + isShown: j, + jumpToKey: L, + allowTryItOut: B, + request: V, + displayOperationId: U, + displayRequestDuration: z, + isDeepLinkingEnabled: Y, + executeInProgress: this.state.executeInProgress, + tryItOutEnabled: this.state.tryItOutEnabled + }); + return Pe.createElement(we, { + operation: xe, + response: $, + request: V, + isShown: j, + toggleShown: this.toggleShown, + onTryoutClick: this.onTryoutClick, + onResetClick: this.onResetClick, + onCancelClick: this.onCancelClick, + onExecute: this.onExecute, + specPath: Z, + specActions: ie, + specSelectors: ee, + oas3Actions: ye, + oas3Selectors: be, + layoutActions: pe, + layoutSelectors: ce, + authActions: de, + authSelectors: fe, + getComponent: ae, + getConfigs: le, + fn: _e + }); + } + } + var mk = __webpack_require__(13222), + yk = __webpack_require__.n(mk); + class OperationSummary extends Pe.PureComponent { + static defaultProps = { operationProps: null, specPath: (0, qe.List)(), summary: '' }; + render() { + let { + isShown: s, + toggleShown: o, + getComponent: i, + authActions: u, + authSelectors: _, + operationProps: w, + specPath: x + } = this.props, + { + summary: C, + isAuthorized: j, + method: L, + op: B, + showSummary: $, + path: V, + operationId: U, + originalOperationId: z, + displayOperationId: Y + } = w.toJS(), + { summary: Z } = B, + ee = w.get('security'); + const ie = i('authorizeOperationBtn', !0), + ae = i('OperationSummaryMethod'), + le = i('OperationSummaryPath'), + ce = i('JumpToPath', !0), + pe = i('CopyToClipboardBtn', !0), + de = i('ArrowUpIcon'), + fe = i('ArrowDownIcon'), + ye = ee && !!ee.count(), + be = ye && 1 === ee.size && ee.first().isEmpty(), + _e = !ye || be; + return Pe.createElement( + 'div', + { className: `opblock-summary opblock-summary-${L}` }, + Pe.createElement( + 'button', + { 'aria-expanded': s, className: 'opblock-summary-control', onClick: o }, + Pe.createElement(ae, { method: L }), + Pe.createElement( + 'div', + { className: 'opblock-summary-path-description-wrapper' }, + Pe.createElement(le, { getComponent: i, operationProps: w, specPath: x }), + $ + ? Pe.createElement( + 'div', + { className: 'opblock-summary-description' }, + yk()(Z || C) + ) + : null + ), + Y && (z || U) + ? Pe.createElement('span', { className: 'opblock-summary-operation-id' }, z || U) + : null + ), + Pe.createElement(pe, { textToCopy: `${x.get(1)}` }), + _e + ? null + : Pe.createElement(ie, { + isAuthorized: j, + onClick: () => { + const s = _.definitionsForRequirements(ee); + u.showDefinitions(s); + } + }), + Pe.createElement(ce, { path: x }), + Pe.createElement( + 'button', + { + 'aria-label': `${L} ${V.replace(/\//g, '​/')}`, + className: 'opblock-control-arrow', + 'aria-expanded': s, + tabIndex: '-1', + onClick: o + }, + s + ? Pe.createElement(de, { className: 'arrow' }) + : Pe.createElement(fe, { className: 'arrow' }) + ) + ); + } + } + class OperationSummaryMethod extends Pe.PureComponent { + static defaultProps = { operationProps: null }; + render() { + let { method: s } = this.props; + return Pe.createElement( + 'span', + { className: 'opblock-summary-method' }, + s.toUpperCase() + ); + } + } + class OperationSummaryPath extends Pe.PureComponent { + render() { + let { getComponent: s, operationProps: o } = this.props, + { + deprecated: i, + isShown: u, + path: _, + tag: w, + operationId: x, + isDeepLinkingEnabled: C + } = o.toJS(); + const j = _.split(/(?=\/)/g); + for (let s = 1; s < j.length; s += 2) + j.splice(s, 0, Pe.createElement('wbr', { key: s })); + const L = s('DeepLink'); + return Pe.createElement( + 'span', + { + className: i ? 'opblock-summary-path__deprecated' : 'opblock-summary-path', + 'data-path': _ + }, + Pe.createElement(L, { + enabled: C, + isShown: u, + path: createDeepLinkPath(`${w}/${x}`), + text: j + }) + ); + } + } + const operation_extensions = ({ extensions: s, getComponent: o }) => { + let i = o('OperationExtRow'); + return Pe.createElement( + 'div', + { className: 'opblock-section' }, + Pe.createElement( + 'div', + { className: 'opblock-section-header' }, + Pe.createElement('h4', null, 'Extensions') + ), + Pe.createElement( + 'div', + { className: 'table-container' }, + Pe.createElement( + 'table', + null, + Pe.createElement( + 'thead', + null, + Pe.createElement( + 'tr', + null, + Pe.createElement('td', { className: 'col_header' }, 'Field'), + Pe.createElement('td', { className: 'col_header' }, 'Value') + ) + ), + Pe.createElement( + 'tbody', + null, + s + .entrySeq() + .map(([s, o]) => Pe.createElement(i, { key: `${s}-${o}`, xKey: s, xVal: o })) + ) + ) + ) + ); + }, + operation_extension_row = ({ xKey: s, xVal: o }) => { + const i = o ? (o.toJS ? o.toJS() : o) : null; + return Pe.createElement( + 'tr', + null, + Pe.createElement('td', null, s), + Pe.createElement('td', null, JSON.stringify(i)) + ); + }; + function createHtmlReadyId(s, o = '_') { + return s.replace(/[^\w-]/g, o); + } + class responses_Responses extends Pe.Component { + static defaultProps = { + tryItOutResponse: null, + produces: (0, qe.fromJS)(['application/json']), + displayRequestDuration: !1 + }; + onChangeProducesWrapper = (s) => + this.props.specActions.changeProducesValue([this.props.path, this.props.method], s); + onResponseContentTypeChange = ({ controlsAcceptHeader: s, value: o }) => { + const { oas3Actions: i, path: u, method: _ } = this.props; + s && i.setResponseContentType({ value: o, path: u, method: _ }); + }; + render() { + let { + responses: s, + tryItOutResponse: o, + getComponent: i, + getConfigs: u, + specSelectors: _, + fn: w, + producesValue: x, + displayRequestDuration: C, + specPath: j, + path: L, + method: B, + oas3Selectors: $, + oas3Actions: V + } = this.props, + U = (function defaultStatusCode(s) { + let o = s.keySeq(); + return o.contains(At) + ? At + : o + .filter((s) => '2' === (s + '')[0]) + .sort() + .first(); + })(s); + const z = i('contentType'), + Y = i('liveResponse'), + Z = i('response'); + let ee = + this.props.produces && this.props.produces.size + ? this.props.produces + : responses_Responses.defaultProps.produces; + const ie = _.isOAS3() + ? (function getAcceptControllingResponse(s) { + if (!$e().OrderedMap.isOrderedMap(s)) return null; + if (!s.size) return null; + const o = s.find( + (s, o) => + o.startsWith('2') && Object.keys(s.get('content') || {}).length > 0 + ), + i = s.get('default') || $e().OrderedMap(), + u = (i.get('content') || $e().OrderedMap()).keySeq().toJS().length ? i : null; + return o || u; + })(s) + : null, + ae = createHtmlReadyId(`${B}${L}_responses`), + le = `${ae}_select`; + return Pe.createElement( + 'div', + { className: 'responses-wrapper' }, + Pe.createElement( + 'div', + { className: 'opblock-section-header' }, + Pe.createElement('h4', null, 'Responses'), + _.isOAS3() + ? null + : Pe.createElement( + 'label', + { htmlFor: le }, + Pe.createElement('span', null, 'Response content type'), + Pe.createElement(z, { + value: x, + ariaControls: ae, + ariaLabel: 'Response content type', + className: 'execute-content-type', + contentTypes: ee, + controlId: le, + onChange: this.onChangeProducesWrapper + }) + ) + ), + Pe.createElement( + 'div', + { className: 'responses-inner' }, + o + ? Pe.createElement( + 'div', + null, + Pe.createElement(Y, { + response: o, + getComponent: i, + getConfigs: u, + specSelectors: _, + path: this.props.path, + method: this.props.method, + displayRequestDuration: C + }), + Pe.createElement('h4', null, 'Responses') + ) + : null, + Pe.createElement( + 'table', + { 'aria-live': 'polite', className: 'responses-table', id: ae, role: 'region' }, + Pe.createElement( + 'thead', + null, + Pe.createElement( + 'tr', + { className: 'responses-header' }, + Pe.createElement( + 'td', + { className: 'col_header response-col_status' }, + 'Code' + ), + Pe.createElement( + 'td', + { className: 'col_header response-col_description' }, + 'Description' + ), + _.isOAS3() + ? Pe.createElement( + 'td', + { className: 'col col_header response-col_links' }, + 'Links' + ) + : null + ) + ), + Pe.createElement( + 'tbody', + null, + s + .entrySeq() + .map(([s, C]) => { + let z = o && o.get('status') == s ? 'response_current' : ''; + return Pe.createElement(Z, { + key: s, + path: L, + method: B, + specPath: j.push(s), + isDefault: U === s, + fn: w, + className: z, + code: s, + response: C, + specSelectors: _, + controlsAcceptHeader: C === ie, + onContentTypeChange: this.onResponseContentTypeChange, + contentType: x, + getConfigs: u, + activeExamplesKey: $.activeExamplesMember(L, B, 'responses', s), + oas3Actions: V, + getComponent: i + }); + }) + .toArray() + ) + ) + ) + ); + } + } + function getKnownSyntaxHighlighterLanguage(s) { + const o = (function canJsonParse(s) { + try { + return !!JSON.parse(s); + } catch (s) { + return null; + } + })(s); + return o ? 'json' : null; + } + class response_Response extends Pe.Component { + constructor(s, o) { + super(s, o), (this.state = { responseContentType: '' }); + } + static defaultProps = { response: (0, qe.fromJS)({}), onContentTypeChange: () => {} }; + _onContentTypeChange = (s) => { + const { onContentTypeChange: o, controlsAcceptHeader: i } = this.props; + this.setState({ responseContentType: s }), o({ value: s, controlsAcceptHeader: i }); + }; + getTargetExamplesKey = () => { + const { response: s, contentType: o, activeExamplesKey: i } = this.props, + u = this.state.responseContentType || o, + _ = s + .getIn(['content', u], (0, qe.Map)({})) + .get('examples', null) + .keySeq() + .first(); + return i || _; + }; + render() { + let { + path: s, + method: o, + code: i, + response: u, + className: _, + specPath: w, + fn: x, + getComponent: C, + getConfigs: j, + specSelectors: L, + contentType: B, + controlsAcceptHeader: $, + oas3Actions: V + } = this.props, + { inferSchema: U, getSampleSchema: z } = x, + Y = L.isOAS3(); + const { showExtensions: Z } = j(); + let ee = Z ? getExtensions(u) : null, + ie = u.get('headers'), + ae = u.get('links'); + const le = C('ResponseExtension'), + ce = C('headers'), + pe = C('HighlightCode', !0), + de = C('modelExample'), + fe = C('Markdown', !0), + ye = C('operationLink'), + be = C('contentType'), + _e = C('ExamplesSelect'), + we = C('Example'); + var Se, xe; + const Te = this.state.responseContentType || B, + Re = u.getIn(['content', Te], (0, qe.Map)({})), + $e = Re.get('examples', null); + if (Y) { + const s = Re.get('schema'); + (Se = s ? U(s.toJS()) : null), + (xe = s ? (0, qe.List)(['content', this.state.responseContentType, 'schema']) : w); + } else (Se = u.get('schema')), (xe = u.has('schema') ? w.push('schema') : w); + let ze, + We, + He = !1, + Ye = { includeReadOnly: !0 }; + if (Y) + if (((We = Re.get('schema')?.toJS()), qe.Map.isMap($e) && !$e.isEmpty())) { + const s = this.getTargetExamplesKey(), + getMediaTypeExample = (s) => s.get('value'); + (ze = getMediaTypeExample($e.get(s, (0, qe.Map)({})))), + void 0 === ze && (ze = getMediaTypeExample($e.values().next().value)), + (He = !0); + } else void 0 !== Re.get('example') && ((ze = Re.get('example')), (He = !0)); + else { + (We = Se), (Ye = { ...Ye, includeWriteOnly: !0 }); + const s = u.getIn(['examples', Te]); + s && ((ze = s), (He = !0)); + } + const Xe = ((s, o) => { + if (null == s) return null; + const i = getKnownSyntaxHighlighterLanguage(s) ? 'json' : null; + return Pe.createElement( + 'div', + null, + Pe.createElement(o, { className: 'example', language: i }, stringify(s)) + ); + })(z(We, Te, Ye, He ? ze : void 0), pe); + return Pe.createElement( + 'tr', + { className: 'response ' + (_ || ''), 'data-code': i }, + Pe.createElement('td', { className: 'response-col_status' }, i), + Pe.createElement( + 'td', + { className: 'response-col_description' }, + Pe.createElement( + 'div', + { className: 'response-col_description__inner' }, + Pe.createElement(fe, { source: u.get('description') }) + ), + Z && ee.size + ? ee + .entrySeq() + .map(([s, o]) => Pe.createElement(le, { key: `${s}-${o}`, xKey: s, xVal: o })) + : null, + Y && u.get('content') + ? Pe.createElement( + 'section', + { className: 'response-controls' }, + Pe.createElement( + 'div', + { + className: Hn()('response-control-media-type', { + 'response-control-media-type--accept-controller': $ + }) + }, + Pe.createElement( + 'small', + { className: 'response-control-media-type__title' }, + 'Media type' + ), + Pe.createElement(be, { + value: this.state.responseContentType, + contentTypes: u.get('content') + ? u.get('content').keySeq() + : (0, qe.Seq)(), + onChange: this._onContentTypeChange, + ariaLabel: 'Media Type' + }), + $ + ? Pe.createElement( + 'small', + { className: 'response-control-media-type__accept-message' }, + 'Controls ', + Pe.createElement('code', null, 'Accept'), + ' header.' + ) + : null + ), + qe.Map.isMap($e) && !$e.isEmpty() + ? Pe.createElement( + 'div', + { className: 'response-control-examples' }, + Pe.createElement( + 'small', + { className: 'response-control-examples__title' }, + 'Examples' + ), + Pe.createElement(_e, { + examples: $e, + currentExampleKey: this.getTargetExamplesKey(), + onSelect: (u) => + V.setActiveExamplesMember({ + name: u, + pathMethod: [s, o], + contextType: 'responses', + contextName: i + }), + showLabels: !1 + }) + ) + : null + ) + : null, + Xe || Se + ? Pe.createElement(de, { + specPath: xe, + getComponent: C, + getConfigs: j, + specSelectors: L, + schema: fromJSOrdered(Se), + example: Xe, + includeReadOnly: !0 + }) + : null, + Y && $e + ? Pe.createElement(we, { + example: $e.get(this.getTargetExamplesKey(), (0, qe.Map)({})), + getComponent: C, + getConfigs: j, + omitValue: !0 + }) + : null, + ie ? Pe.createElement(ce, { headers: ie, getComponent: C }) : null + ), + Y + ? Pe.createElement( + 'td', + { className: 'response-col_links' }, + ae + ? ae + .toSeq() + .entrySeq() + .map(([s, o]) => + Pe.createElement(ye, { key: s, name: s, link: o, getComponent: C }) + ) + : Pe.createElement('i', null, 'No links') + ) + : null + ); + } + } + const response_extension = ({ xKey: s, xVal: o }) => + Pe.createElement('div', { className: 'response__extension' }, s, ': ', String(o)); + var vk = __webpack_require__(26657), + _k = __webpack_require__.n(vk), + wk = __webpack_require__(80218), + xk = __webpack_require__.n(wk); + class ResponseBody extends Pe.PureComponent { + state = { parsedContent: null }; + updateParsedContent = (s) => { + const { content: o } = this.props; + if (s !== o) + if (o && o instanceof Blob) { + var i = new FileReader(); + (i.onload = () => { + this.setState({ parsedContent: i.result }); + }), + i.readAsText(o); + } else this.setState({ parsedContent: o.toString() }); + }; + componentDidMount() { + this.updateParsedContent(null); + } + componentDidUpdate(s) { + this.updateParsedContent(s.content); + } + render() { + let { + content: s, + contentType: o, + url: i, + headers: u = {}, + getComponent: _ + } = this.props; + const { parsedContent: w } = this.state, + x = _('HighlightCode', !0), + C = 'response_' + new Date().getTime(); + let j, L; + if ( + ((i = i || ''), + (/^application\/octet-stream/i.test(o) || + (u['Content-Disposition'] && /attachment/i.test(u['Content-Disposition'])) || + (u['content-disposition'] && /attachment/i.test(u['content-disposition'])) || + (u['Content-Description'] && /File Transfer/i.test(u['Content-Description'])) || + (u['content-description'] && /File Transfer/i.test(u['content-description']))) && + (s.size > 0 || s.length > 0)) + ) + if ('Blob' in window) { + let _ = o || 'text/html', + w = s instanceof Blob ? s : new Blob([s], { type: _ }), + x = window.URL.createObjectURL(w), + C = [_, i.substr(i.lastIndexOf('/') + 1), x].join(':'), + j = u['content-disposition'] || u['Content-Disposition']; + if (void 0 !== j) { + let s = (function extractFileNameFromContentDispositionHeader(s) { + let o; + if ( + ([ + /filename\*=[^']+'\w*'"([^"]+)";?/i, + /filename\*=[^']+'\w*'([^;]+);?/i, + /filename="([^;]*);?"/i, + /filename=([^;]*);?/i + ].some((i) => ((o = i.exec(s)), null !== o)), + null !== o && o.length > 1) + ) + try { + return decodeURIComponent(o[1]); + } catch (s) { + console.error(s); + } + return null; + })(j); + null !== s && (C = s); + } + L = + at.navigator && at.navigator.msSaveOrOpenBlob + ? Pe.createElement( + 'div', + null, + Pe.createElement( + 'a', + { href: x, onClick: () => at.navigator.msSaveOrOpenBlob(w, C) }, + 'Download file' + ) + ) + : Pe.createElement( + 'div', + null, + Pe.createElement('a', { href: x, download: C }, 'Download file') + ); + } else + L = Pe.createElement( + 'pre', + { className: 'microlight' }, + 'Download headers detected but your browser does not support downloading binary via XHR (Blob).' + ); + else if (/json/i.test(o)) { + let o = null; + getKnownSyntaxHighlighterLanguage(s) && (o = 'json'); + try { + j = JSON.stringify(JSON.parse(s), null, ' '); + } catch (o) { + j = "can't parse JSON. Raw result:\n\n" + s; + } + L = Pe.createElement( + x, + { language: o, downloadable: !0, fileName: `${C}.json`, canCopy: !0 }, + j + ); + } else + /xml/i.test(o) + ? ((j = _k()(s, { textNodesOnSameLine: !0, indentor: ' ' })), + (L = Pe.createElement( + x, + { downloadable: !0, fileName: `${C}.xml`, canCopy: !0 }, + j + ))) + : (L = + 'text/html' === xk()(o) || /text\/plain/.test(o) + ? Pe.createElement( + x, + { downloadable: !0, fileName: `${C}.html`, canCopy: !0 }, + s + ) + : 'text/csv' === xk()(o) || /text\/csv/.test(o) + ? Pe.createElement( + x, + { downloadable: !0, fileName: `${C}.csv`, canCopy: !0 }, + s + ) + : /^image\//i.test(o) + ? o.includes('svg') + ? Pe.createElement('div', null, ' ', s, ' ') + : Pe.createElement('img', { src: window.URL.createObjectURL(s) }) + : /^audio\//i.test(o) + ? Pe.createElement( + 'pre', + { className: 'microlight' }, + Pe.createElement( + 'audio', + { controls: !0, key: i }, + Pe.createElement('source', { src: i, type: o }) + ) + ) + : 'string' == typeof s + ? Pe.createElement( + x, + { downloadable: !0, fileName: `${C}.txt`, canCopy: !0 }, + s + ) + : s.size > 0 + ? w + ? Pe.createElement( + 'div', + null, + Pe.createElement( + 'p', + { className: 'i' }, + 'Unrecognized response type; displaying content as text.' + ), + Pe.createElement( + x, + { downloadable: !0, fileName: `${C}.txt`, canCopy: !0 }, + w + ) + ) + : Pe.createElement( + 'p', + { className: 'i' }, + 'Unrecognized response type; unable to display.' + ) + : null); + return L + ? Pe.createElement('div', null, Pe.createElement('h5', null, 'Response body'), L) + : null; + } + } + class Parameters extends Pe.Component { + constructor(s) { + super(s), (this.state = { callbackVisible: !1, parametersVisible: !0 }); + } + static defaultProps = { + onTryoutClick: Function.prototype, + onCancelClick: Function.prototype, + tryItOutEnabled: !1, + allowTryItOut: !0, + onChangeKey: [], + specPath: [] + }; + onChange = (s, o, i) => { + let { + specActions: { changeParamByIdentity: u }, + onChangeKey: _ + } = this.props; + u(_, s, o, i); + }; + onChangeConsumesWrapper = (s) => { + let { + specActions: { changeConsumesValue: o }, + onChangeKey: i + } = this.props; + o(i, s); + }; + toggleTab = (s) => + 'parameters' === s + ? this.setState({ parametersVisible: !0, callbackVisible: !1 }) + : 'callbacks' === s + ? this.setState({ callbackVisible: !0, parametersVisible: !1 }) + : void 0; + onChangeMediaType = ({ value: s, pathMethod: o }) => { + let { specActions: i, oas3Selectors: u, oas3Actions: _ } = this.props; + const w = u.hasUserEditedBody(...o), + x = u.shouldRetainRequestBodyValue(...o); + _.setRequestContentType({ value: s, pathMethod: o }), + _.initRequestBodyValidateError({ pathMethod: o }), + w || + (x || _.setRequestBodyValue({ value: void 0, pathMethod: o }), + i.clearResponse(...o), + i.clearRequest(...o), + i.clearValidateParams(o)); + }; + render() { + let { + onTryoutClick: s, + onResetClick: o, + parameters: i, + allowTryItOut: u, + tryItOutEnabled: _, + specPath: w, + fn: x, + getComponent: C, + getConfigs: j, + specSelectors: L, + specActions: B, + pathMethod: $, + oas3Actions: V, + oas3Selectors: U, + operation: z + } = this.props; + const Y = C('parameterRow'), + Z = C('TryItOutButton'), + ee = C('contentType'), + ie = C('Callbacks', !0), + ae = C('RequestBody', !0), + le = _ && u, + ce = L.isOAS3(), + pe = `${createHtmlReadyId(`${$[1]}${$[0]}_requests`)}_select`, + de = z.get('requestBody'), + fe = Object.values( + i.reduce((s, o) => { + const i = o.get('in'); + return (s[i] ??= []), s[i].push(o), s; + }, {}) + ).reduce((s, o) => s.concat(o), []); + return Pe.createElement( + 'div', + { className: 'opblock-section' }, + Pe.createElement( + 'div', + { className: 'opblock-section-header' }, + ce + ? Pe.createElement( + 'div', + { className: 'tab-header' }, + Pe.createElement( + 'div', + { + onClick: () => this.toggleTab('parameters'), + className: `tab-item ${this.state.parametersVisible && 'active'}` + }, + Pe.createElement( + 'h4', + { className: 'opblock-title' }, + Pe.createElement('span', null, 'Parameters') + ) + ), + z.get('callbacks') + ? Pe.createElement( + 'div', + { + onClick: () => this.toggleTab('callbacks'), + className: `tab-item ${this.state.callbackVisible && 'active'}` + }, + Pe.createElement( + 'h4', + { className: 'opblock-title' }, + Pe.createElement('span', null, 'Callbacks') + ) + ) + : null + ) + : Pe.createElement( + 'div', + { className: 'tab-header' }, + Pe.createElement('h4', { className: 'opblock-title' }, 'Parameters') + ), + u + ? Pe.createElement(Z, { + isOAS3: L.isOAS3(), + hasUserEditedBody: U.hasUserEditedBody(...$), + enabled: _, + onCancelClick: this.props.onCancelClick, + onTryoutClick: s, + onResetClick: () => o($) + }) + : null + ), + this.state.parametersVisible + ? Pe.createElement( + 'div', + { className: 'parameters-container' }, + fe.length + ? Pe.createElement( + 'div', + { className: 'table-container' }, + Pe.createElement( + 'table', + { className: 'parameters' }, + Pe.createElement( + 'thead', + null, + Pe.createElement( + 'tr', + null, + Pe.createElement( + 'th', + { className: 'col_header parameters-col_name' }, + 'Name' + ), + Pe.createElement( + 'th', + { className: 'col_header parameters-col_description' }, + 'Description' + ) + ) + ), + Pe.createElement( + 'tbody', + null, + fe.map((s, o) => + Pe.createElement(Y, { + fn: x, + specPath: w.push(o.toString()), + getComponent: C, + getConfigs: j, + rawParam: s, + param: L.parameterWithMetaByIdentity($, s), + key: `${s.get('in')}.${s.get('name')}`, + onChange: this.onChange, + onChangeConsumes: this.onChangeConsumesWrapper, + specSelectors: L, + specActions: B, + oas3Actions: V, + oas3Selectors: U, + pathMethod: $, + isExecute: le + }) + ) + ) + ) + ) + : Pe.createElement( + 'div', + { className: 'opblock-description-wrapper' }, + Pe.createElement('p', null, 'No parameters') + ) + ) + : null, + this.state.callbackVisible + ? Pe.createElement( + 'div', + { className: 'callbacks-container opblock-description-wrapper' }, + Pe.createElement(ie, { + callbacks: (0, qe.Map)(z.get('callbacks')), + specPath: w.slice(0, -1).push('callbacks') + }) + ) + : null, + ce && + de && + this.state.parametersVisible && + Pe.createElement( + 'div', + { className: 'opblock-section opblock-section-request-body' }, + Pe.createElement( + 'div', + { className: 'opblock-section-header' }, + Pe.createElement( + 'h4', + { + className: `opblock-title parameter__name ${de.get('required') && 'required'}` + }, + 'Request body' + ), + Pe.createElement( + 'label', + { id: pe }, + Pe.createElement(ee, { + value: U.requestContentType(...$), + contentTypes: de.get('content', (0, qe.List)()).keySeq(), + onChange: (s) => { + this.onChangeMediaType({ value: s, pathMethod: $ }); + }, + className: 'body-param-content-type', + ariaLabel: 'Request content type', + controlId: pe + }) + ) + ), + Pe.createElement( + 'div', + { className: 'opblock-description-wrapper' }, + Pe.createElement(ae, { + setRetainRequestBodyValueFlag: (s) => + V.setRetainRequestBodyValueFlag({ value: s, pathMethod: $ }), + userHasEditedBody: U.hasUserEditedBody(...$), + specPath: w.slice(0, -1).push('requestBody'), + requestBody: de, + requestBodyValue: U.requestBodyValue(...$), + requestBodyInclusionSetting: U.requestBodyInclusionSetting(...$), + requestBodyErrors: U.requestBodyErrors(...$), + isExecute: le, + getConfigs: j, + activeExamplesKey: U.activeExamplesMember(...$, 'requestBody', 'requestBody'), + updateActiveExamplesKey: (s) => { + this.props.oas3Actions.setActiveExamplesMember({ + name: s, + pathMethod: this.props.pathMethod, + contextType: 'requestBody', + contextName: 'requestBody' + }); + }, + onChange: (s, o) => { + if (o) { + const i = U.requestBodyValue(...$), + u = qe.Map.isMap(i) ? i : (0, qe.Map)(); + return V.setRequestBodyValue({ pathMethod: $, value: u.setIn(o, s) }); + } + V.setRequestBodyValue({ value: s, pathMethod: $ }); + }, + onChangeIncludeEmpty: (s, o) => { + V.setRequestBodyInclusion({ pathMethod: $, value: o, name: s }); + }, + contentType: U.requestContentType(...$) + }) + ) + ) + ); + } + } + const parameter_extension = ({ xKey: s, xVal: o }) => + Pe.createElement('div', { className: 'parameter__extension' }, s, ': ', String(o)), + Ak = { onChange: () => {}, isIncludedOptions: {} }; + class ParameterIncludeEmpty extends Pe.Component { + static defaultProps = Ak; + componentDidMount() { + const { isIncludedOptions: s, onChange: o } = this.props, + { shouldDispatchInit: i, defaultValue: u } = s; + i && o(u); + } + onCheckboxChange = (s) => { + const { onChange: o } = this.props; + o(s.target.checked); + }; + render() { + let { isIncluded: s, isDisabled: o } = this.props; + return Pe.createElement( + 'div', + null, + Pe.createElement( + 'label', + { + htmlFor: 'include_empty_value', + className: Hn()('parameter__empty_value_toggle', { disabled: o }) + }, + Pe.createElement('input', { + id: 'include_empty_value', + type: 'checkbox', + disabled: o, + checked: !o && s, + onChange: this.onCheckboxChange + }), + 'Send empty value' + ) + ); + } + } + class ParameterRow extends Pe.Component { + constructor(s, o) { + super(s, o), this.setDefaultValue(); + } + UNSAFE_componentWillReceiveProps(s) { + let o, + { specSelectors: i, pathMethod: u, rawParam: _ } = s, + w = i.isOAS3(), + x = i.parameterWithMetaByIdentity(u, _) || new qe.Map(); + if (((x = x.isEmpty() ? _ : x), w)) { + let { schema: s } = getParameterSchema(x, { isOAS3: w }); + o = s ? s.get('enum') : void 0; + } else o = x ? x.get('enum') : void 0; + let C, + j = x ? x.get('value') : void 0; + void 0 !== j ? (C = j) : _.get('required') && o && o.size && (C = o.first()), + void 0 !== C && + C !== j && + this.onChangeWrapper( + (function numberToString(s) { + return 'number' == typeof s ? s.toString() : s; + })(C) + ), + this.setDefaultValue(); + } + onChangeWrapper = (s, o = !1) => { + let i, + { onChange: u, rawParam: _ } = this.props; + return (i = '' === s || (s && 0 === s.size) ? null : s), u(_, i, o); + }; + _onExampleSelect = (s) => { + this.props.oas3Actions.setActiveExamplesMember({ + name: s, + pathMethod: this.props.pathMethod, + contextType: 'parameters', + contextName: this.getParamKey() + }); + }; + onChangeIncludeEmpty = (s) => { + let { specActions: o, param: i, pathMethod: u } = this.props; + const _ = i.get('name'), + w = i.get('in'); + return o.updateEmptyParamInclusion(u, _, w, s); + }; + setDefaultValue = () => { + let { + specSelectors: s, + pathMethod: o, + rawParam: i, + oas3Selectors: u, + fn: _ + } = this.props; + const w = s.parameterWithMetaByIdentity(o, i) || (0, qe.Map)(); + let { schema: x } = getParameterSchema(w, { isOAS3: s.isOAS3() }); + const C = w + .get('content', (0, qe.Map)()) + .keySeq() + .first(), + j = x ? _.getSampleSchema(x.toJS(), C, { includeWriteOnly: !0 }) : null; + if (w && void 0 === w.get('value') && 'body' !== w.get('in')) { + let i; + if (s.isSwagger2()) + i = + void 0 !== w.get('x-example') + ? w.get('x-example') + : void 0 !== w.getIn(['schema', 'example']) + ? w.getIn(['schema', 'example']) + : x && x.getIn(['default']); + else if (s.isOAS3()) { + x = this.composeJsonSchema(x); + const s = u.activeExamplesMember(...o, 'parameters', this.getParamKey()); + i = + void 0 !== w.getIn(['examples', s, 'value']) + ? w.getIn(['examples', s, 'value']) + : void 0 !== w.getIn(['content', C, 'example']) + ? w.getIn(['content', C, 'example']) + : void 0 !== w.get('example') + ? w.get('example') + : void 0 !== (x && x.get('example')) + ? x && x.get('example') + : void 0 !== (x && x.get('default')) + ? x && x.get('default') + : w.get('default'); + } + void 0 === i || qe.List.isList(i) || (i = stringify(i)), + void 0 !== i + ? this.onChangeWrapper(i) + : x && + 'object' === x.get('type') && + j && + !w.get('examples') && + this.onChangeWrapper(qe.List.isList(j) ? j : stringify(j)); + } + }; + getParamKey() { + const { param: s } = this.props; + return s ? `${s.get('name')}-${s.get('in')}` : null; + } + composeJsonSchema(s) { + const { fn: o } = this.props, + i = s.get('oneOf')?.get(0)?.toJS(), + u = s.get('anyOf')?.get(0)?.toJS(); + return (0, qe.fromJS)(o.mergeJsonSchema(s.toJS(), i ?? u ?? {})); + } + render() { + let { + param: s, + rawParam: o, + getComponent: i, + getConfigs: u, + isExecute: _, + fn: w, + onChangeConsumes: x, + specSelectors: C, + pathMethod: j, + specPath: L, + oas3Selectors: B + } = this.props, + $ = C.isOAS3(); + const { showExtensions: V, showCommonExtensions: U } = u(); + if ((s || (s = o), !o)) return null; + const z = i('JsonSchemaForm'), + Y = i('ParamBody'); + let Z = s.get('in'), + ee = + 'body' !== Z + ? null + : Pe.createElement(Y, { + getComponent: i, + getConfigs: u, + fn: w, + param: s, + consumes: C.consumesOptionsFor(j), + consumesValue: C.contentTypeValues(j).get('requestContentType'), + onChange: this.onChangeWrapper, + onChangeConsumes: x, + isExecute: _, + specSelectors: C, + pathMethod: j + }); + const ie = i('modelExample'), + ae = i('Markdown', !0), + le = i('ParameterExt'), + ce = i('ParameterIncludeEmpty'), + pe = i('ExamplesSelectValueRetainer'), + de = i('Example'); + let { schema: fe } = getParameterSchema(s, { isOAS3: $ }), + ye = C.parameterWithMetaByIdentity(j, o) || (0, qe.Map)(); + $ && (fe = this.composeJsonSchema(fe)); + let be, + _e, + we, + Se, + xe = fe ? fe.get('format') : null, + Te = fe ? fe.get('type') : null, + Re = fe ? fe.getIn(['items', 'type']) : null, + $e = 'formData' === Z, + ze = 'FormData' in at, + We = s.get('required'), + He = ye ? ye.get('value') : '', + Ye = U ? getCommonExtensions(fe) : null, + Xe = V ? getExtensions(s) : null, + Qe = !1; + return ( + void 0 !== s && fe && (be = fe.get('items')), + void 0 !== be + ? ((_e = be.get('enum')), (we = be.get('default'))) + : fe && (_e = fe.get('enum')), + _e && _e.size && _e.size > 0 && (Qe = !0), + void 0 !== s && + (fe && (we = fe.get('default')), + void 0 === we && (we = s.get('default')), + (Se = s.get('example')), + void 0 === Se && (Se = s.get('x-example'))), + Pe.createElement( + 'tr', + { 'data-param-name': s.get('name'), 'data-param-in': s.get('in') }, + Pe.createElement( + 'td', + { className: 'parameters-col_name' }, + Pe.createElement( + 'div', + { className: We ? 'parameter__name required' : 'parameter__name' }, + s.get('name'), + We ? Pe.createElement('span', null, ' *') : null + ), + Pe.createElement( + 'div', + { className: 'parameter__type' }, + Te, + Re && `[${Re}]`, + xe && Pe.createElement('span', { className: 'prop-format' }, '($', xe, ')') + ), + Pe.createElement( + 'div', + { className: 'parameter__deprecated' }, + $ && s.get('deprecated') ? 'deprecated' : null + ), + Pe.createElement('div', { className: 'parameter__in' }, '(', s.get('in'), ')') + ), + Pe.createElement( + 'td', + { className: 'parameters-col_description' }, + s.get('description') + ? Pe.createElement(ae, { source: s.get('description') }) + : null, + (!ee && _) || !Qe + ? null + : Pe.createElement(ae, { + className: 'parameter__enum', + source: + 'Available values : ' + + _e + .map(function (s) { + return s; + }) + .toArray() + .map(String) + .join(', ') + }), + (!ee && _) || void 0 === we + ? null + : Pe.createElement(ae, { + className: 'parameter__default', + source: 'Default value : ' + we + }), + (!ee && _) || void 0 === Se + ? null + : Pe.createElement(ae, { source: 'Example : ' + Se }), + $e && + !ze && + Pe.createElement('div', null, 'Error: your browser does not support FormData'), + $ && s.get('examples') + ? Pe.createElement( + 'section', + { className: 'parameter-controls' }, + Pe.createElement(pe, { + examples: s.get('examples'), + onSelect: this._onExampleSelect, + updateValue: this.onChangeWrapper, + getComponent: i, + defaultToFirstExample: !0, + currentKey: B.activeExamplesMember( + ...j, + 'parameters', + this.getParamKey() + ), + currentUserInputValue: He + }) + ) + : null, + ee + ? null + : Pe.createElement(z, { + fn: w, + getComponent: i, + value: He, + required: We, + disabled: !_, + description: s.get('name'), + onChange: this.onChangeWrapper, + errors: ye.get('errors'), + schema: fe + }), + ee && fe + ? Pe.createElement(ie, { + getComponent: i, + specPath: L.push('schema'), + getConfigs: u, + isExecute: _, + specSelectors: C, + schema: fe, + example: ee, + includeWriteOnly: !0 + }) + : null, + !ee && _ && s.get('allowEmptyValue') + ? Pe.createElement(ce, { + onChange: this.onChangeIncludeEmpty, + isIncluded: C.parameterInclusionSettingFor(j, s.get('name'), s.get('in')), + isDisabled: !isEmptyValue(He) + }) + : null, + $ && s.get('examples') + ? Pe.createElement(de, { + example: s.getIn([ + 'examples', + B.activeExamplesMember(...j, 'parameters', this.getParamKey()) + ]), + getComponent: i, + getConfigs: u + }) + : null, + U && Ye.size + ? Ye.entrySeq().map(([s, o]) => + Pe.createElement(le, { key: `${s}-${o}`, xKey: s, xVal: o }) + ) + : null, + V && Xe.size + ? Xe.entrySeq().map(([s, o]) => + Pe.createElement(le, { key: `${s}-${o}`, xKey: s, xVal: o }) + ) + : null + ) + ) + ); + } + } + class Execute extends Pe.Component { + handleValidateParameters = () => { + let { specSelectors: s, specActions: o, path: i, method: u } = this.props; + return o.validateParams([i, u]), s.validateBeforeExecute([i, u]); + }; + handleValidateRequestBody = () => { + let { + path: s, + method: o, + specSelectors: i, + oas3Selectors: u, + oas3Actions: _ + } = this.props, + w = { missingBodyValue: !1, missingRequiredKeys: [] }; + _.clearRequestBodyValidateError({ path: s, method: o }); + let x = i.getOAS3RequiredRequestBodyContentType([s, o]), + C = u.requestBodyValue(s, o), + j = u.validateBeforeExecute([s, o]), + L = u.requestContentType(s, o); + if (!j) + return ( + (w.missingBodyValue = !0), + _.setRequestBodyValidateError({ path: s, method: o, validationErrors: w }), + !1 + ); + if (!x) return !0; + let B = u.validateShallowRequired({ + oas3RequiredRequestBodyContentType: x, + oas3RequestContentType: L, + oas3RequestBodyValue: C + }); + return ( + !B || + B.length < 1 || + (B.forEach((s) => { + w.missingRequiredKeys.push(s); + }), + _.setRequestBodyValidateError({ path: s, method: o, validationErrors: w }), + !1) + ); + }; + handleValidationResultPass = () => { + let { specActions: s, operation: o, path: i, method: u } = this.props; + this.props.onExecute && this.props.onExecute(), + s.execute({ operation: o, path: i, method: u }); + }; + handleValidationResultFail = () => { + let { specActions: s, path: o, method: i } = this.props; + s.clearValidateParams([o, i]), + setTimeout(() => { + s.validateParams([o, i]); + }, 40); + }; + handleValidationResult = (s) => { + s ? this.handleValidationResultPass() : this.handleValidationResultFail(); + }; + onClick = () => { + let s = this.handleValidateParameters(), + o = this.handleValidateRequestBody(), + i = s && o; + this.handleValidationResult(i); + }; + onChangeProducesWrapper = (s) => + this.props.specActions.changeProducesValue([this.props.path, this.props.method], s); + render() { + const { disabled: s } = this.props; + return Pe.createElement( + 'button', + { className: 'btn execute opblock-control__btn', onClick: this.onClick, disabled: s }, + 'Execute' + ); + } + } + class headers_Headers extends Pe.Component { + render() { + let { headers: s, getComponent: o } = this.props; + const i = o('Property'), + u = o('Markdown', !0); + return s && s.size + ? Pe.createElement( + 'div', + { className: 'headers-wrapper' }, + Pe.createElement('h4', { className: 'headers__title' }, 'Headers:'), + Pe.createElement( + 'table', + { className: 'headers' }, + Pe.createElement( + 'thead', + null, + Pe.createElement( + 'tr', + { className: 'header-row' }, + Pe.createElement('th', { className: 'header-col' }, 'Name'), + Pe.createElement('th', { className: 'header-col' }, 'Description'), + Pe.createElement('th', { className: 'header-col' }, 'Type') + ) + ), + Pe.createElement( + 'tbody', + null, + s + .entrySeq() + .map(([s, o]) => { + if (!$e().Map.isMap(o)) return null; + const _ = o.get('description'), + w = o.getIn(['schema']) + ? o.getIn(['schema', 'type']) + : o.getIn(['type']), + x = o.getIn(['schema', 'example']); + return Pe.createElement( + 'tr', + { key: s }, + Pe.createElement('td', { className: 'header-col' }, s), + Pe.createElement( + 'td', + { className: 'header-col' }, + _ ? Pe.createElement(u, { source: _ }) : null + ), + Pe.createElement( + 'td', + { className: 'header-col' }, + w, + ' ', + x + ? Pe.createElement(i, { + propKey: 'Example', + propVal: x, + propClass: 'header-example' + }) + : null + ) + ); + }) + .toArray() + ) + ) + ) + : null; + } + } + class Errors extends Pe.Component { + render() { + let { + editorActions: s, + errSelectors: o, + layoutSelectors: i, + layoutActions: u, + getComponent: _ + } = this.props; + const w = _('Collapse'); + if (s && s.jumpToLine) var x = s.jumpToLine; + let C = o + .allErrors() + .filter((s) => 'thrown' === s.get('type') || 'error' === s.get('level')); + if (!C || C.count() < 1) return null; + let j = i.isShown(['errorPane'], !0), + L = C.sortBy((s) => s.get('line')); + return Pe.createElement( + 'pre', + { className: 'errors-wrapper' }, + Pe.createElement( + 'hgroup', + { className: 'error' }, + Pe.createElement('h4', { className: 'errors__title' }, 'Errors'), + Pe.createElement( + 'button', + { className: 'btn errors__clear-btn', onClick: () => u.show(['errorPane'], !j) }, + j ? 'Hide' : 'Show' + ) + ), + Pe.createElement( + w, + { isOpened: j, animated: !0 }, + Pe.createElement( + 'div', + { className: 'errors' }, + L.map((s, o) => { + let i = s.get('type'); + return 'thrown' === i || 'auth' === i + ? Pe.createElement(ThrownErrorItem, { + key: o, + error: s.get('error') || s, + jumpToLine: x + }) + : 'spec' === i + ? Pe.createElement(SpecErrorItem, { key: o, error: s, jumpToLine: x }) + : void 0; + }) + ) + ) + ); + } + } + const ThrownErrorItem = ({ error: s, jumpToLine: o }) => { + if (!s) return null; + let i = s.get('line'); + return Pe.createElement( + 'div', + { className: 'error-wrapper' }, + s + ? Pe.createElement( + 'div', + null, + Pe.createElement( + 'h4', + null, + s.get('source') && s.get('level') + ? toTitleCase(s.get('source')) + ' ' + s.get('level') + : '', + s.get('path') ? Pe.createElement('small', null, ' at ', s.get('path')) : null + ), + Pe.createElement('span', { className: 'message thrown' }, s.get('message')), + Pe.createElement( + 'div', + { className: 'error-line' }, + i && o + ? Pe.createElement('a', { onClick: o.bind(null, i) }, 'Jump to line ', i) + : null + ) + ) + : null + ); + }, + SpecErrorItem = ({ error: s, jumpToLine: o = null }) => { + let i = null; + return ( + s.get('path') + ? (i = qe.List.isList(s.get('path')) + ? Pe.createElement('small', null, 'at ', s.get('path').join('.')) + : Pe.createElement('small', null, 'at ', s.get('path'))) + : s.get('line') && + !o && + (i = Pe.createElement('small', null, 'on line ', s.get('line'))), + Pe.createElement( + 'div', + { className: 'error-wrapper' }, + s + ? Pe.createElement( + 'div', + null, + Pe.createElement( + 'h4', + null, + toTitleCase(s.get('source')) + ' ' + s.get('level'), + ' ', + i + ), + Pe.createElement('span', { className: 'message' }, s.get('message')), + Pe.createElement( + 'div', + { className: 'error-line' }, + o + ? Pe.createElement( + 'a', + { onClick: o.bind(null, s.get('line')) }, + 'Jump to line ', + s.get('line') + ) + : null + ) + ) + : null + ) + ); + }; + function toTitleCase(s) { + return (s || '') + .split(' ') + .map((s) => s[0].toUpperCase() + s.slice(1)) + .join(' '); + } + const content_type_noop = () => {}; + class ContentType extends Pe.Component { + static defaultProps = { + onChange: content_type_noop, + value: null, + contentTypes: (0, qe.fromJS)(['application/json']) + }; + componentDidMount() { + this.props.contentTypes && this.props.onChange(this.props.contentTypes.first()); + } + UNSAFE_componentWillReceiveProps(s) { + s.contentTypes && + s.contentTypes.size && + (s.contentTypes.includes(s.value) || s.onChange(s.contentTypes.first())); + } + onChangeWrapper = (s) => this.props.onChange(s.target.value); + render() { + let { + ariaControls: s, + ariaLabel: o, + className: i, + contentTypes: u, + controlId: _, + value: w + } = this.props; + return u && u.size + ? Pe.createElement( + 'div', + { className: 'content-type-wrapper ' + (i || '') }, + Pe.createElement( + 'select', + { + 'aria-controls': s, + 'aria-label': o, + className: 'content-type', + id: _, + onChange: this.onChangeWrapper, + value: w || '' + }, + u.map((s) => Pe.createElement('option', { key: s, value: s }, s)).toArray() + ) + ) + : null; + } + } + function xclass(...s) { + return s + .filter((s) => !!s) + .join(' ') + .trim(); + } + class Container extends Pe.Component { + render() { + let { fullscreen: s, full: o, ...i } = this.props; + if (s) return Pe.createElement('section', i); + let u = 'swagger-container' + (o ? '-full' : ''); + return Pe.createElement('section', Rn()({}, i, { className: xclass(i.className, u) })); + } + } + const Bk = { mobile: '', tablet: '-tablet', desktop: '-desktop', large: '-hd' }; + class Col extends Pe.Component { + render() { + const { + hide: s, + keepContents: o, + mobile: i, + tablet: u, + desktop: _, + large: w, + ...x + } = this.props; + if (s && !o) return Pe.createElement('span', null); + let C = []; + for (let s in Bk) { + if (!Object.prototype.hasOwnProperty.call(Bk, s)) continue; + let o = Bk[s]; + if (s in this.props) { + let i = this.props[s]; + if (i < 1) { + C.push('none' + o); + continue; + } + C.push('block' + o), C.push('col-' + i + o); + } + } + s && C.push('hidden'); + let j = xclass(x.className, ...C); + return Pe.createElement('section', Rn()({}, x, { className: j })); + } + } + class Row extends Pe.Component { + render() { + return Pe.createElement( + 'div', + Rn()({}, this.props, { className: xclass(this.props.className, 'wrapper') }) + ); + } + } + class Button extends Pe.Component { + static defaultProps = { className: '' }; + render() { + return Pe.createElement( + 'button', + Rn()({}, this.props, { className: xclass(this.props.className, 'button') }) + ); + } + } + const TextArea = (s) => Pe.createElement('textarea', s), + Input = (s) => Pe.createElement('input', s); + class Select extends Pe.Component { + static defaultProps = { multiple: !1, allowEmptyValue: !0 }; + constructor(s, o) { + let i; + super(s, o), + (i = s.value ? s.value : s.multiple ? [''] : ''), + (this.state = { value: i }); + } + onChange = (s) => { + let o, + { onChange: i, multiple: u } = this.props, + _ = [].slice.call(s.target.options); + (o = u + ? _.filter(function (s) { + return s.selected; + }).map(function (s) { + return s.value; + }) + : s.target.value), + this.setState({ value: o }), + i && i(o); + }; + UNSAFE_componentWillReceiveProps(s) { + s.value !== this.props.value && this.setState({ value: s.value }); + } + render() { + let { allowedValues: s, multiple: o, allowEmptyValue: i, disabled: u } = this.props, + _ = this.state.value?.toJS?.() || this.state.value; + return Pe.createElement( + 'select', + { + className: this.props.className, + multiple: o, + value: _, + onChange: this.onChange, + disabled: u + }, + i ? Pe.createElement('option', { value: '' }, '--') : null, + s.map(function (s, o) { + return Pe.createElement('option', { key: o, value: String(s) }, String(s)); + }) + ); + } + } + class layout_utils_Link extends Pe.Component { + render() { + return Pe.createElement( + 'a', + Rn()({}, this.props, { + rel: 'noopener noreferrer', + className: xclass(this.props.className, 'link') + }) + ); + } + } + const NoMargin = ({ children: s }) => + Pe.createElement('div', { className: 'no-margin' }, ' ', s, ' '); + class Collapse extends Pe.Component { + static defaultProps = { isOpened: !1, animated: !1 }; + renderNotAnimated() { + return this.props.isOpened + ? Pe.createElement(NoMargin, null, this.props.children) + : Pe.createElement('noscript', null); + } + render() { + let { animated: s, isOpened: o, children: i } = this.props; + return s + ? ((i = o ? i : null), Pe.createElement(NoMargin, null, i)) + : this.renderNotAnimated(); + } + } + class Overview extends Pe.Component { + constructor(...s) { + super(...s), (this.setTagShown = this._setTagShown.bind(this)); + } + _setTagShown(s, o) { + this.props.layoutActions.show(s, o); + } + showOp(s, o) { + let { layoutActions: i } = this.props; + i.show(s, o); + } + render() { + let { + specSelectors: s, + layoutSelectors: o, + layoutActions: i, + getComponent: u + } = this.props, + _ = s.taggedOperations(); + const w = u('Collapse'); + return Pe.createElement( + 'div', + null, + Pe.createElement('h4', { className: 'overview-title' }, 'Overview'), + _.map((s, u) => { + let _ = s.get('operations'), + x = ['overview-tags', u], + C = o.isShown(x, !0); + return Pe.createElement( + 'div', + { key: 'overview-' + u }, + Pe.createElement( + 'h4', + { onClick: () => i.show(x, !C), className: 'link overview-tag' }, + ' ', + C ? '-' : '+', + u + ), + Pe.createElement( + w, + { isOpened: C, animated: !0 }, + _.map((s) => { + let { path: u, method: _, id: w } = s.toObject(), + x = 'operations', + C = w, + j = o.isShown([x, C]); + return Pe.createElement(OperationLink, { + key: w, + path: u, + method: _, + id: u + '-' + _, + shown: j, + showOpId: C, + showOpIdPrefix: x, + href: `#operation-${C}`, + onClick: i.show + }); + }).toArray() + ) + ); + }).toArray(), + _.size < 1 && Pe.createElement('h3', null, ' No operations defined in spec! ') + ); + } + } + class OperationLink extends Pe.Component { + constructor(s) { + super(s), (this.onClick = this._onClick.bind(this)); + } + _onClick() { + let { showOpId: s, showOpIdPrefix: o, onClick: i, shown: u } = this.props; + i([o, s], !u); + } + render() { + let { id: s, method: o, shown: i, href: u } = this.props; + return Pe.createElement( + layout_utils_Link, + { + href: u, + onClick: this.onClick, + className: 'block opblock-link ' + (i ? 'shown' : '') + }, + Pe.createElement( + 'div', + null, + Pe.createElement('small', { className: `bold-label-${o}` }, o.toUpperCase()), + Pe.createElement('span', { className: 'bold-label' }, s) + ) + ); + } + } + class InitializedInput extends Pe.Component { + componentDidMount() { + this.props.initialValue && (this.inputRef.value = this.props.initialValue); + } + render() { + const { value: s, defaultValue: o, initialValue: i, ...u } = this.props; + return Pe.createElement('input', Rn()({}, u, { ref: (s) => (this.inputRef = s) })); + } + } + class InfoBasePath extends Pe.Component { + render() { + const { host: s, basePath: o } = this.props; + return Pe.createElement('pre', { className: 'base-url' }, '[ Base URL: ', s, o, ' ]'); + } + } + class InfoUrl extends Pe.PureComponent { + render() { + const { url: s, getComponent: o } = this.props, + i = o('Link'); + return Pe.createElement( + i, + { target: '_blank', href: sanitizeUrl(s) }, + Pe.createElement('span', { className: 'url' }, ' ', s) + ); + } + } + class info_Info extends Pe.Component { + render() { + const { + info: s, + url: o, + host: i, + basePath: u, + getComponent: _, + externalDocs: w, + selectedServer: x, + url: C + } = this.props, + j = s.get('version'), + L = s.get('description'), + B = s.get('title'), + $ = safeBuildUrl(s.get('termsOfService'), C, { selectedServer: x }), + V = s.get('contact'), + U = s.get('license'), + z = safeBuildUrl(w && w.get('url'), C, { selectedServer: x }), + Y = w && w.get('description'), + Z = _('Markdown', !0), + ee = _('Link'), + ie = _('VersionStamp'), + ae = _('OpenAPIVersion'), + le = _('InfoUrl'), + ce = _('InfoBasePath'), + pe = _('License'), + de = _('Contact'); + return Pe.createElement( + 'div', + { className: 'info' }, + Pe.createElement( + 'hgroup', + { className: 'main' }, + Pe.createElement( + 'h2', + { className: 'title' }, + B, + Pe.createElement( + 'span', + null, + j && Pe.createElement(ie, { version: j }), + Pe.createElement(ae, { oasVersion: '2.0' }) + ) + ), + i || u ? Pe.createElement(ce, { host: i, basePath: u }) : null, + o && Pe.createElement(le, { getComponent: _, url: o }) + ), + Pe.createElement( + 'div', + { className: 'description' }, + Pe.createElement(Z, { source: L }) + ), + $ && + Pe.createElement( + 'div', + { className: 'info__tos' }, + Pe.createElement( + ee, + { target: '_blank', href: sanitizeUrl($) }, + 'Terms of service' + ) + ), + V?.size > 0 && + Pe.createElement(de, { getComponent: _, data: V, selectedServer: x, url: o }), + U?.size > 0 && + Pe.createElement(pe, { getComponent: _, license: U, selectedServer: x, url: o }), + z + ? Pe.createElement( + ee, + { className: 'info__extdocs', target: '_blank', href: sanitizeUrl(z) }, + Y || z + ) + : null + ); + } + } + const qk = info_Info; + class InfoContainer extends Pe.Component { + render() { + const { specSelectors: s, getComponent: o, oas3Selectors: i } = this.props, + u = s.info(), + _ = s.url(), + w = s.basePath(), + x = s.host(), + C = s.externalDocs(), + j = i.selectedServer(), + L = o('info'); + return Pe.createElement( + 'div', + null, + u && u.count() + ? Pe.createElement(L, { + info: u, + url: _, + host: x, + basePath: w, + externalDocs: C, + getComponent: o, + selectedServer: j + }) + : null + ); + } + } + class contact_Contact extends Pe.Component { + render() { + const { data: s, getComponent: o, selectedServer: i, url: u } = this.props, + _ = s.get('name', 'the developer'), + w = safeBuildUrl(s.get('url'), u, { selectedServer: i }), + x = s.get('email'), + C = o('Link'); + return Pe.createElement( + 'div', + { className: 'info__contact' }, + w && + Pe.createElement( + 'div', + null, + Pe.createElement(C, { href: sanitizeUrl(w), target: '_blank' }, _, ' - Website') + ), + x && + Pe.createElement( + C, + { href: sanitizeUrl(`mailto:${x}`) }, + w ? `Send email to ${_}` : `Contact ${_}` + ) + ); + } + } + const Vk = contact_Contact; + class license_License extends Pe.Component { + render() { + const { license: s, getComponent: o, selectedServer: i, url: u } = this.props, + _ = s.get('name', 'License'), + w = safeBuildUrl(s.get('url'), u, { selectedServer: i }), + x = o('Link'); + return Pe.createElement( + 'div', + { className: 'info__license' }, + w + ? Pe.createElement( + 'div', + { className: 'info__license__url' }, + Pe.createElement(x, { target: '_blank', href: sanitizeUrl(w) }, _) + ) + : Pe.createElement('span', null, _) + ); + } + } + const zk = license_License; + class JumpToPath extends Pe.Component { + render() { + return null; + } + } + class CopyToClipboardBtn extends Pe.Component { + render() { + let { getComponent: s } = this.props; + const o = s('CopyIcon'); + return Pe.createElement( + 'div', + { className: 'view-line-link copy-to-clipboard', title: 'Copy to clipboard' }, + Pe.createElement( + Jn.CopyToClipboard, + { text: this.props.textToCopy }, + Pe.createElement(o, null) + ) + ); + } + } + class Footer extends Pe.Component { + render() { + return Pe.createElement('div', { className: 'footer' }); + } + } + class FilterContainer extends Pe.Component { + onFilterChange = (s) => { + const { + target: { value: o } + } = s; + this.props.layoutActions.updateFilter(o); + }; + render() { + const { specSelectors: s, layoutSelectors: o, getComponent: i } = this.props, + u = i('Col'), + _ = 'loading' === s.loadingStatus(), + w = 'failed' === s.loadingStatus(), + x = o.currentFilter(), + C = ['operation-filter-input']; + return ( + w && C.push('failed'), + _ && C.push('loading'), + Pe.createElement( + 'div', + null, + !1 === x + ? null + : Pe.createElement( + 'div', + { className: 'filter-container' }, + Pe.createElement( + u, + { className: 'filter wrapper', mobile: 12 }, + Pe.createElement('input', { + className: C.join(' '), + placeholder: 'Filter by tag', + type: 'text', + onChange: this.onFilterChange, + value: 'string' == typeof x ? x : '', + disabled: _ + }) + ) + ) + ) + ); + } + } + const eC = Function.prototype; + class ParamBody extends Pe.PureComponent { + static defaultProp = { + consumes: (0, qe.fromJS)(['application/json']), + param: (0, qe.fromJS)({}), + onChange: eC, + onChangeConsumes: eC + }; + constructor(s, o) { + super(s, o), (this.state = { isEditBox: !1, value: '' }); + } + componentDidMount() { + this.updateValues.call(this, this.props); + } + UNSAFE_componentWillReceiveProps(s) { + this.updateValues.call(this, s); + } + updateValues = (s) => { + let { param: o, isExecute: i, consumesValue: u = '' } = s, + _ = /xml/i.test(u), + w = /json/i.test(u), + x = _ ? o.get('value_xml') : o.get('value'); + if (void 0 !== x) { + let s = !x && w ? '{}' : x; + this.setState({ value: s }), this.onChange(s, { isXml: _, isEditBox: i }); + } else + _ + ? this.onChange(this.sample('xml'), { isXml: _, isEditBox: i }) + : this.onChange(this.sample(), { isEditBox: i }); + }; + sample = (s) => { + let { param: o, fn: i } = this.props, + u = i.inferSchema(o.toJS()); + return i.getSampleSchema(u, s, { includeWriteOnly: !0 }); + }; + onChange = (s, { isEditBox: o, isXml: i }) => { + this.setState({ value: s, isEditBox: o }), this._onChange(s, i); + }; + _onChange = (s, o) => { + (this.props.onChange || eC)(s, o); + }; + handleOnChange = (s) => { + const { consumesValue: o } = this.props, + i = /xml/i.test(o), + u = s.target.value; + this.onChange(u, { isXml: i, isEditBox: this.state.isEditBox }); + }; + toggleIsEditBox = () => this.setState((s) => ({ isEditBox: !s.isEditBox })); + render() { + let { + onChangeConsumes: s, + param: o, + isExecute: i, + specSelectors: u, + pathMethod: _, + getComponent: w + } = this.props; + const x = w('Button'), + C = w('TextArea'), + j = w('HighlightCode', !0), + L = w('contentType'); + let B = (u ? u.parameterWithMetaByIdentity(_, o) : o).get('errors', (0, qe.List)()), + $ = u.contentTypeValues(_).get('requestContentType'), + V = + this.props.consumes && this.props.consumes.size + ? this.props.consumes + : ParamBody.defaultProp.consumes, + { value: U, isEditBox: z } = this.state, + Y = null; + getKnownSyntaxHighlighterLanguage(U) && (Y = 'json'); + const Z = `${createHtmlReadyId(`${_[1]}${_[0]}_parameters`)}_select`; + return Pe.createElement( + 'div', + { + className: 'body-param', + 'data-param-name': o.get('name'), + 'data-param-in': o.get('in') + }, + z && i + ? Pe.createElement(C, { + className: 'body-param__text' + (B.count() ? ' invalid' : ''), + value: U, + onChange: this.handleOnChange + }) + : U && Pe.createElement(j, { className: 'body-param__example', language: Y }, U), + Pe.createElement( + 'div', + { className: 'body-param-options' }, + i + ? Pe.createElement( + 'div', + { className: 'body-param-edit' }, + Pe.createElement( + x, + { + className: z + ? 'btn cancel body-param__example-edit' + : 'btn edit body-param__example-edit', + onClick: this.toggleIsEditBox + }, + z ? 'Cancel' : 'Edit' + ) + ) + : null, + Pe.createElement( + 'label', + { htmlFor: Z }, + Pe.createElement('span', null, 'Parameter content type'), + Pe.createElement(L, { + value: $, + contentTypes: V, + onChange: s, + className: 'body-param-content-type', + ariaLabel: 'Parameter content type', + controlId: Z + }) + ) + ) + ); + } + } + class Curl extends Pe.Component { + render() { + const { request: s, getComponent: o } = this.props, + i = requestSnippetGenerator_curl_bash(s), + u = o('SyntaxHighlighter', !0); + return Pe.createElement( + 'div', + { className: 'curl-command' }, + Pe.createElement('h4', null, 'Curl'), + Pe.createElement( + 'div', + { className: 'copy-to-clipboard' }, + Pe.createElement(Jn.CopyToClipboard, { text: i }, Pe.createElement('button', null)) + ), + Pe.createElement( + 'div', + null, + Pe.createElement( + u, + { + language: 'bash', + className: 'curl microlight', + renderPlainText: ({ children: s, PlainTextViewer: o }) => + Pe.createElement(o, { className: 'curl' }, s) + }, + i + ) + ) + ); + } + } + const property = ({ propKey: s, propVal: o, propClass: i }) => + Pe.createElement( + 'span', + { className: i }, + Pe.createElement('br', null), + s, + ': ', + String(o) + ); + class TryItOutButton extends Pe.Component { + static defaultProps = { + onTryoutClick: Function.prototype, + onCancelClick: Function.prototype, + onResetClick: Function.prototype, + enabled: !1, + hasUserEditedBody: !1, + isOAS3: !1 + }; + render() { + const { + onTryoutClick: s, + onCancelClick: o, + onResetClick: i, + enabled: u, + hasUserEditedBody: _, + isOAS3: w + } = this.props, + x = w && _; + return Pe.createElement( + 'div', + { className: x ? 'try-out btn-group' : 'try-out' }, + u + ? Pe.createElement( + 'button', + { className: 'btn try-out__btn cancel', onClick: o }, + 'Cancel' + ) + : Pe.createElement( + 'button', + { className: 'btn try-out__btn', onClick: s }, + 'Try it out ' + ), + x && + Pe.createElement( + 'button', + { className: 'btn try-out__btn reset', onClick: i }, + 'Reset' + ) + ); + } + } + class VersionPragmaFilter extends Pe.PureComponent { + static defaultProps = { alsoShow: null, children: null, bypass: !1 }; + render() { + const { bypass: s, isSwagger2: o, isOAS3: i, alsoShow: u } = this.props; + return s + ? Pe.createElement('div', null, this.props.children) + : o && i + ? Pe.createElement( + 'div', + { className: 'version-pragma' }, + u, + Pe.createElement( + 'div', + { className: 'version-pragma__message version-pragma__message--ambiguous' }, + Pe.createElement( + 'div', + null, + Pe.createElement('h3', null, 'Unable to render this definition'), + Pe.createElement( + 'p', + null, + Pe.createElement('code', null, 'swagger'), + ' and ', + Pe.createElement('code', null, 'openapi'), + ' fields cannot be present in the same Swagger or OpenAPI definition. Please remove one of the fields.' + ), + Pe.createElement( + 'p', + null, + 'Supported version fields are ', + Pe.createElement('code', null, 'swagger: ', '"2.0"'), + ' and those that match ', + Pe.createElement('code', null, 'openapi: 3.0.n'), + ' (for example, ', + Pe.createElement('code', null, 'openapi: 3.0.0'), + ').' + ) + ) + ) + ) + : o || i + ? Pe.createElement('div', null, this.props.children) + : Pe.createElement( + 'div', + { className: 'version-pragma' }, + u, + Pe.createElement( + 'div', + { className: 'version-pragma__message version-pragma__message--missing' }, + Pe.createElement( + 'div', + null, + Pe.createElement('h3', null, 'Unable to render this definition'), + Pe.createElement( + 'p', + null, + 'The provided definition does not specify a valid version field.' + ), + Pe.createElement( + 'p', + null, + 'Please indicate a valid Swagger or OpenAPI version field. Supported version fields are ', + Pe.createElement('code', null, 'swagger: ', '"2.0"'), + ' and those that match ', + Pe.createElement('code', null, 'openapi: 3.0.n'), + ' (for example, ', + Pe.createElement('code', null, 'openapi: 3.0.0'), + ').' + ) + ) + ) + ); + } + } + const version_stamp = ({ version: s }) => + Pe.createElement( + 'small', + null, + Pe.createElement('pre', { className: 'version' }, ' ', s, ' ') + ), + openapi_version = ({ oasVersion: s }) => + Pe.createElement( + 'small', + { className: 'version-stamp' }, + Pe.createElement('pre', { className: 'version' }, 'OAS ', s) + ), + deep_link = ({ enabled: s, path: o, text: i }) => + Pe.createElement( + 'a', + { + className: 'nostyle', + onClick: s ? (s) => s.preventDefault() : null, + href: s ? `#/${o}` : null + }, + Pe.createElement('span', null, i) + ), + svg_assets = () => + Pe.createElement( + 'div', + null, + Pe.createElement( + 'svg', + { + xmlns: 'http://www.w3.org/2000/svg', + xmlnsXlink: 'http://www.w3.org/1999/xlink', + className: 'svg-assets' + }, + Pe.createElement( + 'defs', + null, + Pe.createElement( + 'symbol', + { viewBox: '0 0 20 20', id: 'unlocked' }, + Pe.createElement('path', { + d: 'M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V6h2v-.801C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8z' + }) + ), + Pe.createElement( + 'symbol', + { viewBox: '0 0 20 20', id: 'locked' }, + Pe.createElement('path', { + d: 'M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8zM12 8H8V5.199C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8z' + }) + ), + Pe.createElement( + 'symbol', + { viewBox: '0 0 20 20', id: 'close' }, + Pe.createElement('path', { + d: 'M14.348 14.849c-.469.469-1.229.469-1.697 0L10 11.819l-2.651 3.029c-.469.469-1.229.469-1.697 0-.469-.469-.469-1.229 0-1.697l2.758-3.15-2.759-3.152c-.469-.469-.469-1.228 0-1.697.469-.469 1.228-.469 1.697 0L10 8.183l2.651-3.031c.469-.469 1.228-.469 1.697 0 .469.469.469 1.229 0 1.697l-2.758 3.152 2.758 3.15c.469.469.469 1.229 0 1.698z' + }) + ), + Pe.createElement( + 'symbol', + { viewBox: '0 0 20 20', id: 'large-arrow' }, + Pe.createElement('path', { + d: 'M13.25 10L6.109 2.58c-.268-.27-.268-.707 0-.979.268-.27.701-.27.969 0l7.83 7.908c.268.271.268.709 0 .979l-7.83 7.908c-.268.271-.701.27-.969 0-.268-.269-.268-.707 0-.979L13.25 10z' + }) + ), + Pe.createElement( + 'symbol', + { viewBox: '0 0 20 20', id: 'large-arrow-down' }, + Pe.createElement('path', { + d: 'M17.418 6.109c.272-.268.709-.268.979 0s.271.701 0 .969l-7.908 7.83c-.27.268-.707.268-.979 0l-7.908-7.83c-.27-.268-.27-.701 0-.969.271-.268.709-.268.979 0L10 13.25l7.418-7.141z' + }) + ), + Pe.createElement( + 'symbol', + { viewBox: '0 0 20 20', id: 'large-arrow-up' }, + Pe.createElement('path', { + d: 'M 17.418 14.908 C 17.69 15.176 18.127 15.176 18.397 14.908 C 18.667 14.64 18.668 14.207 18.397 13.939 L 10.489 6.109 C 10.219 5.841 9.782 5.841 9.51 6.109 L 1.602 13.939 C 1.332 14.207 1.332 14.64 1.602 14.908 C 1.873 15.176 2.311 15.176 2.581 14.908 L 10 7.767 L 17.418 14.908 Z' + }) + ), + Pe.createElement( + 'symbol', + { viewBox: '0 0 24 24', id: 'jump-to' }, + Pe.createElement('path', { + d: 'M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.41L5.83 13H21V7z' + }) + ), + Pe.createElement( + 'symbol', + { viewBox: '0 0 24 24', id: 'expand' }, + Pe.createElement('path', { + d: 'M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z' + }) + ), + Pe.createElement( + 'symbol', + { viewBox: '0 0 15 16', id: 'copy' }, + Pe.createElement( + 'g', + { transform: 'translate(2, -1)' }, + Pe.createElement('path', { + fill: '#ffffff', + fillRule: 'evenodd', + d: 'M2 13h4v1H2v-1zm5-6H2v1h5V7zm2 3V8l-3 3 3 3v-2h5v-2H9zM4.5 9H2v1h2.5V9zM2 12h2.5v-1H2v1zm9 1h1v2c-.02.28-.11.52-.3.7-.19.18-.42.28-.7.3H1c-.55 0-1-.45-1-1V4c0-.55.45-1 1-1h3c0-1.11.89-2 2-2 1.11 0 2 .89 2 2h3c.55 0 1 .45 1 1v5h-1V6H1v9h10v-2zM2 5h8c0-.55-.45-1-1-1H8c-.55 0-1-.45-1-1s-.45-1-1-1-1 .45-1 1-.45 1-1 1H3c-.55 0-1 .45-1 1z' + }) + ) + ) + ) + ) + ); + var tC; + function decodeEntity(s) { + return ( + ((tC = tC || document.createElement('textarea')).innerHTML = '&' + s + ';'), tC.value + ); + } + var rC = Object.prototype.hasOwnProperty; + function index_browser_has(s, o) { + return !!s && rC.call(s, o); + } + function index_browser_assign(s) { + return ( + [].slice.call(arguments, 1).forEach(function (o) { + if (o) { + if ('object' != typeof o) throw new TypeError(o + 'must be object'); + Object.keys(o).forEach(function (i) { + s[i] = o[i]; + }); + } + }), + s + ); + } + var nC = /\\([\\!"#$%&'()*+,.\/:;<=>?@[\]^_`{|}~-])/g; + function unescapeMd(s) { + return s.indexOf('\\') < 0 ? s : s.replace(nC, '$1'); + } + function isValidEntityCode(s) { + return ( + !(s >= 55296 && s <= 57343) && + !(s >= 64976 && s <= 65007) && + !!(65535 & ~s && 65534 != (65535 & s)) && + !(s >= 0 && s <= 8) && + 11 !== s && + !(s >= 14 && s <= 31) && + !(s >= 127 && s <= 159) && + !(s > 1114111) + ); + } + function fromCodePoint(s) { + if (s > 65535) { + var o = 55296 + ((s -= 65536) >> 10), + i = 56320 + (1023 & s); + return String.fromCharCode(o, i); + } + return String.fromCharCode(s); + } + var sC = /&([a-z#][a-z0-9]{1,31});/gi, + oC = /^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))/i; + function replaceEntityPattern(s, o) { + var i = 0, + u = decodeEntity(o); + return o !== u + ? u + : 35 === o.charCodeAt(0) && + oC.test(o) && + isValidEntityCode( + (i = + 'x' === o[1].toLowerCase() + ? parseInt(o.slice(2), 16) + : parseInt(o.slice(1), 10)) + ) + ? fromCodePoint(i) + : s; + } + function replaceEntities(s) { + return s.indexOf('&') < 0 ? s : s.replace(sC, replaceEntityPattern); + } + var iC = /[&<>"]/, + aC = /[&<>"]/g, + lC = { '&': '&', '<': '<', '>': '>', '"': '"' }; + function replaceUnsafeChar(s) { + return lC[s]; + } + function escapeHtml(s) { + return iC.test(s) ? s.replace(aC, replaceUnsafeChar) : s; + } + var cC = {}; + function nextToken(s, o) { + return ++o >= s.length - 2 + ? o + : 'paragraph_open' === s[o].type && + s[o].tight && + 'inline' === s[o + 1].type && + 0 === s[o + 1].content.length && + 'paragraph_close' === s[o + 2].type && + s[o + 2].tight + ? nextToken(s, o + 2) + : o; + } + (cC.blockquote_open = function () { + return '
        \n'; + }), + (cC.blockquote_close = function (s, o) { + return '
        ' + uC(s, o); + }), + (cC.code = function (s, o) { + return s[o].block + ? '
        ' + escapeHtml(s[o].content) + '
        ' + uC(s, o) + : '' + escapeHtml(s[o].content) + ''; + }), + (cC.fence = function (s, o, i, u, _) { + var w, + x, + C = s[o], + j = '', + L = i.langPrefix; + if (C.params) { + if ( + ((x = (w = C.params.split(/\s+/g)).join(' ')), + index_browser_has(_.rules.fence_custom, w[0])) + ) + return _.rules.fence_custom[w[0]](s, o, i, u, _); + j = ' class="' + L + escapeHtml(replaceEntities(unescapeMd(x))) + '"'; + } + return ( + '
        ' +
        +							((i.highlight && i.highlight.apply(i.highlight, [C.content].concat(w))) ||
        +								escapeHtml(C.content)) +
        +							'
        ' + + uC(s, o) + ); + }), + (cC.fence_custom = {}), + (cC.heading_open = function (s, o) { + return ''; + }), + (cC.heading_close = function (s, o) { + return '\n'; + }), + (cC.hr = function (s, o, i) { + return (i.xhtmlOut ? '
        ' : '
        ') + uC(s, o); + }), + (cC.bullet_list_open = function () { + return '
          \n'; + }), + (cC.bullet_list_close = function (s, o) { + return '
        ' + uC(s, o); + }), + (cC.list_item_open = function () { + return '
      • '; + }), + (cC.list_item_close = function () { + return '
      • \n'; + }), + (cC.ordered_list_open = function (s, o) { + var i = s[o]; + return ' 1 ? ' start="' + i.order + '"' : '') + '>\n'; + }), + (cC.ordered_list_close = function (s, o) { + return '' + uC(s, o); + }), + (cC.paragraph_open = function (s, o) { + return s[o].tight ? '' : '

        '; + }), + (cC.paragraph_close = function (s, o) { + var i = !(s[o].tight && o && 'inline' === s[o - 1].type && !s[o - 1].content); + return (s[o].tight ? '' : '

        ') + (i ? uC(s, o) : ''); + }), + (cC.link_open = function (s, o, i) { + var u = s[o].title ? ' title="' + escapeHtml(replaceEntities(s[o].title)) + '"' : '', + _ = i.linkTarget ? ' target="' + i.linkTarget + '"' : ''; + return ''; + }), + (cC.link_close = function () { + return ''; + }), + (cC.image = function (s, o, i) { + var u = ' src="' + escapeHtml(s[o].src) + '"', + _ = s[o].title ? ' title="' + escapeHtml(replaceEntities(s[o].title)) + '"' : ''; + return ( + '' + ); + }), + (cC.table_open = function () { + return '\n'; + }), + (cC.table_close = function () { + return '
        \n'; + }), + (cC.thead_open = function () { + return '\n'; + }), + (cC.thead_close = function () { + return '\n'; + }), + (cC.tbody_open = function () { + return '\n'; + }), + (cC.tbody_close = function () { + return '\n'; + }), + (cC.tr_open = function () { + return ''; + }), + (cC.tr_close = function () { + return '\n'; + }), + (cC.th_open = function (s, o) { + var i = s[o]; + return ''; + }), + (cC.th_close = function () { + return ''; + }), + (cC.td_open = function (s, o) { + var i = s[o]; + return ''; + }), + (cC.td_close = function () { + return ''; + }), + (cC.strong_open = function () { + return ''; + }), + (cC.strong_close = function () { + return ''; + }), + (cC.em_open = function () { + return ''; + }), + (cC.em_close = function () { + return ''; + }), + (cC.del_open = function () { + return ''; + }), + (cC.del_close = function () { + return ''; + }), + (cC.ins_open = function () { + return ''; + }), + (cC.ins_close = function () { + return ''; + }), + (cC.mark_open = function () { + return ''; + }), + (cC.mark_close = function () { + return ''; + }), + (cC.sub = function (s, o) { + return '' + escapeHtml(s[o].content) + ''; + }), + (cC.sup = function (s, o) { + return '' + escapeHtml(s[o].content) + ''; + }), + (cC.hardbreak = function (s, o, i) { + return i.xhtmlOut ? '
        \n' : '
        \n'; + }), + (cC.softbreak = function (s, o, i) { + return i.breaks ? (i.xhtmlOut ? '
        \n' : '
        \n') : '\n'; + }), + (cC.text = function (s, o) { + return escapeHtml(s[o].content); + }), + (cC.htmlblock = function (s, o) { + return s[o].content; + }), + (cC.htmltag = function (s, o) { + return s[o].content; + }), + (cC.abbr_open = function (s, o) { + return ''; + }), + (cC.abbr_close = function () { + return ''; + }), + (cC.footnote_ref = function (s, o) { + var i = Number(s[o].id + 1).toString(), + u = 'fnref' + i; + return ( + s[o].subId > 0 && (u += ':' + s[o].subId), + '[' + + i + + ']' + ); + }), + (cC.footnote_block_open = function (s, o, i) { + return ( + (i.xhtmlOut ? '
        \n' : '
        \n') + + '
        \n
          \n' + ); + }), + (cC.footnote_block_close = function () { + return '
        \n
        \n'; + }), + (cC.footnote_open = function (s, o) { + return '
      • '; + }), + (cC.footnote_close = function () { + return '
      • \n'; + }), + (cC.footnote_anchor = function (s, o) { + var i = 'fnref' + Number(s[o].id + 1).toString(); + return ( + s[o].subId > 0 && (i += ':' + s[o].subId), + ' ' + ); + }), + (cC.dl_open = function () { + return '
        \n'; + }), + (cC.dt_open = function () { + return '
        '; + }), + (cC.dd_open = function () { + return '
        '; + }), + (cC.dl_close = function () { + return '
        \n'; + }), + (cC.dt_close = function () { + return '\n'; + }), + (cC.dd_close = function () { + return '\n'; + }); + var uC = (cC.getBreak = function getBreak(s, o) { + return (o = nextToken(s, o)) < s.length && 'list_item_close' === s[o].type ? '' : '\n'; + }); + function Renderer() { + (this.rules = index_browser_assign({}, cC)), (this.getBreak = cC.getBreak); + } + function Ruler() { + (this.__rules__ = []), (this.__cache__ = null); + } + function StateInline(s, o, i, u, _) { + (this.src = s), + (this.env = u), + (this.options = i), + (this.parser = o), + (this.tokens = _), + (this.pos = 0), + (this.posMax = this.src.length), + (this.level = 0), + (this.pending = ''), + (this.pendingLevel = 0), + (this.cache = []), + (this.isInLabel = !1), + (this.linkLevel = 0), + (this.linkContent = ''), + (this.labelUnmatchedScopes = 0); + } + function parseLinkLabel(s, o) { + var i, + u, + _, + w = -1, + x = s.posMax, + C = s.pos, + j = s.isInLabel; + if (s.isInLabel) return -1; + if (s.labelUnmatchedScopes) return s.labelUnmatchedScopes--, -1; + for (s.pos = o + 1, s.isInLabel = !0, i = 1; s.pos < x; ) { + if (91 === (_ = s.src.charCodeAt(s.pos))) i++; + else if (93 === _ && 0 === --i) { + u = !0; + break; + } + s.parser.skipToken(s); + } + return ( + u ? ((w = s.pos), (s.labelUnmatchedScopes = 0)) : (s.labelUnmatchedScopes = i - 1), + (s.pos = C), + (s.isInLabel = j), + w + ); + } + function parseAbbr(s, o, i, u) { + var _, w, x, C, j, L; + if (42 !== s.charCodeAt(0)) return -1; + if (91 !== s.charCodeAt(1)) return -1; + if (-1 === s.indexOf(']:')) return -1; + if ( + (w = parseLinkLabel((_ = new StateInline(s, o, i, u, [])), 1)) < 0 || + 58 !== s.charCodeAt(w + 1) + ) + return -1; + for (C = _.posMax, x = w + 2; x < C && 10 !== _.src.charCodeAt(x); x++); + return ( + (j = s.slice(2, w)), + 0 === (L = s.slice(w + 2, x).trim()).length + ? -1 + : (u.abbreviations || (u.abbreviations = {}), + void 0 === u.abbreviations[':' + j] && (u.abbreviations[':' + j] = L), + x) + ); + } + function normalizeLink(s) { + var o = replaceEntities(s); + try { + o = decodeURI(o); + } catch (s) {} + return encodeURI(o); + } + function parseLinkDestination(s, o) { + var i, + u, + _, + w = o, + x = s.posMax; + if (60 === s.src.charCodeAt(o)) { + for (o++; o < x; ) { + if (10 === (i = s.src.charCodeAt(o))) return !1; + if (62 === i) + return ( + (_ = normalizeLink(unescapeMd(s.src.slice(w + 1, o)))), + !!s.parser.validateLink(_) && ((s.pos = o + 1), (s.linkContent = _), !0) + ); + 92 === i && o + 1 < x ? (o += 2) : o++; + } + return !1; + } + for (u = 0; o < x && 32 !== (i = s.src.charCodeAt(o)) && !(i < 32 || 127 === i); ) + if (92 === i && o + 1 < x) o += 2; + else { + if (40 === i && ++u > 1) break; + if (41 === i && --u < 0) break; + o++; + } + return ( + w !== o && + ((_ = unescapeMd(s.src.slice(w, o))), + !!s.parser.validateLink(_) && ((s.linkContent = _), (s.pos = o), !0)) + ); + } + function parseLinkTitle(s, o) { + var i, + u = o, + _ = s.posMax, + w = s.src.charCodeAt(o); + if (34 !== w && 39 !== w && 40 !== w) return !1; + for (o++, 40 === w && (w = 41); o < _; ) { + if ((i = s.src.charCodeAt(o)) === w) + return (s.pos = o + 1), (s.linkContent = unescapeMd(s.src.slice(u + 1, o))), !0; + 92 === i && o + 1 < _ ? (o += 2) : o++; + } + return !1; + } + function normalizeReference(s) { + return s.trim().replace(/\s+/g, ' ').toUpperCase(); + } + function parseReference(s, o, i, u) { + var _, w, x, C, j, L, B, $, V; + if (91 !== s.charCodeAt(0)) return -1; + if (-1 === s.indexOf(']:')) return -1; + if ( + (w = parseLinkLabel((_ = new StateInline(s, o, i, u, [])), 0)) < 0 || + 58 !== s.charCodeAt(w + 1) + ) + return -1; + for ( + C = _.posMax, x = w + 2; + x < C && (32 === (j = _.src.charCodeAt(x)) || 10 === j); + x++ + ); + if (!parseLinkDestination(_, x)) return -1; + for ( + B = _.linkContent, L = x = _.pos, x += 1; + x < C && (32 === (j = _.src.charCodeAt(x)) || 10 === j); + x++ + ); + for ( + x < C && L !== x && parseLinkTitle(_, x) + ? (($ = _.linkContent), (x = _.pos)) + : (($ = ''), (x = L)); + x < C && 32 === _.src.charCodeAt(x); + + ) + x++; + return x < C && 10 !== _.src.charCodeAt(x) + ? -1 + : ((V = normalizeReference(s.slice(1, w))), + void 0 === u.references[V] && (u.references[V] = { title: $, href: B }), + x); + } + (Renderer.prototype.renderInline = function (s, o, i) { + for (var u = this.rules, _ = s.length, w = 0, x = ''; _--; ) + x += u[s[w].type](s, w++, o, i, this); + return x; + }), + (Renderer.prototype.render = function (s, o, i) { + for (var u = this.rules, _ = s.length, w = -1, x = ''; ++w < _; ) + 'inline' === s[w].type + ? (x += this.renderInline(s[w].children, o, i)) + : (x += u[s[w].type](s, w, o, i, this)); + return x; + }), + (Ruler.prototype.__find__ = function (s) { + for (var o = this.__rules__.length, i = -1; o--; ) + if (this.__rules__[++i].name === s) return i; + return -1; + }), + (Ruler.prototype.__compile__ = function () { + var s = this, + o = ['']; + s.__rules__.forEach(function (s) { + s.enabled && + s.alt.forEach(function (s) { + o.indexOf(s) < 0 && o.push(s); + }); + }), + (s.__cache__ = {}), + o.forEach(function (o) { + (s.__cache__[o] = []), + s.__rules__.forEach(function (i) { + i.enabled && ((o && i.alt.indexOf(o) < 0) || s.__cache__[o].push(i.fn)); + }); + }); + }), + (Ruler.prototype.at = function (s, o, i) { + var u = this.__find__(s), + _ = i || {}; + if (-1 === u) throw new Error('Parser rule not found: ' + s); + (this.__rules__[u].fn = o), + (this.__rules__[u].alt = _.alt || []), + (this.__cache__ = null); + }), + (Ruler.prototype.before = function (s, o, i, u) { + var _ = this.__find__(s), + w = u || {}; + if (-1 === _) throw new Error('Parser rule not found: ' + s); + this.__rules__.splice(_, 0, { name: o, enabled: !0, fn: i, alt: w.alt || [] }), + (this.__cache__ = null); + }), + (Ruler.prototype.after = function (s, o, i, u) { + var _ = this.__find__(s), + w = u || {}; + if (-1 === _) throw new Error('Parser rule not found: ' + s); + this.__rules__.splice(_ + 1, 0, { name: o, enabled: !0, fn: i, alt: w.alt || [] }), + (this.__cache__ = null); + }), + (Ruler.prototype.push = function (s, o, i) { + var u = i || {}; + this.__rules__.push({ name: s, enabled: !0, fn: o, alt: u.alt || [] }), + (this.__cache__ = null); + }), + (Ruler.prototype.enable = function (s, o) { + (s = Array.isArray(s) ? s : [s]), + o && + this.__rules__.forEach(function (s) { + s.enabled = !1; + }), + s.forEach(function (s) { + var o = this.__find__(s); + if (o < 0) throw new Error('Rules manager: invalid rule name ' + s); + this.__rules__[o].enabled = !0; + }, this), + (this.__cache__ = null); + }), + (Ruler.prototype.disable = function (s) { + (s = Array.isArray(s) ? s : [s]).forEach(function (s) { + var o = this.__find__(s); + if (o < 0) throw new Error('Rules manager: invalid rule name ' + s); + this.__rules__[o].enabled = !1; + }, this), + (this.__cache__ = null); + }), + (Ruler.prototype.getRules = function (s) { + return null === this.__cache__ && this.__compile__(), this.__cache__[s] || []; + }), + (StateInline.prototype.pushPending = function () { + this.tokens.push({ type: 'text', content: this.pending, level: this.pendingLevel }), + (this.pending = ''); + }), + (StateInline.prototype.push = function (s) { + this.pending && this.pushPending(), + this.tokens.push(s), + (this.pendingLevel = this.level); + }), + (StateInline.prototype.cacheSet = function (s, o) { + for (var i = this.cache.length; i <= s; i++) this.cache.push(0); + this.cache[s] = o; + }), + (StateInline.prototype.cacheGet = function (s) { + return s < this.cache.length ? this.cache[s] : 0; + }); + var pC = ' \n()[]\'".,!?-'; + function regEscape(s) { + return s.replace(/([-()\[\]{}+?*.$\^|,:#= s.length) && !yC.test(s[o]); + } + function replaceAt(s, o, i) { + return s.substr(0, o) + i + s.substr(o + 1); + } + var vC = [ + [ + 'block', + function block(s) { + s.inlineMode + ? s.tokens.push({ + type: 'inline', + content: s.src.replace(/\n/g, ' ').trim(), + level: 0, + lines: [0, 1], + children: [] + }) + : s.block.parse(s.src, s.options, s.env, s.tokens); + } + ], + [ + 'abbr', + function abbr(s) { + var o, + i, + u, + _, + w = s.tokens; + if (!s.inlineMode) + for (o = 1, i = w.length - 1; o < i; o++) + if ( + 'paragraph_open' === w[o - 1].type && + 'inline' === w[o].type && + 'paragraph_close' === w[o + 1].type + ) { + for ( + u = w[o].content; + u.length && !((_ = parseAbbr(u, s.inline, s.options, s.env)) < 0); + + ) + u = u.slice(_).trim(); + (w[o].content = u), u.length || ((w[o - 1].tight = !0), (w[o + 1].tight = !0)); + } + } + ], + [ + 'references', + function references(s) { + var o, + i, + u, + _, + w = s.tokens; + if (((s.env.references = s.env.references || {}), !s.inlineMode)) + for (o = 1, i = w.length - 1; o < i; o++) + if ( + 'inline' === w[o].type && + 'paragraph_open' === w[o - 1].type && + 'paragraph_close' === w[o + 1].type + ) { + for ( + u = w[o].content; + u.length && !((_ = parseReference(u, s.inline, s.options, s.env)) < 0); + + ) + u = u.slice(_).trim(); + (w[o].content = u), u.length || ((w[o - 1].tight = !0), (w[o + 1].tight = !0)); + } + } + ], + [ + 'inline', + function inline(s) { + var o, + i, + u, + _ = s.tokens; + for (i = 0, u = _.length; i < u; i++) + 'inline' === (o = _[i]).type && + s.inline.parse(o.content, s.options, s.env, o.children); + } + ], + [ + 'footnote_tail', + function footnote_block(s) { + var o, + i, + u, + _, + w, + x, + C, + j, + L, + B = 0, + $ = !1, + V = {}; + if ( + s.env.footnotes && + ((s.tokens = s.tokens.filter(function (s) { + return 'footnote_reference_open' === s.type + ? (($ = !0), (j = []), (L = s.label), !1) + : 'footnote_reference_close' === s.type + ? (($ = !1), (V[':' + L] = j), !1) + : ($ && j.push(s), !$); + })), + s.env.footnotes.list) + ) { + for ( + x = s.env.footnotes.list, + s.tokens.push({ type: 'footnote_block_open', level: B++ }), + o = 0, + i = x.length; + o < i; + o++ + ) { + for ( + s.tokens.push({ type: 'footnote_open', id: o, level: B++ }), + x[o].tokens + ? ((C = []).push({ type: 'paragraph_open', tight: !1, level: B++ }), + C.push({ type: 'inline', content: '', level: B, children: x[o].tokens }), + C.push({ type: 'paragraph_close', tight: !1, level: --B })) + : x[o].label && (C = V[':' + x[o].label]), + s.tokens = s.tokens.concat(C), + w = + 'paragraph_close' === s.tokens[s.tokens.length - 1].type + ? s.tokens.pop() + : null, + _ = x[o].count > 0 ? x[o].count : 1, + u = 0; + u < _; + u++ + ) + s.tokens.push({ type: 'footnote_anchor', id: o, subId: u, level: B }); + w && s.tokens.push(w), s.tokens.push({ type: 'footnote_close', level: --B }); + } + s.tokens.push({ type: 'footnote_block_close', level: --B }); + } + } + ], + [ + 'abbr2', + function abbr2(s) { + var o, + i, + u, + _, + w, + x, + C, + j, + L, + B, + $, + V, + U = s.tokens; + if (s.env.abbreviations) + for ( + s.env.abbrRegExp || + ((V = + '(^|[' + + pC.split('').map(regEscape).join('') + + '])(' + + Object.keys(s.env.abbreviations) + .map(function (s) { + return s.substr(1); + }) + .sort(function (s, o) { + return o.length - s.length; + }) + .map(regEscape) + .join('|') + + ')($|[' + + pC.split('').map(regEscape).join('') + + '])'), + (s.env.abbrRegExp = new RegExp(V, 'g'))), + B = s.env.abbrRegExp, + i = 0, + u = U.length; + i < u; + i++ + ) + if ('inline' === U[i].type) + for (o = (_ = U[i].children).length - 1; o >= 0; o--) + if ('text' === (w = _[o]).type) { + for ( + j = 0, x = w.content, B.lastIndex = 0, L = w.level, C = []; + ($ = B.exec(x)); + + ) + B.lastIndex > j && + C.push({ + type: 'text', + content: x.slice(j, $.index + $[1].length), + level: L + }), + C.push({ + type: 'abbr_open', + title: s.env.abbreviations[':' + $[2]], + level: L++ + }), + C.push({ type: 'text', content: $[2], level: L }), + C.push({ type: 'abbr_close', level: --L }), + (j = B.lastIndex - $[3].length); + C.length && + (j < x.length && C.push({ type: 'text', content: x.slice(j), level: L }), + (U[i].children = _ = [].concat(_.slice(0, o), C, _.slice(o + 1)))); + } + } + ], + [ + 'replacements', + function index_browser_replace(s) { + var o, i, u, _, w; + if (s.options.typographer) + for (w = s.tokens.length - 1; w >= 0; w--) + if ('inline' === s.tokens[w].type) + for (o = (_ = s.tokens[w].children).length - 1; o >= 0; o--) + 'text' === (i = _[o]).type && + ((u = replaceScopedAbbr((u = i.content))), + hC.test(u) && + (u = u + .replace(/\+-/g, '±') + .replace(/\.{2,}/g, '…') + .replace(/([?!])…/g, '$1..') + .replace(/([?!]){4,}/g, '$1$1$1') + .replace(/,{2,}/g, ',') + .replace(/(^|[^-])---([^-]|$)/gm, '$1—$2') + .replace(/(^|\s)--(\s|$)/gm, '$1–$2') + .replace(/(^|[^-\s])--([^-\s]|$)/gm, '$1–$2')), + (i.content = u)); + } + ], + [ + 'smartquotes', + function smartquotes(s) { + var o, i, u, _, w, x, C, j, L, B, $, V, U, z, Y, Z, ee; + if (s.options.typographer) + for (ee = [], Y = s.tokens.length - 1; Y >= 0; Y--) + if ('inline' === s.tokens[Y].type) + for (Z = s.tokens[Y].children, ee.length = 0, o = 0; o < Z.length; o++) + if ('text' === (i = Z[o]).type && !mC.test(i.text)) { + for (C = Z[o].level, U = ee.length - 1; U >= 0 && !(ee[U].level <= C); U--); + (ee.length = U + 1), (w = 0), (x = (u = i.content).length); + e: for (; w < x && ((gC.lastIndex = w), (_ = gC.exec(u))); ) + if ( + ((j = !isLetter(u, _.index - 1)), + (w = _.index + 1), + (z = "'" === _[0]), + (L = !isLetter(u, w)) || j) + ) { + if ((($ = !L), (V = !j))) + for ( + U = ee.length - 1; + U >= 0 && ((B = ee[U]), !(ee[U].level < C)); + U-- + ) + if (B.single === z && ee[U].level === C) { + (B = ee[U]), + z + ? ((Z[B.token].content = replaceAt( + Z[B.token].content, + B.pos, + s.options.quotes[2] + )), + (i.content = replaceAt( + i.content, + _.index, + s.options.quotes[3] + ))) + : ((Z[B.token].content = replaceAt( + Z[B.token].content, + B.pos, + s.options.quotes[0] + )), + (i.content = replaceAt( + i.content, + _.index, + s.options.quotes[1] + ))), + (ee.length = U); + continue e; + } + $ + ? ee.push({ token: o, pos: _.index, single: z, level: C }) + : V && z && (i.content = replaceAt(i.content, _.index, '’')); + } else z && (i.content = replaceAt(i.content, _.index, '’')); + } + } + ] + ]; + function Core() { + (this.options = {}), (this.ruler = new Ruler()); + for (var s = 0; s < vC.length; s++) this.ruler.push(vC[s][0], vC[s][1]); + } + function StateBlock(s, o, i, u, _) { + var w, x, C, j, L, B, $; + for ( + this.src = s, + this.parser = o, + this.options = i, + this.env = u, + this.tokens = _, + this.bMarks = [], + this.eMarks = [], + this.tShift = [], + this.blkIndent = 0, + this.line = 0, + this.lineMax = 0, + this.tight = !1, + this.parentType = 'root', + this.ddIndent = -1, + this.level = 0, + this.result = '', + B = 0, + $ = !1, + C = j = B = 0, + L = (x = this.src).length; + j < L; + j++ + ) { + if (((w = x.charCodeAt(j)), !$)) { + if (32 === w) { + B++; + continue; + } + $ = !0; + } + (10 !== w && j !== L - 1) || + (10 !== w && j++, + this.bMarks.push(C), + this.eMarks.push(j), + this.tShift.push(B), + ($ = !1), + (B = 0), + (C = j + 1)); + } + this.bMarks.push(x.length), + this.eMarks.push(x.length), + this.tShift.push(0), + (this.lineMax = this.bMarks.length - 1); + } + function skipBulletListMarker(s, o) { + var i, u, _; + return (u = s.bMarks[o] + s.tShift[o]) >= (_ = s.eMarks[o]) || + (42 !== (i = s.src.charCodeAt(u++)) && 45 !== i && 43 !== i) || + (u < _ && 32 !== s.src.charCodeAt(u)) + ? -1 + : u; + } + function skipOrderedListMarker(s, o) { + var i, + u = s.bMarks[o] + s.tShift[o], + _ = s.eMarks[o]; + if (u + 1 >= _) return -1; + if ((i = s.src.charCodeAt(u++)) < 48 || i > 57) return -1; + for (;;) { + if (u >= _) return -1; + if (!((i = s.src.charCodeAt(u++)) >= 48 && i <= 57)) { + if (41 === i || 46 === i) break; + return -1; + } + } + return u < _ && 32 !== s.src.charCodeAt(u) ? -1 : u; + } + (Core.prototype.process = function (s) { + var o, i, u; + for (o = 0, i = (u = this.ruler.getRules('')).length; o < i; o++) u[o](s); + }), + (StateBlock.prototype.isEmpty = function isEmpty(s) { + return this.bMarks[s] + this.tShift[s] >= this.eMarks[s]; + }), + (StateBlock.prototype.skipEmptyLines = function skipEmptyLines(s) { + for ( + var o = this.lineMax; + s < o && !(this.bMarks[s] + this.tShift[s] < this.eMarks[s]); + s++ + ); + return s; + }), + (StateBlock.prototype.skipSpaces = function skipSpaces(s) { + for (var o = this.src.length; s < o && 32 === this.src.charCodeAt(s); s++); + return s; + }), + (StateBlock.prototype.skipChars = function skipChars(s, o) { + for (var i = this.src.length; s < i && this.src.charCodeAt(s) === o; s++); + return s; + }), + (StateBlock.prototype.skipCharsBack = function skipCharsBack(s, o, i) { + if (s <= i) return s; + for (; s > i; ) if (o !== this.src.charCodeAt(--s)) return s + 1; + return s; + }), + (StateBlock.prototype.getLines = function getLines(s, o, i, u) { + var _, + w, + x, + C, + j, + L = s; + if (s >= o) return ''; + if (L + 1 === o) + return ( + (w = this.bMarks[L] + Math.min(this.tShift[L], i)), + (x = u ? this.eMarks[L] + 1 : this.eMarks[L]), + this.src.slice(w, x) + ); + for (C = new Array(o - s), _ = 0; L < o; L++, _++) + (j = this.tShift[L]) > i && (j = i), + j < 0 && (j = 0), + (w = this.bMarks[L] + j), + (x = L + 1 < o || u ? this.eMarks[L] + 1 : this.eMarks[L]), + (C[_] = this.src.slice(w, x)); + return C.join(''); + }); + var bC = {}; + [ + 'article', + 'aside', + 'button', + 'blockquote', + 'body', + 'canvas', + 'caption', + 'col', + 'colgroup', + 'dd', + 'div', + 'dl', + 'dt', + 'embed', + 'fieldset', + 'figcaption', + 'figure', + 'footer', + 'form', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'header', + 'hgroup', + 'hr', + 'iframe', + 'li', + 'map', + 'object', + 'ol', + 'output', + 'p', + 'pre', + 'progress', + 'script', + 'section', + 'style', + 'table', + 'tbody', + 'td', + 'textarea', + 'tfoot', + 'th', + 'tr', + 'thead', + 'ul', + 'video' + ].forEach(function (s) { + bC[s] = !0; + }); + var _C = /^<([a-zA-Z]{1,15})[\s\/>]/, + EC = /^<\/([a-zA-Z]{1,15})[\s>]/; + function index_browser_getLine(s, o) { + var i = s.bMarks[o] + s.blkIndent, + u = s.eMarks[o]; + return s.src.substr(i, u - i); + } + function skipMarker(s, o) { + var i, + u, + _ = s.bMarks[o] + s.tShift[o], + w = s.eMarks[o]; + return _ >= w || + (126 !== (u = s.src.charCodeAt(_++)) && 58 !== u) || + _ === (i = s.skipSpaces(_)) || + i >= w + ? -1 + : i; + } + var wC = [ + [ + 'code', + function code(s, o, i) { + var u, _; + if (s.tShift[o] - s.blkIndent < 4) return !1; + for (_ = u = o + 1; u < i; ) + if (s.isEmpty(u)) u++; + else { + if (!(s.tShift[u] - s.blkIndent >= 4)) break; + _ = ++u; + } + return ( + (s.line = u), + s.tokens.push({ + type: 'code', + content: s.getLines(o, _, 4 + s.blkIndent, !0), + block: !0, + lines: [o, s.line], + level: s.level + }), + !0 + ); + } + ], + [ + 'fences', + function fences(s, o, i, u) { + var _, + w, + x, + C, + j, + L = !1, + B = s.bMarks[o] + s.tShift[o], + $ = s.eMarks[o]; + if (B + 3 > $) return !1; + if (126 !== (_ = s.src.charCodeAt(B)) && 96 !== _) return !1; + if (((j = B), (w = (B = s.skipChars(B, _)) - j) < 3)) return !1; + if ((x = s.src.slice(B, $).trim()).indexOf('`') >= 0) return !1; + if (u) return !0; + for ( + C = o; + !(++C >= i) && + !( + (B = j = s.bMarks[C] + s.tShift[C]) < ($ = s.eMarks[C]) && + s.tShift[C] < s.blkIndent + ); + + ) + if ( + s.src.charCodeAt(B) === _ && + !( + s.tShift[C] - s.blkIndent >= 4 || + (B = s.skipChars(B, _)) - j < w || + (B = s.skipSpaces(B)) < $ + ) + ) { + L = !0; + break; + } + return ( + (w = s.tShift[o]), + (s.line = C + (L ? 1 : 0)), + s.tokens.push({ + type: 'fence', + params: x, + content: s.getLines(o + 1, C, w, !0), + lines: [o, s.line], + level: s.level + }), + !0 + ); + }, + ['paragraph', 'blockquote', 'list'] + ], + [ + 'blockquote', + function blockquote(s, o, i, u) { + var _, + w, + x, + C, + j, + L, + B, + $, + V, + U, + z, + Y = s.bMarks[o] + s.tShift[o], + Z = s.eMarks[o]; + if (Y > Z) return !1; + if (62 !== s.src.charCodeAt(Y++)) return !1; + if (s.level >= s.options.maxNesting) return !1; + if (u) return !0; + for ( + 32 === s.src.charCodeAt(Y) && Y++, + j = s.blkIndent, + s.blkIndent = 0, + C = [s.bMarks[o]], + s.bMarks[o] = Y, + w = (Y = Y < Z ? s.skipSpaces(Y) : Y) >= Z, + x = [s.tShift[o]], + s.tShift[o] = Y - s.bMarks[o], + $ = s.parser.ruler.getRules('blockquote'), + _ = o + 1; + _ < i && !((Y = s.bMarks[_] + s.tShift[_]) >= (Z = s.eMarks[_])); + _++ + ) + if (62 !== s.src.charCodeAt(Y++)) { + if (w) break; + for (z = !1, V = 0, U = $.length; V < U; V++) + if ($[V](s, _, i, !0)) { + z = !0; + break; + } + if (z) break; + C.push(s.bMarks[_]), x.push(s.tShift[_]), (s.tShift[_] = -1337); + } else + 32 === s.src.charCodeAt(Y) && Y++, + C.push(s.bMarks[_]), + (s.bMarks[_] = Y), + (w = (Y = Y < Z ? s.skipSpaces(Y) : Y) >= Z), + x.push(s.tShift[_]), + (s.tShift[_] = Y - s.bMarks[_]); + for ( + L = s.parentType, + s.parentType = 'blockquote', + s.tokens.push({ type: 'blockquote_open', lines: (B = [o, 0]), level: s.level++ }), + s.parser.tokenize(s, o, _), + s.tokens.push({ type: 'blockquote_close', level: --s.level }), + s.parentType = L, + B[1] = s.line, + V = 0; + V < x.length; + V++ + ) + (s.bMarks[V + o] = C[V]), (s.tShift[V + o] = x[V]); + return (s.blkIndent = j), !0; + }, + ['paragraph', 'blockquote', 'list'] + ], + [ + 'hr', + function hr(s, o, i, u) { + var _, + w, + x, + C = s.bMarks[o], + j = s.eMarks[o]; + if ((C += s.tShift[o]) > j) return !1; + if (42 !== (_ = s.src.charCodeAt(C++)) && 45 !== _ && 95 !== _) return !1; + for (w = 1; C < j; ) { + if ((x = s.src.charCodeAt(C++)) !== _ && 32 !== x) return !1; + x === _ && w++; + } + return ( + !(w < 3) && + (u || + ((s.line = o + 1), + s.tokens.push({ type: 'hr', lines: [o, s.line], level: s.level })), + !0) + ); + }, + ['paragraph', 'blockquote', 'list'] + ], + [ + 'list', + function index_browser_list(s, o, i, u) { + var _, + w, + x, + C, + j, + L, + B, + $, + V, + U, + z, + Y, + Z, + ee, + ie, + ae, + le, + ce, + pe, + de, + fe, + ye = !0; + if (($ = skipOrderedListMarker(s, o)) >= 0) Y = !0; + else { + if (!(($ = skipBulletListMarker(s, o)) >= 0)) return !1; + Y = !1; + } + if (s.level >= s.options.maxNesting) return !1; + if (((z = s.src.charCodeAt($ - 1)), u)) return !0; + for ( + ee = s.tokens.length, + Y + ? ((B = s.bMarks[o] + s.tShift[o]), + (U = Number(s.src.substr(B, $ - B - 1))), + s.tokens.push({ + type: 'ordered_list_open', + order: U, + lines: (ae = [o, 0]), + level: s.level++ + })) + : s.tokens.push({ + type: 'bullet_list_open', + lines: (ae = [o, 0]), + level: s.level++ + }), + _ = o, + ie = !1, + ce = s.parser.ruler.getRules('list'); + !( + !(_ < i) || + ((V = (Z = s.skipSpaces($)) >= s.eMarks[_] ? 1 : Z - $) > 4 && (V = 1), + V < 1 && (V = 1), + (w = $ - s.bMarks[_] + V), + s.tokens.push({ type: 'list_item_open', lines: (le = [o, 0]), level: s.level++ }), + (C = s.blkIndent), + (j = s.tight), + (x = s.tShift[o]), + (L = s.parentType), + (s.tShift[o] = Z - s.bMarks[o]), + (s.blkIndent = w), + (s.tight = !0), + (s.parentType = 'list'), + s.parser.tokenize(s, o, i, !0), + (s.tight && !ie) || (ye = !1), + (ie = s.line - o > 1 && s.isEmpty(s.line - 1)), + (s.blkIndent = C), + (s.tShift[o] = x), + (s.tight = j), + (s.parentType = L), + s.tokens.push({ type: 'list_item_close', level: --s.level }), + (_ = o = s.line), + (le[1] = _), + (Z = s.bMarks[o]), + _ >= i) || + s.isEmpty(_) || + s.tShift[_] < s.blkIndent + ); + + ) { + for (fe = !1, pe = 0, de = ce.length; pe < de; pe++) + if (ce[pe](s, _, i, !0)) { + fe = !0; + break; + } + if (fe) break; + if (Y) { + if (($ = skipOrderedListMarker(s, _)) < 0) break; + } else if (($ = skipBulletListMarker(s, _)) < 0) break; + if (z !== s.src.charCodeAt($ - 1)) break; + } + return ( + s.tokens.push({ + type: Y ? 'ordered_list_close' : 'bullet_list_close', + level: --s.level + }), + (ae[1] = _), + (s.line = _), + ye && + (function markTightParagraphs(s, o) { + var i, + u, + _ = s.level + 2; + for (i = o + 2, u = s.tokens.length - 2; i < u; i++) + s.tokens[i].level === _ && + 'paragraph_open' === s.tokens[i].type && + ((s.tokens[i + 2].tight = !0), (s.tokens[i].tight = !0), (i += 2)); + })(s, ee), + !0 + ); + }, + ['paragraph', 'blockquote'] + ], + [ + 'footnote', + function footnote(s, o, i, u) { + var _, + w, + x, + C, + j, + L = s.bMarks[o] + s.tShift[o], + B = s.eMarks[o]; + if (L + 4 > B) return !1; + if (91 !== s.src.charCodeAt(L)) return !1; + if (94 !== s.src.charCodeAt(L + 1)) return !1; + if (s.level >= s.options.maxNesting) return !1; + for (C = L + 2; C < B; C++) { + if (32 === s.src.charCodeAt(C)) return !1; + if (93 === s.src.charCodeAt(C)) break; + } + return ( + C !== L + 2 && + !(C + 1 >= B || 58 !== s.src.charCodeAt(++C)) && + (u || + (C++, + s.env.footnotes || (s.env.footnotes = {}), + s.env.footnotes.refs || (s.env.footnotes.refs = {}), + (j = s.src.slice(L + 2, C - 2)), + (s.env.footnotes.refs[':' + j] = -1), + s.tokens.push({ type: 'footnote_reference_open', label: j, level: s.level++ }), + (_ = s.bMarks[o]), + (w = s.tShift[o]), + (x = s.parentType), + (s.tShift[o] = s.skipSpaces(C) - C), + (s.bMarks[o] = C), + (s.blkIndent += 4), + (s.parentType = 'footnote'), + s.tShift[o] < s.blkIndent && + ((s.tShift[o] += s.blkIndent), (s.bMarks[o] -= s.blkIndent)), + s.parser.tokenize(s, o, i, !0), + (s.parentType = x), + (s.blkIndent -= 4), + (s.tShift[o] = w), + (s.bMarks[o] = _), + s.tokens.push({ type: 'footnote_reference_close', level: --s.level })), + !0) + ); + }, + ['paragraph'] + ], + [ + 'heading', + function heading(s, o, i, u) { + var _, + w, + x, + C = s.bMarks[o] + s.tShift[o], + j = s.eMarks[o]; + if (C >= j) return !1; + if (35 !== (_ = s.src.charCodeAt(C)) || C >= j) return !1; + for (w = 1, _ = s.src.charCodeAt(++C); 35 === _ && C < j && w <= 6; ) + w++, (_ = s.src.charCodeAt(++C)); + return ( + !(w > 6 || (C < j && 32 !== _)) && + (u || + ((j = s.skipCharsBack(j, 32, C)), + (x = s.skipCharsBack(j, 35, C)) > C && 32 === s.src.charCodeAt(x - 1) && (j = x), + (s.line = o + 1), + s.tokens.push({ + type: 'heading_open', + hLevel: w, + lines: [o, s.line], + level: s.level + }), + C < j && + s.tokens.push({ + type: 'inline', + content: s.src.slice(C, j).trim(), + level: s.level + 1, + lines: [o, s.line], + children: [] + }), + s.tokens.push({ type: 'heading_close', hLevel: w, level: s.level })), + !0) + ); + }, + ['paragraph', 'blockquote'] + ], + [ + 'lheading', + function lheading(s, o, i) { + var u, + _, + w, + x = o + 1; + return ( + !(x >= i) && + !(s.tShift[x] < s.blkIndent) && + !(s.tShift[x] - s.blkIndent > 3) && + !((_ = s.bMarks[x] + s.tShift[x]) >= (w = s.eMarks[x])) && + (45 === (u = s.src.charCodeAt(_)) || 61 === u) && + ((_ = s.skipChars(_, u)), + !((_ = s.skipSpaces(_)) < w) && + ((_ = s.bMarks[o] + s.tShift[o]), + (s.line = x + 1), + s.tokens.push({ + type: 'heading_open', + hLevel: 61 === u ? 1 : 2, + lines: [o, s.line], + level: s.level + }), + s.tokens.push({ + type: 'inline', + content: s.src.slice(_, s.eMarks[o]).trim(), + level: s.level + 1, + lines: [o, s.line - 1], + children: [] + }), + s.tokens.push({ + type: 'heading_close', + hLevel: 61 === u ? 1 : 2, + level: s.level + }), + !0)) + ); + } + ], + [ + 'htmlblock', + function htmlblock(s, o, i, u) { + var _, + w, + x, + C = s.bMarks[o], + j = s.eMarks[o], + L = s.tShift[o]; + if (((C += L), !s.options.html)) return !1; + if (L > 3 || C + 2 >= j) return !1; + if (60 !== s.src.charCodeAt(C)) return !1; + if (33 === (_ = s.src.charCodeAt(C + 1)) || 63 === _) { + if (u) return !0; + } else { + if ( + 47 !== _ && + !(function isLetter$1(s) { + var o = 32 | s; + return o >= 97 && o <= 122; + })(_) + ) + return !1; + if (47 === _) { + if (!(w = s.src.slice(C, j).match(EC))) return !1; + } else if (!(w = s.src.slice(C, j).match(_C))) return !1; + if (!0 !== bC[w[1].toLowerCase()]) return !1; + if (u) return !0; + } + for (x = o + 1; x < s.lineMax && !s.isEmpty(x); ) x++; + return ( + (s.line = x), + s.tokens.push({ + type: 'htmlblock', + level: s.level, + lines: [o, s.line], + content: s.getLines(o, x, 0, !0) + }), + !0 + ); + }, + ['paragraph', 'blockquote'] + ], + [ + 'table', + function table(s, o, i, u) { + var _, w, x, C, j, L, B, $, V, U, z; + if (o + 2 > i) return !1; + if (((j = o + 1), s.tShift[j] < s.blkIndent)) return !1; + if ((x = s.bMarks[j] + s.tShift[j]) >= s.eMarks[j]) return !1; + if (124 !== (_ = s.src.charCodeAt(x)) && 45 !== _ && 58 !== _) return !1; + if (((w = index_browser_getLine(s, o + 1)), !/^[-:| ]+$/.test(w))) return !1; + if ((L = w.split('|')) <= 2) return !1; + for ($ = [], C = 0; C < L.length; C++) { + if (!(V = L[C].trim())) { + if (0 === C || C === L.length - 1) continue; + return !1; + } + if (!/^:?-+:?$/.test(V)) return !1; + 58 === V.charCodeAt(V.length - 1) + ? $.push(58 === V.charCodeAt(0) ? 'center' : 'right') + : 58 === V.charCodeAt(0) + ? $.push('left') + : $.push(''); + } + if (-1 === (w = index_browser_getLine(s, o).trim()).indexOf('|')) return !1; + if (((L = w.replace(/^\||\|$/g, '').split('|')), $.length !== L.length)) return !1; + if (u) return !0; + for ( + s.tokens.push({ type: 'table_open', lines: (U = [o, 0]), level: s.level++ }), + s.tokens.push({ type: 'thead_open', lines: [o, o + 1], level: s.level++ }), + s.tokens.push({ type: 'tr_open', lines: [o, o + 1], level: s.level++ }), + C = 0; + C < L.length; + C++ + ) + s.tokens.push({ + type: 'th_open', + align: $[C], + lines: [o, o + 1], + level: s.level++ + }), + s.tokens.push({ + type: 'inline', + content: L[C].trim(), + lines: [o, o + 1], + level: s.level, + children: [] + }), + s.tokens.push({ type: 'th_close', level: --s.level }); + for ( + s.tokens.push({ type: 'tr_close', level: --s.level }), + s.tokens.push({ type: 'thead_close', level: --s.level }), + s.tokens.push({ type: 'tbody_open', lines: (z = [o + 2, 0]), level: s.level++ }), + j = o + 2; + j < i && + !(s.tShift[j] < s.blkIndent) && + -1 !== (w = index_browser_getLine(s, j).trim()).indexOf('|'); + j++ + ) { + for ( + L = w.replace(/^\||\|$/g, '').split('|'), + s.tokens.push({ type: 'tr_open', level: s.level++ }), + C = 0; + C < L.length; + C++ + ) + s.tokens.push({ type: 'td_open', align: $[C], level: s.level++ }), + (B = L[C].substring( + 124 === L[C].charCodeAt(0) ? 1 : 0, + 124 === L[C].charCodeAt(L[C].length - 1) ? L[C].length - 1 : L[C].length + ).trim()), + s.tokens.push({ type: 'inline', content: B, level: s.level, children: [] }), + s.tokens.push({ type: 'td_close', level: --s.level }); + s.tokens.push({ type: 'tr_close', level: --s.level }); + } + return ( + s.tokens.push({ type: 'tbody_close', level: --s.level }), + s.tokens.push({ type: 'table_close', level: --s.level }), + (U[1] = z[1] = j), + (s.line = j), + !0 + ); + }, + ['paragraph'] + ], + [ + 'deflist', + function deflist(s, o, i, u) { + var _, w, x, C, j, L, B, $, V, U, z, Y, Z, ee; + if (u) return !(s.ddIndent < 0) && skipMarker(s, o) >= 0; + if (((B = o + 1), s.isEmpty(B) && ++B > i)) return !1; + if (s.tShift[B] < s.blkIndent) return !1; + if ((_ = skipMarker(s, B)) < 0) return !1; + if (s.level >= s.options.maxNesting) return !1; + (L = s.tokens.length), + s.tokens.push({ type: 'dl_open', lines: (j = [o, 0]), level: s.level++ }), + (x = o), + (w = B); + e: for (;;) { + for ( + ee = !0, + Z = !1, + s.tokens.push({ type: 'dt_open', lines: [x, x], level: s.level++ }), + s.tokens.push({ + type: 'inline', + content: s.getLines(x, x + 1, s.blkIndent, !1).trim(), + level: s.level + 1, + lines: [x, x], + children: [] + }), + s.tokens.push({ type: 'dt_close', level: --s.level }); + ; + + ) { + if ( + (s.tokens.push({ type: 'dd_open', lines: (C = [B, 0]), level: s.level++ }), + (Y = s.tight), + (V = s.ddIndent), + ($ = s.blkIndent), + (z = s.tShift[w]), + (U = s.parentType), + (s.blkIndent = s.ddIndent = s.tShift[w] + 2), + (s.tShift[w] = _ - s.bMarks[w]), + (s.tight = !0), + (s.parentType = 'deflist'), + s.parser.tokenize(s, w, i, !0), + (s.tight && !Z) || (ee = !1), + (Z = s.line - w > 1 && s.isEmpty(s.line - 1)), + (s.tShift[w] = z), + (s.tight = Y), + (s.parentType = U), + (s.blkIndent = $), + (s.ddIndent = V), + s.tokens.push({ type: 'dd_close', level: --s.level }), + (C[1] = B = s.line), + B >= i) + ) + break e; + if (s.tShift[B] < s.blkIndent) break e; + if ((_ = skipMarker(s, B)) < 0) break; + w = B; + } + if (B >= i) break; + if (((x = B), s.isEmpty(x))) break; + if (s.tShift[x] < s.blkIndent) break; + if ((w = x + 1) >= i) break; + if ((s.isEmpty(w) && w++, w >= i)) break; + if (s.tShift[w] < s.blkIndent) break; + if ((_ = skipMarker(s, w)) < 0) break; + } + return ( + s.tokens.push({ type: 'dl_close', level: --s.level }), + (j[1] = B), + (s.line = B), + ee && + (function markTightParagraphs$1(s, o) { + var i, + u, + _ = s.level + 2; + for (i = o + 2, u = s.tokens.length - 2; i < u; i++) + s.tokens[i].level === _ && + 'paragraph_open' === s.tokens[i].type && + ((s.tokens[i + 2].tight = !0), (s.tokens[i].tight = !0), (i += 2)); + })(s, L), + !0 + ); + }, + ['paragraph'] + ], + [ + 'paragraph', + function paragraph(s, o) { + var i, + u, + _, + w, + x, + C, + j = o + 1; + if (j < (i = s.lineMax) && !s.isEmpty(j)) + for (C = s.parser.ruler.getRules('paragraph'); j < i && !s.isEmpty(j); j++) + if (!(s.tShift[j] - s.blkIndent > 3)) { + for (_ = !1, w = 0, x = C.length; w < x; w++) + if (C[w](s, j, i, !0)) { + _ = !0; + break; + } + if (_) break; + } + return ( + (u = s.getLines(o, j, s.blkIndent, !1).trim()), + (s.line = j), + u.length && + (s.tokens.push({ + type: 'paragraph_open', + tight: !1, + lines: [o, s.line], + level: s.level + }), + s.tokens.push({ + type: 'inline', + content: u, + level: s.level + 1, + lines: [o, s.line], + children: [] + }), + s.tokens.push({ type: 'paragraph_close', tight: !1, level: s.level })), + !0 + ); + } + ] + ]; + function ParserBlock() { + this.ruler = new Ruler(); + for (var s = 0; s < wC.length; s++) + this.ruler.push(wC[s][0], wC[s][1], { alt: (wC[s][2] || []).slice() }); + } + ParserBlock.prototype.tokenize = function (s, o, i) { + for ( + var u, _ = this.ruler.getRules(''), w = _.length, x = o, C = !1; + x < i && + ((s.line = x = s.skipEmptyLines(x)), !(x >= i)) && + !(s.tShift[x] < s.blkIndent); + + ) { + for (u = 0; u < w && !_[u](s, x, i, !1); u++); + if ( + ((s.tight = !C), s.isEmpty(s.line - 1) && (C = !0), (x = s.line) < i && s.isEmpty(x)) + ) { + if (((C = !0), ++x < i && 'list' === s.parentType && s.isEmpty(x))) break; + s.line = x; + } + } + }; + var SC = /[\n\t]/g, + xC = /\r[\n\u0085]|[\u2424\u2028\u0085]/g, + kC = /\u00a0/g; + function isTerminatorChar(s) { + switch (s) { + case 10: + case 92: + case 96: + case 42: + case 95: + case 94: + case 91: + case 93: + case 33: + case 38: + case 60: + case 62: + case 123: + case 125: + case 36: + case 37: + case 64: + case 126: + case 43: + case 61: + case 58: + return !0; + default: + return !1; + } + } + ParserBlock.prototype.parse = function (s, o, i, u) { + var _, + w = 0, + x = 0; + if (!s) return []; + (s = (s = s.replace(kC, ' ')).replace(xC, '\n')).indexOf('\t') >= 0 && + (s = s.replace(SC, function (o, i) { + var u; + return 10 === s.charCodeAt(i) + ? ((w = i + 1), (x = 0), o) + : ((u = ' '.slice((i - w - x) % 4)), (x = i - w + 1), u); + })), + (_ = new StateBlock(s, this, o, i, u)), + this.tokenize(_, _.line, _.lineMax); + }; + for (var CC = [], OC = 0; OC < 256; OC++) CC.push(0); + function isAlphaNum(s) { + return (s >= 48 && s <= 57) || (s >= 65 && s <= 90) || (s >= 97 && s <= 122); + } + function scanDelims(s, o) { + var i, + u, + _, + w = o, + x = !0, + C = !0, + j = s.posMax, + L = s.src.charCodeAt(o); + for (i = o > 0 ? s.src.charCodeAt(o - 1) : -1; w < j && s.src.charCodeAt(w) === L; ) w++; + return ( + w >= j && (x = !1), + (_ = w - o) >= 4 + ? (x = C = !1) + : ((32 !== (u = w < j ? s.src.charCodeAt(w) : -1) && 10 !== u) || (x = !1), + (32 !== i && 10 !== i) || (C = !1), + 95 === L && (isAlphaNum(i) && (x = !1), isAlphaNum(u) && (C = !1))), + { can_open: x, can_close: C, delims: _ } + ); + } + '\\!"#$%&\'()*+,./:;<=>?@[]^_`{|}~-'.split('').forEach(function (s) { + CC[s.charCodeAt(0)] = 1; + }); + var AC = /\\([ \\!"#$%&'()*+,.\/:;<=>?@[\]^_`{|}~-])/g; + var jC = /\\([ \\!"#$%&'()*+,.\/:;<=>?@[\]^_`{|}~-])/g; + var IC = [ + 'coap', + 'doi', + 'javascript', + 'aaa', + 'aaas', + 'about', + 'acap', + 'cap', + 'cid', + 'crid', + 'data', + 'dav', + 'dict', + 'dns', + 'file', + 'ftp', + 'geo', + 'go', + 'gopher', + 'h323', + 'http', + 'https', + 'iax', + 'icap', + 'im', + 'imap', + 'info', + 'ipp', + 'iris', + 'iris.beep', + 'iris.xpc', + 'iris.xpcs', + 'iris.lwz', + 'ldap', + 'mailto', + 'mid', + 'msrp', + 'msrps', + 'mtqp', + 'mupdate', + 'news', + 'nfs', + 'ni', + 'nih', + 'nntp', + 'opaquelocktoken', + 'pop', + 'pres', + 'rtsp', + 'service', + 'session', + 'shttp', + 'sieve', + 'sip', + 'sips', + 'sms', + 'snmp', + 'soap.beep', + 'soap.beeps', + 'tag', + 'tel', + 'telnet', + 'tftp', + 'thismessage', + 'tn3270', + 'tip', + 'tv', + 'urn', + 'vemmi', + 'ws', + 'wss', + 'xcon', + 'xcon-userid', + 'xmlrpc.beep', + 'xmlrpc.beeps', + 'xmpp', + 'z39.50r', + 'z39.50s', + 'adiumxtra', + 'afp', + 'afs', + 'aim', + 'apt', + 'attachment', + 'aw', + 'beshare', + 'bitcoin', + 'bolo', + 'callto', + 'chrome', + 'chrome-extension', + 'com-eventbrite-attendee', + 'content', + 'cvs', + 'dlna-playsingle', + 'dlna-playcontainer', + 'dtn', + 'dvb', + 'ed2k', + 'facetime', + 'feed', + 'finger', + 'fish', + 'gg', + 'git', + 'gizmoproject', + 'gtalk', + 'hcp', + 'icon', + 'ipn', + 'irc', + 'irc6', + 'ircs', + 'itms', + 'jar', + 'jms', + 'keyparc', + 'lastfm', + 'ldaps', + 'magnet', + 'maps', + 'market', + 'message', + 'mms', + 'ms-help', + 'msnim', + 'mumble', + 'mvn', + 'notes', + 'oid', + 'palm', + 'paparazzi', + 'platform', + 'proxy', + 'psyc', + 'query', + 'res', + 'resource', + 'rmi', + 'rsync', + 'rtmp', + 'secondlife', + 'sftp', + 'sgn', + 'skype', + 'smb', + 'soldat', + 'spotify', + 'ssh', + 'steam', + 'svn', + 'teamspeak', + 'things', + 'udp', + 'unreal', + 'ut2004', + 'ventrilo', + 'view-source', + 'webcal', + 'wtai', + 'wyciwyg', + 'xfire', + 'xri', + 'ymsgr' + ], + PC = + /^<([a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)>/, + MC = /^<([a-zA-Z.\-]{1,25}):([^<>\x00-\x20]*)>/; + function replace$1(s, o) { + return ( + (s = s.source), + (o = o || ''), + function self(i, u) { + return i ? ((u = u.source || u), (s = s.replace(i, u)), self) : new RegExp(s, o); + } + ); + } + var TC = replace$1(/(?:unquoted|single_quoted|double_quoted)/)( + 'unquoted', + /[^"'=<>`\x00-\x20]+/ + )('single_quoted', /'[^']*'/)('double_quoted', /"[^"]*"/)(), + NC = replace$1(/(?:\s+attr_name(?:\s*=\s*attr_value)?)/)( + 'attr_name', + /[a-zA-Z_:][a-zA-Z0-9:._-]*/ + )('attr_value', TC)(), + RC = replace$1(/<[A-Za-z][A-Za-z0-9]*attribute*\s*\/?>/)('attribute', NC)(), + DC = replace$1(/^(?:open_tag|close_tag|comment|processing|declaration|cdata)/)( + 'open_tag', + RC + )('close_tag', /<\/[A-Za-z][A-Za-z0-9]*\s*>/)( + 'comment', + /|/ + )('processing', /<[?].*?[?]>/)('declaration', /]*>/)( + 'cdata', + // + )(); + var LC = /^&#((?:x[a-f0-9]{1,8}|[0-9]{1,8}));/i, + BC = /^&([a-z][a-z0-9]{1,31});/i; + var FC = [ + [ + 'text', + function index_browser_text(s, o) { + for (var i = s.pos; i < s.posMax && !isTerminatorChar(s.src.charCodeAt(i)); ) i++; + return i !== s.pos && (o || (s.pending += s.src.slice(s.pos, i)), (s.pos = i), !0); + } + ], + [ + 'newline', + function newline(s, o) { + var i, + u, + _ = s.pos; + if (10 !== s.src.charCodeAt(_)) return !1; + if (((i = s.pending.length - 1), (u = s.posMax), !o)) + if (i >= 0 && 32 === s.pending.charCodeAt(i)) + if (i >= 1 && 32 === s.pending.charCodeAt(i - 1)) { + for (var w = i - 2; w >= 0; w--) + if (32 !== s.pending.charCodeAt(w)) { + s.pending = s.pending.substring(0, w + 1); + break; + } + s.push({ type: 'hardbreak', level: s.level }); + } else + (s.pending = s.pending.slice(0, -1)), + s.push({ type: 'softbreak', level: s.level }); + else s.push({ type: 'softbreak', level: s.level }); + for (_++; _ < u && 32 === s.src.charCodeAt(_); ) _++; + return (s.pos = _), !0; + } + ], + [ + 'escape', + function index_browser_escape(s, o) { + var i, + u = s.pos, + _ = s.posMax; + if (92 !== s.src.charCodeAt(u)) return !1; + if (++u < _) { + if ((i = s.src.charCodeAt(u)) < 256 && 0 !== CC[i]) + return o || (s.pending += s.src[u]), (s.pos += 2), !0; + if (10 === i) { + for ( + o || s.push({ type: 'hardbreak', level: s.level }), u++; + u < _ && 32 === s.src.charCodeAt(u); + + ) + u++; + return (s.pos = u), !0; + } + } + return o || (s.pending += '\\'), s.pos++, !0; + } + ], + [ + 'backticks', + function backticks(s, o) { + var i, + u, + _, + w, + x, + C = s.pos; + if (96 !== s.src.charCodeAt(C)) return !1; + for (i = C, C++, u = s.posMax; C < u && 96 === s.src.charCodeAt(C); ) C++; + for (_ = s.src.slice(i, C), w = x = C; -1 !== (w = s.src.indexOf('`', x)); ) { + for (x = w + 1; x < u && 96 === s.src.charCodeAt(x); ) x++; + if (x - w === _.length) + return ( + o || + s.push({ + type: 'code', + content: s.src + .slice(C, w) + .replace(/[ \n]+/g, ' ') + .trim(), + block: !1, + level: s.level + }), + (s.pos = x), + !0 + ); + } + return o || (s.pending += _), (s.pos += _.length), !0; + } + ], + [ + 'del', + function del(s, o) { + var i, + u, + _, + w, + x, + C = s.posMax, + j = s.pos; + if (126 !== s.src.charCodeAt(j)) return !1; + if (o) return !1; + if (j + 4 >= C) return !1; + if (126 !== s.src.charCodeAt(j + 1)) return !1; + if (s.level >= s.options.maxNesting) return !1; + if ( + ((w = j > 0 ? s.src.charCodeAt(j - 1) : -1), + (x = s.src.charCodeAt(j + 2)), + 126 === w) + ) + return !1; + if (126 === x) return !1; + if (32 === x || 10 === x) return !1; + for (u = j + 2; u < C && 126 === s.src.charCodeAt(u); ) u++; + if (u > j + 3) return (s.pos += u - j), o || (s.pending += s.src.slice(j, u)), !0; + for (s.pos = j + 2, _ = 1; s.pos + 1 < C; ) { + if ( + 126 === s.src.charCodeAt(s.pos) && + 126 === s.src.charCodeAt(s.pos + 1) && + ((w = s.src.charCodeAt(s.pos - 1)), + 126 !== (x = s.pos + 2 < C ? s.src.charCodeAt(s.pos + 2) : -1) && + 126 !== w && + (32 !== w && 10 !== w ? _-- : 32 !== x && 10 !== x && _++, _ <= 0)) + ) { + i = !0; + break; + } + s.parser.skipToken(s); + } + return i + ? ((s.posMax = s.pos), + (s.pos = j + 2), + o || + (s.push({ type: 'del_open', level: s.level++ }), + s.parser.tokenize(s), + s.push({ type: 'del_close', level: --s.level })), + (s.pos = s.posMax + 2), + (s.posMax = C), + !0) + : ((s.pos = j), !1); + } + ], + [ + 'ins', + function ins(s, o) { + var i, + u, + _, + w, + x, + C = s.posMax, + j = s.pos; + if (43 !== s.src.charCodeAt(j)) return !1; + if (o) return !1; + if (j + 4 >= C) return !1; + if (43 !== s.src.charCodeAt(j + 1)) return !1; + if (s.level >= s.options.maxNesting) return !1; + if ( + ((w = j > 0 ? s.src.charCodeAt(j - 1) : -1), + (x = s.src.charCodeAt(j + 2)), + 43 === w) + ) + return !1; + if (43 === x) return !1; + if (32 === x || 10 === x) return !1; + for (u = j + 2; u < C && 43 === s.src.charCodeAt(u); ) u++; + if (u !== j + 2) return (s.pos += u - j), o || (s.pending += s.src.slice(j, u)), !0; + for (s.pos = j + 2, _ = 1; s.pos + 1 < C; ) { + if ( + 43 === s.src.charCodeAt(s.pos) && + 43 === s.src.charCodeAt(s.pos + 1) && + ((w = s.src.charCodeAt(s.pos - 1)), + 43 !== (x = s.pos + 2 < C ? s.src.charCodeAt(s.pos + 2) : -1) && + 43 !== w && + (32 !== w && 10 !== w ? _-- : 32 !== x && 10 !== x && _++, _ <= 0)) + ) { + i = !0; + break; + } + s.parser.skipToken(s); + } + return i + ? ((s.posMax = s.pos), + (s.pos = j + 2), + o || + (s.push({ type: 'ins_open', level: s.level++ }), + s.parser.tokenize(s), + s.push({ type: 'ins_close', level: --s.level })), + (s.pos = s.posMax + 2), + (s.posMax = C), + !0) + : ((s.pos = j), !1); + } + ], + [ + 'mark', + function mark(s, o) { + var i, + u, + _, + w, + x, + C = s.posMax, + j = s.pos; + if (61 !== s.src.charCodeAt(j)) return !1; + if (o) return !1; + if (j + 4 >= C) return !1; + if (61 !== s.src.charCodeAt(j + 1)) return !1; + if (s.level >= s.options.maxNesting) return !1; + if ( + ((w = j > 0 ? s.src.charCodeAt(j - 1) : -1), + (x = s.src.charCodeAt(j + 2)), + 61 === w) + ) + return !1; + if (61 === x) return !1; + if (32 === x || 10 === x) return !1; + for (u = j + 2; u < C && 61 === s.src.charCodeAt(u); ) u++; + if (u !== j + 2) return (s.pos += u - j), o || (s.pending += s.src.slice(j, u)), !0; + for (s.pos = j + 2, _ = 1; s.pos + 1 < C; ) { + if ( + 61 === s.src.charCodeAt(s.pos) && + 61 === s.src.charCodeAt(s.pos + 1) && + ((w = s.src.charCodeAt(s.pos - 1)), + 61 !== (x = s.pos + 2 < C ? s.src.charCodeAt(s.pos + 2) : -1) && + 61 !== w && + (32 !== w && 10 !== w ? _-- : 32 !== x && 10 !== x && _++, _ <= 0)) + ) { + i = !0; + break; + } + s.parser.skipToken(s); + } + return i + ? ((s.posMax = s.pos), + (s.pos = j + 2), + o || + (s.push({ type: 'mark_open', level: s.level++ }), + s.parser.tokenize(s), + s.push({ type: 'mark_close', level: --s.level })), + (s.pos = s.posMax + 2), + (s.posMax = C), + !0) + : ((s.pos = j), !1); + } + ], + [ + 'emphasis', + function emphasis(s, o) { + var i, + u, + _, + w, + x, + C, + j, + L = s.posMax, + B = s.pos, + $ = s.src.charCodeAt(B); + if (95 !== $ && 42 !== $) return !1; + if (o) return !1; + if (((i = (j = scanDelims(s, B)).delims), !j.can_open)) + return (s.pos += i), o || (s.pending += s.src.slice(B, s.pos)), !0; + if (s.level >= s.options.maxNesting) return !1; + for (s.pos = B + i, C = [i]; s.pos < L; ) + if (s.src.charCodeAt(s.pos) !== $) s.parser.skipToken(s); + else { + if (((u = (j = scanDelims(s, s.pos)).delims), j.can_close)) { + for (w = C.pop(), x = u; w !== x; ) { + if (x < w) { + C.push(w - x); + break; + } + if (((x -= w), 0 === C.length)) break; + (s.pos += w), (w = C.pop()); + } + if (0 === C.length) { + (i = w), (_ = !0); + break; + } + s.pos += u; + continue; + } + j.can_open && C.push(u), (s.pos += u); + } + return _ + ? ((s.posMax = s.pos), + (s.pos = B + i), + o || + ((2 !== i && 3 !== i) || s.push({ type: 'strong_open', level: s.level++ }), + (1 !== i && 3 !== i) || s.push({ type: 'em_open', level: s.level++ }), + s.parser.tokenize(s), + (1 !== i && 3 !== i) || s.push({ type: 'em_close', level: --s.level }), + (2 !== i && 3 !== i) || s.push({ type: 'strong_close', level: --s.level })), + (s.pos = s.posMax + i), + (s.posMax = L), + !0) + : ((s.pos = B), !1); + } + ], + [ + 'sub', + function sub(s, o) { + var i, + u, + _ = s.posMax, + w = s.pos; + if (126 !== s.src.charCodeAt(w)) return !1; + if (o) return !1; + if (w + 2 >= _) return !1; + if (s.level >= s.options.maxNesting) return !1; + for (s.pos = w + 1; s.pos < _; ) { + if (126 === s.src.charCodeAt(s.pos)) { + i = !0; + break; + } + s.parser.skipToken(s); + } + return i && w + 1 !== s.pos + ? (u = s.src.slice(w + 1, s.pos)).match(/(^|[^\\])(\\\\)*\s/) + ? ((s.pos = w), !1) + : ((s.posMax = s.pos), + (s.pos = w + 1), + o || s.push({ type: 'sub', level: s.level, content: u.replace(AC, '$1') }), + (s.pos = s.posMax + 1), + (s.posMax = _), + !0) + : ((s.pos = w), !1); + } + ], + [ + 'sup', + function sup(s, o) { + var i, + u, + _ = s.posMax, + w = s.pos; + if (94 !== s.src.charCodeAt(w)) return !1; + if (o) return !1; + if (w + 2 >= _) return !1; + if (s.level >= s.options.maxNesting) return !1; + for (s.pos = w + 1; s.pos < _; ) { + if (94 === s.src.charCodeAt(s.pos)) { + i = !0; + break; + } + s.parser.skipToken(s); + } + return i && w + 1 !== s.pos + ? (u = s.src.slice(w + 1, s.pos)).match(/(^|[^\\])(\\\\)*\s/) + ? ((s.pos = w), !1) + : ((s.posMax = s.pos), + (s.pos = w + 1), + o || s.push({ type: 'sup', level: s.level, content: u.replace(jC, '$1') }), + (s.pos = s.posMax + 1), + (s.posMax = _), + !0) + : ((s.pos = w), !1); + } + ], + [ + 'links', + function links(s, o) { + var i, + u, + _, + w, + x, + C, + j, + L, + B = !1, + $ = s.pos, + V = s.posMax, + U = s.pos, + z = s.src.charCodeAt(U); + if ((33 === z && ((B = !0), (z = s.src.charCodeAt(++U))), 91 !== z)) return !1; + if (s.level >= s.options.maxNesting) return !1; + if (((i = U + 1), (u = parseLinkLabel(s, U)) < 0)) return !1; + if ((C = u + 1) < V && 40 === s.src.charCodeAt(C)) { + for (C++; C < V && (32 === (L = s.src.charCodeAt(C)) || 10 === L); C++); + if (C >= V) return !1; + for ( + U = C, + parseLinkDestination(s, C) ? ((w = s.linkContent), (C = s.pos)) : (w = ''), + U = C; + C < V && (32 === (L = s.src.charCodeAt(C)) || 10 === L); + C++ + ); + if (C < V && U !== C && parseLinkTitle(s, C)) + for ( + x = s.linkContent, C = s.pos; + C < V && (32 === (L = s.src.charCodeAt(C)) || 10 === L); + C++ + ); + else x = ''; + if (C >= V || 41 !== s.src.charCodeAt(C)) return (s.pos = $), !1; + C++; + } else { + if (s.linkLevel > 0) return !1; + for (; C < V && (32 === (L = s.src.charCodeAt(C)) || 10 === L); C++); + if ( + (C < V && + 91 === s.src.charCodeAt(C) && + ((U = C + 1), + (C = parseLinkLabel(s, C)) >= 0 ? (_ = s.src.slice(U, C++)) : (C = U - 1)), + _ || (void 0 === _ && (C = u + 1), (_ = s.src.slice(i, u))), + !(j = s.env.references[normalizeReference(_)])) + ) + return (s.pos = $), !1; + (w = j.href), (x = j.title); + } + return ( + o || + ((s.pos = i), + (s.posMax = u), + B + ? s.push({ + type: 'image', + src: w, + title: x, + alt: s.src.substr(i, u - i), + level: s.level + }) + : (s.push({ type: 'link_open', href: w, title: x, level: s.level++ }), + s.linkLevel++, + s.parser.tokenize(s), + s.linkLevel--, + s.push({ type: 'link_close', level: --s.level }))), + (s.pos = C), + (s.posMax = V), + !0 + ); + } + ], + [ + 'footnote_inline', + function footnote_inline(s, o) { + var i, + u, + _, + w, + x = s.posMax, + C = s.pos; + return ( + !(C + 2 >= x) && + 94 === s.src.charCodeAt(C) && + 91 === s.src.charCodeAt(C + 1) && + !(s.level >= s.options.maxNesting) && + ((i = C + 2), + !((u = parseLinkLabel(s, C + 1)) < 0) && + (o || + (s.env.footnotes || (s.env.footnotes = {}), + s.env.footnotes.list || (s.env.footnotes.list = []), + (_ = s.env.footnotes.list.length), + (s.pos = i), + (s.posMax = u), + s.push({ type: 'footnote_ref', id: _, level: s.level }), + s.linkLevel++, + (w = s.tokens.length), + s.parser.tokenize(s), + (s.env.footnotes.list[_] = { tokens: s.tokens.splice(w) }), + s.linkLevel--), + (s.pos = u + 1), + (s.posMax = x), + !0)) + ); + } + ], + [ + 'footnote_ref', + function footnote_ref(s, o) { + var i, + u, + _, + w, + x = s.posMax, + C = s.pos; + if (C + 3 > x) return !1; + if (!s.env.footnotes || !s.env.footnotes.refs) return !1; + if (91 !== s.src.charCodeAt(C)) return !1; + if (94 !== s.src.charCodeAt(C + 1)) return !1; + if (s.level >= s.options.maxNesting) return !1; + for (u = C + 2; u < x; u++) { + if (32 === s.src.charCodeAt(u)) return !1; + if (10 === s.src.charCodeAt(u)) return !1; + if (93 === s.src.charCodeAt(u)) break; + } + return ( + u !== C + 2 && + !(u >= x) && + (u++, + (i = s.src.slice(C + 2, u - 1)), + void 0 !== s.env.footnotes.refs[':' + i] && + (o || + (s.env.footnotes.list || (s.env.footnotes.list = []), + s.env.footnotes.refs[':' + i] < 0 + ? ((_ = s.env.footnotes.list.length), + (s.env.footnotes.list[_] = { label: i, count: 0 }), + (s.env.footnotes.refs[':' + i] = _)) + : (_ = s.env.footnotes.refs[':' + i]), + (w = s.env.footnotes.list[_].count), + s.env.footnotes.list[_].count++, + s.push({ type: 'footnote_ref', id: _, subId: w, level: s.level })), + (s.pos = u), + (s.posMax = x), + !0)) + ); + } + ], + [ + 'autolink', + function autolink(s, o) { + var i, + u, + _, + w, + x, + C = s.pos; + return ( + 60 === s.src.charCodeAt(C) && + !((i = s.src.slice(C)).indexOf('>') < 0) && + ((u = i.match(MC)) + ? !(IC.indexOf(u[1].toLowerCase()) < 0) && + ((x = normalizeLink((w = u[0].slice(1, -1)))), + !!s.parser.validateLink(w) && + (o || + (s.push({ type: 'link_open', href: x, level: s.level }), + s.push({ type: 'text', content: w, level: s.level + 1 }), + s.push({ type: 'link_close', level: s.level })), + (s.pos += u[0].length), + !0)) + : !!(_ = i.match(PC)) && + ((x = normalizeLink('mailto:' + (w = _[0].slice(1, -1)))), + !!s.parser.validateLink(x) && + (o || + (s.push({ type: 'link_open', href: x, level: s.level }), + s.push({ type: 'text', content: w, level: s.level + 1 }), + s.push({ type: 'link_close', level: s.level })), + (s.pos += _[0].length), + !0))) + ); + } + ], + [ + 'htmltag', + function htmltag(s, o) { + var i, + u, + _, + w = s.pos; + return ( + !!s.options.html && + ((_ = s.posMax), + !(60 !== s.src.charCodeAt(w) || w + 2 >= _) && + !( + 33 !== (i = s.src.charCodeAt(w + 1)) && + 63 !== i && + 47 !== i && + !(function isLetter$2(s) { + var o = 32 | s; + return o >= 97 && o <= 122; + })(i) + ) && + !!(u = s.src.slice(w).match(DC)) && + (o || + s.push({ + type: 'htmltag', + content: s.src.slice(w, w + u[0].length), + level: s.level + }), + (s.pos += u[0].length), + !0)) + ); + } + ], + [ + 'entity', + function entity(s, o) { + var i, + u, + _ = s.pos, + w = s.posMax; + if (38 !== s.src.charCodeAt(_)) return !1; + if (_ + 1 < w) + if (35 === s.src.charCodeAt(_ + 1)) { + if ((u = s.src.slice(_).match(LC))) + return ( + o || + ((i = + 'x' === u[1][0].toLowerCase() + ? parseInt(u[1].slice(1), 16) + : parseInt(u[1], 10)), + (s.pending += isValidEntityCode(i) + ? fromCodePoint(i) + : fromCodePoint(65533))), + (s.pos += u[0].length), + !0 + ); + } else if ((u = s.src.slice(_).match(BC))) { + var x = decodeEntity(u[1]); + if (u[1] !== x) return o || (s.pending += x), (s.pos += u[0].length), !0; + } + return o || (s.pending += '&'), s.pos++, !0; + } + ] + ]; + function ParserInline() { + this.ruler = new Ruler(); + for (var s = 0; s < FC.length; s++) this.ruler.push(FC[s][0], FC[s][1]); + this.validateLink = validateLink; + } + function validateLink(s) { + var o = s.trim().toLowerCase(); + return ( + -1 === (o = replaceEntities(o)).indexOf(':') || + -1 === ['vbscript', 'javascript', 'file', 'data'].indexOf(o.split(':')[0]) + ); + } + (ParserInline.prototype.skipToken = function (s) { + var o, + i, + u = this.ruler.getRules(''), + _ = u.length, + w = s.pos; + if ((i = s.cacheGet(w)) > 0) s.pos = i; + else { + for (o = 0; o < _; o++) if (u[o](s, !0)) return void s.cacheSet(w, s.pos); + s.pos++, s.cacheSet(w, s.pos); + } + }), + (ParserInline.prototype.tokenize = function (s) { + for (var o, i, u = this.ruler.getRules(''), _ = u.length, w = s.posMax; s.pos < w; ) { + for (i = 0; i < _ && !(o = u[i](s, !1)); i++); + if (o) { + if (s.pos >= w) break; + } else s.pending += s.src[s.pos++]; + } + s.pending && s.pushPending(); + }), + (ParserInline.prototype.parse = function (s, o, i, u) { + var _ = new StateInline(s, this, o, i, u); + this.tokenize(_); + }); + var qC = { + default: { + options: { + html: !1, + xhtmlOut: !1, + breaks: !1, + langPrefix: 'language-', + linkTarget: '', + typographer: !1, + quotes: '“”‘’', + highlight: null, + maxNesting: 20 + }, + components: { + core: { + rules: [ + 'block', + 'inline', + 'references', + 'replacements', + 'smartquotes', + 'references', + 'abbr2', + 'footnote_tail' + ] + }, + block: { + rules: [ + 'blockquote', + 'code', + 'fences', + 'footnote', + 'heading', + 'hr', + 'htmlblock', + 'lheading', + 'list', + 'paragraph', + 'table' + ] + }, + inline: { + rules: [ + 'autolink', + 'backticks', + 'del', + 'emphasis', + 'entity', + 'escape', + 'footnote_ref', + 'htmltag', + 'links', + 'newline', + 'text' + ] + } + } + }, + full: { + options: { + html: !1, + xhtmlOut: !1, + breaks: !1, + langPrefix: 'language-', + linkTarget: '', + typographer: !1, + quotes: '“”‘’', + highlight: null, + maxNesting: 20 + }, + components: { core: {}, block: {}, inline: {} } + }, + commonmark: { + options: { + html: !0, + xhtmlOut: !0, + breaks: !1, + langPrefix: 'language-', + linkTarget: '', + typographer: !1, + quotes: '“”‘’', + highlight: null, + maxNesting: 20 + }, + components: { + core: { rules: ['block', 'inline', 'references', 'abbr2'] }, + block: { + rules: [ + 'blockquote', + 'code', + 'fences', + 'heading', + 'hr', + 'htmlblock', + 'lheading', + 'list', + 'paragraph' + ] + }, + inline: { + rules: [ + 'autolink', + 'backticks', + 'emphasis', + 'entity', + 'escape', + 'htmltag', + 'links', + 'newline', + 'text' + ] + } + } + } + }; + function StateCore(s, o, i) { + (this.src = o), + (this.env = i), + (this.options = s.options), + (this.tokens = []), + (this.inlineMode = !1), + (this.inline = s.inline), + (this.block = s.block), + (this.renderer = s.renderer), + (this.typographer = s.typographer); + } + function Remarkable(s, o) { + 'string' != typeof s && ((o = s), (s = 'default')), + o && + null != o.linkify && + console.warn( + "linkify option is removed. Use linkify plugin instead:\n\nimport Remarkable from 'remarkable';\nimport linkify from 'remarkable/linkify';\nnew Remarkable().use(linkify)\n" + ), + (this.inline = new ParserInline()), + (this.block = new ParserBlock()), + (this.core = new Core()), + (this.renderer = new Renderer()), + (this.ruler = new Ruler()), + (this.options = {}), + this.configure(qC[s]), + this.set(o || {}); + } + (Remarkable.prototype.set = function (s) { + index_browser_assign(this.options, s); + }), + (Remarkable.prototype.configure = function (s) { + var o = this; + if (!s) throw new Error('Wrong `remarkable` preset, check name/content'); + s.options && o.set(s.options), + s.components && + Object.keys(s.components).forEach(function (i) { + s.components[i].rules && o[i].ruler.enable(s.components[i].rules, !0); + }); + }), + (Remarkable.prototype.use = function (s, o) { + return s(this, o), this; + }), + (Remarkable.prototype.parse = function (s, o) { + var i = new StateCore(this, s, o); + return this.core.process(i), i.tokens; + }), + (Remarkable.prototype.render = function (s, o) { + return (o = o || {}), this.renderer.render(this.parse(s, o), this.options, o); + }), + (Remarkable.prototype.parseInline = function (s, o) { + var i = new StateCore(this, s, o); + return (i.inlineMode = !0), this.core.process(i), i.tokens; + }), + (Remarkable.prototype.renderInline = function (s, o) { + return (o = o || {}), this.renderer.render(this.parseInline(s, o), this.options, o); + }); + function indexOf(s, o) { + if (Array.prototype.indexOf) return s.indexOf(o); + for (var i = 0, u = s.length; i < u; i++) if (s[i] === o) return i; + return -1; + } + function utils_remove(s, o) { + for (var i = s.length - 1; i >= 0; i--) !0 === o(s[i]) && s.splice(i, 1); + } + function throwUnhandledCaseError(s) { + throw new Error("Unhandled case for value: '".concat(s, "'")); + } + var $C = (function () { + function HtmlTag(s) { + void 0 === s && (s = {}), + (this.tagName = ''), + (this.attrs = {}), + (this.innerHTML = ''), + (this.whitespaceRegex = /\s+/), + (this.tagName = s.tagName || ''), + (this.attrs = s.attrs || {}), + (this.innerHTML = s.innerHtml || s.innerHTML || ''); + } + return ( + (HtmlTag.prototype.setTagName = function (s) { + return (this.tagName = s), this; + }), + (HtmlTag.prototype.getTagName = function () { + return this.tagName || ''; + }), + (HtmlTag.prototype.setAttr = function (s, o) { + return (this.getAttrs()[s] = o), this; + }), + (HtmlTag.prototype.getAttr = function (s) { + return this.getAttrs()[s]; + }), + (HtmlTag.prototype.setAttrs = function (s) { + return Object.assign(this.getAttrs(), s), this; + }), + (HtmlTag.prototype.getAttrs = function () { + return this.attrs || (this.attrs = {}); + }), + (HtmlTag.prototype.setClass = function (s) { + return this.setAttr('class', s); + }), + (HtmlTag.prototype.addClass = function (s) { + for ( + var o, + i = this.getClass(), + u = this.whitespaceRegex, + _ = i ? i.split(u) : [], + w = s.split(u); + (o = w.shift()); + + ) + -1 === indexOf(_, o) && _.push(o); + return (this.getAttrs().class = _.join(' ')), this; + }), + (HtmlTag.prototype.removeClass = function (s) { + for ( + var o, + i = this.getClass(), + u = this.whitespaceRegex, + _ = i ? i.split(u) : [], + w = s.split(u); + _.length && (o = w.shift()); + + ) { + var x = indexOf(_, o); + -1 !== x && _.splice(x, 1); + } + return (this.getAttrs().class = _.join(' ')), this; + }), + (HtmlTag.prototype.getClass = function () { + return this.getAttrs().class || ''; + }), + (HtmlTag.prototype.hasClass = function (s) { + return -1 !== (' ' + this.getClass() + ' ').indexOf(' ' + s + ' '); + }), + (HtmlTag.prototype.setInnerHTML = function (s) { + return (this.innerHTML = s), this; + }), + (HtmlTag.prototype.setInnerHtml = function (s) { + return this.setInnerHTML(s); + }), + (HtmlTag.prototype.getInnerHTML = function () { + return this.innerHTML || ''; + }), + (HtmlTag.prototype.getInnerHtml = function () { + return this.getInnerHTML(); + }), + (HtmlTag.prototype.toAnchorString = function () { + var s = this.getTagName(), + o = this.buildAttrsStr(); + return ['<', s, (o = o ? ' ' + o : ''), '>', this.getInnerHtml(), ''].join( + '' + ); + }), + (HtmlTag.prototype.buildAttrsStr = function () { + if (!this.attrs) return ''; + var s = this.getAttrs(), + o = []; + for (var i in s) s.hasOwnProperty(i) && o.push(i + '="' + s[i] + '"'); + return o.join(' '); + }), + HtmlTag + ); + })(); + var VC = (function () { + function AnchorTagBuilder(s) { + void 0 === s && (s = {}), + (this.newWindow = !1), + (this.truncate = {}), + (this.className = ''), + (this.newWindow = s.newWindow || !1), + (this.truncate = s.truncate || {}), + (this.className = s.className || ''); + } + return ( + (AnchorTagBuilder.prototype.build = function (s) { + return new $C({ + tagName: 'a', + attrs: this.createAttrs(s), + innerHtml: this.processAnchorText(s.getAnchorText()) + }); + }), + (AnchorTagBuilder.prototype.createAttrs = function (s) { + var o = { href: s.getAnchorHref() }, + i = this.createCssClass(s); + return ( + i && (o.class = i), + this.newWindow && ((o.target = '_blank'), (o.rel = 'noopener noreferrer')), + this.truncate && + this.truncate.length && + this.truncate.length < s.getAnchorText().length && + (o.title = s.getAnchorHref()), + o + ); + }), + (AnchorTagBuilder.prototype.createCssClass = function (s) { + var o = this.className; + if (o) { + for (var i = [o], u = s.getCssClassSuffixes(), _ = 0, w = u.length; _ < w; _++) + i.push(o + '-' + u[_]); + return i.join(' '); + } + return ''; + }), + (AnchorTagBuilder.prototype.processAnchorText = function (s) { + return (s = this.doTruncate(s)); + }), + (AnchorTagBuilder.prototype.doTruncate = function (s) { + var o = this.truncate; + if (!o || !o.length) return s; + var i = o.length, + u = o.location; + return 'smart' === u + ? (function truncateSmart(s, o, i) { + var u, _; + null == i + ? ((i = '…'), (_ = 3), (u = 8)) + : ((_ = i.length), (u = i.length)); + var buildUrl = function (s) { + var o = ''; + return ( + s.scheme && s.host && (o += s.scheme + '://'), + s.host && (o += s.host), + s.path && (o += '/' + s.path), + s.query && (o += '?' + s.query), + s.fragment && (o += '#' + s.fragment), + o + ); + }, + buildSegment = function (s, o) { + var u = o / 2, + _ = Math.ceil(u), + w = -1 * Math.floor(u), + x = ''; + return w < 0 && (x = s.substr(w)), s.substr(0, _) + i + x; + }; + if (s.length <= o) return s; + var w = o - _, + x = (function (s) { + var o = {}, + i = s, + u = i.match(/^([a-z]+):\/\//i); + return ( + u && ((o.scheme = u[1]), (i = i.substr(u[0].length))), + (u = i.match(/^(.*?)(?=(\?|#|\/|$))/i)) && + ((o.host = u[1]), (i = i.substr(u[0].length))), + (u = i.match(/^\/(.*?)(?=(\?|#|$))/i)) && + ((o.path = u[1]), (i = i.substr(u[0].length))), + (u = i.match(/^\?(.*?)(?=(#|$))/i)) && + ((o.query = u[1]), (i = i.substr(u[0].length))), + (u = i.match(/^#(.*?)$/i)) && (o.fragment = u[1]), + o + ); + })(s); + if (x.query) { + var C = x.query.match(/^(.*?)(?=(\?|\#))(.*?)$/i); + C && ((x.query = x.query.substr(0, C[1].length)), (s = buildUrl(x))); + } + if (s.length <= o) return s; + if ( + (x.host && ((x.host = x.host.replace(/^www\./, '')), (s = buildUrl(x))), + s.length <= o) + ) + return s; + var j = ''; + if ((x.host && (j += x.host), j.length >= w)) + return x.host.length == o + ? (x.host.substr(0, o - _) + i).substr(0, w + u) + : buildSegment(j, w).substr(0, w + u); + var L = ''; + if ((x.path && (L += '/' + x.path), x.query && (L += '?' + x.query), L)) { + if ((j + L).length >= w) + return (j + L).length == o + ? (j + L).substr(0, o) + : (j + buildSegment(L, w - j.length)).substr(0, w + u); + j += L; + } + if (x.fragment) { + var B = '#' + x.fragment; + if ((j + B).length >= w) + return (j + B).length == o + ? (j + B).substr(0, o) + : (j + buildSegment(B, w - j.length)).substr(0, w + u); + j += B; + } + if (x.scheme && x.host) { + var $ = x.scheme + '://'; + if ((j + $).length < w) return ($ + j).substr(0, o); + } + if (j.length <= o) return j; + var V = ''; + return ( + w > 0 && (V = j.substr(-1 * Math.floor(w / 2))), + (j.substr(0, Math.ceil(w / 2)) + i + V).substr(0, w + u) + ); + })(s, i) + : 'middle' === u + ? (function truncateMiddle(s, o, i) { + if (s.length <= o) return s; + var u, _; + null == i + ? ((i = '…'), (u = 8), (_ = 3)) + : ((u = i.length), (_ = i.length)); + var w = o - _, + x = ''; + return ( + w > 0 && (x = s.substr(-1 * Math.floor(w / 2))), + (s.substr(0, Math.ceil(w / 2)) + i + x).substr(0, w + u) + ); + })(s, i) + : (function truncateEnd(s, o, i) { + return (function ellipsis(s, o, i) { + var u; + return ( + s.length > o && + (null == i ? ((i = '…'), (u = 3)) : (u = i.length), + (s = s.substring(0, o - u) + i)), + s + ); + })(s, o, i); + })(s, i); + }), + AnchorTagBuilder + ); + })(), + UC = (function () { + function Match(s) { + (this.__jsduckDummyDocProp = null), + (this.matchedText = ''), + (this.offset = 0), + (this.tagBuilder = s.tagBuilder), + (this.matchedText = s.matchedText), + (this.offset = s.offset); + } + return ( + (Match.prototype.getMatchedText = function () { + return this.matchedText; + }), + (Match.prototype.setOffset = function (s) { + this.offset = s; + }), + (Match.prototype.getOffset = function () { + return this.offset; + }), + (Match.prototype.getCssClassSuffixes = function () { + return [this.getType()]; + }), + (Match.prototype.buildTag = function () { + return this.tagBuilder.build(this); + }), + Match + ); + })(), + extendStatics = function (s, o) { + return ( + (extendStatics = + Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && + function (s, o) { + s.__proto__ = o; + }) || + function (s, o) { + for (var i in o) Object.prototype.hasOwnProperty.call(o, i) && (s[i] = o[i]); + }), + extendStatics(s, o) + ); + }; + function tslib_es6_extends(s, o) { + if ('function' != typeof o && null !== o) + throw new TypeError( + 'Class extends value ' + String(o) + ' is not a constructor or null' + ); + function __() { + this.constructor = s; + } + extendStatics(s, o), + (s.prototype = + null === o ? Object.create(o) : ((__.prototype = o.prototype), new __())); + } + var __assign = function () { + return ( + (__assign = + Object.assign || + function __assign(s) { + for (var o, i = 1, u = arguments.length; i < u; i++) + for (var _ in (o = arguments[i])) + Object.prototype.hasOwnProperty.call(o, _) && (s[_] = o[_]); + return s; + }), + __assign.apply(this, arguments) + ); + }; + Object.create; + Object.create; + 'function' == typeof SuppressedError && SuppressedError; + var zC, + WC = (function (s) { + function EmailMatch(o) { + var i = s.call(this, o) || this; + return (i.email = ''), (i.email = o.email), i; + } + return ( + tslib_es6_extends(EmailMatch, s), + (EmailMatch.prototype.getType = function () { + return 'email'; + }), + (EmailMatch.prototype.getEmail = function () { + return this.email; + }), + (EmailMatch.prototype.getAnchorHref = function () { + return 'mailto:' + this.email; + }), + (EmailMatch.prototype.getAnchorText = function () { + return this.email; + }), + EmailMatch + ); + })(UC), + KC = (function (s) { + function HashtagMatch(o) { + var i = s.call(this, o) || this; + return ( + (i.serviceName = ''), + (i.hashtag = ''), + (i.serviceName = o.serviceName), + (i.hashtag = o.hashtag), + i + ); + } + return ( + tslib_es6_extends(HashtagMatch, s), + (HashtagMatch.prototype.getType = function () { + return 'hashtag'; + }), + (HashtagMatch.prototype.getServiceName = function () { + return this.serviceName; + }), + (HashtagMatch.prototype.getHashtag = function () { + return this.hashtag; + }), + (HashtagMatch.prototype.getAnchorHref = function () { + var s = this.serviceName, + o = this.hashtag; + switch (s) { + case 'twitter': + return 'https://twitter.com/hashtag/' + o; + case 'facebook': + return 'https://www.facebook.com/hashtag/' + o; + case 'instagram': + return 'https://instagram.com/explore/tags/' + o; + case 'tiktok': + return 'https://www.tiktok.com/tag/' + o; + default: + throw new Error('Unknown service name to point hashtag to: ' + s); + } + }), + (HashtagMatch.prototype.getAnchorText = function () { + return '#' + this.hashtag; + }), + HashtagMatch + ); + })(UC), + HC = (function (s) { + function MentionMatch(o) { + var i = s.call(this, o) || this; + return ( + (i.serviceName = 'twitter'), + (i.mention = ''), + (i.mention = o.mention), + (i.serviceName = o.serviceName), + i + ); + } + return ( + tslib_es6_extends(MentionMatch, s), + (MentionMatch.prototype.getType = function () { + return 'mention'; + }), + (MentionMatch.prototype.getMention = function () { + return this.mention; + }), + (MentionMatch.prototype.getServiceName = function () { + return this.serviceName; + }), + (MentionMatch.prototype.getAnchorHref = function () { + switch (this.serviceName) { + case 'twitter': + return 'https://twitter.com/' + this.mention; + case 'instagram': + return 'https://instagram.com/' + this.mention; + case 'soundcloud': + return 'https://soundcloud.com/' + this.mention; + case 'tiktok': + return 'https://www.tiktok.com/@' + this.mention; + default: + throw new Error( + 'Unknown service name to point mention to: ' + this.serviceName + ); + } + }), + (MentionMatch.prototype.getAnchorText = function () { + return '@' + this.mention; + }), + (MentionMatch.prototype.getCssClassSuffixes = function () { + var o = s.prototype.getCssClassSuffixes.call(this), + i = this.getServiceName(); + return i && o.push(i), o; + }), + MentionMatch + ); + })(UC), + JC = (function (s) { + function PhoneMatch(o) { + var i = s.call(this, o) || this; + return ( + (i.number = ''), + (i.plusSign = !1), + (i.number = o.number), + (i.plusSign = o.plusSign), + i + ); + } + return ( + tslib_es6_extends(PhoneMatch, s), + (PhoneMatch.prototype.getType = function () { + return 'phone'; + }), + (PhoneMatch.prototype.getPhoneNumber = function () { + return this.number; + }), + (PhoneMatch.prototype.getNumber = function () { + return this.getPhoneNumber(); + }), + (PhoneMatch.prototype.getAnchorHref = function () { + return 'tel:' + (this.plusSign ? '+' : '') + this.number; + }), + (PhoneMatch.prototype.getAnchorText = function () { + return this.matchedText; + }), + PhoneMatch + ); + })(UC), + GC = (function (s) { + function UrlMatch(o) { + var i = s.call(this, o) || this; + return ( + (i.url = ''), + (i.urlMatchType = 'scheme'), + (i.protocolUrlMatch = !1), + (i.protocolRelativeMatch = !1), + (i.stripPrefix = { scheme: !0, www: !0 }), + (i.stripTrailingSlash = !0), + (i.decodePercentEncoding = !0), + (i.schemePrefixRegex = /^(https?:\/\/)?/i), + (i.wwwPrefixRegex = /^(https?:\/\/)?(www\.)?/i), + (i.protocolRelativeRegex = /^\/\//), + (i.protocolPrepended = !1), + (i.urlMatchType = o.urlMatchType), + (i.url = o.url), + (i.protocolUrlMatch = o.protocolUrlMatch), + (i.protocolRelativeMatch = o.protocolRelativeMatch), + (i.stripPrefix = o.stripPrefix), + (i.stripTrailingSlash = o.stripTrailingSlash), + (i.decodePercentEncoding = o.decodePercentEncoding), + i + ); + } + return ( + tslib_es6_extends(UrlMatch, s), + (UrlMatch.prototype.getType = function () { + return 'url'; + }), + (UrlMatch.prototype.getUrlMatchType = function () { + return this.urlMatchType; + }), + (UrlMatch.prototype.getUrl = function () { + var s = this.url; + return ( + this.protocolRelativeMatch || + this.protocolUrlMatch || + this.protocolPrepended || + ((s = this.url = 'http://' + s), (this.protocolPrepended = !0)), + s + ); + }), + (UrlMatch.prototype.getAnchorHref = function () { + return this.getUrl().replace(/&/g, '&'); + }), + (UrlMatch.prototype.getAnchorText = function () { + var s = this.getMatchedText(); + return ( + this.protocolRelativeMatch && (s = this.stripProtocolRelativePrefix(s)), + this.stripPrefix.scheme && (s = this.stripSchemePrefix(s)), + this.stripPrefix.www && (s = this.stripWwwPrefix(s)), + this.stripTrailingSlash && (s = this.removeTrailingSlash(s)), + this.decodePercentEncoding && (s = this.removePercentEncoding(s)), + s + ); + }), + (UrlMatch.prototype.stripSchemePrefix = function (s) { + return s.replace(this.schemePrefixRegex, ''); + }), + (UrlMatch.prototype.stripWwwPrefix = function (s) { + return s.replace(this.wwwPrefixRegex, '$1'); + }), + (UrlMatch.prototype.stripProtocolRelativePrefix = function (s) { + return s.replace(this.protocolRelativeRegex, ''); + }), + (UrlMatch.prototype.removeTrailingSlash = function (s) { + return '/' === s.charAt(s.length - 1) && (s = s.slice(0, -1)), s; + }), + (UrlMatch.prototype.removePercentEncoding = function (s) { + var o = s + .replace(/%22/gi, '"') + .replace(/%26/gi, '&') + .replace(/%27/gi, ''') + .replace(/%3C/gi, '<') + .replace(/%3E/gi, '>'); + try { + return decodeURIComponent(o); + } catch (s) { + return o; + } + }), + UrlMatch + ); + })(UC), + YC = function YC(s) { + (this.__jsduckDummyDocProp = null), (this.tagBuilder = s.tagBuilder); + }, + XC = /[A-Za-z]/, + ZC = /[\d]/, + QC = /[\D]/, + eO = /\s/, + tO = /['"]/, + rO = /[\x00-\x1F\x7F]/, + nO = + /A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC/ + .source, + sO = + nO + + /\u2700-\u27bf\udde6-\uddff\ud800-\udbff\udc00-\udfff\ufe0e\ufe0f\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0\ud83c\udffb-\udfff\u200d\u3299\u3297\u303d\u3030\u24c2\ud83c\udd70-\udd71\udd7e-\udd7f\udd8e\udd91-\udd9a\udde6-\uddff\ude01-\ude02\ude1a\ude2f\ude32-\ude3a\ude50-\ude51\u203c\u2049\u25aa-\u25ab\u25b6\u25c0\u25fb-\u25fe\u00a9\u00ae\u2122\u2139\udc04\u2600-\u26FF\u2b05\u2b06\u2b07\u2b1b\u2b1c\u2b50\u2b55\u231a\u231b\u2328\u23cf\u23e9-\u23f3\u23f8-\u23fa\udccf\u2935\u2934\u2190-\u21ff/ + .source + + /\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08D4-\u08E1\u08E3-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D01-\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u1885\u1886\u18A9\u1920-\u192B\u1930-\u193B\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFB-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C5\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F/ + .source, + oO = + /0-9\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0BE6-\u0BEF\u0C66-\u0C6F\u0CE6-\u0CEF\u0D66-\u0D6F\u0DE6-\u0DEF\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29\u1040-\u1049\u1090-\u1099\u17E0-\u17E9\u1810-\u1819\u1946-\u194F\u19D0-\u19D9\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\uA620-\uA629\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uA9F0-\uA9F9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19/ + .source, + iO = sO + oO, + aO = sO + oO, + lO = new RegExp('['.concat(aO, ']')), + cO = '(?:[' + oO + ']{1,3}\\.){3}[' + oO + ']{1,3}', + uO = '[' + aO + '](?:[' + aO + '\\-_]{0,61}[' + aO + '])?', + getDomainLabelStr = function (s) { + return '(?=(' + uO + '))\\' + s; + }, + getDomainNameStr = function (s) { + return ( + '(?:' + + getDomainLabelStr(s) + + '(?:\\.' + + getDomainLabelStr(s + 1) + + '){0,126}|' + + cO + + ')' + ); + }, + pO = (new RegExp('[' + aO + '.\\-]*[' + aO + '\\-]'), lO), + hO = + /(?:xn--vermgensberatung-pwb|xn--vermgensberater-ctb|xn--clchc0ea0b2g2a9gcd|xn--w4r85el8fhu5dnra|northwesternmutual|travelersinsurance|vermögensberatung|xn--5su34j936bgsg|xn--bck1b9a5dre4c|xn--mgbah1a3hjkrd|xn--mgbai9azgqp6j|xn--mgberp4a5d4ar|xn--xkc2dl3a5ee0h|vermögensberater|xn--fzys8d69uvgm|xn--mgba7c0bbn0a|xn--mgbcpq6gpa1a|xn--xkc2al3hye2a|americanexpress|kerryproperties|sandvikcoromant|xn--i1b6b1a6a2e|xn--kcrx77d1x4a|xn--lgbbat1ad8j|xn--mgba3a4f16a|xn--mgbaakc7dvf|xn--mgbc0a9azcg|xn--nqv7fs00ema|americanfamily|bananarepublic|cancerresearch|cookingchannel|kerrylogistics|weatherchannel|xn--54b7fta0cc|xn--6qq986b3xl|xn--80aqecdr1a|xn--b4w605ferd|xn--fiq228c5hs|xn--h2breg3eve|xn--jlq480n2rg|xn--jlq61u9w7b|xn--mgba3a3ejt|xn--mgbaam7a8h|xn--mgbayh7gpa|xn--mgbbh1a71e|xn--mgbca7dzdo|xn--mgbi4ecexp|xn--mgbx4cd0ab|xn--rvc1e0am3e|international|lifeinsurance|travelchannel|wolterskluwer|xn--cckwcxetd|xn--eckvdtc9d|xn--fpcrj9c3d|xn--fzc2c9e2c|xn--h2brj9c8c|xn--tiq49xqyj|xn--yfro4i67o|xn--ygbi2ammx|construction|lplfinancial|scholarships|versicherung|xn--3e0b707e|xn--45br5cyl|xn--4dbrk0ce|xn--80adxhks|xn--80asehdb|xn--8y0a063a|xn--gckr3f0f|xn--mgb9awbf|xn--mgbab2bd|xn--mgbgu82a|xn--mgbpl2fh|xn--mgbt3dhd|xn--mk1bu44c|xn--ngbc5azd|xn--ngbe9e0a|xn--ogbpf8fl|xn--qcka1pmc|accountants|barclaycard|blackfriday|blockbuster|bridgestone|calvinklein|contractors|creditunion|engineering|enterprises|foodnetwork|investments|kerryhotels|lamborghini|motorcycles|olayangroup|photography|playstation|productions|progressive|redumbrella|williamhill|xn--11b4c3d|xn--1ck2e1b|xn--1qqw23a|xn--2scrj9c|xn--3bst00m|xn--3ds443g|xn--3hcrj9c|xn--42c2d9a|xn--45brj9c|xn--55qw42g|xn--6frz82g|xn--80ao21a|xn--9krt00a|xn--cck2b3b|xn--czr694b|xn--d1acj3b|xn--efvy88h|xn--fct429k|xn--fjq720a|xn--flw351e|xn--g2xx48c|xn--gecrj9c|xn--gk3at1e|xn--h2brj9c|xn--hxt814e|xn--imr513n|xn--j6w193g|xn--jvr189m|xn--kprw13d|xn--kpry57d|xn--mgbbh1a|xn--mgbtx2b|xn--mix891f|xn--nyqy26a|xn--otu796d|xn--pgbs0dh|xn--q9jyb4c|xn--rhqv96g|xn--rovu88b|xn--s9brj9c|xn--ses554g|xn--t60b56a|xn--vuq861b|xn--w4rs40l|xn--xhq521b|xn--zfr164b|சிங்கப்பூர்|accountant|apartments|associates|basketball|bnpparibas|boehringer|capitalone|consulting|creditcard|cuisinella|eurovision|extraspace|foundation|healthcare|immobilien|industries|management|mitsubishi|nextdirect|properties|protection|prudential|realestate|republican|restaurant|schaeffler|tatamotors|technology|university|vlaanderen|volkswagen|xn--30rr7y|xn--3pxu8k|xn--45q11c|xn--4gbrim|xn--55qx5d|xn--5tzm5g|xn--80aswg|xn--90a3ac|xn--9dbq2a|xn--9et52u|xn--c2br7g|xn--cg4bki|xn--czrs0t|xn--czru2d|xn--fiq64b|xn--fiqs8s|xn--fiqz9s|xn--io0a7i|xn--kput3i|xn--mxtq1m|xn--o3cw4h|xn--pssy2u|xn--q7ce6a|xn--unup4y|xn--wgbh1c|xn--wgbl6a|xn--y9a3aq|accenture|alfaromeo|allfinanz|amsterdam|analytics|aquarelle|barcelona|bloomberg|christmas|community|directory|education|equipment|fairwinds|financial|firestone|fresenius|frontdoor|furniture|goldpoint|hisamitsu|homedepot|homegoods|homesense|institute|insurance|kuokgroup|lancaster|landrover|lifestyle|marketing|marshalls|melbourne|microsoft|panasonic|passagens|pramerica|richardli|shangrila|solutions|statebank|statefarm|stockholm|travelers|vacations|xn--90ais|xn--c1avg|xn--d1alf|xn--e1a4c|xn--fhbei|xn--j1aef|xn--j1amh|xn--l1acc|xn--ngbrx|xn--nqv7f|xn--p1acf|xn--qxa6a|xn--tckwe|xn--vhquv|yodobashi|موريتانيا|abudhabi|airforce|allstate|attorney|barclays|barefoot|bargains|baseball|boutique|bradesco|broadway|brussels|builders|business|capetown|catering|catholic|cipriani|cityeats|cleaning|clinique|clothing|commbank|computer|delivery|deloitte|democrat|diamonds|discount|discover|download|engineer|ericsson|etisalat|exchange|feedback|fidelity|firmdale|football|frontier|goodyear|grainger|graphics|guardian|hdfcbank|helsinki|holdings|hospital|infiniti|ipiranga|istanbul|jpmorgan|lighting|lundbeck|marriott|maserati|mckinsey|memorial|merckmsd|mortgage|observer|partners|pharmacy|pictures|plumbing|property|redstone|reliance|saarland|samsclub|security|services|shopping|showtime|softbank|software|stcgroup|supplies|training|vanguard|ventures|verisign|woodside|xn--90ae|xn--node|xn--p1ai|xn--qxam|yokohama|السعودية|abogado|academy|agakhan|alibaba|android|athleta|auction|audible|auspost|avianca|banamex|bauhaus|bentley|bestbuy|booking|brother|bugatti|capital|caravan|careers|channel|charity|chintai|citadel|clubmed|college|cologne|comcast|company|compare|contact|cooking|corsica|country|coupons|courses|cricket|cruises|dentist|digital|domains|exposed|express|farmers|fashion|ferrari|ferrero|finance|fishing|fitness|flights|florist|flowers|forsale|frogans|fujitsu|gallery|genting|godaddy|grocery|guitars|hamburg|hangout|hitachi|holiday|hosting|hoteles|hotmail|hyundai|ismaili|jewelry|juniper|kitchen|komatsu|lacaixa|lanxess|lasalle|latrobe|leclerc|limited|lincoln|markets|monster|netbank|netflix|network|neustar|okinawa|oldnavy|organic|origins|philips|pioneer|politie|realtor|recipes|rentals|reviews|rexroth|samsung|sandvik|schmidt|schwarz|science|shiksha|singles|staples|storage|support|surgery|systems|temasek|theater|theatre|tickets|tiffany|toshiba|trading|walmart|wanggou|watches|weather|website|wedding|whoswho|windows|winners|xfinity|yamaxun|youtube|zuerich|католик|اتصالات|البحرين|الجزائر|العليان|پاکستان|كاثوليك|இந்தியா|abarth|abbott|abbvie|africa|agency|airbus|airtel|alipay|alsace|alstom|amazon|anquan|aramco|author|bayern|beauty|berlin|bharti|bostik|boston|broker|camera|career|casino|center|chanel|chrome|church|circle|claims|clinic|coffee|comsec|condos|coupon|credit|cruise|dating|datsun|dealer|degree|dental|design|direct|doctor|dunlop|dupont|durban|emerck|energy|estate|events|expert|family|flickr|futbol|gallup|garden|george|giving|global|google|gratis|health|hermes|hiphop|hockey|hotels|hughes|imamat|insure|intuit|jaguar|joburg|juegos|kaufen|kinder|kindle|kosher|lancia|latino|lawyer|lefrak|living|locker|london|luxury|madrid|maison|makeup|market|mattel|mobile|monash|mormon|moscow|museum|mutual|nagoya|natura|nissan|nissay|norton|nowruz|office|olayan|online|oracle|orange|otsuka|pfizer|photos|physio|pictet|quebec|racing|realty|reisen|repair|report|review|rocher|rogers|ryukyu|safety|sakura|sanofi|school|schule|search|secure|select|shouji|soccer|social|stream|studio|supply|suzuki|swatch|sydney|taipei|taobao|target|tattoo|tennis|tienda|tjmaxx|tkmaxx|toyota|travel|unicom|viajes|viking|villas|virgin|vision|voting|voyage|vuelos|walter|webcam|xihuan|yachts|yandex|zappos|москва|онлайн|ابوظبي|ارامكو|الاردن|المغرب|امارات|فلسطين|مليسيا|भारतम्|இலங்கை|ファッション|actor|adult|aetna|amfam|amica|apple|archi|audio|autos|azure|baidu|beats|bible|bingo|black|boats|bosch|build|canon|cards|chase|cheap|cisco|citic|click|cloud|coach|codes|crown|cymru|dabur|dance|deals|delta|drive|dubai|earth|edeka|email|epson|faith|fedex|final|forex|forum|gallo|games|gifts|gives|glass|globo|gmail|green|gripe|group|gucci|guide|homes|honda|horse|house|hyatt|ikano|irish|jetzt|koeln|kyoto|lamer|lease|legal|lexus|lilly|linde|lipsy|loans|locus|lotte|lotto|macys|mango|media|miami|money|movie|music|nexus|nikon|ninja|nokia|nowtv|omega|osaka|paris|parts|party|phone|photo|pizza|place|poker|praxi|press|prime|promo|quest|radio|rehab|reise|ricoh|rocks|rodeo|rugby|salon|sener|seven|sharp|shell|shoes|skype|sling|smart|smile|solar|space|sport|stada|store|study|style|sucks|swiss|tatar|tires|tirol|tmall|today|tokyo|tools|toray|total|tours|trade|trust|tunes|tushu|ubank|vegas|video|vodka|volvo|wales|watch|weber|weibo|works|world|xerox|yahoo|ישראל|ایران|بازار|بھارت|سودان|سورية|همراه|भारोत|संगठन|বাংলা|భారత్|ഭാരതം|嘉里大酒店|aarp|able|adac|aero|akdn|ally|amex|arab|army|arpa|arte|asda|asia|audi|auto|baby|band|bank|bbva|beer|best|bike|bing|blog|blue|bofa|bond|book|buzz|cafe|call|camp|care|cars|casa|case|cash|cbre|cern|chat|citi|city|club|cool|coop|cyou|data|date|dclk|deal|dell|desi|diet|dish|docs|dvag|erni|fage|fail|fans|farm|fast|fiat|fido|film|fire|fish|flir|food|ford|free|fund|game|gbiz|gent|ggee|gift|gmbh|gold|golf|goog|guge|guru|hair|haus|hdfc|help|here|hgtv|host|hsbc|icbc|ieee|imdb|immo|info|itau|java|jeep|jobs|jprs|kddi|kids|kiwi|kpmg|kred|land|lego|lgbt|lidl|life|like|limo|link|live|loan|loft|love|ltda|luxe|maif|meet|meme|menu|mini|mint|mobi|moda|moto|name|navy|news|next|nico|nike|ollo|open|page|pars|pccw|pics|ping|pink|play|plus|pohl|porn|post|prod|prof|qpon|read|reit|rent|rest|rich|room|rsvp|ruhr|safe|sale|sarl|save|saxo|scot|seat|seek|sexy|shaw|shia|shop|show|silk|sina|site|skin|sncf|sohu|song|sony|spot|star|surf|talk|taxi|team|tech|teva|tiaa|tips|town|toys|tube|vana|visa|viva|vivo|vote|voto|wang|weir|wien|wiki|wine|work|xbox|yoga|zara|zero|zone|дети|сайт|بارت|بيتك|ڀارت|تونس|شبكة|عراق|عمان|موقع|भारत|ভারত|ভাৰত|ਭਾਰਤ|ભારત|ଭାରତ|ಭಾರತ|ලංකා|アマゾン|グーグル|クラウド|ポイント|组织机构|電訊盈科|香格里拉|aaa|abb|abc|aco|ads|aeg|afl|aig|anz|aol|app|art|aws|axa|bar|bbc|bbt|bcg|bcn|bet|bid|bio|biz|bms|bmw|bom|boo|bot|box|buy|bzh|cab|cal|cam|car|cat|cba|cbn|cbs|ceo|cfa|cfd|com|cpa|crs|dad|day|dds|dev|dhl|diy|dnp|dog|dot|dtv|dvr|eat|eco|edu|esq|eus|fan|fit|fly|foo|fox|frl|ftr|fun|fyi|gal|gap|gay|gdn|gea|gle|gmo|gmx|goo|gop|got|gov|hbo|hiv|hkt|hot|how|ibm|ice|icu|ifm|inc|ing|ink|int|ist|itv|jcb|jio|jll|jmp|jnj|jot|joy|kfh|kia|kim|kpn|krd|lat|law|lds|llc|llp|lol|lpl|ltd|man|map|mba|med|men|mil|mit|mlb|mls|mma|moe|moi|mom|mov|msd|mtn|mtr|nab|nba|nec|net|new|nfl|ngo|nhk|now|nra|nrw|ntt|nyc|obi|one|ong|onl|ooo|org|ott|ovh|pay|pet|phd|pid|pin|pnc|pro|pru|pub|pwc|red|ren|ril|rio|rip|run|rwe|sap|sas|sbi|sbs|sca|scb|ses|sew|sex|sfr|ski|sky|soy|spa|srl|stc|tab|tax|tci|tdk|tel|thd|tjx|top|trv|tui|tvs|ubs|uno|uol|ups|vet|vig|vin|vip|wed|win|wme|wow|wtc|wtf|xin|xxx|xyz|you|yun|zip|бел|ком|қаз|мкд|мон|орг|рус|срб|укр|հայ|קום|عرب|قطر|كوم|مصر|कॉम|नेट|คอม|ไทย|ລາວ|ストア|セール|みんな|中文网|亚马逊|天主教|我爱你|新加坡|淡马锡|诺基亚|飞利浦|ac|ad|ae|af|ag|ai|al|am|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cw|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw|ελ|ευ|бг|ею|рф|გე|닷넷|닷컴|삼성|한국|コム|世界|中信|中国|中國|企业|佛山|信息|健康|八卦|公司|公益|台湾|台灣|商城|商店|商标|嘉里|在线|大拿|娱乐|家電|广东|微博|慈善|手机|招聘|政务|政府|新闻|时尚|書籍|机构|游戏|澳門|点看|移动|网址|网店|网站|网络|联通|谷歌|购物|通販|集团|食品|餐厅|香港)/, + dO = new RegExp('['.concat(aO, "!#$%&'*+/=?^_`{|}~-]")), + fO = new RegExp('^'.concat(hO.source, '$')), + mO = (function (s) { + function EmailMatcher() { + var o = (null !== s && s.apply(this, arguments)) || this; + return (o.localPartCharRegex = dO), (o.strictTldRegex = fO), o; + } + return ( + tslib_es6_extends(EmailMatcher, s), + (EmailMatcher.prototype.parseMatches = function (s) { + for ( + var o = this.tagBuilder, + i = this.localPartCharRegex, + u = this.strictTldRegex, + _ = [], + w = s.length, + x = new gO(), + C = { m: 'a', a: 'i', i: 'l', l: 't', t: 'o', o: ':' }, + j = 0, + L = 0, + B = x; + j < w; + + ) { + var $ = s.charAt(j); + switch (L) { + case 0: + stateNonEmailAddress($); + break; + case 1: + stateMailTo(s.charAt(j - 1), $); + break; + case 2: + stateLocalPart($); + break; + case 3: + stateLocalPartDot($); + break; + case 4: + stateAtSign($); + break; + case 5: + stateDomainChar($); + break; + case 6: + stateDomainHyphen($); + break; + case 7: + stateDomainDot($); + break; + default: + throwUnhandledCaseError(L); + } + j++; + } + return captureMatchIfValidAndReset(), _; + function stateNonEmailAddress(s) { + 'm' === s ? beginEmailMatch(1) : i.test(s) && beginEmailMatch(); + } + function stateMailTo(s, o) { + ':' === s + ? i.test(o) + ? ((L = 2), (B = new gO(__assign(__assign({}, B), { hasMailtoPrefix: !0 })))) + : resetToNonEmailMatchState() + : C[s] === o || + (i.test(o) + ? (L = 2) + : '.' === o + ? (L = 3) + : '@' === o + ? (L = 4) + : resetToNonEmailMatchState()); + } + function stateLocalPart(s) { + '.' === s + ? (L = 3) + : '@' === s + ? (L = 4) + : i.test(s) || resetToNonEmailMatchState(); + } + function stateLocalPartDot(s) { + '.' === s || '@' === s + ? resetToNonEmailMatchState() + : i.test(s) + ? (L = 2) + : resetToNonEmailMatchState(); + } + function stateAtSign(s) { + pO.test(s) ? (L = 5) : resetToNonEmailMatchState(); + } + function stateDomainChar(s) { + '.' === s + ? (L = 7) + : '-' === s + ? (L = 6) + : pO.test(s) || captureMatchIfValidAndReset(); + } + function stateDomainHyphen(s) { + '-' === s || '.' === s + ? captureMatchIfValidAndReset() + : pO.test(s) + ? (L = 5) + : captureMatchIfValidAndReset(); + } + function stateDomainDot(s) { + '.' === s || '-' === s + ? captureMatchIfValidAndReset() + : pO.test(s) + ? ((L = 5), (B = new gO(__assign(__assign({}, B), { hasDomainDot: !0 })))) + : captureMatchIfValidAndReset(); + } + function beginEmailMatch(s) { + void 0 === s && (s = 2), (L = s), (B = new gO({ idx: j })); + } + function resetToNonEmailMatchState() { + (L = 0), (B = x); + } + function captureMatchIfValidAndReset() { + if (B.hasDomainDot) { + var i = s.slice(B.idx, j); + /[-.]$/.test(i) && (i = i.slice(0, -1)); + var w = B.hasMailtoPrefix ? i.slice(7) : i; + (function doesEmailHaveValidTld(s) { + var o = s.split('.').pop() || '', + i = o.toLowerCase(); + return u.test(i); + })(w) && + _.push(new WC({ tagBuilder: o, matchedText: i, offset: B.idx, email: w })); + } + resetToNonEmailMatchState(); + } + }), + EmailMatcher + ); + })(YC), + gO = function gO(s) { + void 0 === s && (s = {}), + (this.idx = void 0 !== s.idx ? s.idx : -1), + (this.hasMailtoPrefix = !!s.hasMailtoPrefix), + (this.hasDomainDot = !!s.hasDomainDot); + }, + yO = (function () { + function UrlMatchValidator() {} + return ( + (UrlMatchValidator.isValid = function (s, o) { + return !( + (o && !this.isValidUriScheme(o)) || + this.urlMatchDoesNotHaveProtocolOrDot(s, o) || + (this.urlMatchDoesNotHaveAtLeastOneWordChar(s, o) && !this.isValidIpAddress(s)) || + this.containsMultipleDots(s) + ); + }), + (UrlMatchValidator.isValidIpAddress = function (s) { + var o = new RegExp(this.hasFullProtocolRegex.source + this.ipRegex.source); + return null !== s.match(o); + }), + (UrlMatchValidator.containsMultipleDots = function (s) { + var o = s; + return ( + this.hasFullProtocolRegex.test(s) && (o = s.split('://')[1]), + o.split('/')[0].indexOf('..') > -1 + ); + }), + (UrlMatchValidator.isValidUriScheme = function (s) { + var o = s.match(this.uriSchemeRegex), + i = o && o[0].toLowerCase(); + return 'javascript:' !== i && 'vbscript:' !== i; + }), + (UrlMatchValidator.urlMatchDoesNotHaveProtocolOrDot = function (s, o) { + return !(!s || (o && this.hasFullProtocolRegex.test(o)) || -1 !== s.indexOf('.')); + }), + (UrlMatchValidator.urlMatchDoesNotHaveAtLeastOneWordChar = function (s, o) { + return ( + !(!s || !o) && + !this.hasFullProtocolRegex.test(o) && + !this.hasWordCharAfterProtocolRegex.test(s) + ); + }), + (UrlMatchValidator.hasFullProtocolRegex = /^[A-Za-z][-.+A-Za-z0-9]*:\/\//), + (UrlMatchValidator.uriSchemeRegex = /^[A-Za-z][-.+A-Za-z0-9]*:/), + (UrlMatchValidator.hasWordCharAfterProtocolRegex = new RegExp( + ':[^\\s]*?[' + nO + ']' + )), + (UrlMatchValidator.ipRegex = + /[0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?(:[0-9]*)?\/?$/), + UrlMatchValidator + ); + })(), + vO = + ((zC = new RegExp( + '[/?#](?:[' + + aO + + "\\-+&@#/%=~_()|'$*\\[\\]{}?!:,.;^✓]*[" + + aO + + "\\-+&@#/%=~_()|'$*\\[\\]{}✓])?" + )), + new RegExp( + [ + '(?:', + '(', + /(?:[A-Za-z][-.+A-Za-z0-9]{0,63}:(?![A-Za-z][-.+A-Za-z0-9]{0,63}:\/\/)(?!\d+\/?)(?:\/\/)?)/ + .source, + getDomainNameStr(2), + ')', + '|', + '(', + '(//)?', + /(?:www\.)/.source, + getDomainNameStr(6), + ')', + '|', + '(', + '(//)?', + getDomainNameStr(10) + '\\.', + hO.source, + '(?![-' + iO + '])', + ')', + ')', + '(?::[0-9]+)?', + '(?:' + zC.source + ')?' + ].join(''), + 'gi' + )), + bO = new RegExp('[' + aO + ']'), + _O = (function (s) { + function UrlMatcher(o) { + var i = s.call(this, o) || this; + return ( + (i.stripPrefix = { scheme: !0, www: !0 }), + (i.stripTrailingSlash = !0), + (i.decodePercentEncoding = !0), + (i.matcherRegex = vO), + (i.wordCharRegExp = bO), + (i.stripPrefix = o.stripPrefix), + (i.stripTrailingSlash = o.stripTrailingSlash), + (i.decodePercentEncoding = o.decodePercentEncoding), + i + ); + } + return ( + tslib_es6_extends(UrlMatcher, s), + (UrlMatcher.prototype.parseMatches = function (s) { + for ( + var o, + i = this.matcherRegex, + u = this.stripPrefix, + _ = this.stripTrailingSlash, + w = this.decodePercentEncoding, + x = this.tagBuilder, + C = [], + _loop_1 = function () { + var i = o[0], + L = o[1], + B = o[4], + $ = o[5], + V = o[9], + U = o.index, + z = $ || V, + Y = s.charAt(U - 1); + if (!yO.isValid(i, L)) return 'continue'; + if (U > 0 && '@' === Y) return 'continue'; + if (U > 0 && z && j.wordCharRegExp.test(Y)) return 'continue'; + if ( + (/\?$/.test(i) && (i = i.substr(0, i.length - 1)), + j.matchHasUnbalancedClosingParen(i)) + ) + i = i.substr(0, i.length - 1); + else { + var Z = j.matchHasInvalidCharAfterTld(i, L); + Z > -1 && (i = i.substr(0, Z)); + } + var ee = ['http://', 'https://'].find(function (s) { + return !!L && -1 !== L.indexOf(s); + }); + if (ee) { + var ie = i.indexOf(ee); + (i = i.substr(ie)), (L = L.substr(ie)), (U += ie); + } + var ae = L ? 'scheme' : B ? 'www' : 'tld', + le = !!L; + C.push( + new GC({ + tagBuilder: x, + matchedText: i, + offset: U, + urlMatchType: ae, + url: i, + protocolUrlMatch: le, + protocolRelativeMatch: !!z, + stripPrefix: u, + stripTrailingSlash: _, + decodePercentEncoding: w + }) + ); + }, + j = this; + null !== (o = i.exec(s)); + + ) + _loop_1(); + return C; + }), + (UrlMatcher.prototype.matchHasUnbalancedClosingParen = function (s) { + var o, + i = s.charAt(s.length - 1); + if (')' === i) o = '('; + else if (']' === i) o = '['; + else { + if ('}' !== i) return !1; + o = '{'; + } + for (var u = 0, _ = 0, w = s.length - 1; _ < w; _++) { + var x = s.charAt(_); + x === o ? u++ : x === i && (u = Math.max(u - 1, 0)); + } + return 0 === u; + }), + (UrlMatcher.prototype.matchHasInvalidCharAfterTld = function (s, o) { + if (!s) return -1; + var i = 0; + o && ((i = s.indexOf(':')), (s = s.slice(i))); + var u = new RegExp('^((.?//)?[-.' + aO + ']*[-' + aO + ']\\.[-' + aO + ']+)').exec( + s + ); + return null === u + ? -1 + : ((i += u[1].length), + (s = s.slice(u[1].length)), + /^[^-.A-Za-z0-9:\/?#]/.test(s) ? i : -1); + }), + UrlMatcher + ); + })(YC), + EO = new RegExp('[_'.concat(aO, ']')), + wO = (function (s) { + function HashtagMatcher(o) { + var i = s.call(this, o) || this; + return (i.serviceName = 'twitter'), (i.serviceName = o.serviceName), i; + } + return ( + tslib_es6_extends(HashtagMatcher, s), + (HashtagMatcher.prototype.parseMatches = function (s) { + for ( + var o = this.tagBuilder, + i = this.serviceName, + u = [], + _ = s.length, + w = 0, + x = -1, + C = 0; + w < _; + + ) { + var j = s.charAt(w); + switch (C) { + case 0: + stateNone(j); + break; + case 1: + stateNonHashtagWordChar(j); + break; + case 2: + stateHashtagHashChar(j); + break; + case 3: + stateHashtagTextChar(j); + break; + default: + throwUnhandledCaseError(C); + } + w++; + } + return captureMatchIfValid(), u; + function stateNone(s) { + '#' === s ? ((C = 2), (x = w)) : lO.test(s) && (C = 1); + } + function stateNonHashtagWordChar(s) { + lO.test(s) || (C = 0); + } + function stateHashtagHashChar(s) { + C = EO.test(s) ? 3 : lO.test(s) ? 1 : 0; + } + function stateHashtagTextChar(s) { + EO.test(s) || (captureMatchIfValid(), (x = -1), (C = lO.test(s) ? 1 : 0)); + } + function captureMatchIfValid() { + if (x > -1 && w - x <= 140) { + var _ = s.slice(x, w), + C = new KC({ + tagBuilder: o, + matchedText: _, + offset: x, + serviceName: i, + hashtag: _.slice(1) + }); + u.push(C); + } + } + }), + HashtagMatcher + ); + })(YC), + SO = ['twitter', 'facebook', 'instagram', 'tiktok'], + xO = new RegExp( + '' + .concat( + /(?:(?:(?:(\+)?\d{1,3}[-\040.]?)?\(?\d{3}\)?[-\040.]?\d{3}[-\040.]?\d{4})|(?:(\+)(?:9[976]\d|8[987530]\d|6[987]\d|5[90]\d|42\d|3[875]\d|2[98654321]\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|4[987654310]|3[9643210]|2[70]|7|1)[-\040.]?(?:\d[-\040.]?){6,12}\d+))([,;]+[0-9]+#?)*/ + .source, + '|' + ) + .concat( + /(0([1-9]{1}-?[1-9]\d{3}|[1-9]{2}-?\d{3}|[1-9]{2}\d{1}-?\d{2}|[1-9]{2}\d{2}-?\d{1})-?\d{4}|0[789]0-?\d{4}-?\d{4}|050-?\d{4}-?\d{4})/ + .source + ), + 'g' + ), + kO = (function (s) { + function PhoneMatcher() { + var o = (null !== s && s.apply(this, arguments)) || this; + return (o.matcherRegex = xO), o; + } + return ( + tslib_es6_extends(PhoneMatcher, s), + (PhoneMatcher.prototype.parseMatches = function (s) { + for ( + var o, i = this.matcherRegex, u = this.tagBuilder, _ = []; + null !== (o = i.exec(s)); + + ) { + var w = o[0], + x = w.replace(/[^0-9,;#]/g, ''), + C = !(!o[1] && !o[2]), + j = 0 == o.index ? '' : s.substr(o.index - 1, 1), + L = s.substr(o.index + w.length, 1), + B = !j.match(/\d/) && !L.match(/\d/); + this.testMatch(o[3]) && + this.testMatch(w) && + B && + _.push( + new JC({ + tagBuilder: u, + matchedText: w, + offset: o.index, + number: x, + plusSign: C + }) + ); + } + return _; + }), + (PhoneMatcher.prototype.testMatch = function (s) { + return QC.test(s); + }), + PhoneMatcher + ); + })(YC), + CO = new RegExp('@[_'.concat(aO, ']{1,50}(?![_').concat(aO, '])'), 'g'), + OO = new RegExp('@[_.'.concat(aO, ']{1,30}(?![_').concat(aO, '])'), 'g'), + AO = new RegExp('@[-_.'.concat(aO, ']{1,50}(?![-_').concat(aO, '])'), 'g'), + jO = new RegExp( + '@[_.'.concat(aO, ']{1,23}[_').concat(aO, '](?![_').concat(aO, '])'), + 'g' + ), + IO = new RegExp('[^' + aO + ']'), + PO = (function (s) { + function MentionMatcher(o) { + var i = s.call(this, o) || this; + return ( + (i.serviceName = 'twitter'), + (i.matcherRegexes = { twitter: CO, instagram: OO, soundcloud: AO, tiktok: jO }), + (i.nonWordCharRegex = IO), + (i.serviceName = o.serviceName), + i + ); + } + return ( + tslib_es6_extends(MentionMatcher, s), + (MentionMatcher.prototype.parseMatches = function (s) { + var o, + i = this.serviceName, + u = this.matcherRegexes[this.serviceName], + _ = this.nonWordCharRegex, + w = this.tagBuilder, + x = []; + if (!u) return x; + for (; null !== (o = u.exec(s)); ) { + var C = o.index, + j = s.charAt(C - 1); + if (0 === C || _.test(j)) { + var L = o[0].replace(/\.+$/g, ''), + B = L.slice(1); + x.push( + new HC({ + tagBuilder: w, + matchedText: L, + offset: C, + serviceName: i, + mention: B + }) + ); + } + } + return x; + }), + MentionMatcher + ); + })(YC); + function parseHtml(s, o) { + for ( + var i = o.onOpenTag, + u = o.onCloseTag, + _ = o.onText, + w = o.onComment, + x = o.onDoctype, + C = new MO(), + j = 0, + L = s.length, + B = 0, + $ = 0, + V = C; + j < L; + + ) { + var U = s.charAt(j); + switch (B) { + case 0: + stateData(U); + break; + case 1: + stateTagOpen(U); + break; + case 2: + stateEndTagOpen(U); + break; + case 3: + stateTagName(U); + break; + case 4: + stateBeforeAttributeName(U); + break; + case 5: + stateAttributeName(U); + break; + case 6: + stateAfterAttributeName(U); + break; + case 7: + stateBeforeAttributeValue(U); + break; + case 8: + stateAttributeValueDoubleQuoted(U); + break; + case 9: + stateAttributeValueSingleQuoted(U); + break; + case 10: + stateAttributeValueUnquoted(U); + break; + case 11: + stateAfterAttributeValueQuoted(U); + break; + case 12: + stateSelfClosingStartTag(U); + break; + case 13: + stateMarkupDeclarationOpen(U); + break; + case 14: + stateCommentStart(U); + break; + case 15: + stateCommentStartDash(U); + break; + case 16: + stateComment(U); + break; + case 17: + stateCommentEndDash(U); + break; + case 18: + stateCommentEnd(U); + break; + case 19: + stateCommentEndBang(U); + break; + case 20: + stateDoctype(U); + break; + default: + throwUnhandledCaseError(B); + } + j++; + } + function stateData(s) { + '<' === s && startNewTag(); + } + function stateTagOpen(s) { + '!' === s + ? (B = 13) + : '/' === s + ? ((B = 2), (V = new MO(__assign(__assign({}, V), { isClosing: !0 })))) + : '<' === s + ? startNewTag() + : XC.test(s) + ? ((B = 3), (V = new MO(__assign(__assign({}, V), { isOpening: !0 })))) + : ((B = 0), (V = C)); + } + function stateTagName(s) { + eO.test(s) + ? ((V = new MO(__assign(__assign({}, V), { name: captureTagName() }))), (B = 4)) + : '<' === s + ? startNewTag() + : '/' === s + ? ((V = new MO(__assign(__assign({}, V), { name: captureTagName() }))), (B = 12)) + : '>' === s + ? ((V = new MO(__assign(__assign({}, V), { name: captureTagName() }))), + emitTagAndPreviousTextNode()) + : XC.test(s) || ZC.test(s) || ':' === s || resetToDataState(); + } + function stateEndTagOpen(s) { + '>' === s ? resetToDataState() : XC.test(s) ? (B = 3) : resetToDataState(); + } + function stateBeforeAttributeName(s) { + eO.test(s) || + ('/' === s + ? (B = 12) + : '>' === s + ? emitTagAndPreviousTextNode() + : '<' === s + ? startNewTag() + : '=' === s || tO.test(s) || rO.test(s) + ? resetToDataState() + : (B = 5)); + } + function stateAttributeName(s) { + eO.test(s) + ? (B = 6) + : '/' === s + ? (B = 12) + : '=' === s + ? (B = 7) + : '>' === s + ? emitTagAndPreviousTextNode() + : '<' === s + ? startNewTag() + : tO.test(s) && resetToDataState(); + } + function stateAfterAttributeName(s) { + eO.test(s) || + ('/' === s + ? (B = 12) + : '=' === s + ? (B = 7) + : '>' === s + ? emitTagAndPreviousTextNode() + : '<' === s + ? startNewTag() + : tO.test(s) + ? resetToDataState() + : (B = 5)); + } + function stateBeforeAttributeValue(s) { + eO.test(s) || + ('"' === s + ? (B = 8) + : "'" === s + ? (B = 9) + : /[>=`]/.test(s) + ? resetToDataState() + : '<' === s + ? startNewTag() + : (B = 10)); + } + function stateAttributeValueDoubleQuoted(s) { + '"' === s && (B = 11); + } + function stateAttributeValueSingleQuoted(s) { + "'" === s && (B = 11); + } + function stateAttributeValueUnquoted(s) { + eO.test(s) + ? (B = 4) + : '>' === s + ? emitTagAndPreviousTextNode() + : '<' === s && startNewTag(); + } + function stateAfterAttributeValueQuoted(s) { + eO.test(s) + ? (B = 4) + : '/' === s + ? (B = 12) + : '>' === s + ? emitTagAndPreviousTextNode() + : '<' === s + ? startNewTag() + : ((B = 4), + (function reconsumeCurrentCharacter() { + j--; + })()); + } + function stateSelfClosingStartTag(s) { + '>' === s + ? ((V = new MO(__assign(__assign({}, V), { isClosing: !0 }))), + emitTagAndPreviousTextNode()) + : (B = 4); + } + function stateMarkupDeclarationOpen(o) { + '--' === s.substr(j, 2) + ? ((j += 2), (V = new MO(__assign(__assign({}, V), { type: 'comment' }))), (B = 14)) + : 'DOCTYPE' === s.substr(j, 7).toUpperCase() + ? ((j += 7), (V = new MO(__assign(__assign({}, V), { type: 'doctype' }))), (B = 20)) + : resetToDataState(); + } + function stateCommentStart(s) { + '-' === s ? (B = 15) : '>' === s ? resetToDataState() : (B = 16); + } + function stateCommentStartDash(s) { + '-' === s ? (B = 18) : '>' === s ? resetToDataState() : (B = 16); + } + function stateComment(s) { + '-' === s && (B = 17); + } + function stateCommentEndDash(s) { + B = '-' === s ? 18 : 16; + } + function stateCommentEnd(s) { + '>' === s ? emitTagAndPreviousTextNode() : '!' === s ? (B = 19) : '-' === s || (B = 16); + } + function stateCommentEndBang(s) { + '-' === s ? (B = 17) : '>' === s ? emitTagAndPreviousTextNode() : (B = 16); + } + function stateDoctype(s) { + '>' === s ? emitTagAndPreviousTextNode() : '<' === s && startNewTag(); + } + function resetToDataState() { + (B = 0), (V = C); + } + function startNewTag() { + (B = 1), (V = new MO({ idx: j })); + } + function emitTagAndPreviousTextNode() { + var o = s.slice($, V.idx); + o && _(o, $), + 'comment' === V.type + ? w(V.idx) + : 'doctype' === V.type + ? x(V.idx) + : (V.isOpening && i(V.name, V.idx), V.isClosing && u(V.name, V.idx)), + resetToDataState(), + ($ = j + 1); + } + function captureTagName() { + var o = V.idx + (V.isClosing ? 2 : 1); + return s.slice(o, j).toLowerCase(); + } + $ < j && + (function emitText() { + var o = s.slice($, j); + _(o, $), ($ = j + 1); + })(); + } + var MO = function MO(s) { + void 0 === s && (s = {}), + (this.idx = void 0 !== s.idx ? s.idx : -1), + (this.type = s.type || 'tag'), + (this.name = s.name || ''), + (this.isOpening = !!s.isOpening), + (this.isClosing = !!s.isClosing); + }, + TO = (function () { + function Autolinker(s) { + void 0 === s && (s = {}), + (this.version = Autolinker.version), + (this.urls = {}), + (this.email = !0), + (this.phone = !0), + (this.hashtag = !1), + (this.mention = !1), + (this.newWindow = !0), + (this.stripPrefix = { scheme: !0, www: !0 }), + (this.stripTrailingSlash = !0), + (this.decodePercentEncoding = !0), + (this.truncate = { length: 0, location: 'end' }), + (this.className = ''), + (this.replaceFn = null), + (this.context = void 0), + (this.sanitizeHtml = !1), + (this.matchers = null), + (this.tagBuilder = null), + (this.urls = this.normalizeUrlsCfg(s.urls)), + (this.email = 'boolean' == typeof s.email ? s.email : this.email), + (this.phone = 'boolean' == typeof s.phone ? s.phone : this.phone), + (this.hashtag = s.hashtag || this.hashtag), + (this.mention = s.mention || this.mention), + (this.newWindow = 'boolean' == typeof s.newWindow ? s.newWindow : this.newWindow), + (this.stripPrefix = this.normalizeStripPrefixCfg(s.stripPrefix)), + (this.stripTrailingSlash = + 'boolean' == typeof s.stripTrailingSlash + ? s.stripTrailingSlash + : this.stripTrailingSlash), + (this.decodePercentEncoding = + 'boolean' == typeof s.decodePercentEncoding + ? s.decodePercentEncoding + : this.decodePercentEncoding), + (this.sanitizeHtml = s.sanitizeHtml || !1); + var o = this.mention; + if (!1 !== o && -1 === ['twitter', 'instagram', 'soundcloud', 'tiktok'].indexOf(o)) + throw new Error("invalid `mention` cfg '".concat(o, "' - see docs")); + var i = this.hashtag; + if (!1 !== i && -1 === SO.indexOf(i)) + throw new Error("invalid `hashtag` cfg '".concat(i, "' - see docs")); + (this.truncate = this.normalizeTruncateCfg(s.truncate)), + (this.className = s.className || this.className), + (this.replaceFn = s.replaceFn || this.replaceFn), + (this.context = s.context || this); + } + return ( + (Autolinker.link = function (s, o) { + return new Autolinker(o).link(s); + }), + (Autolinker.parse = function (s, o) { + return new Autolinker(o).parse(s); + }), + (Autolinker.prototype.normalizeUrlsCfg = function (s) { + return ( + null == s && (s = !0), + 'boolean' == typeof s + ? { schemeMatches: s, wwwMatches: s, tldMatches: s } + : { + schemeMatches: 'boolean' != typeof s.schemeMatches || s.schemeMatches, + wwwMatches: 'boolean' != typeof s.wwwMatches || s.wwwMatches, + tldMatches: 'boolean' != typeof s.tldMatches || s.tldMatches + } + ); + }), + (Autolinker.prototype.normalizeStripPrefixCfg = function (s) { + return ( + null == s && (s = !0), + 'boolean' == typeof s + ? { scheme: s, www: s } + : { + scheme: 'boolean' != typeof s.scheme || s.scheme, + www: 'boolean' != typeof s.www || s.www + } + ); + }), + (Autolinker.prototype.normalizeTruncateCfg = function (s) { + return 'number' == typeof s + ? { length: s, location: 'end' } + : (function defaults(s, o) { + for (var i in o) o.hasOwnProperty(i) && void 0 === s[i] && (s[i] = o[i]); + return s; + })(s || {}, { length: Number.POSITIVE_INFINITY, location: 'end' }); + }), + (Autolinker.prototype.parse = function (s) { + var o = this, + i = ['a', 'style', 'script'], + u = 0, + _ = []; + return ( + parseHtml(s, { + onOpenTag: function (s) { + i.indexOf(s) >= 0 && u++; + }, + onText: function (s, i) { + if (0 === u) { + var w = (function splitAndCapture(s, o) { + if (!o.global) + throw new Error("`splitRegex` must have the 'g' flag set"); + for (var i, u = [], _ = 0; (i = o.exec(s)); ) + u.push(s.substring(_, i.index)), + u.push(i[0]), + (_ = i.index + i[0].length); + return u.push(s.substring(_)), u; + })(s, /( | |<|<|>|>|"|"|')/gi), + x = i; + w.forEach(function (s, i) { + if (i % 2 == 0) { + var u = o.parseText(s, x); + _.push.apply(_, u); + } + x += s.length; + }); + } + }, + onCloseTag: function (s) { + i.indexOf(s) >= 0 && (u = Math.max(u - 1, 0)); + }, + onComment: function (s) {}, + onDoctype: function (s) {} + }), + (_ = this.compactMatches(_)), + (_ = this.removeUnwantedMatches(_)) + ); + }), + (Autolinker.prototype.compactMatches = function (s) { + s.sort(function (s, o) { + return s.getOffset() - o.getOffset(); + }); + for (var o = 0; o < s.length - 1; ) { + var i = s[o], + u = i.getOffset(), + _ = i.getMatchedText().length, + w = u + _; + if (o + 1 < s.length) { + if (s[o + 1].getOffset() === u) { + var x = s[o + 1].getMatchedText().length > _ ? o : o + 1; + s.splice(x, 1); + continue; + } + if (s[o + 1].getOffset() < w) { + s.splice(o + 1, 1); + continue; + } + } + o++; + } + return s; + }), + (Autolinker.prototype.removeUnwantedMatches = function (s) { + return ( + this.hashtag || + utils_remove(s, function (s) { + return 'hashtag' === s.getType(); + }), + this.email || + utils_remove(s, function (s) { + return 'email' === s.getType(); + }), + this.phone || + utils_remove(s, function (s) { + return 'phone' === s.getType(); + }), + this.mention || + utils_remove(s, function (s) { + return 'mention' === s.getType(); + }), + this.urls.schemeMatches || + utils_remove(s, function (s) { + return 'url' === s.getType() && 'scheme' === s.getUrlMatchType(); + }), + this.urls.wwwMatches || + utils_remove(s, function (s) { + return 'url' === s.getType() && 'www' === s.getUrlMatchType(); + }), + this.urls.tldMatches || + utils_remove(s, function (s) { + return 'url' === s.getType() && 'tld' === s.getUrlMatchType(); + }), + s + ); + }), + (Autolinker.prototype.parseText = function (s, o) { + void 0 === o && (o = 0), (o = o || 0); + for (var i = this.getMatchers(), u = [], _ = 0, w = i.length; _ < w; _++) { + for (var x = i[_].parseMatches(s), C = 0, j = x.length; C < j; C++) + x[C].setOffset(o + x[C].getOffset()); + u.push.apply(u, x); + } + return u; + }), + (Autolinker.prototype.link = function (s) { + if (!s) return ''; + this.sanitizeHtml && (s = s.replace(//g, '>')); + for (var o = this.parse(s), i = [], u = 0, _ = 0, w = o.length; _ < w; _++) { + var x = o[_]; + i.push(s.substring(u, x.getOffset())), + i.push(this.createMatchReturnVal(x)), + (u = x.getOffset() + x.getMatchedText().length); + } + return i.push(s.substring(u)), i.join(''); + }), + (Autolinker.prototype.createMatchReturnVal = function (s) { + var o; + return ( + this.replaceFn && (o = this.replaceFn.call(this.context, s)), + 'string' == typeof o + ? o + : !1 === o + ? s.getMatchedText() + : o instanceof $C + ? o.toAnchorString() + : s.buildTag().toAnchorString() + ); + }), + (Autolinker.prototype.getMatchers = function () { + if (this.matchers) return this.matchers; + var s = this.getTagBuilder(), + o = [ + new wO({ tagBuilder: s, serviceName: this.hashtag }), + new mO({ tagBuilder: s }), + new kO({ tagBuilder: s }), + new PO({ tagBuilder: s, serviceName: this.mention }), + new _O({ + tagBuilder: s, + stripPrefix: this.stripPrefix, + stripTrailingSlash: this.stripTrailingSlash, + decodePercentEncoding: this.decodePercentEncoding + }) + ]; + return (this.matchers = o); + }), + (Autolinker.prototype.getTagBuilder = function () { + var s = this.tagBuilder; + return ( + s || + (s = this.tagBuilder = + new VC({ + newWindow: this.newWindow, + truncate: this.truncate, + className: this.className + })), + s + ); + }), + (Autolinker.version = '3.16.2'), + (Autolinker.AnchorTagBuilder = VC), + (Autolinker.HtmlTag = $C), + (Autolinker.matcher = { + Email: mO, + Hashtag: wO, + Matcher: YC, + Mention: PO, + Phone: kO, + Url: _O + }), + (Autolinker.match = { + Email: WC, + Hashtag: KC, + Match: UC, + Mention: HC, + Phone: JC, + Url: GC + }), + Autolinker + ); + })(); + const NO = TO; + var RO = /www|@|\:\/\//; + function isLinkOpen(s) { + return /^\s]/i.test(s); + } + function isLinkClose(s) { + return /^<\/a\s*>/i.test(s); + } + function createLinkifier() { + var s = [], + o = new NO({ + stripPrefix: !1, + url: !0, + email: !0, + replaceFn: function (o) { + switch (o.getType()) { + case 'url': + s.push({ text: o.matchedText, url: o.getUrl() }); + break; + case 'email': + s.push({ + text: o.matchedText, + url: 'mailto:' + o.getEmail().replace(/^mailto:/i, '') + }); + } + return !1; + } + }); + return { links: s, autolinker: o }; + } + function parseTokens(s) { + var o, + i, + u, + _, + w, + x, + C, + j, + L, + B, + $, + V, + U, + z = s.tokens, + Y = null; + for (i = 0, u = z.length; i < u; i++) + if ('inline' === z[i].type) + for ($ = 0, o = (_ = z[i].children).length - 1; o >= 0; o--) + if ('link_close' !== (w = _[o]).type) { + if ( + ('htmltag' === w.type && + (isLinkOpen(w.content) && $ > 0 && $--, isLinkClose(w.content) && $++), + !($ > 0) && 'text' === w.type && RO.test(w.content)) + ) { + if ( + (Y || ((V = (Y = createLinkifier()).links), (U = Y.autolinker)), + (x = w.content), + (V.length = 0), + U.link(x), + !V.length) + ) + continue; + for (C = [], B = w.level, j = 0; j < V.length; j++) + s.inline.validateLink(V[j].url) && + ((L = x.indexOf(V[j].text)) && + C.push({ type: 'text', content: x.slice(0, L), level: B }), + C.push({ type: 'link_open', href: V[j].url, title: '', level: B++ }), + C.push({ type: 'text', content: V[j].text, level: B }), + C.push({ type: 'link_close', level: --B }), + (x = x.slice(L + V[j].text.length))); + x.length && C.push({ type: 'text', content: x, level: B }), + (z[i].children = _ = [].concat(_.slice(0, o), C, _.slice(o + 1))); + } + } else for (o--; _[o].level !== w.level && 'link_open' !== _[o].type; ) o--; + } + function linkify(s) { + s.core.ruler.push('linkify', parseTokens); + } + var DO = __webpack_require__(42838), + LO = __webpack_require__.n(DO); + LO().addHook && + LO().addHook('beforeSanitizeElements', function (s) { + return s.href && s.setAttribute('rel', 'noopener noreferrer'), s; + }); + const BO = function Markdown({ + source: s, + className: o = '', + getConfigs: i = () => ({ useUnsafeMarkdown: !1 }) + }) { + if ('string' != typeof s) return null; + const u = new Remarkable({ + html: !0, + typographer: !0, + breaks: !0, + linkTarget: '_blank' + }).use(linkify); + u.core.ruler.disable(['replacements', 'smartquotes']); + const { useUnsafeMarkdown: _ } = i(), + w = u.render(s), + x = sanitizer(w, { useUnsafeMarkdown: _ }); + return s && w && x + ? Pe.createElement('div', { + className: Hn()(o, 'markdown'), + dangerouslySetInnerHTML: { __html: x } + }) + : null; + }; + function sanitizer(s, { useUnsafeMarkdown: o = !1 } = {}) { + const i = o, + u = o ? [] : ['style', 'class']; + return ( + o && + !sanitizer.hasWarnedAboutDeprecation && + (console.warn( + 'useUnsafeMarkdown display configuration parameter is deprecated since >3.26.0 and will be removed in v4.0.0.' + ), + (sanitizer.hasWarnedAboutDeprecation = !0)), + LO().sanitize(s, { + ADD_ATTR: ['target'], + FORBID_TAGS: ['style', 'form'], + ALLOW_DATA_ATTR: i, + FORBID_ATTR: u + }) + ); + } + sanitizer.hasWarnedAboutDeprecation = !1; + class BaseLayout extends Pe.Component { + render() { + const { errSelectors: s, specSelectors: o, getComponent: i } = this.props, + u = i('SvgAssets'), + _ = i('InfoContainer', !0), + w = i('VersionPragmaFilter'), + x = i('operations', !0), + C = i('Models', !0), + j = i('Webhooks', !0), + L = i('Row'), + B = i('Col'), + $ = i('errors', !0), + V = i('ServersContainer', !0), + U = i('SchemesContainer', !0), + z = i('AuthorizeBtnContainer', !0), + Y = i('FilterContainer', !0), + Z = o.isSwagger2(), + ee = o.isOAS3(), + ie = o.isOAS31(), + ae = !o.specStr(), + le = o.loadingStatus(); + let ce = null; + if ( + ('loading' === le && + (ce = Pe.createElement( + 'div', + { className: 'info' }, + Pe.createElement( + 'div', + { className: 'loading-container' }, + Pe.createElement('div', { className: 'loading' }) + ) + )), + 'failed' === le && + (ce = Pe.createElement( + 'div', + { className: 'info' }, + Pe.createElement( + 'div', + { className: 'loading-container' }, + Pe.createElement( + 'h4', + { className: 'title' }, + 'Failed to load API definition.' + ), + Pe.createElement($, null) + ) + )), + 'failedConfig' === le) + ) { + const o = s.lastError(), + i = o ? o.get('message') : ''; + ce = Pe.createElement( + 'div', + { className: 'info failed-config' }, + Pe.createElement( + 'div', + { className: 'loading-container' }, + Pe.createElement( + 'h4', + { className: 'title' }, + 'Failed to load remote configuration.' + ), + Pe.createElement('p', null, i) + ) + ); + } + if ( + (!ce && ae && (ce = Pe.createElement('h4', null, 'No API definition provided.')), ce) + ) + return Pe.createElement( + 'div', + { className: 'swagger-ui' }, + Pe.createElement('div', { className: 'loading-container' }, ce) + ); + const pe = o.servers(), + de = o.schemes(), + fe = pe && pe.size, + ye = de && de.size, + be = !!o.securityDefinitions(); + return Pe.createElement( + 'div', + { className: 'swagger-ui' }, + Pe.createElement(u, null), + Pe.createElement( + w, + { isSwagger2: Z, isOAS3: ee, alsoShow: Pe.createElement($, null) }, + Pe.createElement($, null), + Pe.createElement( + L, + { className: 'information-container' }, + Pe.createElement(B, { mobile: 12 }, Pe.createElement(_, null)) + ), + fe || ye || be + ? Pe.createElement( + 'div', + { className: 'scheme-container' }, + Pe.createElement( + B, + { className: 'schemes wrapper', mobile: 12 }, + fe || ye + ? Pe.createElement( + 'div', + { className: 'schemes-server-container' }, + fe ? Pe.createElement(V, null) : null, + ye ? Pe.createElement(U, null) : null + ) + : null, + be ? Pe.createElement(z, null) : null + ) + ) + : null, + Pe.createElement(Y, null), + Pe.createElement( + L, + null, + Pe.createElement(B, { mobile: 12, desktop: 12 }, Pe.createElement(x, null)) + ), + ie && + Pe.createElement( + L, + { className: 'webhooks-container' }, + Pe.createElement(B, { mobile: 12, desktop: 12 }, Pe.createElement(j, null)) + ), + Pe.createElement( + L, + null, + Pe.createElement(B, { mobile: 12, desktop: 12 }, Pe.createElement(C, null)) + ) + ) + ); + } + } + const core_components = () => ({ + components: { + App: fk, + authorizationPopup: AuthorizationPopup, + authorizeBtn: AuthorizeBtn, + AuthorizeBtnContainer, + authorizeOperationBtn: AuthorizeOperationBtn, + auths: Auths, + AuthItem: auth_item_Auths, + authError: AuthError, + oauth2: Oauth2, + apiKeyAuth: ApiKeyAuth, + basicAuth: BasicAuth, + clear: Clear, + liveResponse: LiveResponse, + InitializedInput, + info: qk, + InfoContainer, + InfoUrl, + InfoBasePath, + Contact: Vk, + License: zk, + JumpToPath, + CopyToClipboardBtn, + onlineValidatorBadge: OnlineValidatorBadge, + operations: Operations, + operation: operation_Operation, + OperationSummary, + OperationSummaryMethod, + OperationSummaryPath, + responses: responses_Responses, + response: response_Response, + ResponseExtension: response_extension, + responseBody: ResponseBody, + parameters: Parameters, + parameterRow: ParameterRow, + execute: Execute, + headers: headers_Headers, + errors: Errors, + contentType: ContentType, + overview: Overview, + footer: Footer, + FilterContainer, + ParamBody, + curl: Curl, + Property: property, + TryItOutButton, + Markdown: BO, + BaseLayout, + VersionPragmaFilter, + VersionStamp: version_stamp, + OperationExt: operation_extensions, + OperationExtRow: operation_extension_row, + ParameterExt: parameter_extension, + ParameterIncludeEmpty, + OperationTag, + OperationContainer, + OpenAPIVersion: openapi_version, + DeepLink: deep_link, + SvgAssets: svg_assets, + Example: example_Example, + ExamplesSelect, + ExamplesSelectValueRetainer + } + }), + form_components = () => ({ components: { ...ye } }), + base = () => [ + configsPlugin, + util, + logs, + view, + view_legacy, + plugins_spec, + err, + icons, + plugins_layout, + json_schema_5, + json_schema_5_samples, + core_components, + form_components, + swagger_client, + auth, + downloadUrlPlugin, + deep_linking, + filter, + on_complete, + plugins_request_snippets, + syntax_highlighting, + versions, + safe_render() + ], + FO = (0, qe.Map)(); + function onlyOAS3(s) { + return (o, i) => + (...u) => { + if (i.getSystem().specSelectors.isOAS3()) { + const o = s(...u); + return 'function' == typeof o ? o(i) : o; + } + return o(...u); + }; + } + const qO = onlyOAS3(Ss()(null)), + $O = onlyOAS3((s, o) => (s) => s.getSystem().specSelectors.findSchema(o)), + VO = onlyOAS3(() => (s) => { + const o = s.getSystem().specSelectors.specJson().getIn(['components', 'schemas']); + return qe.Map.isMap(o) ? o : FO; + }), + UO = onlyOAS3(() => (s) => s.getSystem().specSelectors.specJson().hasIn(['servers', 0])), + zO = onlyOAS3(Ut(Ms, (s) => s.getIn(['components', 'securitySchemes']) || null)), + wrap_selectors_validOperationMethods = + (s, o) => + (i, ...u) => + o.specSelectors.isOAS3() ? o.oas3Selectors.validOperationMethods() : s(...u), + WO = qO, + KO = qO, + HO = qO, + JO = qO, + GO = qO; + const YO = (function wrap_selectors_onlyOAS3(s) { + return (o, i) => + (...u) => { + if (i.getSystem().specSelectors.isOAS3()) { + let o = i + .getState() + .getIn(['spec', 'resolvedSubtrees', 'components', 'securitySchemes']); + return s(i, o, ...u); + } + return o(...u); + }; + })( + Ut( + (s) => s, + ({ specSelectors: s }) => s.securityDefinitions(), + (s, o) => { + let i = (0, qe.List)(); + return o + ? (o.entrySeq().forEach(([s, o]) => { + const u = o.get('type'); + if ( + ('oauth2' === u && + o + .get('flows') + .entrySeq() + .forEach(([u, _]) => { + let w = (0, qe.fromJS)({ + flow: u, + authorizationUrl: _.get('authorizationUrl'), + tokenUrl: _.get('tokenUrl'), + scopes: _.get('scopes'), + type: o.get('type'), + description: o.get('description') + }); + i = i.push(new qe.Map({ [s]: w.filter((s) => void 0 !== s) })); + }), + ('http' !== u && 'apiKey' !== u) || (i = i.push(new qe.Map({ [s]: o }))), + 'openIdConnect' === u && o.get('openIdConnectData')) + ) { + let u = o.get('openIdConnectData'); + ( + u.get('grant_types_supported') || ['authorization_code', 'implicit'] + ).forEach((_) => { + let w = + u.get('scopes_supported') && + u.get('scopes_supported').reduce((s, o) => s.set(o, ''), new qe.Map()), + x = (0, qe.fromJS)({ + flow: _, + authorizationUrl: u.get('authorization_endpoint'), + tokenUrl: u.get('token_endpoint'), + scopes: w, + type: 'oauth2', + openIdConnectUrl: o.get('openIdConnectUrl') + }); + i = i.push(new qe.Map({ [s]: x.filter((s) => void 0 !== s) })); + }); + } + }), + i) + : i; + } + ) + ); + function OAS3ComponentWrapFactory(s) { + return (o, i) => (u) => + 'function' == typeof i.specSelectors?.isOAS3 + ? i.specSelectors.isOAS3() + ? Pe.createElement(s, Rn()({}, u, i, { Ori: o })) + : Pe.createElement(o, u) + : (console.warn("OAS3 wrapper: couldn't get spec"), null); + } + const XO = (0, qe.Map)(), + selectors_isSwagger2 = () => (s) => + (function isSwagger2(s) { + const o = s.get('swagger'); + return 'string' == typeof o && '2.0' === o; + })(s.getSystem().specSelectors.specJson()), + selectors_isOAS30 = () => (s) => + (function isOAS30(s) { + const o = s.get('openapi'); + return 'string' == typeof o && /^3\.0\.([0123])(?:-rc[012])?$/.test(o); + })(s.getSystem().specSelectors.specJson()), + selectors_isOAS3 = () => (s) => s.getSystem().specSelectors.isOAS30(); + function selectors_onlyOAS3(s) { + return (o, ...i) => + (u) => { + if (u.specSelectors.isOAS3()) { + const _ = s(o, ...i); + return 'function' == typeof _ ? _(u) : _; + } + return null; + }; + } + const ZO = selectors_onlyOAS3(() => (s) => s.specSelectors.specJson().get('servers', XO)), + findSchema = (s, o) => { + const i = s.getIn(['resolvedSubtrees', 'components', 'schemas', o], null), + u = s.getIn(['json', 'components', 'schemas', o], null); + return i || u || null; + }, + QO = selectors_onlyOAS3((s, { callbacks: o, specPath: i }) => (s) => { + const u = s.specSelectors.validOperationMethods(); + return qe.Map.isMap(o) + ? o + .reduce( + (s, o, _) => { + if (!qe.Map.isMap(o)) return s; + const w = o.reduce( + (s, o, w) => { + if (!qe.Map.isMap(o)) return s; + const x = o + .entrySeq() + .filter(([s]) => u.includes(s)) + .map(([s, o]) => ({ + operation: (0, qe.Map)({ operation: o }), + method: s, + path: w, + callbackName: _, + specPath: i.concat([_, w, s]) + })); + return s.concat(x); + }, + (0, qe.List)() + ); + return s.concat(w); + }, + (0, qe.List)() + ) + .groupBy((s) => s.callbackName) + .map((s) => s.toArray()) + .toObject() + : {}; + }), + callbacks = ({ callbacks: s, specPath: o, specSelectors: i, getComponent: u }) => { + const _ = i.callbacksOperations({ callbacks: s, specPath: o }), + w = Object.keys(_), + x = u('OperationContainer', !0); + return 0 === w.length + ? Pe.createElement('span', null, 'No callbacks') + : Pe.createElement( + 'div', + null, + w.map((s) => + Pe.createElement( + 'div', + { key: `${s}` }, + Pe.createElement('h2', null, s), + _[s].map((o) => + Pe.createElement(x, { + key: `${s}-${o.path}-${o.method}`, + op: o.operation, + tag: 'callbacks', + method: o.method, + path: o.path, + specPath: o.specPath, + allowTryItOut: !1 + }) + ) + ) + ) + ); + }, + getDefaultRequestBodyValue = (s, o, i, u) => { + const _ = s.getIn(['content', o]) ?? (0, qe.OrderedMap)(), + w = _.get('schema', (0, qe.OrderedMap)()).toJS(), + x = void 0 !== _.get('examples'), + C = _.get('example'), + j = x ? _.getIn(['examples', i, 'value']) : C; + return stringify(u.getSampleSchema(w, o, { includeWriteOnly: !0 }, j)); + }, + components_request_body = ({ + userHasEditedBody: s, + requestBody: o, + requestBodyValue: i, + requestBodyInclusionSetting: u, + requestBodyErrors: _, + getComponent: w, + getConfigs: x, + specSelectors: C, + fn: j, + contentType: L, + isExecute: B, + specPath: $, + onChange: V, + onChangeIncludeEmpty: U, + activeExamplesKey: z, + updateActiveExamplesKey: Y, + setRetainRequestBodyValueFlag: Z + }) => { + const handleFile = (s) => { + V(s.target.files[0]); + }, + setIsIncludedOptions = (s) => { + let o = { key: s, shouldDispatchInit: !1, defaultValue: !0 }; + return 'no value' === u.get(s, 'no value') && (o.shouldDispatchInit = !0), o; + }, + ee = w('Markdown', !0), + ie = w('modelExample'), + ae = w('RequestBodyEditor'), + le = w('HighlightCode', !0), + ce = w('ExamplesSelectValueRetainer'), + pe = w('Example'), + de = w('ParameterIncludeEmpty'), + { showCommonExtensions: fe } = x(), + ye = o?.get('description') ?? null, + be = o?.get('content') ?? new qe.OrderedMap(); + L = L || be.keySeq().first() || ''; + const _e = be.get(L) ?? (0, qe.OrderedMap)(), + we = _e.get('schema', (0, qe.OrderedMap)()), + Se = _e.get('examples', null), + xe = Se?.map((s, i) => { + const u = s?.get('value', null); + return u && (s = s.set('value', getDefaultRequestBodyValue(o, L, i, j), u)), s; + }); + if (((_ = qe.List.isList(_) ? _ : (0, qe.List)()), !_e.size)) return null; + const Te = 'object' === _e.getIn(['schema', 'type']), + Re = 'binary' === _e.getIn(['schema', 'format']), + $e = 'base64' === _e.getIn(['schema', 'format']); + if ( + 'application/octet-stream' === L || + 0 === L.indexOf('image/') || + 0 === L.indexOf('audio/') || + 0 === L.indexOf('video/') || + Re || + $e + ) { + const s = w('Input'); + return B + ? Pe.createElement(s, { type: 'file', onChange: handleFile }) + : Pe.createElement( + 'i', + null, + 'Example values are not available for ', + Pe.createElement('code', null, L), + ' media types.' + ); + } + if ( + Te && + ('application/x-www-form-urlencoded' === L || 0 === L.indexOf('multipart/')) && + we.get('properties', (0, qe.OrderedMap)()).size > 0 + ) { + const s = w('JsonSchemaForm'), + o = w('ParameterExt'), + x = we.get('properties', (0, qe.OrderedMap)()); + return ( + (i = qe.Map.isMap(i) ? i : (0, qe.OrderedMap)()), + Pe.createElement( + 'div', + { className: 'table-container' }, + ye && Pe.createElement(ee, { source: ye }), + Pe.createElement( + 'table', + null, + Pe.createElement( + 'tbody', + null, + qe.Map.isMap(x) && + x.entrySeq().map(([x, C]) => { + if (C.get('readOnly')) return; + const L = C.get('oneOf')?.get(0)?.toJS(), + $ = C.get('anyOf')?.get(0)?.toJS(); + C = (0, qe.fromJS)(j.mergeJsonSchema(C.toJS(), L ?? $ ?? {})); + let z = fe ? getCommonExtensions(C) : null; + const Y = we.get('required', (0, qe.List)()).includes(x), + Z = C.get('type'), + ie = C.get('format'), + ae = C.get('description'), + le = i.getIn([x, 'value']), + ce = i.getIn([x, 'errors']) || _, + pe = u.get(x) || !1; + let ye = j.getSampleSchema(C, !1, { includeWriteOnly: !0 }); + !1 === ye && (ye = 'false'), + 0 === ye && (ye = '0'), + 'string' != typeof ye && 'object' === Z && (ye = stringify(ye)), + 'string' == typeof ye && 'array' === Z && (ye = JSON.parse(ye)); + const be = 'string' === Z && ('binary' === ie || 'base64' === ie); + return Pe.createElement( + 'tr', + { key: x, className: 'parameters', 'data-property-name': x }, + Pe.createElement( + 'td', + { className: 'parameters-col_name' }, + Pe.createElement( + 'div', + { className: Y ? 'parameter__name required' : 'parameter__name' }, + x, + Y ? Pe.createElement('span', null, ' *') : null + ), + Pe.createElement( + 'div', + { className: 'parameter__type' }, + Z, + ie && + Pe.createElement( + 'span', + { className: 'prop-format' }, + '($', + ie, + ')' + ), + fe && z.size + ? z + .entrySeq() + .map(([s, i]) => + Pe.createElement(o, { key: `${s}-${i}`, xKey: s, xVal: i }) + ) + : null + ), + Pe.createElement( + 'div', + { className: 'parameter__deprecated' }, + C.get('deprecated') ? 'deprecated' : null + ) + ), + Pe.createElement( + 'td', + { className: 'parameters-col_description' }, + Pe.createElement(ee, { source: ae }), + B + ? Pe.createElement( + 'div', + null, + Pe.createElement(s, { + fn: j, + dispatchInitialValue: !be, + schema: C, + description: x, + getComponent: w, + value: void 0 === le ? ye : le, + required: Y, + errors: ce, + onChange: (s) => { + V(s, [x]); + } + }), + Y + ? null + : Pe.createElement(de, { + onChange: (s) => U(x, s), + isIncluded: pe, + isIncludedOptions: setIsIncludedOptions(x), + isDisabled: Array.isArray(le) + ? 0 !== le.length + : !isEmptyValue(le) + }) + ) + : null + ) + ); + }) + ) + ) + ) + ); + } + const ze = getDefaultRequestBodyValue(o, L, z, j); + let We = null; + return ( + getKnownSyntaxHighlighterLanguage(ze) && (We = 'json'), + Pe.createElement( + 'div', + null, + ye && Pe.createElement(ee, { source: ye }), + xe + ? Pe.createElement(ce, { + userHasEditedBody: s, + examples: xe, + currentKey: z, + currentUserInputValue: i, + onSelect: (s) => { + Y(s); + }, + updateValue: V, + defaultToFirstExample: !0, + getComponent: w, + setRetainRequestBodyValueFlag: Z + }) + : null, + B + ? Pe.createElement( + 'div', + null, + Pe.createElement(ae, { + value: i, + errors: _, + defaultValue: ze, + onChange: V, + getComponent: w + }) + ) + : Pe.createElement(ie, { + getComponent: w, + getConfigs: x, + specSelectors: C, + expandDepth: 1, + isExecute: B, + schema: _e.get('schema'), + specPath: $.push('content', L), + example: Pe.createElement( + le, + { className: 'body-param__example', language: We }, + stringify(i) || ze + ), + includeWriteOnly: !0 + }), + xe + ? Pe.createElement(pe, { example: xe.get(z), getComponent: w, getConfigs: x }) + : null + ) + ); + }; + class operation_link_OperationLink extends Pe.Component { + render() { + const { link: s, name: o, getComponent: i } = this.props, + u = i('Markdown', !0); + let _ = s.get('operationId') || s.get('operationRef'), + w = s.get('parameters') && s.get('parameters').toJS(), + x = s.get('description'); + return Pe.createElement( + 'div', + { className: 'operation-link' }, + Pe.createElement( + 'div', + { className: 'description' }, + Pe.createElement('b', null, Pe.createElement('code', null, o)), + x ? Pe.createElement(u, { source: x }) : null + ), + Pe.createElement( + 'pre', + null, + 'Operation `', + _, + '`', + Pe.createElement('br', null), + Pe.createElement('br', null), + 'Parameters ', + (function padString(s, o) { + if ('string' != typeof o) return ''; + return o + .split('\n') + .map((o, i) => (i > 0 ? Array(s + 1).join(' ') + o : o)) + .join('\n'); + })(0, JSON.stringify(w, null, 2)) || '{}', + Pe.createElement('br', null) + ) + ); + } + } + const eA = operation_link_OperationLink, + components_servers = ({ + servers: s, + currentServer: o, + setSelectedServer: i, + setServerVariableValue: u, + getServerVariable: _, + getEffectiveServerValue: w + }) => { + const x = + (s.find((s) => s.get('url') === o) || (0, qe.OrderedMap)()).get('variables') || + (0, qe.OrderedMap)(), + C = 0 !== x.size; + (0, Pe.useEffect)(() => { + o || i(s.first()?.get('url')); + }, []), + (0, Pe.useEffect)(() => { + const _ = s.find((s) => s.get('url') === o); + if (!_) return void i(s.first().get('url')); + (_.get('variables') || (0, qe.OrderedMap)()).map((s, i) => { + u({ server: o, key: i, val: s.get('default') || '' }); + }); + }, [o, s]); + const j = (0, Pe.useCallback)( + (s) => { + i(s.target.value); + }, + [i] + ), + L = (0, Pe.useCallback)( + (s) => { + const i = s.target.getAttribute('data-variable'), + _ = s.target.value; + u({ server: o, key: i, val: _ }); + }, + [u, o] + ); + return Pe.createElement( + 'div', + { className: 'servers' }, + Pe.createElement( + 'label', + { htmlFor: 'servers' }, + Pe.createElement( + 'select', + { onChange: j, value: o, id: 'servers' }, + s + .valueSeq() + .map((s) => + Pe.createElement( + 'option', + { value: s.get('url'), key: s.get('url') }, + s.get('url'), + s.get('description') && ` - ${s.get('description')}` + ) + ) + .toArray() + ) + ), + C && + Pe.createElement( + 'div', + null, + Pe.createElement( + 'div', + { className: 'computed-url' }, + 'Computed URL:', + Pe.createElement('code', null, w(o)) + ), + Pe.createElement('h4', null, 'Server variables'), + Pe.createElement( + 'table', + null, + Pe.createElement( + 'tbody', + null, + x.entrySeq().map(([s, i]) => + Pe.createElement( + 'tr', + { key: s }, + Pe.createElement('td', null, s), + Pe.createElement( + 'td', + null, + i.get('enum') + ? Pe.createElement( + 'select', + { 'data-variable': s, onChange: L }, + i + .get('enum') + .map((i) => + Pe.createElement( + 'option', + { selected: i === _(o, s), key: i, value: i }, + i + ) + ) + ) + : Pe.createElement('input', { + type: 'text', + value: _(o, s) || '', + onChange: L, + 'data-variable': s + }) + ) + ) + ) + ) + ) + ) + ); + }; + class ServersContainer extends Pe.Component { + render() { + const { + specSelectors: s, + oas3Selectors: o, + oas3Actions: i, + getComponent: u + } = this.props, + _ = s.servers(), + w = u('Servers'); + return _ && _.size + ? Pe.createElement( + 'div', + null, + Pe.createElement('span', { className: 'servers-title' }, 'Servers'), + Pe.createElement(w, { + servers: _, + currentServer: o.selectedServer(), + setSelectedServer: i.setSelectedServer, + setServerVariableValue: i.setServerVariableValue, + getServerVariable: o.serverVariableValue, + getEffectiveServerValue: o.serverEffectiveValue + }) + ) + : null; + } + } + const tA = Function.prototype; + class RequestBodyEditor extends Pe.PureComponent { + static defaultProps = { onChange: tA, userHasEditedBody: !1 }; + constructor(s, o) { + super(s, o), + (this.state = { value: stringify(s.value) || s.defaultValue }), + s.onChange(s.value); + } + applyDefaultValue = (s) => { + const { onChange: o, defaultValue: i } = s || this.props; + return this.setState({ value: i }), o(i); + }; + onChange = (s) => { + this.props.onChange(stringify(s)); + }; + onDomChange = (s) => { + const o = s.target.value; + this.setState({ value: o }, () => this.onChange(o)); + }; + UNSAFE_componentWillReceiveProps(s) { + this.props.value !== s.value && + s.value !== this.state.value && + this.setState({ value: stringify(s.value) }), + !s.value && s.defaultValue && this.state.value && this.applyDefaultValue(s); + } + render() { + let { getComponent: s, errors: o } = this.props, + { value: i } = this.state, + u = o.size > 0; + const _ = s('TextArea'); + return Pe.createElement( + 'div', + { className: 'body-param' }, + Pe.createElement(_, { + className: Hn()('body-param__text', { invalid: u }), + title: o.size ? o.join(', ') : '', + value: i, + onChange: this.onDomChange + }) + ); + } + } + class HttpAuth extends Pe.Component { + constructor(s, o) { + super(s, o); + let { name: i, schema: u } = this.props, + _ = this.getValue(); + this.state = { name: i, schema: u, value: _ }; + } + getValue() { + let { name: s, authorized: o } = this.props; + return o && o.getIn([s, 'value']); + } + onChange = (s) => { + let { onChange: o } = this.props, + { value: i, name: u } = s.target, + _ = Object.assign({}, this.state.value); + u ? (_[u] = i) : (_ = i), this.setState({ value: _ }, () => o(this.state)); + }; + render() { + let { schema: s, getComponent: o, errSelectors: i, name: u } = this.props; + const _ = o('Input'), + w = o('Row'), + x = o('Col'), + C = o('authError'), + j = o('Markdown', !0), + L = o('JumpToPath', !0), + B = (s.get('scheme') || '').toLowerCase(); + let $ = this.getValue(), + V = i.allErrors().filter((s) => s.get('authId') === u); + if ('basic' === B) { + let o = $ ? $.get('username') : null; + return Pe.createElement( + 'div', + null, + Pe.createElement( + 'h4', + null, + Pe.createElement('code', null, u || s.get('name')), + '  (http, Basic)', + Pe.createElement(L, { path: ['securityDefinitions', u] }) + ), + o && Pe.createElement('h6', null, 'Authorized'), + Pe.createElement(w, null, Pe.createElement(j, { source: s.get('description') })), + Pe.createElement( + w, + null, + Pe.createElement('label', { htmlFor: 'auth-basic-username' }, 'Username:'), + o + ? Pe.createElement('code', null, ' ', o, ' ') + : Pe.createElement( + x, + null, + Pe.createElement(_, { + id: 'auth-basic-username', + type: 'text', + required: 'required', + name: 'username', + 'aria-label': 'auth-basic-username', + onChange: this.onChange, + autoFocus: !0 + }) + ) + ), + Pe.createElement( + w, + null, + Pe.createElement('label', { htmlFor: 'auth-basic-password' }, 'Password:'), + o + ? Pe.createElement('code', null, ' ****** ') + : Pe.createElement( + x, + null, + Pe.createElement(_, { + id: 'auth-basic-password', + autoComplete: 'new-password', + name: 'password', + type: 'password', + 'aria-label': 'auth-basic-password', + onChange: this.onChange + }) + ) + ), + V.valueSeq().map((s, o) => Pe.createElement(C, { error: s, key: o })) + ); + } + return 'bearer' === B + ? Pe.createElement( + 'div', + null, + Pe.createElement( + 'h4', + null, + Pe.createElement('code', null, u || s.get('name')), + '  (http, Bearer)', + Pe.createElement(L, { path: ['securityDefinitions', u] }) + ), + $ && Pe.createElement('h6', null, 'Authorized'), + Pe.createElement(w, null, Pe.createElement(j, { source: s.get('description') })), + Pe.createElement( + w, + null, + Pe.createElement('label', { htmlFor: 'auth-bearer-value' }, 'Value:'), + $ + ? Pe.createElement('code', null, ' ****** ') + : Pe.createElement( + x, + null, + Pe.createElement(_, { + id: 'auth-bearer-value', + type: 'text', + 'aria-label': 'auth-bearer-value', + onChange: this.onChange, + autoFocus: !0 + }) + ) + ), + V.valueSeq().map((s, o) => Pe.createElement(C, { error: s, key: o })) + ) + : Pe.createElement( + 'div', + null, + Pe.createElement( + 'em', + null, + Pe.createElement('b', null, u), + ' HTTP authentication: unsupported scheme ', + `'${B}'` + ) + ); + } + } + class operation_servers_OperationServers extends Pe.Component { + setSelectedServer = (s) => { + const { path: o, method: i } = this.props; + return this.forceUpdate(), this.props.setSelectedServer(s, `${o}:${i}`); + }; + setServerVariableValue = (s) => { + const { path: o, method: i } = this.props; + return ( + this.forceUpdate(), + this.props.setServerVariableValue({ ...s, namespace: `${o}:${i}` }) + ); + }; + getSelectedServer = () => { + const { path: s, method: o } = this.props; + return this.props.getSelectedServer(`${s}:${o}`); + }; + getServerVariable = (s, o) => { + const { path: i, method: u } = this.props; + return this.props.getServerVariable({ namespace: `${i}:${u}`, server: s }, o); + }; + getEffectiveServerValue = (s) => { + const { path: o, method: i } = this.props; + return this.props.getEffectiveServerValue({ server: s, namespace: `${o}:${i}` }); + }; + render() { + const { operationServers: s, pathServers: o, getComponent: i } = this.props; + if (!s && !o) return null; + const u = i('Servers'), + _ = s || o, + w = s ? 'operation' : 'path'; + return Pe.createElement( + 'div', + { className: 'opblock-section operation-servers' }, + Pe.createElement( + 'div', + { className: 'opblock-section-header' }, + Pe.createElement( + 'div', + { className: 'tab-header' }, + Pe.createElement('h4', { className: 'opblock-title' }, 'Servers') + ) + ), + Pe.createElement( + 'div', + { className: 'opblock-description-wrapper' }, + Pe.createElement( + 'h4', + { className: 'message' }, + 'These ', + w, + '-level options override the global server options.' + ), + Pe.createElement(u, { + servers: _, + currentServer: this.getSelectedServer(), + setSelectedServer: this.setSelectedServer, + setServerVariableValue: this.setServerVariableValue, + getServerVariable: this.getServerVariable, + getEffectiveServerValue: this.getEffectiveServerValue + }) + ) + ); + } + } + const rA = { + Callbacks: callbacks, + HttpAuth, + RequestBody: components_request_body, + Servers: components_servers, + ServersContainer, + RequestBodyEditor, + OperationServers: operation_servers_OperationServers, + operationLink: eA + }, + nA = new Remarkable('commonmark'); + nA.block.ruler.enable(['table']), nA.set({ linkTarget: '_blank' }); + const sA = OAS3ComponentWrapFactory( + ({ + source: s, + className: o = '', + getConfigs: i = () => ({ useUnsafeMarkdown: !1 }) + }) => { + if ('string' != typeof s) return null; + if (s) { + const { useUnsafeMarkdown: u } = i(), + _ = sanitizer(nA.render(s), { useUnsafeMarkdown: u }); + let w; + return ( + 'string' == typeof _ && (w = _.trim()), + Pe.createElement('div', { + dangerouslySetInnerHTML: { __html: w }, + className: Hn()(o, 'renderedMarkdown') + }) + ); + } + return null; + } + ), + oA = OAS3ComponentWrapFactory(({ Ori: s, ...o }) => { + const { + schema: i, + getComponent: u, + errSelectors: _, + authorized: w, + onAuthChange: x, + name: C + } = o, + j = u('HttpAuth'); + return 'http' === i.get('type') + ? Pe.createElement(j, { + key: C, + schema: i, + name: C, + errSelectors: _, + authorized: w, + getComponent: u, + onChange: x + }) + : Pe.createElement(s, o); + }), + iA = OAS3ComponentWrapFactory(OnlineValidatorBadge); + class ModelComponent extends Pe.Component { + render() { + let { getConfigs: s, schema: o, Ori: i } = this.props, + u = ['model-box'], + _ = null; + return ( + !0 === o.get('deprecated') && + (u.push('deprecated'), + (_ = Pe.createElement( + 'span', + { className: 'model-deprecated-warning' }, + 'Deprecated:' + ))), + Pe.createElement( + 'div', + { className: u.join(' ') }, + _, + Pe.createElement( + i, + Rn()({}, this.props, { + getConfigs: s, + depth: 1, + expandDepth: this.props.expandDepth || 0 + }) + ) + ) + ); + } + } + const aA = OAS3ComponentWrapFactory(ModelComponent), + lA = OAS3ComponentWrapFactory(({ Ori: s, ...o }) => { + const { schema: i, getComponent: u, errors: _, onChange: w } = o, + x = i && i.get ? i.get('format') : null, + C = i && i.get ? i.get('type') : null, + j = u('Input'); + return C && 'string' === C && x && ('binary' === x || 'base64' === x) + ? Pe.createElement(j, { + type: 'file', + className: _.length ? 'invalid' : '', + title: _.length ? _ : '', + onChange: (s) => { + w(s.target.files[0]); + }, + disabled: s.isDisabled + }) + : Pe.createElement(s, o); + }), + cA = { + Markdown: sA, + AuthItem: oA, + OpenAPIVersion: (function OAS30ComponentWrapFactory(s) { + return (o, i) => (u) => + 'function' == typeof i.specSelectors?.isOAS30 + ? i.specSelectors.isOAS30() + ? Pe.createElement(s, Rn()({}, u, i, { Ori: o })) + : Pe.createElement(o, u) + : (console.warn("OAS30 wrapper: couldn't get spec"), null); + })((s) => { + const { Ori: o } = s; + return Pe.createElement(o, { oasVersion: '3.0' }); + }), + JsonSchema_string: lA, + model: aA, + onlineValidatorBadge: iA + }, + uA = 'oas3_set_servers', + pA = 'oas3_set_request_body_value', + hA = 'oas3_set_request_body_retain_flag', + dA = 'oas3_set_request_body_inclusion', + fA = 'oas3_set_active_examples_member', + mA = 'oas3_set_request_content_type', + gA = 'oas3_set_response_content_type', + yA = 'oas3_set_server_variable_value', + vA = 'oas3_set_request_body_validate_error', + bA = 'oas3_clear_request_body_validate_error', + _A = 'oas3_clear_request_body_value'; + function setSelectedServer(s, o) { + return { type: uA, payload: { selectedServerUrl: s, namespace: o } }; + } + function setRequestBodyValue({ value: s, pathMethod: o }) { + return { type: pA, payload: { value: s, pathMethod: o } }; + } + const setRetainRequestBodyValueFlag = ({ value: s, pathMethod: o }) => ({ + type: hA, + payload: { value: s, pathMethod: o } + }); + function setRequestBodyInclusion({ value: s, pathMethod: o, name: i }) { + return { type: dA, payload: { value: s, pathMethod: o, name: i } }; + } + function setActiveExamplesMember({ + name: s, + pathMethod: o, + contextType: i, + contextName: u + }) { + return { type: fA, payload: { name: s, pathMethod: o, contextType: i, contextName: u } }; + } + function setRequestContentType({ value: s, pathMethod: o }) { + return { type: mA, payload: { value: s, pathMethod: o } }; + } + function setResponseContentType({ value: s, path: o, method: i }) { + return { type: gA, payload: { value: s, path: o, method: i } }; + } + function setServerVariableValue({ server: s, namespace: o, key: i, val: u }) { + return { type: yA, payload: { server: s, namespace: o, key: i, val: u } }; + } + const setRequestBodyValidateError = ({ path: s, method: o, validationErrors: i }) => ({ + type: vA, + payload: { path: s, method: o, validationErrors: i } + }), + clearRequestBodyValidateError = ({ path: s, method: o }) => ({ + type: bA, + payload: { path: s, method: o } + }), + initRequestBodyValidateError = ({ pathMethod: s }) => ({ + type: bA, + payload: { path: s[0], method: s[1] } + }), + clearRequestBodyValue = ({ pathMethod: s }) => ({ type: _A, payload: { pathMethod: s } }); + var EA = __webpack_require__(60680), + wA = __webpack_require__.n(EA); + const oas3_selectors_onlyOAS3 = + (s) => + (o, ...i) => + (u) => { + if (u.getSystem().specSelectors.isOAS3()) { + const _ = s(o, ...i); + return 'function' == typeof _ ? _(u) : _; + } + return null; + }; + const SA = oas3_selectors_onlyOAS3((s, o) => { + const i = o ? [o, 'selectedServer'] : ['selectedServer']; + return s.getIn(i) || ''; + }), + xA = oas3_selectors_onlyOAS3( + (s, o, i) => s.getIn(['requestData', o, i, 'bodyValue']) || null + ), + kA = oas3_selectors_onlyOAS3( + (s, o, i) => s.getIn(['requestData', o, i, 'retainBodyValue']) || !1 + ), + selectDefaultRequestBodyValue = (s, o, i) => (s) => { + const { oas3Selectors: u, specSelectors: _, fn: w } = s.getSystem(); + if (_.isOAS3()) { + const s = u.requestContentType(o, i); + if (s) + return getDefaultRequestBodyValue( + _.specResolvedSubtree(['paths', o, i, 'requestBody']), + s, + u.activeExamplesMember(o, i, 'requestBody', 'requestBody'), + w + ); + } + return null; + }, + CA = oas3_selectors_onlyOAS3((s, o, i) => (s) => { + const { oas3Selectors: u, specSelectors: _, fn: w } = s; + let x = !1; + const C = u.requestContentType(o, i); + let j = u.requestBodyValue(o, i); + const L = _.specResolvedSubtree(['paths', o, i, 'requestBody']); + if (!L) return !1; + if ( + (qe.Map.isMap(j) && + (j = stringify( + j.mapEntries((s) => (qe.Map.isMap(s[1]) ? [s[0], s[1].get('value')] : s)).toJS() + )), + qe.List.isList(j) && (j = stringify(j)), + C) + ) { + const s = getDefaultRequestBodyValue( + L, + C, + u.activeExamplesMember(o, i, 'requestBody', 'requestBody'), + w + ); + x = !!j && j !== s; + } + return x; + }), + OA = oas3_selectors_onlyOAS3( + (s, o, i) => s.getIn(['requestData', o, i, 'bodyInclusion']) || (0, qe.Map)() + ), + AA = oas3_selectors_onlyOAS3( + (s, o, i) => s.getIn(['requestData', o, i, 'errors']) || null + ), + jA = oas3_selectors_onlyOAS3( + (s, o, i, u, _) => s.getIn(['examples', o, i, u, _, 'activeExample']) || null + ), + IA = oas3_selectors_onlyOAS3( + (s, o, i) => s.getIn(['requestData', o, i, 'requestContentType']) || null + ), + PA = oas3_selectors_onlyOAS3( + (s, o, i) => s.getIn(['requestData', o, i, 'responseContentType']) || null + ), + MA = oas3_selectors_onlyOAS3((s, o, i) => { + let u; + if ('string' != typeof o) { + const { server: s, namespace: _ } = o; + u = _ ? [_, 'serverVariableValues', s, i] : ['serverVariableValues', s, i]; + } else { + u = ['serverVariableValues', o, i]; + } + return s.getIn(u) || null; + }), + TA = oas3_selectors_onlyOAS3((s, o) => { + let i; + if ('string' != typeof o) { + const { server: s, namespace: u } = o; + i = u ? [u, 'serverVariableValues', s] : ['serverVariableValues', s]; + } else { + i = ['serverVariableValues', o]; + } + return s.getIn(i) || (0, qe.OrderedMap)(); + }), + NA = oas3_selectors_onlyOAS3((s, o) => { + var i, u; + if ('string' != typeof o) { + const { server: _, namespace: w } = o; + (u = _), + (i = w + ? s.getIn([w, 'serverVariableValues', u]) + : s.getIn(['serverVariableValues', u])); + } else (u = o), (i = s.getIn(['serverVariableValues', u])); + i = i || (0, qe.OrderedMap)(); + let _ = u; + return ( + i.map((s, o) => { + _ = _.replace(new RegExp(`{${wA()(o)}}`, 'g'), s); + }), + _ + ); + }), + RA = (function validateRequestBodyIsRequired(s) { + return (...o) => + (i) => { + const u = i.getSystem().specSelectors.specJson(); + let _ = [...o][1] || []; + return !u.getIn(['paths', ..._, 'requestBody', 'required']) || s(...o); + }; + })((s, o) => + ((s, o) => ((o = o || []), !!s.getIn(['requestData', ...o, 'bodyValue'])))(s, o) + ), + validateShallowRequired = ( + s, + { + oas3RequiredRequestBodyContentType: o, + oas3RequestContentType: i, + oas3RequestBodyValue: u + } + ) => { + let _ = []; + if (!qe.Map.isMap(u)) return _; + let w = []; + return ( + Object.keys(o.requestContentType).forEach((s) => { + if (s === i) { + o.requestContentType[s].forEach((s) => { + w.indexOf(s) < 0 && w.push(s); + }); + } + }), + w.forEach((s) => { + u.getIn([s, 'value']) || _.push(s); + }), + _ + ); + }, + DA = Ss()(['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace']), + LA = { + [uA]: (s, { payload: { selectedServerUrl: o, namespace: i } }) => { + const u = i ? [i, 'selectedServer'] : ['selectedServer']; + return s.setIn(u, o); + }, + [pA]: (s, { payload: { value: o, pathMethod: i } }) => { + let [u, _] = i; + if (!qe.Map.isMap(o)) return s.setIn(['requestData', u, _, 'bodyValue'], o); + let w, + x = s.getIn(['requestData', u, _, 'bodyValue']) || (0, qe.Map)(); + qe.Map.isMap(x) || (x = (0, qe.Map)()); + const [...C] = o.keys(); + return ( + C.forEach((s) => { + let i = o.getIn([s]); + (x.has(s) && qe.Map.isMap(i)) || (w = x.setIn([s, 'value'], i)); + }), + s.setIn(['requestData', u, _, 'bodyValue'], w) + ); + }, + [hA]: (s, { payload: { value: o, pathMethod: i } }) => { + let [u, _] = i; + return s.setIn(['requestData', u, _, 'retainBodyValue'], o); + }, + [dA]: (s, { payload: { value: o, pathMethod: i, name: u } }) => { + let [_, w] = i; + return s.setIn(['requestData', _, w, 'bodyInclusion', u], o); + }, + [fA]: (s, { payload: { name: o, pathMethod: i, contextType: u, contextName: _ } }) => { + let [w, x] = i; + return s.setIn(['examples', w, x, u, _, 'activeExample'], o); + }, + [mA]: (s, { payload: { value: o, pathMethod: i } }) => { + let [u, _] = i; + return s.setIn(['requestData', u, _, 'requestContentType'], o); + }, + [gA]: (s, { payload: { value: o, path: i, method: u } }) => + s.setIn(['requestData', i, u, 'responseContentType'], o), + [yA]: (s, { payload: { server: o, namespace: i, key: u, val: _ } }) => { + const w = i ? [i, 'serverVariableValues', o, u] : ['serverVariableValues', o, u]; + return s.setIn(w, _); + }, + [vA]: (s, { payload: { path: o, method: i, validationErrors: u } }) => { + let _ = []; + if ((_.push('Required field is not provided'), u.missingBodyValue)) + return s.setIn(['requestData', o, i, 'errors'], (0, qe.fromJS)(_)); + if (u.missingRequiredKeys && u.missingRequiredKeys.length > 0) { + const { missingRequiredKeys: w } = u; + return s.updateIn(['requestData', o, i, 'bodyValue'], (0, qe.fromJS)({}), (s) => + w.reduce((s, o) => s.setIn([o, 'errors'], (0, qe.fromJS)(_)), s) + ); + } + return console.warn('unexpected result: SET_REQUEST_BODY_VALIDATE_ERROR'), s; + }, + [bA]: (s, { payload: { path: o, method: i } }) => { + const u = s.getIn(['requestData', o, i, 'bodyValue']); + if (!qe.Map.isMap(u)) + return s.setIn(['requestData', o, i, 'errors'], (0, qe.fromJS)([])); + const [..._] = u.keys(); + return _ + ? s.updateIn(['requestData', o, i, 'bodyValue'], (0, qe.fromJS)({}), (s) => + _.reduce((s, o) => s.setIn([o, 'errors'], (0, qe.fromJS)([])), s) + ) + : s; + }, + [_A]: (s, { payload: { pathMethod: o } }) => { + let [i, u] = o; + const _ = s.getIn(['requestData', i, u, 'bodyValue']); + return _ + ? qe.Map.isMap(_) + ? s.setIn(['requestData', i, u, 'bodyValue'], (0, qe.Map)()) + : s.setIn(['requestData', i, u, 'bodyValue'], '') + : s; + } + }; + function oas3() { + return { + components: rA, + wrapComponents: cA, + statePlugins: { + spec: { wrapSelectors: be, selectors: we }, + auth: { wrapSelectors: _e }, + oas3: { actions: { ...Se }, reducers: LA, selectors: { ...xe } } + } + }; + } + const webhooks = ({ specSelectors: s, getComponent: o }) => { + const i = s.selectWebhooksOperations(), + u = Object.keys(i), + _ = o('OperationContainer', !0); + return 0 === u.length + ? null + : Pe.createElement( + 'div', + { className: 'webhooks' }, + Pe.createElement('h2', null, 'Webhooks'), + u.map((s) => + Pe.createElement( + 'div', + { key: `${s}-webhook` }, + i[s].map((o) => + Pe.createElement(_, { + key: `${s}-${o.method}-webhook`, + op: o.operation, + tag: 'webhooks', + method: o.method, + path: s, + specPath: (0, qe.List)(o.specPath), + allowTryItOut: !1 + }) + ) + ) + ) + ); + }, + oas31_components_license = ({ getComponent: s, specSelectors: o }) => { + const i = o.selectLicenseNameField(), + u = o.selectLicenseUrl(), + _ = s('Link'); + return Pe.createElement( + 'div', + { className: 'info__license' }, + u + ? Pe.createElement( + 'div', + { className: 'info__license__url' }, + Pe.createElement(_, { target: '_blank', href: sanitizeUrl(u) }, i) + ) + : Pe.createElement('span', null, i) + ); + }, + oas31_components_contact = ({ getComponent: s, specSelectors: o }) => { + const i = o.selectContactNameField(), + u = o.selectContactUrl(), + _ = o.selectContactEmailField(), + w = s('Link'); + return Pe.createElement( + 'div', + { className: 'info__contact' }, + u && + Pe.createElement( + 'div', + null, + Pe.createElement(w, { href: sanitizeUrl(u), target: '_blank' }, i, ' - Website') + ), + _ && + Pe.createElement( + w, + { href: sanitizeUrl(`mailto:${_}`) }, + u ? `Send email to ${i}` : `Contact ${i}` + ) + ); + }, + oas31_components_info = ({ getComponent: s, specSelectors: o }) => { + const i = o.version(), + u = o.url(), + _ = o.basePath(), + w = o.host(), + x = o.selectInfoSummaryField(), + C = o.selectInfoDescriptionField(), + j = o.selectInfoTitleField(), + L = o.selectInfoTermsOfServiceUrl(), + B = o.selectExternalDocsUrl(), + $ = o.selectExternalDocsDescriptionField(), + V = o.contact(), + U = o.license(), + z = s('Markdown', !0), + Y = s('Link'), + Z = s('VersionStamp'), + ee = s('OpenAPIVersion'), + ie = s('InfoUrl'), + ae = s('InfoBasePath'), + le = s('License', !0), + ce = s('Contact', !0), + pe = s('JsonSchemaDialect', !0); + return Pe.createElement( + 'div', + { className: 'info' }, + Pe.createElement( + 'hgroup', + { className: 'main' }, + Pe.createElement( + 'h2', + { className: 'title' }, + j, + Pe.createElement( + 'span', + null, + i && Pe.createElement(Z, { version: i }), + Pe.createElement(ee, { oasVersion: '3.1' }) + ) + ), + (w || _) && Pe.createElement(ae, { host: w, basePath: _ }), + u && Pe.createElement(ie, { getComponent: s, url: u }) + ), + x && Pe.createElement('p', { className: 'info__summary' }, x), + Pe.createElement( + 'div', + { className: 'info__description description' }, + Pe.createElement(z, { source: C }) + ), + L && + Pe.createElement( + 'div', + { className: 'info__tos' }, + Pe.createElement( + Y, + { target: '_blank', href: sanitizeUrl(L) }, + 'Terms of service' + ) + ), + V.size > 0 && Pe.createElement(ce, null), + U.size > 0 && Pe.createElement(le, null), + B && + Pe.createElement( + Y, + { className: 'info__extdocs', target: '_blank', href: sanitizeUrl(B) }, + $ || B + ), + Pe.createElement(pe, null) + ); + }, + json_schema_dialect = ({ getComponent: s, specSelectors: o }) => { + const i = o.selectJsonSchemaDialectField(), + u = o.selectJsonSchemaDialectDefault(), + _ = s('Link'); + return Pe.createElement( + Pe.Fragment, + null, + i && + i === u && + Pe.createElement( + 'p', + { className: 'info__jsonschemadialect' }, + 'JSON Schema dialect:', + ' ', + Pe.createElement(_, { target: '_blank', href: sanitizeUrl(i) }, i) + ), + i && + i !== u && + Pe.createElement( + 'div', + { className: 'error-wrapper' }, + Pe.createElement( + 'div', + { className: 'no-margin' }, + Pe.createElement( + 'div', + { className: 'errors' }, + Pe.createElement( + 'div', + { className: 'errors-wrapper' }, + Pe.createElement('h4', { className: 'center' }, 'Warning'), + Pe.createElement( + 'p', + { className: 'message' }, + Pe.createElement('strong', null, 'OpenAPI.jsonSchemaDialect'), + ' field contains a value different from the default value of', + ' ', + Pe.createElement(_, { target: '_blank', href: u }, u), + '. Values different from the default one are currently not supported. Please either omit the field or provide it with the default value.' + ) + ) + ) + ) + ) + ); + }, + version_pragma_filter = ({ + bypass: s, + isSwagger2: o, + isOAS3: i, + isOAS31: u, + alsoShow: _, + children: w + }) => + s + ? Pe.createElement('div', null, w) + : o && (i || u) + ? Pe.createElement( + 'div', + { className: 'version-pragma' }, + _, + Pe.createElement( + 'div', + { className: 'version-pragma__message version-pragma__message--ambiguous' }, + Pe.createElement( + 'div', + null, + Pe.createElement('h3', null, 'Unable to render this definition'), + Pe.createElement( + 'p', + null, + Pe.createElement('code', null, 'swagger'), + ' and ', + Pe.createElement('code', null, 'openapi'), + ' fields cannot be present in the same Swagger or OpenAPI definition. Please remove one of the fields.' + ), + Pe.createElement( + 'p', + null, + 'Supported version fields are ', + Pe.createElement('code', null, 'swagger: "2.0"'), + ' and those that match ', + Pe.createElement('code', null, 'openapi: 3.x.y'), + ' (for example,', + ' ', + Pe.createElement('code', null, 'openapi: 3.1.0'), + ').' + ) + ) + ) + ) + : o || i || u + ? Pe.createElement('div', null, w) + : Pe.createElement( + 'div', + { className: 'version-pragma' }, + _, + Pe.createElement( + 'div', + { className: 'version-pragma__message version-pragma__message--missing' }, + Pe.createElement( + 'div', + null, + Pe.createElement('h3', null, 'Unable to render this definition'), + Pe.createElement( + 'p', + null, + 'The provided definition does not specify a valid version field.' + ), + Pe.createElement( + 'p', + null, + 'Please indicate a valid Swagger or OpenAPI version field. Supported version fields are ', + Pe.createElement('code', null, 'swagger: "2.0"'), + ' and those that match ', + Pe.createElement('code', null, 'openapi: 3.x.y'), + ' (for example,', + ' ', + Pe.createElement('code', null, 'openapi: 3.1.0'), + ').' + ) + ) + ) + ), + getModelName = (s) => + 'string' == typeof s && s.includes('#/components/schemas/') + ? ((s) => { + const o = s.replace(/~1/g, '/').replace(/~0/g, '~'); + try { + return decodeURIComponent(o); + } catch { + return o; + } + })(s.replace(/^.*#\/components\/schemas\//, '')) + : null, + BA = (0, Pe.forwardRef)(({ schema: s, getComponent: o, onToggle: i = () => {} }, u) => { + const _ = o('JSONSchema202012'), + w = getModelName(s.get('$$ref')), + x = (0, Pe.useCallback)( + (s, o) => { + i(w, o); + }, + [w, i] + ); + return Pe.createElement(_, { name: w, schema: s.toJS(), ref: u, onExpand: x }); + }), + FA = BA, + models = ({ + specActions: s, + specSelectors: o, + layoutSelectors: i, + layoutActions: u, + getComponent: _, + getConfigs: w, + fn: x + }) => { + const C = o.selectSchemas(), + j = Object.keys(C).length > 0, + L = ['components', 'schemas'], + { docExpansion: B, defaultModelsExpandDepth: $ } = w(), + V = $ > 0 && 'none' !== B, + U = i.isShown(L, V), + z = _('Collapse'), + Y = _('JSONSchema202012'), + Z = _('ArrowUpIcon'), + ee = _('ArrowDownIcon'), + { getTitle: ie } = x.jsonSchema202012.useFn(); + (0, Pe.useEffect)(() => { + const i = U && $ > 1, + u = null != o.specResolvedSubtree(L); + i && !u && s.requestResolvedSubtree(L); + }, [U, $]); + const ae = (0, Pe.useCallback)(() => { + u.show(L, !U); + }, [U]), + le = (0, Pe.useCallback)((s) => { + null !== s && u.readyToScroll(L, s); + }, []), + handleJSONSchema202012Ref = (s) => (o) => { + null !== o && u.readyToScroll([...L, s], o); + }, + handleJSONSchema202012Expand = (i) => (u, _) => { + if (_) { + const u = [...L, i]; + null != o.specResolvedSubtree(u) || s.requestResolvedSubtree([...L, i]); + } + }; + return !j || $ < 0 + ? null + : Pe.createElement( + 'section', + { className: Hn()('models', { 'is-open': U }), ref: le }, + Pe.createElement( + 'h4', + null, + Pe.createElement( + 'button', + { 'aria-expanded': U, className: 'models-control', onClick: ae }, + Pe.createElement('span', null, 'Schemas'), + U ? Pe.createElement(Z, null) : Pe.createElement(ee, null) + ) + ), + Pe.createElement( + z, + { isOpened: U }, + Object.entries(C).map(([s, o]) => { + const i = ie(o, { lookup: 'basic' }) || s; + return Pe.createElement(Y, { + key: s, + ref: handleJSONSchema202012Ref(s), + schema: o, + name: i, + onExpand: handleJSONSchema202012Expand(s) + }); + }) + ) + ); + }, + mutual_tls_auth = ({ schema: s, getComponent: o }) => { + const i = o('JumpToPath', !0); + return Pe.createElement( + 'div', + null, + Pe.createElement( + 'h4', + null, + s.get('name'), + ' (mutualTLS)', + ' ', + Pe.createElement(i, { path: ['securityDefinitions', s.get('name')] }) + ), + Pe.createElement( + 'p', + null, + 'Mutual TLS is required by this API/Operation. Certificates are managed via your Operating System and/or your browser.' + ), + Pe.createElement('p', null, s.get('description')) + ); + }; + class auths_Auths extends Pe.Component { + constructor(s, o) { + super(s, o), (this.state = {}); + } + onAuthChange = (s) => { + let { name: o } = s; + this.setState({ [o]: s }); + }; + submitAuth = (s) => { + s.preventDefault(); + let { authActions: o } = this.props; + o.authorizeWithPersistOption(this.state); + }; + logoutClick = (s) => { + s.preventDefault(); + let { authActions: o, definitions: i } = this.props, + u = i.map((s, o) => o).toArray(); + this.setState(u.reduce((s, o) => ((s[o] = ''), s), {})), o.logoutWithPersistOption(u); + }; + close = (s) => { + s.preventDefault(); + let { authActions: o } = this.props; + o.showDefinitions(!1); + }; + render() { + let { definitions: s, getComponent: o, authSelectors: i, errSelectors: u } = this.props; + const _ = o('AuthItem'), + w = o('oauth2', !0), + x = o('Button'), + C = i.authorized(), + j = s.filter((s, o) => !!C.get(o)), + L = s.filter((s) => 'oauth2' !== s.get('type') && 'mutualTLS' !== s.get('type')), + B = s.filter((s) => 'oauth2' === s.get('type')), + $ = s.filter((s) => 'mutualTLS' === s.get('type')); + return Pe.createElement( + 'div', + { className: 'auth-container' }, + L.size > 0 && + Pe.createElement( + 'form', + { onSubmit: this.submitAuth }, + L.map((s, i) => + Pe.createElement(_, { + key: i, + schema: s, + name: i, + getComponent: o, + onAuthChange: this.onAuthChange, + authorized: C, + errSelectors: u + }) + ).toArray(), + Pe.createElement( + 'div', + { className: 'auth-btn-wrapper' }, + L.size === j.size + ? Pe.createElement( + x, + { + className: 'btn modal-btn auth', + onClick: this.logoutClick, + 'aria-label': 'Remove authorization' + }, + 'Logout' + ) + : Pe.createElement( + x, + { + type: 'submit', + className: 'btn modal-btn auth authorize', + 'aria-label': 'Apply credentials' + }, + 'Authorize' + ), + Pe.createElement( + x, + { className: 'btn modal-btn auth btn-done', onClick: this.close }, + 'Close' + ) + ) + ), + B.size > 0 + ? Pe.createElement( + 'div', + null, + Pe.createElement( + 'div', + { className: 'scope-def' }, + Pe.createElement( + 'p', + null, + 'Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes.' + ), + Pe.createElement( + 'p', + null, + 'API requires the following scopes. Select which ones you want to grant to Swagger UI.' + ) + ), + s + .filter((s) => 'oauth2' === s.get('type')) + .map((s, o) => + Pe.createElement( + 'div', + { key: o }, + Pe.createElement(w, { authorized: C, schema: s, name: o }) + ) + ) + .toArray() + ) + : null, + $.size > 0 && + Pe.createElement( + 'div', + null, + $.map((s, i) => + Pe.createElement(_, { + key: i, + schema: s, + name: i, + getComponent: o, + onAuthChange: this.onAuthChange, + authorized: C, + errSelectors: u + }) + ).toArray() + ) + ); + } + } + const qA = auths_Auths, + isOAS31 = (s) => { + const o = s.get('openapi'); + return 'string' == typeof o && /^3\.1\.(?:[1-9]\d*|0)$/.test(o); + }, + fn_createOnlyOAS31Selector = + (s) => + (o, ...i) => + (u) => { + if (u.getSystem().specSelectors.isOAS31()) { + const _ = s(o, ...i); + return 'function' == typeof _ ? _(u) : _; + } + return null; + }, + createOnlyOAS31SelectorWrapper = + (s) => + (o, i) => + (u, ..._) => { + if (i.getSystem().specSelectors.isOAS31()) { + const w = s(u, ..._); + return 'function' == typeof w ? w(o, i) : w; + } + return o(..._); + }, + fn_createSystemSelector = + (s) => + (o, ...i) => + (u) => { + const _ = s(o, u, ...i); + return 'function' == typeof _ ? _(u) : _; + }, + createOnlyOAS31ComponentWrapper = (s) => (o, i) => (u) => + i.specSelectors.isOAS31() + ? Pe.createElement(s, Rn()({}, u, { originalComponent: o, getSystem: i.getSystem })) + : Pe.createElement(o, u), + $A = createOnlyOAS31ComponentWrapper(({ getSystem: s }) => { + const o = s().getComponent('OAS31License', !0); + return Pe.createElement(o, null); + }), + VA = createOnlyOAS31ComponentWrapper(({ getSystem: s }) => { + const o = s().getComponent('OAS31Contact', !0); + return Pe.createElement(o, null); + }), + UA = createOnlyOAS31ComponentWrapper(({ getSystem: s }) => { + const o = s().getComponent('OAS31Info', !0); + return Pe.createElement(o, null); + }), + zA = createOnlyOAS31ComponentWrapper(({ getSystem: s, ...o }) => { + const i = s(), + { getComponent: u, fn: _, getConfigs: w } = i, + x = w(), + C = u('OAS31Model'), + j = u('JSONSchema202012'), + L = u('JSONSchema202012Keyword$schema'), + B = u('JSONSchema202012Keyword$vocabulary'), + $ = u('JSONSchema202012Keyword$id'), + V = u('JSONSchema202012Keyword$anchor'), + U = u('JSONSchema202012Keyword$dynamicAnchor'), + z = u('JSONSchema202012Keyword$ref'), + Y = u('JSONSchema202012Keyword$dynamicRef'), + Z = u('JSONSchema202012Keyword$defs'), + ee = u('JSONSchema202012Keyword$comment'), + ie = u('JSONSchema202012KeywordAllOf'), + ae = u('JSONSchema202012KeywordAnyOf'), + le = u('JSONSchema202012KeywordOneOf'), + ce = u('JSONSchema202012KeywordNot'), + pe = u('JSONSchema202012KeywordIf'), + de = u('JSONSchema202012KeywordThen'), + fe = u('JSONSchema202012KeywordElse'), + ye = u('JSONSchema202012KeywordDependentSchemas'), + be = u('JSONSchema202012KeywordPrefixItems'), + _e = u('JSONSchema202012KeywordItems'), + we = u('JSONSchema202012KeywordContains'), + Se = u('JSONSchema202012KeywordProperties'), + xe = u('JSONSchema202012KeywordPatternProperties'), + Te = u('JSONSchema202012KeywordAdditionalProperties'), + Re = u('JSONSchema202012KeywordPropertyNames'), + qe = u('JSONSchema202012KeywordUnevaluatedItems'), + $e = u('JSONSchema202012KeywordUnevaluatedProperties'), + ze = u('JSONSchema202012KeywordType'), + We = u('JSONSchema202012KeywordEnum'), + He = u('JSONSchema202012KeywordConst'), + Ye = u('JSONSchema202012KeywordConstraint'), + Xe = u('JSONSchema202012KeywordDependentRequired'), + Qe = u('JSONSchema202012KeywordContentSchema'), + et = u('JSONSchema202012KeywordTitle'), + tt = u('JSONSchema202012KeywordDescription'), + rt = u('JSONSchema202012KeywordDefault'), + nt = u('JSONSchema202012KeywordDeprecated'), + st = u('JSONSchema202012KeywordReadOnly'), + ot = u('JSONSchema202012KeywordWriteOnly'), + it = u('JSONSchema202012Accordion'), + at = u('JSONSchema202012ExpandDeepButton'), + lt = u('JSONSchema202012ChevronRightIcon'), + ct = u('withJSONSchema202012Context')(C, { + config: { + default$schema: 'https://spec.openapis.org/oas/3.1/dialect/base', + defaultExpandedLevels: x.defaultModelExpandDepth, + includeReadOnly: Boolean(o.includeReadOnly), + includeWriteOnly: Boolean(o.includeWriteOnly) + }, + components: { + JSONSchema: j, + Keyword$schema: L, + Keyword$vocabulary: B, + Keyword$id: $, + Keyword$anchor: V, + Keyword$dynamicAnchor: U, + Keyword$ref: z, + Keyword$dynamicRef: Y, + Keyword$defs: Z, + Keyword$comment: ee, + KeywordAllOf: ie, + KeywordAnyOf: ae, + KeywordOneOf: le, + KeywordNot: ce, + KeywordIf: pe, + KeywordThen: de, + KeywordElse: fe, + KeywordDependentSchemas: ye, + KeywordPrefixItems: be, + KeywordItems: _e, + KeywordContains: we, + KeywordProperties: Se, + KeywordPatternProperties: xe, + KeywordAdditionalProperties: Te, + KeywordPropertyNames: Re, + KeywordUnevaluatedItems: qe, + KeywordUnevaluatedProperties: $e, + KeywordType: ze, + KeywordEnum: We, + KeywordConst: He, + KeywordConstraint: Ye, + KeywordDependentRequired: Xe, + KeywordContentSchema: Qe, + KeywordTitle: et, + KeywordDescription: tt, + KeywordDefault: rt, + KeywordDeprecated: nt, + KeywordReadOnly: st, + KeywordWriteOnly: ot, + Accordion: it, + ExpandDeepButton: at, + ChevronRightIcon: lt + }, + fn: { + upperFirst: _.upperFirst, + isExpandable: _.jsonSchema202012.isExpandable, + getProperties: _.jsonSchema202012.getProperties + } + }); + return Pe.createElement(ct, o); + }), + WA = zA, + KA = createOnlyOAS31ComponentWrapper(({ getSystem: s }) => { + const { getComponent: o, fn: i, getConfigs: u } = s(), + _ = u(); + if (KA.ModelsWithJSONSchemaContext) + return Pe.createElement(KA.ModelsWithJSONSchemaContext, null); + const w = o('OAS31Models', !0), + x = o('JSONSchema202012'), + C = o('JSONSchema202012Keyword$schema'), + j = o('JSONSchema202012Keyword$vocabulary'), + L = o('JSONSchema202012Keyword$id'), + B = o('JSONSchema202012Keyword$anchor'), + $ = o('JSONSchema202012Keyword$dynamicAnchor'), + V = o('JSONSchema202012Keyword$ref'), + U = o('JSONSchema202012Keyword$dynamicRef'), + z = o('JSONSchema202012Keyword$defs'), + Y = o('JSONSchema202012Keyword$comment'), + Z = o('JSONSchema202012KeywordAllOf'), + ee = o('JSONSchema202012KeywordAnyOf'), + ie = o('JSONSchema202012KeywordOneOf'), + ae = o('JSONSchema202012KeywordNot'), + le = o('JSONSchema202012KeywordIf'), + ce = o('JSONSchema202012KeywordThen'), + pe = o('JSONSchema202012KeywordElse'), + de = o('JSONSchema202012KeywordDependentSchemas'), + fe = o('JSONSchema202012KeywordPrefixItems'), + ye = o('JSONSchema202012KeywordItems'), + be = o('JSONSchema202012KeywordContains'), + _e = o('JSONSchema202012KeywordProperties'), + we = o('JSONSchema202012KeywordPatternProperties'), + Se = o('JSONSchema202012KeywordAdditionalProperties'), + xe = o('JSONSchema202012KeywordPropertyNames'), + Te = o('JSONSchema202012KeywordUnevaluatedItems'), + Re = o('JSONSchema202012KeywordUnevaluatedProperties'), + qe = o('JSONSchema202012KeywordType'), + $e = o('JSONSchema202012KeywordEnum'), + ze = o('JSONSchema202012KeywordConst'), + We = o('JSONSchema202012KeywordConstraint'), + He = o('JSONSchema202012KeywordDependentRequired'), + Ye = o('JSONSchema202012KeywordContentSchema'), + Xe = o('JSONSchema202012KeywordTitle'), + Qe = o('JSONSchema202012KeywordDescription'), + et = o('JSONSchema202012KeywordDefault'), + tt = o('JSONSchema202012KeywordDeprecated'), + rt = o('JSONSchema202012KeywordReadOnly'), + nt = o('JSONSchema202012KeywordWriteOnly'), + st = o('JSONSchema202012Accordion'), + ot = o('JSONSchema202012ExpandDeepButton'), + it = o('JSONSchema202012ChevronRightIcon'), + at = o('withJSONSchema202012Context'); + return ( + (KA.ModelsWithJSONSchemaContext = at(w, { + config: { + default$schema: 'https://spec.openapis.org/oas/3.1/dialect/base', + defaultExpandedLevels: _.defaultModelsExpandDepth - 1, + includeReadOnly: !0, + includeWriteOnly: !0 + }, + components: { + JSONSchema: x, + Keyword$schema: C, + Keyword$vocabulary: j, + Keyword$id: L, + Keyword$anchor: B, + Keyword$dynamicAnchor: $, + Keyword$ref: V, + Keyword$dynamicRef: U, + Keyword$defs: z, + Keyword$comment: Y, + KeywordAllOf: Z, + KeywordAnyOf: ee, + KeywordOneOf: ie, + KeywordNot: ae, + KeywordIf: le, + KeywordThen: ce, + KeywordElse: pe, + KeywordDependentSchemas: de, + KeywordPrefixItems: fe, + KeywordItems: ye, + KeywordContains: be, + KeywordProperties: _e, + KeywordPatternProperties: we, + KeywordAdditionalProperties: Se, + KeywordPropertyNames: xe, + KeywordUnevaluatedItems: Te, + KeywordUnevaluatedProperties: Re, + KeywordType: qe, + KeywordEnum: $e, + KeywordConst: ze, + KeywordConstraint: We, + KeywordDependentRequired: He, + KeywordContentSchema: Ye, + KeywordTitle: Xe, + KeywordDescription: Qe, + KeywordDefault: et, + KeywordDeprecated: tt, + KeywordReadOnly: rt, + KeywordWriteOnly: nt, + Accordion: st, + ExpandDeepButton: ot, + ChevronRightIcon: it + }, + fn: { + upperFirst: i.upperFirst, + isExpandable: i.jsonSchema202012.isExpandable, + getProperties: i.jsonSchema202012.getProperties + } + })), + Pe.createElement(KA.ModelsWithJSONSchemaContext, null) + ); + }); + KA.ModelsWithJSONSchemaContext = null; + const HA = KA, + wrap_components_version_pragma_filter = (s, o) => (s) => { + const i = o.specSelectors.isOAS31(), + u = o.getComponent('OAS31VersionPragmaFilter'); + return Pe.createElement(u, Rn()({ isOAS31: i }, s)); + }, + JA = createOnlyOAS31ComponentWrapper(({ originalComponent: s, ...o }) => { + const { getComponent: i, schema: u } = o, + _ = i('MutualTLSAuth', !0); + return 'mutualTLS' === u.get('type') + ? Pe.createElement(_, { schema: u }) + : Pe.createElement(s, o); + }), + GA = JA, + YA = createOnlyOAS31ComponentWrapper(({ getSystem: s, ...o }) => { + const i = s().getComponent('OAS31Auths', !0); + return Pe.createElement(i, o); + }), + XA = (0, qe.Map)(), + ZA = Ut((s, o) => o.specSelectors.specJson(), isOAS31), + selectors_webhooks = () => (s) => { + const o = s.specSelectors.specJson().get('webhooks'); + return qe.Map.isMap(o) ? o : XA; + }, + QA = Ut( + [ + (s, o) => o.specSelectors.webhooks(), + (s, o) => o.specSelectors.validOperationMethods(), + (s, o) => o.specSelectors.specResolvedSubtree(['webhooks']) + ], + (s, o) => + s + .reduce( + (s, i, u) => { + if (!qe.Map.isMap(i)) return s; + const _ = i + .entrySeq() + .filter(([s]) => o.includes(s)) + .map(([s, o]) => ({ + operation: (0, qe.Map)({ operation: o }), + method: s, + path: u, + specPath: ['webhooks', u, s] + })); + return s.concat(_); + }, + (0, qe.List)() + ) + .groupBy((s) => s.path) + .map((s) => s.toArray()) + .toObject() + ), + selectors_license = () => (s) => { + const o = s.specSelectors.info().get('license'); + return qe.Map.isMap(o) ? o : XA; + }, + selectLicenseNameField = () => (s) => s.specSelectors.license().get('name', 'License'), + selectLicenseUrlField = () => (s) => s.specSelectors.license().get('url'), + ej = Ut( + [ + (s, o) => o.specSelectors.url(), + (s, o) => o.oas3Selectors.selectedServer(), + (s, o) => o.specSelectors.selectLicenseUrlField() + ], + (s, o, i) => { + if (i) return safeBuildUrl(i, s, { selectedServer: o }); + } + ), + selectLicenseIdentifierField = () => (s) => s.specSelectors.license().get('identifier'), + selectors_contact = () => (s) => { + const o = s.specSelectors.info().get('contact'); + return qe.Map.isMap(o) ? o : XA; + }, + selectContactNameField = () => (s) => + s.specSelectors.contact().get('name', 'the developer'), + selectContactEmailField = () => (s) => s.specSelectors.contact().get('email'), + selectContactUrlField = () => (s) => s.specSelectors.contact().get('url'), + fj = Ut( + [ + (s, o) => o.specSelectors.url(), + (s, o) => o.oas3Selectors.selectedServer(), + (s, o) => o.specSelectors.selectContactUrlField() + ], + (s, o, i) => { + if (i) return safeBuildUrl(i, s, { selectedServer: o }); + } + ), + selectInfoTitleField = () => (s) => s.specSelectors.info().get('title'), + selectInfoSummaryField = () => (s) => s.specSelectors.info().get('summary'), + selectInfoDescriptionField = () => (s) => s.specSelectors.info().get('description'), + selectInfoTermsOfServiceField = () => (s) => s.specSelectors.info().get('termsOfService'), + mj = Ut( + [ + (s, o) => o.specSelectors.url(), + (s, o) => o.oas3Selectors.selectedServer(), + (s, o) => o.specSelectors.selectInfoTermsOfServiceField() + ], + (s, o, i) => { + if (i) return safeBuildUrl(i, s, { selectedServer: o }); + } + ), + selectExternalDocsDescriptionField = () => (s) => + s.specSelectors.externalDocs().get('description'), + selectExternalDocsUrlField = () => (s) => s.specSelectors.externalDocs().get('url'), + _j = Ut( + [ + (s, o) => o.specSelectors.url(), + (s, o) => o.oas3Selectors.selectedServer(), + (s, o) => o.specSelectors.selectExternalDocsUrlField() + ], + (s, o, i) => { + if (i) return safeBuildUrl(i, s, { selectedServer: o }); + } + ), + selectJsonSchemaDialectField = () => (s) => + s.specSelectors.specJson().get('jsonSchemaDialect'), + selectJsonSchemaDialectDefault = () => 'https://spec.openapis.org/oas/3.1/dialect/base', + Cj = Ut( + (s, o) => o.specSelectors.definitions(), + (s, o) => o.specSelectors.specResolvedSubtree(['components', 'schemas']), + (s, o) => + qe.Map.isMap(s) + ? qe.Map.isMap(o) + ? Object.entries(s.toJS()).reduce((s, [i, u]) => { + const _ = o.get(i); + return (s[i] = _?.toJS() || u), s; + }, {}) + : s.toJS() + : {} + ), + wrap_selectors_isOAS3 = + (s, o) => + (i, ...u) => + o.specSelectors.isOAS31() || s(...u), + Aj = createOnlyOAS31SelectorWrapper(() => (s, o) => o.oas31Selectors.selectLicenseUrl()), + Nj = createOnlyOAS31SelectorWrapper(() => (s, o) => { + const i = o.specSelectors.securityDefinitions(); + let u = s(); + return i + ? (i.entrySeq().forEach(([s, o]) => { + 'mutualTLS' === o.get('type') && (u = u.push(new qe.Map({ [s]: o }))); + }), + u) + : u; + }), + Bj = Ut( + [ + (s, o) => o.specSelectors.url(), + (s, o) => o.oas3Selectors.selectedServer(), + (s, o) => o.specSelectors.selectLicenseUrlField(), + (s, o) => o.specSelectors.selectLicenseIdentifierField() + ], + (s, o, i, u) => + i + ? safeBuildUrl(i, s, { selectedServer: o }) + : u + ? `https://spdx.org/licenses/${u}.html` + : void 0 + ), + keywords_Example = ({ schema: s, getSystem: o }) => { + const { fn: i } = o(), + { hasKeyword: u, stringify: _ } = i.jsonSchema202012.useFn(); + return u(s, 'example') + ? Pe.createElement( + 'div', + { className: 'json-schema-2020-12-keyword json-schema-2020-12-keyword--example' }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary' + }, + 'Example' + ), + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--const' + }, + _(s.example) + ) + ) + : null; + }, + keywords_Xml = ({ schema: s, getSystem: o }) => { + const i = s?.xml || {}, + { fn: u, getComponent: _ } = o(), + { useIsExpandedDeeply: w, useComponent: x } = u.jsonSchema202012, + C = w(), + j = !!(i.name || i.namespace || i.prefix), + [L, B] = (0, Pe.useState)(C), + [$, V] = (0, Pe.useState)(!1), + U = x('Accordion'), + z = x('ExpandDeepButton'), + Y = _('JSONSchema202012DeepExpansionContext')(), + Z = (0, Pe.useCallback)(() => { + B((s) => !s); + }, []), + ee = (0, Pe.useCallback)((s, o) => { + B(o), V(o); + }, []); + return 0 === Object.keys(i).length + ? null + : Pe.createElement( + Y.Provider, + { value: $ }, + Pe.createElement( + 'div', + { className: 'json-schema-2020-12-keyword json-schema-2020-12-keyword--xml' }, + j + ? Pe.createElement( + Pe.Fragment, + null, + Pe.createElement( + U, + { expanded: L, onChange: Z }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary' + }, + 'XML' + ) + ), + Pe.createElement(z, { expanded: L, onClick: ee }) + ) + : Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary' + }, + 'XML' + ), + !0 === i.attribute && + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12__attribute json-schema-2020-12__attribute--muted' + }, + 'attribute' + ), + !0 === i.wrapped && + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12__attribute json-schema-2020-12__attribute--muted' + }, + 'wrapped' + ), + Pe.createElement( + 'strong', + { + className: + 'json-schema-2020-12__attribute json-schema-2020-12__attribute--primary' + }, + 'object' + ), + Pe.createElement( + 'ul', + { + className: Hn()('json-schema-2020-12-keyword__children', { + 'json-schema-2020-12-keyword__children--collapsed': !L + }) + }, + L && + Pe.createElement( + Pe.Fragment, + null, + i.name && + Pe.createElement( + 'li', + { className: 'json-schema-2020-12-property' }, + Pe.createElement( + 'div', + { + className: + 'json-schema-2020-12-keyword json-schema-2020-12-keyword' + }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary' + }, + 'name' + ), + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary' + }, + i.name + ) + ) + ), + i.namespace && + Pe.createElement( + 'li', + { className: 'json-schema-2020-12-property' }, + Pe.createElement( + 'div', + { className: 'json-schema-2020-12-keyword' }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary' + }, + 'namespace' + ), + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary' + }, + i.namespace + ) + ) + ), + i.prefix && + Pe.createElement( + 'li', + { className: 'json-schema-2020-12-property' }, + Pe.createElement( + 'div', + { className: 'json-schema-2020-12-keyword' }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary' + }, + 'prefix' + ), + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary' + }, + i.prefix + ) + ) + ) + ) + ) + ) + ); + }, + Discriminator_DiscriminatorMapping = ({ discriminator: s }) => { + const o = s?.mapping || {}; + return 0 === Object.keys(o).length + ? null + : Object.entries(o).map(([s, o]) => + Pe.createElement( + 'div', + { key: `${s}-${o}`, className: 'json-schema-2020-12-keyword' }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary' + }, + s + ), + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary' + }, + o + ) + ) + ); + }, + keywords_Discriminator_Discriminator = ({ schema: s, getSystem: o }) => { + const i = s?.discriminator || {}, + { fn: u, getComponent: _ } = o(), + { useIsExpandedDeeply: w, useComponent: x } = u.jsonSchema202012, + C = w(), + j = !!i.mapping, + [L, B] = (0, Pe.useState)(C), + [$, V] = (0, Pe.useState)(!1), + U = x('Accordion'), + z = x('ExpandDeepButton'), + Y = _('JSONSchema202012DeepExpansionContext')(), + Z = (0, Pe.useCallback)(() => { + B((s) => !s); + }, []), + ee = (0, Pe.useCallback)((s, o) => { + B(o), V(o); + }, []); + return 0 === Object.keys(i).length + ? null + : Pe.createElement( + Y.Provider, + { value: $ }, + Pe.createElement( + 'div', + { + className: + 'json-schema-2020-12-keyword json-schema-2020-12-keyword--discriminator' + }, + j + ? Pe.createElement( + Pe.Fragment, + null, + Pe.createElement( + U, + { expanded: L, onChange: Z }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary' + }, + 'Discriminator' + ) + ), + Pe.createElement(z, { expanded: L, onClick: ee }) + ) + : Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary' + }, + 'Discriminator' + ), + i.propertyName && + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12__attribute json-schema-2020-12__attribute--muted' + }, + i.propertyName + ), + Pe.createElement( + 'strong', + { + className: + 'json-schema-2020-12__attribute json-schema-2020-12__attribute--primary' + }, + 'object' + ), + Pe.createElement( + 'ul', + { + className: Hn()('json-schema-2020-12-keyword__children', { + 'json-schema-2020-12-keyword__children--collapsed': !L + }) + }, + L && + Pe.createElement( + 'li', + { className: 'json-schema-2020-12-property' }, + Pe.createElement(Discriminator_DiscriminatorMapping, { discriminator: i }) + ) + ) + ) + ); + }, + keywords_ExternalDocs = ({ schema: s, getSystem: o }) => { + const i = s?.externalDocs || {}, + { fn: u, getComponent: _ } = o(), + { useIsExpandedDeeply: w, useComponent: x } = u.jsonSchema202012, + C = w(), + j = !(!i.description && !i.url), + [L, B] = (0, Pe.useState)(C), + [$, V] = (0, Pe.useState)(!1), + U = x('Accordion'), + z = x('ExpandDeepButton'), + Y = _('JSONSchema202012KeywordDescription'), + Z = _('Link'), + ee = _('JSONSchema202012DeepExpansionContext')(), + ie = (0, Pe.useCallback)(() => { + B((s) => !s); + }, []), + ae = (0, Pe.useCallback)((s, o) => { + B(o), V(o); + }, []); + return 0 === Object.keys(i).length + ? null + : Pe.createElement( + ee.Provider, + { value: $ }, + Pe.createElement( + 'div', + { + className: + 'json-schema-2020-12-keyword json-schema-2020-12-keyword--externalDocs' + }, + j + ? Pe.createElement( + Pe.Fragment, + null, + Pe.createElement( + U, + { expanded: L, onChange: ie }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary' + }, + 'External documentation' + ) + ), + Pe.createElement(z, { expanded: L, onClick: ae }) + ) + : Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary' + }, + 'External documentation' + ), + Pe.createElement( + 'strong', + { + className: + 'json-schema-2020-12__attribute json-schema-2020-12__attribute--primary' + }, + 'object' + ), + Pe.createElement( + 'ul', + { + className: Hn()('json-schema-2020-12-keyword__children', { + 'json-schema-2020-12-keyword__children--collapsed': !L + }) + }, + L && + Pe.createElement( + Pe.Fragment, + null, + i.description && + Pe.createElement( + 'li', + { className: 'json-schema-2020-12-property' }, + Pe.createElement(Y, { schema: i, getSystem: o }) + ), + i.url && + Pe.createElement( + 'li', + { className: 'json-schema-2020-12-property' }, + Pe.createElement( + 'div', + { + className: + 'json-schema-2020-12-keyword json-schema-2020-12-keyword' + }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary' + }, + 'url' + ), + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary' + }, + Pe.createElement( + Z, + { target: '_blank', href: sanitizeUrl(i.url) }, + i.url + ) + ) + ) + ) + ) + ) + ) + ); + }, + keywords_Description = ({ schema: s, getSystem: o }) => { + if (!s?.description) return null; + const { getComponent: i } = o(), + u = i('Markdown'); + return Pe.createElement( + 'div', + { className: 'json-schema-2020-12-keyword json-schema-2020-12-keyword--description' }, + Pe.createElement( + 'div', + { + className: + 'json-schema-2020-12-core-keyword__value json-schema-2020-12-core-keyword__value--secondary' + }, + Pe.createElement(u, { source: s.description }) + ) + ); + }, + $j = createOnlyOAS31ComponentWrapper(keywords_Description), + zj = createOnlyOAS31ComponentWrapper( + ({ schema: s, getSystem: o, originalComponent: i }) => { + const { getComponent: u } = o(), + _ = u('JSONSchema202012KeywordDiscriminator'), + w = u('JSONSchema202012KeywordXml'), + x = u('JSONSchema202012KeywordExample'), + C = u('JSONSchema202012KeywordExternalDocs'); + return Pe.createElement( + Pe.Fragment, + null, + Pe.createElement(i, { schema: s }), + Pe.createElement(_, { schema: s, getSystem: o }), + Pe.createElement(w, { schema: s, getSystem: o }), + Pe.createElement(C, { schema: s, getSystem: o }), + Pe.createElement(x, { schema: s, getSystem: o }) + ); + } + ), + Kj = zj, + keywords_Properties = ({ schema: s, getSystem: o }) => { + const { fn: i } = o(), + { useComponent: u } = i.jsonSchema202012, + { getDependentRequired: _, getProperties: w } = i.jsonSchema202012.useFn(), + x = i.jsonSchema202012.useConfig(), + C = Array.isArray(s?.required) ? s.required : [], + j = u('JSONSchema'), + L = w(s, x); + return 0 === Object.keys(L).length + ? null + : Pe.createElement( + 'div', + { + className: 'json-schema-2020-12-keyword json-schema-2020-12-keyword--properties' + }, + Pe.createElement( + 'ul', + null, + Object.entries(L).map(([o, i]) => { + const u = C.includes(o), + w = _(o, s); + return Pe.createElement( + 'li', + { + key: o, + className: Hn()('json-schema-2020-12-property', { + 'json-schema-2020-12-property--required': u + }) + }, + Pe.createElement(j, { name: o, schema: i, dependentRequired: w }) + ); + }) + ) + ); + }, + Jj = createOnlyOAS31ComponentWrapper(keywords_Properties), + getProperties = (s, { includeReadOnly: o, includeWriteOnly: i }) => { + if (!s?.properties) return {}; + const u = Object.entries(s.properties).filter( + ([, s]) => (!(!0 === s?.readOnly) || o) && (!(!0 === s?.writeOnly) || i) + ); + return Object.fromEntries(u); + }; + const Gj = function oas31_after_load_afterLoad({ fn: s, getSystem: o }) { + if (s.jsonSchema202012) { + const i = ((s, o) => { + const { fn: i } = o(); + if ('function' != typeof s) return null; + const { hasKeyword: u } = i.jsonSchema202012; + return (o) => + s(o) || u(o, 'example') || o?.xml || o?.discriminator || o?.externalDocs; + })(s.jsonSchema202012.isExpandable, o); + Object.assign(this.fn.jsonSchema202012, { isExpandable: i, getProperties }); + } + if ('function' == typeof s.sampleFromSchema && s.jsonSchema202012) { + const i = ((s, o) => { + const { fn: i, specSelectors: u } = o; + return Object.fromEntries( + Object.entries(s).map(([s, o]) => { + const _ = i[s]; + return [ + s, + (...s) => (u.isOAS31() ? o(...s) : 'function' == typeof _ ? _(...s) : void 0) + ]; + }) + ); + })( + { + sampleFromSchema: s.jsonSchema202012.sampleFromSchema, + sampleFromSchemaGeneric: s.jsonSchema202012.sampleFromSchemaGeneric, + createXMLExample: s.jsonSchema202012.createXMLExample, + memoizedSampleFromSchema: s.jsonSchema202012.memoizedSampleFromSchema, + memoizedCreateXMLExample: s.jsonSchema202012.memoizedCreateXMLExample, + getJsonSampleSchema: s.jsonSchema202012.getJsonSampleSchema, + getYamlSampleSchema: s.jsonSchema202012.getYamlSampleSchema, + getXmlSampleSchema: s.jsonSchema202012.getXmlSampleSchema, + getSampleSchema: s.jsonSchema202012.getSampleSchema, + mergeJsonSchema: s.jsonSchema202012.mergeJsonSchema + }, + o() + ); + Object.assign(this.fn, i); + } + }, + oas31 = ({ fn: s }) => { + const o = s.createSystemSelector || fn_createSystemSelector, + i = s.createOnlyOAS31Selector || fn_createOnlyOAS31Selector; + return { + afterLoad: Gj, + fn: { + isOAS31, + createSystemSelector: fn_createSystemSelector, + createOnlyOAS31Selector: fn_createOnlyOAS31Selector + }, + components: { + Webhooks: webhooks, + JsonSchemaDialect: json_schema_dialect, + MutualTLSAuth: mutual_tls_auth, + OAS31Info: oas31_components_info, + OAS31License: oas31_components_license, + OAS31Contact: oas31_components_contact, + OAS31VersionPragmaFilter: version_pragma_filter, + OAS31Model: FA, + OAS31Models: models, + OAS31Auths: qA, + JSONSchema202012KeywordExample: keywords_Example, + JSONSchema202012KeywordXml: keywords_Xml, + JSONSchema202012KeywordDiscriminator: keywords_Discriminator_Discriminator, + JSONSchema202012KeywordExternalDocs: keywords_ExternalDocs + }, + wrapComponents: { + InfoContainer: UA, + License: $A, + Contact: VA, + VersionPragmaFilter: wrap_components_version_pragma_filter, + Model: WA, + Models: HA, + AuthItem: GA, + auths: YA, + JSONSchema202012KeywordDescription: $j, + JSONSchema202012KeywordDefault: Kj, + JSONSchema202012KeywordProperties: Jj + }, + statePlugins: { + auth: { wrapSelectors: { definitionsToAuthorize: Nj } }, + spec: { + selectors: { + isOAS31: o(ZA), + license: selectors_license, + selectLicenseNameField, + selectLicenseUrlField, + selectLicenseIdentifierField: i(selectLicenseIdentifierField), + selectLicenseUrl: o(ej), + contact: selectors_contact, + selectContactNameField, + selectContactEmailField, + selectContactUrlField, + selectContactUrl: o(fj), + selectInfoTitleField, + selectInfoSummaryField: i(selectInfoSummaryField), + selectInfoDescriptionField, + selectInfoTermsOfServiceField, + selectInfoTermsOfServiceUrl: o(mj), + selectExternalDocsDescriptionField, + selectExternalDocsUrlField, + selectExternalDocsUrl: o(_j), + webhooks: i(selectors_webhooks), + selectWebhooksOperations: i(o(QA)), + selectJsonSchemaDialectField, + selectJsonSchemaDialectDefault, + selectSchemas: o(Cj) + }, + wrapSelectors: { isOAS3: wrap_selectors_isOAS3, selectLicenseUrl: Aj } + }, + oas31: { selectors: { selectLicenseUrl: i(o(Bj)) } } + } + }; + }, + Xj = ts().object, + eI = ts().bool, + tI = (ts().oneOfType([Xj, eI]), (0, Pe.createContext)(null)); + tI.displayName = 'JSONSchemaContext'; + const rI = (0, Pe.createContext)(0); + rI.displayName = 'JSONSchemaLevelContext'; + const nI = (0, Pe.createContext)(!1); + nI.displayName = 'JSONSchemaDeepExpansionContext'; + const sI = (0, Pe.createContext)(new Set()), + useConfig = () => { + const { config: s } = (0, Pe.useContext)(tI); + return s; + }, + useComponent = (s) => { + const { components: o } = (0, Pe.useContext)(tI); + return o[s] || null; + }, + useFn = (s = void 0) => { + const { fn: o } = (0, Pe.useContext)(tI); + return void 0 !== s ? o[s] : o; + }, + useLevel = () => { + const s = (0, Pe.useContext)(rI); + return [s, s + 1]; + }, + useIsExpanded = () => { + const [s] = useLevel(), + { defaultExpandedLevels: o } = useConfig(); + return o - s > 0; + }, + useIsExpandedDeeply = () => (0, Pe.useContext)(nI), + useRenderedSchemas = (s = void 0) => { + if (void 0 === s) return (0, Pe.useContext)(sI); + const o = (0, Pe.useContext)(sI); + return new Set([...o, s]); + }, + oI = (0, Pe.forwardRef)( + ({ schema: s, name: o = '', dependentRequired: i = [], onExpand: u = () => {} }, _) => { + const w = useFn(), + x = useIsExpanded(), + C = useIsExpandedDeeply(), + [j, L] = (0, Pe.useState)(x || C), + [B, $] = (0, Pe.useState)(C), + [V, U] = useLevel(), + z = (() => { + const [s] = useLevel(); + return s > 0; + })(), + Y = w.isExpandable(s) || i.length > 0, + Z = ((s) => useRenderedSchemas().has(s))(s), + ee = useRenderedSchemas(s), + ie = w.stringifyConstraints(s), + ae = useComponent('Accordion'), + le = useComponent('Keyword$schema'), + ce = useComponent('Keyword$vocabulary'), + pe = useComponent('Keyword$id'), + de = useComponent('Keyword$anchor'), + fe = useComponent('Keyword$dynamicAnchor'), + ye = useComponent('Keyword$ref'), + be = useComponent('Keyword$dynamicRef'), + _e = useComponent('Keyword$defs'), + we = useComponent('Keyword$comment'), + Se = useComponent('KeywordAllOf'), + xe = useComponent('KeywordAnyOf'), + Te = useComponent('KeywordOneOf'), + Re = useComponent('KeywordNot'), + qe = useComponent('KeywordIf'), + $e = useComponent('KeywordThen'), + ze = useComponent('KeywordElse'), + We = useComponent('KeywordDependentSchemas'), + He = useComponent('KeywordPrefixItems'), + Ye = useComponent('KeywordItems'), + Xe = useComponent('KeywordContains'), + Qe = useComponent('KeywordProperties'), + et = useComponent('KeywordPatternProperties'), + tt = useComponent('KeywordAdditionalProperties'), + rt = useComponent('KeywordPropertyNames'), + nt = useComponent('KeywordUnevaluatedItems'), + st = useComponent('KeywordUnevaluatedProperties'), + ot = useComponent('KeywordType'), + it = useComponent('KeywordEnum'), + at = useComponent('KeywordConst'), + lt = useComponent('KeywordConstraint'), + ct = useComponent('KeywordDependentRequired'), + ut = useComponent('KeywordContentSchema'), + pt = useComponent('KeywordTitle'), + ht = useComponent('KeywordDescription'), + dt = useComponent('KeywordDefault'), + mt = useComponent('KeywordDeprecated'), + gt = useComponent('KeywordReadOnly'), + yt = useComponent('KeywordWriteOnly'), + vt = useComponent('ExpandDeepButton'); + (0, Pe.useEffect)(() => { + $(C); + }, [C]), + (0, Pe.useEffect)(() => { + $(B); + }, [B]); + const bt = (0, Pe.useCallback)( + (s, o) => { + L(o), !o && $(!1), u(s, o, !1); + }, + [u] + ), + _t = (0, Pe.useCallback)( + (s, o) => { + L(o), $(o), u(s, o, !0); + }, + [u] + ); + return Pe.createElement( + rI.Provider, + { value: U }, + Pe.createElement( + nI.Provider, + { value: B }, + Pe.createElement( + sI.Provider, + { value: ee }, + Pe.createElement( + 'article', + { + ref: _, + 'data-json-schema-level': V, + className: Hn()('json-schema-2020-12', { + 'json-schema-2020-12--embedded': z, + 'json-schema-2020-12--circular': Z + }) + }, + Pe.createElement( + 'div', + { className: 'json-schema-2020-12-head' }, + Y && !Z + ? Pe.createElement( + Pe.Fragment, + null, + Pe.createElement( + ae, + { expanded: j, onChange: bt }, + Pe.createElement(pt, { title: o, schema: s }) + ), + Pe.createElement(vt, { expanded: j, onClick: _t }) + ) + : Pe.createElement(pt, { title: o, schema: s }), + Pe.createElement(mt, { schema: s }), + Pe.createElement(gt, { schema: s }), + Pe.createElement(yt, { schema: s }), + Pe.createElement(ot, { schema: s, isCircular: Z }), + ie.length > 0 && + ie.map((s) => + Pe.createElement(lt, { key: `${s.scope}-${s.value}`, constraint: s }) + ) + ), + Pe.createElement( + 'div', + { + className: Hn()('json-schema-2020-12-body', { + 'json-schema-2020-12-body--collapsed': !j + }) + }, + j && + Pe.createElement( + Pe.Fragment, + null, + Pe.createElement(ht, { schema: s }), + !Z && + Y && + Pe.createElement( + Pe.Fragment, + null, + Pe.createElement(Qe, { schema: s }), + Pe.createElement(et, { schema: s }), + Pe.createElement(tt, { schema: s }), + Pe.createElement(st, { schema: s }), + Pe.createElement(rt, { schema: s }), + Pe.createElement(Se, { schema: s }), + Pe.createElement(xe, { schema: s }), + Pe.createElement(Te, { schema: s }), + Pe.createElement(Re, { schema: s }), + Pe.createElement(qe, { schema: s }), + Pe.createElement($e, { schema: s }), + Pe.createElement(ze, { schema: s }), + Pe.createElement(We, { schema: s }), + Pe.createElement(He, { schema: s }), + Pe.createElement(Ye, { schema: s }), + Pe.createElement(nt, { schema: s }), + Pe.createElement(Xe, { schema: s }), + Pe.createElement(ut, { schema: s }) + ), + Pe.createElement(it, { schema: s }), + Pe.createElement(at, { schema: s }), + Pe.createElement(ct, { schema: s, dependentRequired: i }), + Pe.createElement(dt, { schema: s }), + Pe.createElement(le, { schema: s }), + Pe.createElement(ce, { schema: s }), + Pe.createElement(pe, { schema: s }), + Pe.createElement(de, { schema: s }), + Pe.createElement(fe, { schema: s }), + Pe.createElement(ye, { schema: s }), + !Z && Y && Pe.createElement(_e, { schema: s }), + Pe.createElement(be, { schema: s }), + Pe.createElement(we, { schema: s }) + ) + ) + ) + ) + ) + ); + } + ), + iI = oI, + keywords_$schema = ({ schema: s }) => + s?.$schema + ? Pe.createElement( + 'div', + { className: 'json-schema-2020-12-keyword json-schema-2020-12-keyword--$schema' }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary' + }, + '$schema' + ), + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary' + }, + s.$schema + ) + ) + : null, + $vocabulary_$vocabulary = ({ schema: s }) => { + const o = useIsExpanded(), + i = useIsExpandedDeeply(), + [u, _] = (0, Pe.useState)(o || i), + w = useComponent('Accordion'), + x = (0, Pe.useCallback)(() => { + _((s) => !s); + }, []); + return s?.$vocabulary + ? 'object' != typeof s.$vocabulary + ? null + : Pe.createElement( + 'div', + { + className: + 'json-schema-2020-12-keyword json-schema-2020-12-keyword--$vocabulary' + }, + Pe.createElement( + w, + { expanded: u, onChange: x }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary' + }, + '$vocabulary' + ) + ), + Pe.createElement( + 'strong', + { + className: + 'json-schema-2020-12__attribute json-schema-2020-12__attribute--primary' + }, + 'object' + ), + Pe.createElement( + 'ul', + null, + u && + Object.entries(s.$vocabulary).map(([s, o]) => + Pe.createElement( + 'li', + { + key: s, + className: Hn()('json-schema-2020-12-$vocabulary-uri', { + 'json-schema-2020-12-$vocabulary-uri--disabled': !o + }) + }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary' + }, + s + ) + ) + ) + ) + ) + : null; + }, + keywords_$id = ({ schema: s }) => + s?.$id + ? Pe.createElement( + 'div', + { className: 'json-schema-2020-12-keyword json-schema-2020-12-keyword--$id' }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary' + }, + '$id' + ), + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary' + }, + s.$id + ) + ) + : null, + keywords_$anchor = ({ schema: s }) => + s?.$anchor + ? Pe.createElement( + 'div', + { className: 'json-schema-2020-12-keyword json-schema-2020-12-keyword--$anchor' }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary' + }, + '$anchor' + ), + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary' + }, + s.$anchor + ) + ) + : null, + keywords_$dynamicAnchor = ({ schema: s }) => + s?.$dynamicAnchor + ? Pe.createElement( + 'div', + { + className: + 'json-schema-2020-12-keyword json-schema-2020-12-keyword--$dynamicAnchor' + }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary' + }, + '$dynamicAnchor' + ), + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary' + }, + s.$dynamicAnchor + ) + ) + : null, + keywords_$ref = ({ schema: s }) => + s?.$ref + ? Pe.createElement( + 'div', + { className: 'json-schema-2020-12-keyword json-schema-2020-12-keyword--$ref' }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary' + }, + '$ref' + ), + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary' + }, + s.$ref + ) + ) + : null, + keywords_$dynamicRef = ({ schema: s }) => + s?.$dynamicRef + ? Pe.createElement( + 'div', + { + className: + 'json-schema-2020-12-keyword json-schema-2020-12-keyword--$dynamicRef' + }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary' + }, + '$dynamicRef' + ), + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary' + }, + s.$dynamicRef + ) + ) + : null, + keywords_$defs = ({ schema: s }) => { + const o = s?.$defs || {}, + i = useIsExpanded(), + u = useIsExpandedDeeply(), + [_, w] = (0, Pe.useState)(i || u), + [x, C] = (0, Pe.useState)(!1), + j = useComponent('Accordion'), + L = useComponent('ExpandDeepButton'), + B = useComponent('JSONSchema'), + $ = (0, Pe.useCallback)(() => { + w((s) => !s); + }, []), + V = (0, Pe.useCallback)((s, o) => { + w(o), C(o); + }, []); + return 0 === Object.keys(o).length + ? null + : Pe.createElement( + nI.Provider, + { value: x }, + Pe.createElement( + 'div', + { className: 'json-schema-2020-12-keyword json-schema-2020-12-keyword--$defs' }, + Pe.createElement( + j, + { expanded: _, onChange: $ }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary' + }, + '$defs' + ) + ), + Pe.createElement(L, { expanded: _, onClick: V }), + Pe.createElement( + 'strong', + { + className: + 'json-schema-2020-12__attribute json-schema-2020-12__attribute--primary' + }, + 'object' + ), + Pe.createElement( + 'ul', + { + className: Hn()('json-schema-2020-12-keyword__children', { + 'json-schema-2020-12-keyword__children--collapsed': !_ + }) + }, + _ && + Pe.createElement( + Pe.Fragment, + null, + Object.entries(o).map(([s, o]) => + Pe.createElement( + 'li', + { key: s, className: 'json-schema-2020-12-property' }, + Pe.createElement(B, { name: s, schema: o }) + ) + ) + ) + ) + ) + ); + }, + keywords_$comment = ({ schema: s }) => + s?.$comment + ? Pe.createElement( + 'div', + { + className: 'json-schema-2020-12-keyword json-schema-2020-12-keyword--$comment' + }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary' + }, + '$comment' + ), + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary' + }, + s.$comment + ) + ) + : null, + keywords_AllOf = ({ schema: s }) => { + const o = s?.allOf || [], + i = useFn(), + u = useIsExpanded(), + _ = useIsExpandedDeeply(), + [w, x] = (0, Pe.useState)(u || _), + [C, j] = (0, Pe.useState)(!1), + L = useComponent('Accordion'), + B = useComponent('ExpandDeepButton'), + $ = useComponent('JSONSchema'), + V = useComponent('KeywordType'), + U = (0, Pe.useCallback)(() => { + x((s) => !s); + }, []), + z = (0, Pe.useCallback)((s, o) => { + x(o), j(o); + }, []); + return Array.isArray(o) && 0 !== o.length + ? Pe.createElement( + nI.Provider, + { value: C }, + Pe.createElement( + 'div', + { className: 'json-schema-2020-12-keyword json-schema-2020-12-keyword--allOf' }, + Pe.createElement( + L, + { expanded: w, onChange: U }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary' + }, + 'All of' + ) + ), + Pe.createElement(B, { expanded: w, onClick: z }), + Pe.createElement(V, { schema: { allOf: o } }), + Pe.createElement( + 'ul', + { + className: Hn()('json-schema-2020-12-keyword__children', { + 'json-schema-2020-12-keyword__children--collapsed': !w + }) + }, + w && + Pe.createElement( + Pe.Fragment, + null, + o.map((s, o) => + Pe.createElement( + 'li', + { key: `#${o}`, className: 'json-schema-2020-12-property' }, + Pe.createElement($, { name: `#${o} ${i.getTitle(s)}`, schema: s }) + ) + ) + ) + ) + ) + ) + : null; + }, + keywords_AnyOf = ({ schema: s }) => { + const o = s?.anyOf || [], + i = useFn(), + u = useIsExpanded(), + _ = useIsExpandedDeeply(), + [w, x] = (0, Pe.useState)(u || _), + [C, j] = (0, Pe.useState)(!1), + L = useComponent('Accordion'), + B = useComponent('ExpandDeepButton'), + $ = useComponent('JSONSchema'), + V = useComponent('KeywordType'), + U = (0, Pe.useCallback)(() => { + x((s) => !s); + }, []), + z = (0, Pe.useCallback)((s, o) => { + x(o), j(o); + }, []); + return Array.isArray(o) && 0 !== o.length + ? Pe.createElement( + nI.Provider, + { value: C }, + Pe.createElement( + 'div', + { className: 'json-schema-2020-12-keyword json-schema-2020-12-keyword--anyOf' }, + Pe.createElement( + L, + { expanded: w, onChange: U }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary' + }, + 'Any of' + ) + ), + Pe.createElement(B, { expanded: w, onClick: z }), + Pe.createElement(V, { schema: { anyOf: o } }), + Pe.createElement( + 'ul', + { + className: Hn()('json-schema-2020-12-keyword__children', { + 'json-schema-2020-12-keyword__children--collapsed': !w + }) + }, + w && + Pe.createElement( + Pe.Fragment, + null, + o.map((s, o) => + Pe.createElement( + 'li', + { key: `#${o}`, className: 'json-schema-2020-12-property' }, + Pe.createElement($, { name: `#${o} ${i.getTitle(s)}`, schema: s }) + ) + ) + ) + ) + ) + ) + : null; + }, + keywords_OneOf = ({ schema: s }) => { + const o = s?.oneOf || [], + i = useFn(), + u = useIsExpanded(), + _ = useIsExpandedDeeply(), + [w, x] = (0, Pe.useState)(u || _), + [C, j] = (0, Pe.useState)(!1), + L = useComponent('Accordion'), + B = useComponent('ExpandDeepButton'), + $ = useComponent('JSONSchema'), + V = useComponent('KeywordType'), + U = (0, Pe.useCallback)(() => { + x((s) => !s); + }, []), + z = (0, Pe.useCallback)((s, o) => { + x(o), j(o); + }, []); + return Array.isArray(o) && 0 !== o.length + ? Pe.createElement( + nI.Provider, + { value: C }, + Pe.createElement( + 'div', + { className: 'json-schema-2020-12-keyword json-schema-2020-12-keyword--oneOf' }, + Pe.createElement( + L, + { expanded: w, onChange: U }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary' + }, + 'One of' + ) + ), + Pe.createElement(B, { expanded: w, onClick: z }), + Pe.createElement(V, { schema: { oneOf: o } }), + Pe.createElement( + 'ul', + { + className: Hn()('json-schema-2020-12-keyword__children', { + 'json-schema-2020-12-keyword__children--collapsed': !w + }) + }, + w && + Pe.createElement( + Pe.Fragment, + null, + o.map((s, o) => + Pe.createElement( + 'li', + { key: `#${o}`, className: 'json-schema-2020-12-property' }, + Pe.createElement($, { name: `#${o} ${i.getTitle(s)}`, schema: s }) + ) + ) + ) + ) + ) + ) + : null; + }, + keywords_Not = ({ schema: s }) => { + const o = useFn(), + i = useComponent('JSONSchema'); + if (!o.hasKeyword(s, 'not')) return null; + const u = Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary' + }, + 'Not' + ); + return Pe.createElement( + 'div', + { className: 'json-schema-2020-12-keyword json-schema-2020-12-keyword--not' }, + Pe.createElement(i, { name: u, schema: s.not }) + ); + }, + keywords_If = ({ schema: s }) => { + const o = useFn(), + i = useComponent('JSONSchema'); + if (!o.hasKeyword(s, 'if')) return null; + const u = Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary' + }, + 'If' + ); + return Pe.createElement( + 'div', + { className: 'json-schema-2020-12-keyword json-schema-2020-12-keyword--if' }, + Pe.createElement(i, { name: u, schema: s.if }) + ); + }, + keywords_Then = ({ schema: s }) => { + const o = useFn(), + i = useComponent('JSONSchema'); + if (!o.hasKeyword(s, 'then')) return null; + const u = Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary' + }, + 'Then' + ); + return Pe.createElement( + 'div', + { className: 'json-schema-2020-12-keyword json-schema-2020-12-keyword--then' }, + Pe.createElement(i, { name: u, schema: s.then }) + ); + }, + keywords_Else = ({ schema: s }) => { + const o = useFn(), + i = useComponent('JSONSchema'); + if (!o.hasKeyword(s, 'else')) return null; + const u = Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary' + }, + 'Else' + ); + return Pe.createElement( + 'div', + { className: 'json-schema-2020-12-keyword json-schema-2020-12-keyword--if' }, + Pe.createElement(i, { name: u, schema: s.else }) + ); + }, + keywords_DependentSchemas = ({ schema: s }) => { + const o = s?.dependentSchemas || [], + i = useIsExpanded(), + u = useIsExpandedDeeply(), + [_, w] = (0, Pe.useState)(i || u), + [x, C] = (0, Pe.useState)(!1), + j = useComponent('Accordion'), + L = useComponent('ExpandDeepButton'), + B = useComponent('JSONSchema'), + $ = (0, Pe.useCallback)(() => { + w((s) => !s); + }, []), + V = (0, Pe.useCallback)((s, o) => { + w(o), C(o); + }, []); + return 'object' != typeof o || 0 === Object.keys(o).length + ? null + : Pe.createElement( + nI.Provider, + { value: x }, + Pe.createElement( + 'div', + { + className: + 'json-schema-2020-12-keyword json-schema-2020-12-keyword--dependentSchemas' + }, + Pe.createElement( + j, + { expanded: _, onChange: $ }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary' + }, + 'Dependent schemas' + ) + ), + Pe.createElement(L, { expanded: _, onClick: V }), + Pe.createElement( + 'strong', + { + className: + 'json-schema-2020-12__attribute json-schema-2020-12__attribute--primary' + }, + 'object' + ), + Pe.createElement( + 'ul', + { + className: Hn()('json-schema-2020-12-keyword__children', { + 'json-schema-2020-12-keyword__children--collapsed': !_ + }) + }, + _ && + Pe.createElement( + Pe.Fragment, + null, + Object.entries(o).map(([s, o]) => + Pe.createElement( + 'li', + { key: s, className: 'json-schema-2020-12-property' }, + Pe.createElement(B, { name: s, schema: o }) + ) + ) + ) + ) + ) + ); + }, + keywords_PrefixItems = ({ schema: s }) => { + const o = s?.prefixItems || [], + i = useFn(), + u = useIsExpanded(), + _ = useIsExpandedDeeply(), + [w, x] = (0, Pe.useState)(u || _), + [C, j] = (0, Pe.useState)(!1), + L = useComponent('Accordion'), + B = useComponent('ExpandDeepButton'), + $ = useComponent('JSONSchema'), + V = useComponent('KeywordType'), + U = (0, Pe.useCallback)(() => { + x((s) => !s); + }, []), + z = (0, Pe.useCallback)((s, o) => { + x(o), j(o); + }, []); + return Array.isArray(o) && 0 !== o.length + ? Pe.createElement( + nI.Provider, + { value: C }, + Pe.createElement( + 'div', + { + className: + 'json-schema-2020-12-keyword json-schema-2020-12-keyword--prefixItems' + }, + Pe.createElement( + L, + { expanded: w, onChange: U }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary' + }, + 'Prefix items' + ) + ), + Pe.createElement(B, { expanded: w, onClick: z }), + Pe.createElement(V, { schema: { prefixItems: o } }), + Pe.createElement( + 'ul', + { + className: Hn()('json-schema-2020-12-keyword__children', { + 'json-schema-2020-12-keyword__children--collapsed': !w + }) + }, + w && + Pe.createElement( + Pe.Fragment, + null, + o.map((s, o) => + Pe.createElement( + 'li', + { key: `#${o}`, className: 'json-schema-2020-12-property' }, + Pe.createElement($, { name: `#${o} ${i.getTitle(s)}`, schema: s }) + ) + ) + ) + ) + ) + ) + : null; + }, + keywords_Items = ({ schema: s }) => { + const o = useFn(), + i = useComponent('JSONSchema'); + if (!o.hasKeyword(s, 'items')) return null; + const u = Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary' + }, + 'Items' + ); + return Pe.createElement( + 'div', + { className: 'json-schema-2020-12-keyword json-schema-2020-12-keyword--items' }, + Pe.createElement(i, { name: u, schema: s.items }) + ); + }, + keywords_Contains = ({ schema: s }) => { + const o = useFn(), + i = useComponent('JSONSchema'); + if (!o.hasKeyword(s, 'contains')) return null; + const u = Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary' + }, + 'Contains' + ); + return Pe.createElement( + 'div', + { className: 'json-schema-2020-12-keyword json-schema-2020-12-keyword--contains' }, + Pe.createElement(i, { name: u, schema: s.contains }) + ); + }, + keywords_Properties_Properties = ({ schema: s }) => { + const o = useFn(), + i = s?.properties || {}, + u = Array.isArray(s?.required) ? s.required : [], + _ = useComponent('JSONSchema'); + return 0 === Object.keys(i).length + ? null + : Pe.createElement( + 'div', + { + className: 'json-schema-2020-12-keyword json-schema-2020-12-keyword--properties' + }, + Pe.createElement( + 'ul', + null, + Object.entries(i).map(([i, w]) => { + const x = u.includes(i), + C = o.getDependentRequired(i, s); + return Pe.createElement( + 'li', + { + key: i, + className: Hn()('json-schema-2020-12-property', { + 'json-schema-2020-12-property--required': x + }) + }, + Pe.createElement(_, { name: i, schema: w, dependentRequired: C }) + ); + }) + ) + ); + }, + PatternProperties_PatternProperties = ({ schema: s }) => { + const o = s?.patternProperties || {}, + i = useComponent('JSONSchema'); + return 0 === Object.keys(o).length + ? null + : Pe.createElement( + 'div', + { + className: + 'json-schema-2020-12-keyword json-schema-2020-12-keyword--patternProperties' + }, + Pe.createElement( + 'ul', + null, + Object.entries(o).map(([s, o]) => + Pe.createElement( + 'li', + { key: s, className: 'json-schema-2020-12-property' }, + Pe.createElement(i, { name: s, schema: o }) + ) + ) + ) + ); + }, + keywords_AdditionalProperties = ({ schema: s }) => { + const o = useFn(), + { additionalProperties: i } = s, + u = useComponent('JSONSchema'); + if (!o.hasKeyword(s, 'additionalProperties')) return null; + const _ = Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary' + }, + 'Additional properties' + ); + return Pe.createElement( + 'div', + { + className: + 'json-schema-2020-12-keyword json-schema-2020-12-keyword--additionalProperties' + }, + !0 === i + ? Pe.createElement( + Pe.Fragment, + null, + _, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12__attribute json-schema-2020-12__attribute--primary' + }, + 'allowed' + ) + ) + : !1 === i + ? Pe.createElement( + Pe.Fragment, + null, + _, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12__attribute json-schema-2020-12__attribute--primary' + }, + 'forbidden' + ) + ) + : Pe.createElement(u, { name: _, schema: i }) + ); + }, + keywords_PropertyNames = ({ schema: s }) => { + const o = useFn(), + { propertyNames: i } = s, + u = useComponent('JSONSchema'), + _ = Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary' + }, + 'Property names' + ); + return o.hasKeyword(s, 'propertyNames') + ? Pe.createElement( + 'div', + { + className: + 'json-schema-2020-12-keyword json-schema-2020-12-keyword--propertyNames' + }, + Pe.createElement(u, { name: _, schema: i }) + ) + : null; + }, + keywords_UnevaluatedItems = ({ schema: s }) => { + const o = useFn(), + { unevaluatedItems: i } = s, + u = useComponent('JSONSchema'); + if (!o.hasKeyword(s, 'unevaluatedItems')) return null; + const _ = Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary' + }, + 'Unevaluated items' + ); + return Pe.createElement( + 'div', + { + className: + 'json-schema-2020-12-keyword json-schema-2020-12-keyword--unevaluatedItems' + }, + Pe.createElement(u, { name: _, schema: i }) + ); + }, + keywords_UnevaluatedProperties = ({ schema: s }) => { + const o = useFn(), + { unevaluatedProperties: i } = s, + u = useComponent('JSONSchema'); + if (!o.hasKeyword(s, 'unevaluatedProperties')) return null; + const _ = Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary' + }, + 'Unevaluated properties' + ); + return Pe.createElement( + 'div', + { + className: + 'json-schema-2020-12-keyword json-schema-2020-12-keyword--unevaluatedProperties' + }, + Pe.createElement(u, { name: _, schema: i }) + ); + }, + keywords_Type = ({ schema: s, isCircular: o = !1 }) => { + const i = useFn().getType(s), + u = o ? ' [circular]' : ''; + return Pe.createElement( + 'strong', + { + className: 'json-schema-2020-12__attribute json-schema-2020-12__attribute--primary' + }, + `${i}${u}` + ); + }, + Enum_Enum = ({ schema: s }) => { + const o = useFn(); + return Array.isArray(s?.enum) + ? Pe.createElement( + 'div', + { className: 'json-schema-2020-12-keyword json-schema-2020-12-keyword--enum' }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary' + }, + 'Allowed values' + ), + Pe.createElement( + 'ul', + null, + s.enum.map((s) => { + const i = o.stringify(s); + return Pe.createElement( + 'li', + { key: i }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--const' + }, + i + ) + ); + }) + ) + ) + : null; + }, + keywords_Const = ({ schema: s }) => { + const o = useFn(); + return o.hasKeyword(s, 'const') + ? Pe.createElement( + 'div', + { className: 'json-schema-2020-12-keyword json-schema-2020-12-keyword--const' }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary' + }, + 'Const' + ), + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--const' + }, + o.stringify(s.const) + ) + ) + : null; + }, + Constraint = ({ constraint: s }) => + Pe.createElement( + 'span', + { + className: `json-schema-2020-12__constraint json-schema-2020-12__constraint--${s.scope}` + }, + s.value + ), + aI = Pe.memo(Constraint), + DependentRequired_DependentRequired = ({ dependentRequired: s }) => + 0 === s.length + ? null + : Pe.createElement( + 'div', + { + className: + 'json-schema-2020-12-keyword json-schema-2020-12-keyword--dependentRequired' + }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary' + }, + 'Required when defined' + ), + Pe.createElement( + 'ul', + null, + s.map((s) => + Pe.createElement( + 'li', + { key: s }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--warning' + }, + s + ) + ) + ) + ) + ), + keywords_ContentSchema = ({ schema: s }) => { + const o = useFn(), + i = useComponent('JSONSchema'); + if (!o.hasKeyword(s, 'contentSchema')) return null; + const u = Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary' + }, + 'Content schema' + ); + return Pe.createElement( + 'div', + { + className: 'json-schema-2020-12-keyword json-schema-2020-12-keyword--contentSchema' + }, + Pe.createElement(i, { name: u, schema: s.contentSchema }) + ); + }, + Title_Title = ({ title: s = '', schema: o }) => { + const i = useFn(), + u = s || i.getTitle(o); + return u + ? Pe.createElement('div', { className: 'json-schema-2020-12__title' }, u) + : null; + }, + keywords_Description_Description = ({ schema: s }) => + s?.description + ? Pe.createElement( + 'div', + { + className: + 'json-schema-2020-12-keyword json-schema-2020-12-keyword--description' + }, + Pe.createElement( + 'div', + { + className: + 'json-schema-2020-12-core-keyword__value json-schema-2020-12-core-keyword__value--secondary' + }, + s.description + ) + ) + : null, + keywords_Default = ({ schema: s }) => { + const o = useFn(); + return o.hasKeyword(s, 'default') + ? Pe.createElement( + 'div', + { className: 'json-schema-2020-12-keyword json-schema-2020-12-keyword--default' }, + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary' + }, + 'Default' + ), + Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--const' + }, + o.stringify(s.default) + ) + ) + : null; + }, + keywords_Deprecated = ({ schema: s }) => + !0 !== s?.deprecated + ? null + : Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12__attribute json-schema-2020-12__attribute--warning' + }, + 'deprecated' + ), + keywords_ReadOnly = ({ schema: s }) => + !0 !== s?.readOnly + ? null + : Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12__attribute json-schema-2020-12__attribute--muted' + }, + 'read-only' + ), + keywords_WriteOnly = ({ schema: s }) => + !0 !== s?.writeOnly + ? null + : Pe.createElement( + 'span', + { + className: + 'json-schema-2020-12__attribute json-schema-2020-12__attribute--muted' + }, + 'write-only' + ), + Accordion_Accordion = ({ expanded: s = !1, children: o, onChange: i }) => { + const u = useComponent('ChevronRightIcon'), + _ = (0, Pe.useCallback)( + (o) => { + i(o, !s); + }, + [s, i] + ); + return Pe.createElement( + 'button', + { type: 'button', className: 'json-schema-2020-12-accordion', onClick: _ }, + Pe.createElement('div', { className: 'json-schema-2020-12-accordion__children' }, o), + Pe.createElement( + 'span', + { + className: Hn()('json-schema-2020-12-accordion__icon', { + 'json-schema-2020-12-accordion__icon--expanded': s, + 'json-schema-2020-12-accordion__icon--collapsed': !s + }) + }, + Pe.createElement(u, null) + ) + ); + }, + ExpandDeepButton_ExpandDeepButton = ({ expanded: s, onClick: o }) => { + const i = (0, Pe.useCallback)( + (i) => { + o(i, !s); + }, + [s, o] + ); + return Pe.createElement( + 'button', + { type: 'button', className: 'json-schema-2020-12-expand-deep-button', onClick: i }, + s ? 'Collapse all' : 'Expand all' + ); + }, + icons_ChevronRight = () => + Pe.createElement( + 'svg', + { + xmlns: 'http://www.w3.org/2000/svg', + width: '24', + height: '24', + viewBox: '0 0 24 24' + }, + Pe.createElement('path', { d: 'M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z' }) + ), + fn_upperFirst = (s) => + 'string' == typeof s ? `${s.charAt(0).toUpperCase()}${s.slice(1)}` : s, + getTitle = (s, { lookup: o = 'extended' } = {}) => { + const i = useFn(); + if (null != s?.title) return i.upperFirst(String(s.title)); + if ('extended' === o) { + if (null != s?.$anchor) return i.upperFirst(String(s.$anchor)); + if (null != s?.$id) return String(s.$id); + } + return ''; + }, + getType = (s, o = new WeakSet()) => { + const i = useFn(); + if (null == s) return 'any'; + if (i.isBooleanJSONSchema(s)) return s ? 'any' : 'never'; + if ('object' != typeof s) return 'any'; + if (o.has(s)) return 'any'; + o.add(s); + const { type: u, prefixItems: _, items: w } = s, + getArrayType = () => { + if (Array.isArray(_)) { + const s = _.map((s) => getType(s, o)), + i = w ? getType(w, o) : 'any'; + return `array<[${s.join(', ')}], ${i}>`; + } + if (w) { + return `array<${getType(w, o)}>`; + } + return 'array'; + }; + if (s.not && 'any' === getType(s.not)) return 'never'; + const handleCombiningKeywords = (i, u) => { + if (Array.isArray(s[i])) { + return `(${s[i].map((s) => getType(s, o)).join(u)})`; + } + return null; + }, + x = [ + Array.isArray(u) + ? u.map((s) => ('array' === s ? getArrayType() : s)).join(' | ') + : 'array' === u + ? getArrayType() + : [ + 'null', + 'boolean', + 'object', + 'array', + 'number', + 'integer', + 'string' + ].includes(u) + ? u + : (() => { + if ( + Object.hasOwn(s, 'prefixItems') || + Object.hasOwn(s, 'items') || + Object.hasOwn(s, 'contains') + ) + return getArrayType(); + if ( + Object.hasOwn(s, 'properties') || + Object.hasOwn(s, 'additionalProperties') || + Object.hasOwn(s, 'patternProperties') + ) + return 'object'; + if (['int32', 'int64'].includes(s.format)) return 'integer'; + if (['float', 'double'].includes(s.format)) return 'number'; + if ( + Object.hasOwn(s, 'minimum') || + Object.hasOwn(s, 'maximum') || + Object.hasOwn(s, 'exclusiveMinimum') || + Object.hasOwn(s, 'exclusiveMaximum') || + Object.hasOwn(s, 'multipleOf') + ) + return 'number | integer'; + if ( + Object.hasOwn(s, 'pattern') || + Object.hasOwn(s, 'format') || + Object.hasOwn(s, 'minLength') || + Object.hasOwn(s, 'maxLength') + ) + return 'string'; + if (void 0 !== s.const) { + if (null === s.const) return 'null'; + if ('boolean' == typeof s.const) return 'boolean'; + if ('number' == typeof s.const) + return Number.isInteger(s.const) ? 'integer' : 'number'; + if ('string' == typeof s.const) return 'string'; + if (Array.isArray(s.const)) return 'array'; + if ('object' == typeof s.const) return 'object'; + } + return null; + })(), + handleCombiningKeywords('oneOf', ' | '), + handleCombiningKeywords('anyOf', ' | '), + handleCombiningKeywords('allOf', ' & ') + ] + .filter(Boolean) + .join(' | '); + return o.delete(s), x || 'any'; + }, + isBooleanJSONSchema = (s) => 'boolean' == typeof s, + hasKeyword = (s, o) => null !== s && 'object' == typeof s && Object.hasOwn(s, o), + isExpandable = (s) => { + const o = useFn(); + return ( + s?.$schema || + s?.$vocabulary || + s?.$id || + s?.$anchor || + s?.$dynamicAnchor || + s?.$ref || + s?.$dynamicRef || + s?.$defs || + s?.$comment || + s?.allOf || + s?.anyOf || + s?.oneOf || + o.hasKeyword(s, 'not') || + o.hasKeyword(s, 'if') || + o.hasKeyword(s, 'then') || + o.hasKeyword(s, 'else') || + s?.dependentSchemas || + s?.prefixItems || + o.hasKeyword(s, 'items') || + o.hasKeyword(s, 'contains') || + s?.properties || + s?.patternProperties || + o.hasKeyword(s, 'additionalProperties') || + o.hasKeyword(s, 'propertyNames') || + o.hasKeyword(s, 'unevaluatedItems') || + o.hasKeyword(s, 'unevaluatedProperties') || + s?.description || + s?.enum || + o.hasKeyword(s, 'const') || + o.hasKeyword(s, 'contentSchema') || + o.hasKeyword(s, 'default') + ); + }, + fn_stringify = (s) => + null === s || ['number', 'bigint', 'boolean'].includes(typeof s) + ? String(s) + : Array.isArray(s) + ? `[${s.map(fn_stringify).join(', ')}]` + : JSON.stringify(s), + stringifyConstraintRange = (s, o, i) => { + const u = 'number' == typeof o, + _ = 'number' == typeof i; + return u && _ + ? o === i + ? `${o} ${s}` + : `[${o}, ${i}] ${s}` + : u + ? `>= ${o} ${s}` + : _ + ? `<= ${i} ${s}` + : null; + }, + stringifyConstraints = (s) => { + const o = [], + i = ((s) => { + if ('number' != typeof s?.multipleOf) return null; + if (s.multipleOf <= 0) return null; + if (1 === s.multipleOf) return null; + const { multipleOf: o } = s; + if (Number.isInteger(o)) return `multiple of ${o}`; + const i = 10 ** o.toString().split('.')[1].length; + return `multiple of ${o * i}/${i}`; + })(s); + null !== i && o.push({ scope: 'number', value: i }); + const u = ((s) => { + const o = s?.minimum, + i = s?.maximum, + u = s?.exclusiveMinimum, + _ = s?.exclusiveMaximum, + w = 'number' == typeof o, + x = 'number' == typeof i, + C = 'number' == typeof u, + j = 'number' == typeof _, + L = C && (!w || o < u), + B = j && (!x || i > _); + if ((w || C) && (x || j)) + return `${L ? '(' : '['}${L ? u : o}, ${B ? _ : i}${B ? ')' : ']'}`; + if (w || C) return `${L ? '>' : '≥'} ${L ? u : o}`; + if (x || j) return `${B ? '<' : '≤'} ${B ? _ : i}`; + return null; + })(s); + null !== u && o.push({ scope: 'number', value: u }), + s?.format && o.push({ scope: 'string', value: s.format }); + const _ = stringifyConstraintRange('characters', s?.minLength, s?.maxLength); + null !== _ && o.push({ scope: 'string', value: _ }), + s?.pattern && o.push({ scope: 'string', value: `matches ${s?.pattern}` }), + s?.contentMediaType && + o.push({ scope: 'string', value: `media type: ${s.contentMediaType}` }), + s?.contentEncoding && + o.push({ scope: 'string', value: `encoding: ${s.contentEncoding}` }); + const w = stringifyConstraintRange( + s?.hasUniqueItems ? 'unique items' : 'items', + s?.minItems, + s?.maxItems + ); + null !== w && o.push({ scope: 'array', value: w }); + const x = stringifyConstraintRange('contained items', s?.minContains, s?.maxContains); + null !== x && o.push({ scope: 'array', value: x }); + const C = stringifyConstraintRange('properties', s?.minProperties, s?.maxProperties); + return null !== C && o.push({ scope: 'object', value: C }), o; + }, + getDependentRequired = (s, o) => + o?.dependentRequired + ? Array.from( + Object.entries(o.dependentRequired).reduce( + (o, [i, u]) => (Array.isArray(u) && u.includes(s) ? (o.add(i), o) : o), + new Set() + ) + ) + : [], + withJSONSchemaContext = (s, o = {}) => { + const i = { + components: { + JSONSchema: iI, + Keyword$schema: keywords_$schema, + Keyword$vocabulary: $vocabulary_$vocabulary, + Keyword$id: keywords_$id, + Keyword$anchor: keywords_$anchor, + Keyword$dynamicAnchor: keywords_$dynamicAnchor, + Keyword$ref: keywords_$ref, + Keyword$dynamicRef: keywords_$dynamicRef, + Keyword$defs: keywords_$defs, + Keyword$comment: keywords_$comment, + KeywordAllOf: keywords_AllOf, + KeywordAnyOf: keywords_AnyOf, + KeywordOneOf: keywords_OneOf, + KeywordNot: keywords_Not, + KeywordIf: keywords_If, + KeywordThen: keywords_Then, + KeywordElse: keywords_Else, + KeywordDependentSchemas: keywords_DependentSchemas, + KeywordPrefixItems: keywords_PrefixItems, + KeywordItems: keywords_Items, + KeywordContains: keywords_Contains, + KeywordProperties: keywords_Properties_Properties, + KeywordPatternProperties: PatternProperties_PatternProperties, + KeywordAdditionalProperties: keywords_AdditionalProperties, + KeywordPropertyNames: keywords_PropertyNames, + KeywordUnevaluatedItems: keywords_UnevaluatedItems, + KeywordUnevaluatedProperties: keywords_UnevaluatedProperties, + KeywordType: keywords_Type, + KeywordEnum: Enum_Enum, + KeywordConst: keywords_Const, + KeywordConstraint: aI, + KeywordDependentRequired: DependentRequired_DependentRequired, + KeywordContentSchema: keywords_ContentSchema, + KeywordTitle: Title_Title, + KeywordDescription: keywords_Description_Description, + KeywordDefault: keywords_Default, + KeywordDeprecated: keywords_Deprecated, + KeywordReadOnly: keywords_ReadOnly, + KeywordWriteOnly: keywords_WriteOnly, + Accordion: Accordion_Accordion, + ExpandDeepButton: ExpandDeepButton_ExpandDeepButton, + ChevronRightIcon: icons_ChevronRight, + ...o.components + }, + config: { + default$schema: 'https://json-schema.org/draft/2020-12/schema', + defaultExpandedLevels: 0, + ...o.config + }, + fn: { + upperFirst: fn_upperFirst, + getTitle, + getType, + isBooleanJSONSchema, + hasKeyword, + isExpandable, + stringify: fn_stringify, + stringifyConstraints, + getDependentRequired, + ...o.fn + } + }, + HOC = (o) => Pe.createElement(tI.Provider, { value: i }, Pe.createElement(s, o)); + return ( + (HOC.contexts = { JSONSchemaContext: tI }), (HOC.displayName = s.displayName), HOC + ); + }, + json_schema_2020_12 = () => ({ + components: { + JSONSchema202012: iI, + JSONSchema202012Keyword$schema: keywords_$schema, + JSONSchema202012Keyword$vocabulary: $vocabulary_$vocabulary, + JSONSchema202012Keyword$id: keywords_$id, + JSONSchema202012Keyword$anchor: keywords_$anchor, + JSONSchema202012Keyword$dynamicAnchor: keywords_$dynamicAnchor, + JSONSchema202012Keyword$ref: keywords_$ref, + JSONSchema202012Keyword$dynamicRef: keywords_$dynamicRef, + JSONSchema202012Keyword$defs: keywords_$defs, + JSONSchema202012Keyword$comment: keywords_$comment, + JSONSchema202012KeywordAllOf: keywords_AllOf, + JSONSchema202012KeywordAnyOf: keywords_AnyOf, + JSONSchema202012KeywordOneOf: keywords_OneOf, + JSONSchema202012KeywordNot: keywords_Not, + JSONSchema202012KeywordIf: keywords_If, + JSONSchema202012KeywordThen: keywords_Then, + JSONSchema202012KeywordElse: keywords_Else, + JSONSchema202012KeywordDependentSchemas: keywords_DependentSchemas, + JSONSchema202012KeywordPrefixItems: keywords_PrefixItems, + JSONSchema202012KeywordItems: keywords_Items, + JSONSchema202012KeywordContains: keywords_Contains, + JSONSchema202012KeywordProperties: keywords_Properties_Properties, + JSONSchema202012KeywordPatternProperties: PatternProperties_PatternProperties, + JSONSchema202012KeywordAdditionalProperties: keywords_AdditionalProperties, + JSONSchema202012KeywordPropertyNames: keywords_PropertyNames, + JSONSchema202012KeywordUnevaluatedItems: keywords_UnevaluatedItems, + JSONSchema202012KeywordUnevaluatedProperties: keywords_UnevaluatedProperties, + JSONSchema202012KeywordType: keywords_Type, + JSONSchema202012KeywordEnum: Enum_Enum, + JSONSchema202012KeywordConst: keywords_Const, + JSONSchema202012KeywordConstraint: aI, + JSONSchema202012KeywordDependentRequired: DependentRequired_DependentRequired, + JSONSchema202012KeywordContentSchema: keywords_ContentSchema, + JSONSchema202012KeywordTitle: Title_Title, + JSONSchema202012KeywordDescription: keywords_Description_Description, + JSONSchema202012KeywordDefault: keywords_Default, + JSONSchema202012KeywordDeprecated: keywords_Deprecated, + JSONSchema202012KeywordReadOnly: keywords_ReadOnly, + JSONSchema202012KeywordWriteOnly: keywords_WriteOnly, + JSONSchema202012Accordion: Accordion_Accordion, + JSONSchema202012ExpandDeepButton: ExpandDeepButton_ExpandDeepButton, + JSONSchema202012ChevronRightIcon: icons_ChevronRight, + withJSONSchema202012Context: withJSONSchemaContext, + JSONSchema202012DeepExpansionContext: () => nI + }, + fn: { + upperFirst: fn_upperFirst, + jsonSchema202012: { + isExpandable, + hasKeyword, + useFn, + useConfig, + useComponent, + useIsExpandedDeeply + } + } + }); + var lI = __webpack_require__(11331), + cI = __webpack_require__.n(lI); + const array = (s, { sample: o }) => + ((s, o = {}) => { + const { minItems: i, maxItems: u, uniqueItems: _ } = o, + { contains: w, minContains: x, maxContains: C } = o; + let j = [...s]; + if (null != w && 'object' == typeof w) { + if (Number.isInteger(x) && x > 1) { + const s = j.at(0); + for (let o = 1; o < x; o += 1) j.unshift(s); + } + Number.isInteger(C); + } + if ( + (Number.isInteger(u) && u > 0 && (j = s.slice(0, u)), Number.isInteger(i) && i > 0) + ) + for (let s = 0; j.length < i; s += 1) j.push(j[s % j.length]); + return !0 === _ && (j = Array.from(new Set(j))), j; + })(o, s), + object = () => { + throw new Error('Not implemented'); + }, + bytes = (s) => St()(s), + random_pick = (s) => s.at(0), + predicates_isBooleanJSONSchema = (s) => 'boolean' == typeof s, + isJSONSchemaObject = (s) => cI()(s), + isJSONSchema = (s) => predicates_isBooleanJSONSchema(s) || isJSONSchemaObject(s); + const uI = class Registry { + data = {}; + register(s, o) { + this.data[s] = o; + } + unregister(s) { + void 0 === s ? (this.data = {}) : delete this.data[s]; + } + get(s) { + return this.data[s]; + } + }, + int32 = () => (2 ** 30) >>> 0, + int64 = () => 2 ** 53 - 1, + generators_float = () => 0.1, + generators_double = () => 0.1, + email = () => 'user@example.com', + idn_email = () => '실례@example.com', + hostname = () => 'example.com', + idn_hostname = () => '실례.com', + ipv4 = () => '198.51.100.42', + ipv6 = () => '2001:0db8:5b96:0000:0000:426f:8e17:642a', + uri = () => 'https://example.com/', + uri_reference = () => 'path/index.html', + iri = () => 'https://실례.com/', + iri_reference = () => 'path/실례.html', + uuid = () => '3fa85f64-5717-4562-b3fc-2c963f66afa6', + uri_template = () => 'https://example.com/dictionary/{term:1}/{term}', + json_pointer = () => '/a/b/c', + relative_json_pointer = () => '1/0', + date_time = () => new Date().toISOString(), + date = () => new Date().toISOString().substring(0, 10), + time = () => new Date().toISOString().substring(11), + duration = () => 'P3D', + generators_password = () => '********', + regex = () => '^[a-z]+$'; + const pI = new (class FormatRegistry extends uI { + #t = { + int32, + int64, + float: generators_float, + double: generators_double, + email, + 'idn-email': idn_email, + hostname, + 'idn-hostname': idn_hostname, + ipv4, + ipv6, + uri, + 'uri-reference': uri_reference, + iri, + 'iri-reference': iri_reference, + uuid, + 'uri-template': uri_template, + 'json-pointer': json_pointer, + 'relative-json-pointer': relative_json_pointer, + 'date-time': date_time, + date, + time, + duration, + password: generators_password, + regex + }; + data = { ...this.#t }; + get defaults() { + return { ...this.#t }; + } + })(), + formatAPI = (s, o) => + 'function' == typeof o ? pI.register(s, o) : null === o ? pI.unregister(s) : pI.get(s); + formatAPI.getDefaults = () => pI.defaults; + const hI = formatAPI; + var dI = __webpack_require__(48287).Buffer; + const _7bit = (s) => dI.from(s).toString('ascii'); + var fI = __webpack_require__(48287).Buffer; + const _8bit = (s) => fI.from(s).toString('utf8'); + var mI = __webpack_require__(48287).Buffer; + const encoders_binary = (s) => mI.from(s).toString('binary'), + quoted_printable = (s) => { + let o = ''; + for (let i = 0; i < s.length; i++) { + const u = s.charCodeAt(i); + if (61 === u) o += '=3D'; + else if ((u >= 33 && u <= 60) || (u >= 62 && u <= 126) || 9 === u || 32 === u) + o += s.charAt(i); + else if (13 === u || 10 === u) o += '\r\n'; + else if (u > 126) { + const u = unescape(encodeURIComponent(s.charAt(i))); + for (let s = 0; s < u.length; s++) + o += '=' + ('0' + u.charCodeAt(s).toString(16)).slice(-2).toUpperCase(); + } else o += '=' + ('0' + u.toString(16)).slice(-2).toUpperCase(); + } + return o; + }; + var gI = __webpack_require__(48287).Buffer; + const base16 = (s) => gI.from(s).toString('hex'); + var yI = __webpack_require__(48287).Buffer; + const base32 = (s) => { + const o = yI.from(s).toString('utf8'), + i = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'; + let u = 0, + _ = '', + w = 0, + x = 0; + for (let s = 0; s < o.length; s++) + for (w = (w << 8) | o.charCodeAt(s), x += 8; x >= 5; ) + (_ += i.charAt((w >>> (x - 5)) & 31)), (x -= 5); + x > 0 && ((_ += i.charAt((w << (5 - x)) & 31)), (u = (8 - ((8 * o.length) % 5)) % 5)); + for (let s = 0; s < u; s++) _ += '='; + return _; + }; + var vI = __webpack_require__(48287).Buffer; + const base64 = (s) => vI.from(s).toString('base64'); + var bI = __webpack_require__(48287).Buffer; + const base64url = (s) => bI.from(s).toString('base64url'); + const _I = new (class EncoderRegistry extends uI { + #t = { + '7bit': _7bit, + '8bit': _8bit, + binary: encoders_binary, + 'quoted-printable': quoted_printable, + base16, + base32, + base64, + base64url + }; + data = { ...this.#t }; + get defaults() { + return { ...this.#t }; + } + })(), + encoderAPI = (s, o) => + 'function' == typeof o ? _I.register(s, o) : null === o ? _I.unregister(s) : _I.get(s); + encoderAPI.getDefaults = () => _I.defaults; + const EI = encoderAPI, + wI = { + 'text/plain': () => 'string', + 'text/css': () => '.selector { border: 1px solid red }', + 'text/csv': () => 'value1,value2,value3', + 'text/html': () => '

        content

        ', + 'text/calendar': () => 'BEGIN:VCALENDAR', + 'text/javascript': () => "console.dir('Hello world!');", + 'text/xml': () => 'John Doe', + 'text/*': () => 'string' + }, + SI = { 'image/*': () => bytes(25).toString('binary') }, + xI = { 'audio/*': () => bytes(25).toString('binary') }, + kI = { 'video/*': () => bytes(25).toString('binary') }, + CI = { + 'application/json': () => '{"key":"value"}', + 'application/ld+json': () => '{"name": "John Doe"}', + 'application/x-httpd-php': () => "Hello World!

        '; ?>", + 'application/rtf': () => String.raw`{\rtf1\adeflang1025\ansi\ansicpg1252\uc1`, + 'application/x-sh': () => 'echo "Hello World!"', + 'application/xhtml+xml': () => '

        content

        ', + 'application/*': () => bytes(25).toString('binary') + }; + const OI = new (class MediaTypeRegistry extends uI { + #t = { ...wI, ...SI, ...xI, ...kI, ...CI }; + data = { ...this.#t }; + get defaults() { + return { ...this.#t }; + } + })(), + mediaTypeAPI = (s, o) => { + if ('function' == typeof o) return OI.register(s, o); + if (null === o) return OI.unregister(s); + const i = s.split(';').at(0), + u = `${i.split('/').at(0)}/*`; + return OI.get(s) || OI.get(i) || OI.get(u); + }; + mediaTypeAPI.getDefaults = () => OI.defaults; + const AI = mediaTypeAPI, + applyStringConstraints = (s, o = {}) => { + const { maxLength: i, minLength: u } = o; + let _ = s; + if ( + (Number.isInteger(i) && i > 0 && (_ = _.slice(0, i)), Number.isInteger(u) && u > 0) + ) { + let s = 0; + for (; _.length < u; ) _ += _[s++ % _.length]; + } + return _; + }, + types_string = (s, { sample: o } = {}) => { + const { contentEncoding: i, contentMediaType: u, contentSchema: _ } = s, + { pattern: w, format: x } = s, + C = EI(i) || Mx(); + let j; + return ( + (j = + 'string' == typeof w + ? applyStringConstraints( + ((s) => { + try { + return new (us())(s).gen(); + } catch { + return 'string'; + } + })(w), + s + ) + : 'string' == typeof x + ? ((s) => { + const { format: o } = s, + i = hI(o); + return 'function' == typeof i ? i(s) : 'string'; + })(s) + : isJSONSchema(_) && 'string' == typeof u && void 0 !== o + ? Array.isArray(o) || 'object' == typeof o + ? JSON.stringify(o) + : applyStringConstraints(String(o), s) + : 'string' == typeof u + ? ((s) => { + const { contentMediaType: o } = s, + i = AI(o); + return 'function' == typeof i ? i(s) : 'string'; + })(s) + : applyStringConstraints('string', s)), + C(j) + ); + }, + applyNumberConstraints = (s, o = {}) => { + const { minimum: i, maximum: u, exclusiveMinimum: _, exclusiveMaximum: w } = o, + { multipleOf: x } = o, + C = Number.isInteger(s) ? 1 : Number.EPSILON; + let j = 'number' == typeof i ? i : null, + L = 'number' == typeof u ? u : null, + B = s; + if ( + ('number' == typeof _ && (j = null !== j ? Math.max(j, _ + C) : _ + C), + 'number' == typeof w && (L = null !== L ? Math.min(L, w - C) : w - C), + (B = (j > L && s) || j || L || B), + 'number' == typeof x && x > 0) + ) { + const s = B % x; + B = 0 === s ? B : B + x - s; + } + return B; + }, + types_number = (s) => { + const { format: o } = s; + let i; + return ( + (i = + 'string' == typeof o + ? ((s) => { + const { format: o } = s, + i = hI(o); + return 'function' == typeof i ? i(s) : 0; + })(s) + : 0), + applyNumberConstraints(i, s) + ); + }, + types_integer = (s) => { + const { format: o } = s; + let i; + return ( + (i = + 'string' == typeof o + ? ((s) => { + const { format: o } = s, + i = hI(o); + if ('function' == typeof i) return i(s); + switch (o) { + case 'int32': + return int32(); + case 'int64': + return int64(); + } + return 0; + })(s) + : 0), + applyNumberConstraints(i, s) + ); + }, + types_boolean = (s) => 'boolean' != typeof s.default || s.default, + jI = new Proxy( + { + array, + object, + string: types_string, + number: types_number, + integer: types_integer, + boolean: types_boolean, + null: () => null + }, + { + get: (s, o) => + 'string' == typeof o && Object.hasOwn(s, o) ? s[o] : () => `Unknown Type: ${o}` + } + ), + II = ['array', 'object', 'number', 'integer', 'string', 'boolean', 'null'], + hasExample = (s) => { + if (!isJSONSchemaObject(s)) return !1; + const { examples: o, example: i, default: u } = s; + return !!(Array.isArray(o) && o.length >= 1) || void 0 !== u || void 0 !== i; + }, + extractExample = (s) => { + if (!isJSONSchemaObject(s)) return null; + const { examples: o, example: i, default: u } = s; + return Array.isArray(o) && o.length >= 1 + ? o.at(0) + : void 0 !== u + ? u + : void 0 !== i + ? i + : void 0; + }, + PI = { + array: [ + 'items', + 'prefixItems', + 'contains', + 'maxContains', + 'minContains', + 'maxItems', + 'minItems', + 'uniqueItems', + 'unevaluatedItems' + ], + object: [ + 'properties', + 'additionalProperties', + 'patternProperties', + 'propertyNames', + 'minProperties', + 'maxProperties', + 'required', + 'dependentSchemas', + 'dependentRequired', + 'unevaluatedProperties' + ], + string: [ + 'pattern', + 'format', + 'minLength', + 'maxLength', + 'contentEncoding', + 'contentMediaType', + 'contentSchema' + ], + integer: ['minimum', 'maximum', 'exclusiveMinimum', 'exclusiveMaximum', 'multipleOf'] + }; + PI.number = PI.integer; + const MI = 'string', + inferTypeFromValue = (s) => + void 0 === s + ? null + : null === s + ? 'null' + : Array.isArray(s) + ? 'array' + : Number.isInteger(s) + ? 'integer' + : typeof s, + foldType = (s) => { + if (Array.isArray(s) && s.length >= 1) { + if (s.includes('array')) return 'array'; + if (s.includes('object')) return 'object'; + { + const o = random_pick(s); + if (II.includes(o)) return o; + } + } + return II.includes(s) ? s : null; + }, + inferType = (s, o = new WeakSet()) => { + if (!isJSONSchemaObject(s)) return MI; + if (o.has(s)) return MI; + o.add(s); + let { type: i, const: u } = s; + if (((i = foldType(i)), 'string' != typeof i)) { + const o = Object.keys(PI); + e: for (let u = 0; u < o.length; u += 1) { + const _ = o[u], + w = PI[_]; + for (let o = 0; o < w.length; o += 1) { + const u = w[o]; + if (Object.hasOwn(s, u)) { + i = _; + break e; + } + } + } + } + if ('string' != typeof i && void 0 !== u) { + const s = inferTypeFromValue(u); + i = 'string' == typeof s ? s : i; + } + if ('string' != typeof i) { + const combineTypes = (i) => { + if (Array.isArray(s[i])) { + const u = s[i].map((s) => inferType(s, o)); + return foldType(u); + } + return null; + }, + u = combineTypes('allOf'), + _ = combineTypes('anyOf'), + w = combineTypes('oneOf'), + x = s.not ? inferType(s.not, o) : null; + (u || _ || w || x) && (i = foldType([u, _, w, x].filter(Boolean))); + } + if ('string' != typeof i && hasExample(s)) { + const o = extractExample(s), + u = inferTypeFromValue(o); + i = 'string' == typeof u ? u : i; + } + return o.delete(s), i || MI; + }, + type_getType = (s) => inferType(s), + typeCast = (s) => + predicates_isBooleanJSONSchema(s) + ? ((s) => (!1 === s ? { not: {} } : {}))(s) + : isJSONSchemaObject(s) + ? s + : {}, + merge_merge = (s, o, i = {}) => { + if (predicates_isBooleanJSONSchema(s) && !0 === s) return !0; + if (predicates_isBooleanJSONSchema(s) && !1 === s) return !1; + if (predicates_isBooleanJSONSchema(o) && !0 === o) return !0; + if (predicates_isBooleanJSONSchema(o) && !1 === o) return !1; + if (!isJSONSchema(s)) return o; + if (!isJSONSchema(o)) return s; + const u = { ...o, ...s }; + if (o.type && s.type && Array.isArray(o.type) && 'string' == typeof o.type) { + const i = normalizeArray(o.type).concat(s.type); + u.type = Array.from(new Set(i)); + } + if ( + (Array.isArray(o.required) && + Array.isArray(s.required) && + (u.required = [...new Set([...s.required, ...o.required])]), + o.properties && s.properties) + ) { + const _ = new Set([...Object.keys(o.properties), ...Object.keys(s.properties)]); + u.properties = {}; + for (const w of _) { + const _ = o.properties[w] || {}, + x = s.properties[w] || {}; + (_.readOnly && !i.includeReadOnly) || (_.writeOnly && !i.includeWriteOnly) + ? (u.required = (u.required || []).filter((s) => s !== w)) + : (u.properties[w] = merge_merge(x, _, i)); + } + } + return ( + isJSONSchema(o.items) && + isJSONSchema(s.items) && + (u.items = merge_merge(s.items, o.items, i)), + isJSONSchema(o.contains) && + isJSONSchema(s.contains) && + (u.contains = merge_merge(s.contains, o.contains, i)), + isJSONSchema(o.contentSchema) && + isJSONSchema(s.contentSchema) && + (u.contentSchema = merge_merge(s.contentSchema, o.contentSchema, i)), + u + ); + }, + TI = merge_merge, + main_sampleFromSchemaGeneric = (s, o = {}, i = void 0, u = !1) => { + if (null == s && void 0 === i) return; + 'function' == typeof s?.toJS && (s = s.toJS()), (s = typeCast(s)); + let _ = void 0 !== i || hasExample(s); + const w = !_ && Array.isArray(s.oneOf) && s.oneOf.length > 0, + x = !_ && Array.isArray(s.anyOf) && s.anyOf.length > 0; + if (!_ && (w || x)) { + const i = typeCast(random_pick(w ? s.oneOf : s.anyOf)); + !(s = TI(s, i, o)).xml && i.xml && (s.xml = i.xml), + hasExample(s) && hasExample(i) && (_ = !0); + } + const C = {}; + let { xml: j, properties: L, additionalProperties: B, items: $, contains: V } = s || {}, + U = type_getType(s), + { includeReadOnly: z, includeWriteOnly: Y } = o; + j = j || {}; + let Z, + { name: ee, prefix: ie, namespace: ae } = j, + le = {}; + if ( + (Object.hasOwn(s, 'type') || (s.type = U), + u && ((ee = ee || 'notagname'), (Z = (ie ? `${ie}:` : '') + ee), ae)) + ) { + C[ie ? `xmlns:${ie}` : 'xmlns'] = ae; + } + u && (le[Z] = []); + const ce = objectify(L); + let pe, + de = 0; + const hasExceededMaxProperties = () => + Number.isInteger(s.maxProperties) && s.maxProperties > 0 && de >= s.maxProperties, + canAddProperty = (o) => + !(Number.isInteger(s.maxProperties) && s.maxProperties > 0) || + (!hasExceededMaxProperties() && + (!((o) => + !Array.isArray(s.required) || + 0 === s.required.length || + !s.required.includes(o))(o) || + s.maxProperties - + de - + (() => { + if (!Array.isArray(s.required) || 0 === s.required.length) return 0; + let o = 0; + return ( + u + ? s.required.forEach((s) => (o += void 0 === le[s] ? 0 : 1)) + : s.required.forEach((s) => { + o += void 0 === le[Z]?.find((o) => void 0 !== o[s]) ? 0 : 1; + }), + s.required.length - o + ); + })() > + 0)); + if ( + ((pe = u + ? (i, _ = void 0) => { + if (s && ce[i]) { + if (((ce[i].xml = ce[i].xml || {}), ce[i].xml.attribute)) { + const s = Array.isArray(ce[i].enum) ? random_pick(ce[i].enum) : void 0; + if (hasExample(ce[i])) C[ce[i].xml.name || i] = extractExample(ce[i]); + else if (void 0 !== s) C[ce[i].xml.name || i] = s; + else { + const s = typeCast(ce[i]), + o = type_getType(s), + u = ce[i].xml.name || i; + C[u] = jI[o](s); + } + return; + } + ce[i].xml.name = ce[i].xml.name || i; + } else ce[i] || !1 === B || (ce[i] = { xml: { name: i } }); + let w = main_sampleFromSchemaGeneric(ce[i], o, _, u); + canAddProperty(i) && + (de++, Array.isArray(w) ? (le[Z] = le[Z].concat(w)) : le[Z].push(w)); + } + : (i, _) => { + if (canAddProperty(i)) { + if ( + cI()(s.discriminator?.mapping) && + s.discriminator.propertyName === i && + 'string' == typeof s.$$ref + ) { + for (const o in s.discriminator.mapping) + if (-1 !== s.$$ref.search(s.discriminator.mapping[o])) { + le[i] = o; + break; + } + } else le[i] = main_sampleFromSchemaGeneric(ce[i], o, _, u); + de++; + } + }), + _) + ) { + let _; + if (((_ = void 0 !== i ? i : extractExample(s)), !u)) { + if ('number' == typeof _ && 'string' === U) return `${_}`; + if ('string' != typeof _ || 'string' === U) return _; + try { + return JSON.parse(_); + } catch { + return _; + } + } + if ('array' === U) { + if (!Array.isArray(_)) { + if ('string' == typeof _) return _; + _ = [_]; + } + let i = []; + return ( + isJSONSchemaObject($) && + (($.xml = $.xml || j || {}), + ($.xml.name = $.xml.name || j.name), + (i = _.map((s) => main_sampleFromSchemaGeneric($, o, s, u)))), + isJSONSchemaObject(V) && + ((V.xml = V.xml || j || {}), + (V.xml.name = V.xml.name || j.name), + (i = [main_sampleFromSchemaGeneric(V, o, void 0, u), ...i])), + (i = jI.array(s, { sample: i })), + j.wrapped ? ((le[Z] = i), hs()(C) || le[Z].push({ _attr: C })) : (le = i), + le + ); + } + if ('object' === U) { + if ('string' == typeof _) return _; + for (const s in _) + Object.hasOwn(_, s) && + ((ce[s]?.readOnly && !z) || + (ce[s]?.writeOnly && !Y) || + (ce[s]?.xml?.attribute ? (C[ce[s].xml.name || s] = _[s]) : pe(s, _[s]))); + return hs()(C) || le[Z].push({ _attr: C }), le; + } + return (le[Z] = hs()(C) ? _ : [{ _attr: C }, _]), le; + } + if ('array' === U) { + let i = []; + if (isJSONSchemaObject(V)) + if ( + (u && ((V.xml = V.xml || s.xml || {}), (V.xml.name = V.xml.name || j.name)), + Array.isArray(V.anyOf)) + ) { + const { anyOf: s, ..._ } = $; + i.push( + ...V.anyOf.map((s) => main_sampleFromSchemaGeneric(TI(s, _, o), o, void 0, u)) + ); + } else if (Array.isArray(V.oneOf)) { + const { oneOf: s, ..._ } = $; + i.push( + ...V.oneOf.map((s) => main_sampleFromSchemaGeneric(TI(s, _, o), o, void 0, u)) + ); + } else { + if (!(!u || (u && j.wrapped))) + return main_sampleFromSchemaGeneric(V, o, void 0, u); + i.push(main_sampleFromSchemaGeneric(V, o, void 0, u)); + } + if (isJSONSchemaObject($)) + if ( + (u && (($.xml = $.xml || s.xml || {}), ($.xml.name = $.xml.name || j.name)), + Array.isArray($.anyOf)) + ) { + const { anyOf: s, ..._ } = $; + i.push( + ...$.anyOf.map((s) => main_sampleFromSchemaGeneric(TI(s, _, o), o, void 0, u)) + ); + } else if (Array.isArray($.oneOf)) { + const { oneOf: s, ..._ } = $; + i.push( + ...$.oneOf.map((s) => main_sampleFromSchemaGeneric(TI(s, _, o), o, void 0, u)) + ); + } else { + if (!(!u || (u && j.wrapped))) + return main_sampleFromSchemaGeneric($, o, void 0, u); + i.push(main_sampleFromSchemaGeneric($, o, void 0, u)); + } + return ( + (i = jI.array(s, { sample: i })), + u && j.wrapped ? ((le[Z] = i), hs()(C) || le[Z].push({ _attr: C }), le) : i + ); + } + if ('object' === U) { + for (let s in ce) + Object.hasOwn(ce, s) && + (ce[s]?.deprecated || + (ce[s]?.readOnly && !z) || + (ce[s]?.writeOnly && !Y) || + pe(s)); + if ((u && C && le[Z].push({ _attr: C }), hasExceededMaxProperties())) return le; + if (predicates_isBooleanJSONSchema(B) && B) + u + ? le[Z].push({ additionalProp: 'Anything can be here' }) + : (le.additionalProp1 = {}), + de++; + else if (isJSONSchemaObject(B)) { + const i = B, + _ = main_sampleFromSchemaGeneric(i, o, void 0, u); + if (u && 'string' == typeof i?.xml?.name && 'notagname' !== i?.xml?.name) + le[Z].push(_); + else { + const o = + Number.isInteger(s.minProperties) && s.minProperties > 0 && de < s.minProperties + ? s.minProperties - de + : 3; + for (let s = 1; s <= o; s++) { + if (hasExceededMaxProperties()) return le; + if (u) { + const o = {}; + (o['additionalProp' + s] = _.notagname), le[Z].push(o); + } else le['additionalProp' + s] = _; + de++; + } + } + } + return le; + } + let fe; + if (void 0 !== s.const) fe = s.const; + else if (s && Array.isArray(s.enum)) fe = random_pick(normalizeArray(s.enum)); + else { + const i = isJSONSchemaObject(s.contentSchema) + ? main_sampleFromSchemaGeneric(s.contentSchema, o, void 0, u) + : void 0; + fe = jI[U](s, { sample: i }); + } + return u ? ((le[Z] = hs()(C) ? fe : [{ _attr: C }, fe]), le) : fe; + }, + main_createXMLExample = (s, o, i) => { + const u = main_sampleFromSchemaGeneric(s, o, i, !0); + if (u) return 'string' == typeof u ? u : ls()(u, { declaration: !0, indent: '\t' }); + }, + main_sampleFromSchema = (s, o, i) => main_sampleFromSchemaGeneric(s, o, i, !1), + main_resolver = (s, o, i) => [s, JSON.stringify(o), JSON.stringify(i)], + NI = utils_memoizeN(main_createXMLExample, main_resolver), + RI = utils_memoizeN(main_sampleFromSchema, main_resolver); + const DI = new (class OptionRegistry extends uI { + #t = {}; + data = { ...this.#t }; + get defaults() { + return { ...this.#t }; + } + })(), + api_optionAPI = (s, o) => (void 0 !== o && DI.register(s, o), DI.get(s)), + LI = [{ when: /json/, shouldStringifyTypes: ['string'] }], + BI = ['object'], + fn_get_json_sample_schema = (s) => (o, i, u, _) => { + const { fn: w } = s(), + x = w.jsonSchema202012.memoizedSampleFromSchema(o, i, _), + C = typeof x, + j = LI.reduce((s, o) => (o.when.test(u) ? [...s, ...o.shouldStringifyTypes] : s), BI); + return mt()(j, (s) => s === C) ? JSON.stringify(x, null, 2) : x; + }, + fn_get_yaml_sample_schema = (s) => (o, i, u, _) => { + const { fn: w } = s(), + x = w.jsonSchema202012.getJsonSampleSchema(o, i, u, _); + let C; + try { + (C = mn.dump(mn.load(x), { lineWidth: -1 }, { schema: nn })), + '\n' === C[C.length - 1] && (C = C.slice(0, C.length - 1)); + } catch (s) { + return console.error(s), 'error: could not generate yaml example'; + } + return C.replace(/\t/g, ' '); + }, + fn_get_xml_sample_schema = (s) => (o, i, u) => { + const { fn: _ } = s(); + if ((o && !o.xml && (o.xml = {}), o && !o.xml.name)) { + if (!o.$$ref && (o.type || o.items || o.properties || o.additionalProperties)) + return '\n\x3c!-- XML example cannot be generated; root element name is undefined --\x3e'; + if (o.$$ref) { + let s = o.$$ref.match(/\S*\/(\S+)$/); + o.xml.name = s[1]; + } + } + return _.jsonSchema202012.memoizedCreateXMLExample(o, i, u); + }, + fn_get_sample_schema = + (s) => + (o, i = '', u = {}, _ = void 0) => { + const { fn: w } = s(); + return ( + 'function' == typeof o?.toJS && (o = o.toJS()), + 'function' == typeof _?.toJS && (_ = _.toJS()), + /xml/.test(i) + ? w.jsonSchema202012.getXmlSampleSchema(o, u, _) + : /(yaml|yml)/.test(i) + ? w.jsonSchema202012.getYamlSampleSchema(o, u, i, _) + : w.jsonSchema202012.getJsonSampleSchema(o, u, i, _) + ); + }, + json_schema_2020_12_samples = ({ getSystem: s }) => { + const o = fn_get_json_sample_schema(s), + i = fn_get_yaml_sample_schema(s), + u = fn_get_xml_sample_schema(s), + _ = fn_get_sample_schema(s); + return { + fn: { + jsonSchema202012: { + sampleFromSchema: main_sampleFromSchema, + sampleFromSchemaGeneric: main_sampleFromSchemaGeneric, + sampleOptionAPI: api_optionAPI, + sampleEncoderAPI: EI, + sampleFormatAPI: hI, + sampleMediaTypeAPI: AI, + createXMLExample: main_createXMLExample, + memoizedSampleFromSchema: RI, + memoizedCreateXMLExample: NI, + getJsonSampleSchema: o, + getYamlSampleSchema: i, + getXmlSampleSchema: u, + getSampleSchema: _, + mergeJsonSchema: TI + } + } + }; + }; + function PresetApis() { + return [base, oas3, json_schema_2020_12, json_schema_2020_12_samples, oas31]; + } + const inline_plugin = (s) => () => ({ fn: s.fn, components: s.components }), + factorization_system = (s) => { + const o = We()( + { + layout: { layout: s.layout, filter: s.filter }, + spec: { spec: '', url: s.url }, + requestSnippets: s.requestSnippets + }, + s.initialState + ); + if (s.initialState) + for (const [i, u] of Object.entries(s.initialState)) void 0 === u && delete o[i]; + return { system: { configs: s.configs }, plugins: s.presets, state: o }; + }, + sources_query = () => (s) => { + const o = s.queryConfigEnabled + ? (() => { + const s = new URLSearchParams(at.location.search); + return Object.fromEntries(s); + })() + : {}; + return Object.entries(o).reduce( + (s, [o, i]) => ( + 'config' === o + ? (s.configUrl = i) + : 'urls.primaryName' === o + ? (s[o] = i) + : (s = ao()(s, o, i)), + s + ), + {} + ); + }, + sources_url = + ({ url: s, system: o }) => + async (i) => { + if (!s) return {}; + if ('function' != typeof o.configsActions?.getConfigByUrl) return {}; + const u = (() => { + const s = {}; + return ( + (s.promise = new Promise((o, i) => { + (s.resolve = o), (s.reject = i); + })), + s + ); + })(); + return ( + o.configsActions.getConfigByUrl( + { + url: s, + loadRemoteConfig: !0, + requestInterceptor: i.requestInterceptor, + responseInterceptor: i.responseInterceptor + }, + (s) => { + u.resolve(s); + } + ), + u.promise + ); + }, + runtime = () => () => { + const s = {}; + return ( + globalThis.location && + (s.oauth2RedirectUrl = `${globalThis.location.protocol}//${globalThis.location.host}${globalThis.location.pathname.substring(0, globalThis.location.pathname.lastIndexOf('/'))}/oauth2-redirect.html`), + s + ); + }, + FI = Object.freeze({ + dom_id: null, + domNode: null, + spec: {}, + url: '', + urls: null, + configUrl: null, + layout: 'BaseLayout', + docExpansion: 'list', + maxDisplayedTags: -1, + filter: !1, + validatorUrl: 'https://validator.swagger.io/validator', + oauth2RedirectUrl: void 0, + persistAuthorization: !1, + configs: {}, + displayOperationId: !1, + displayRequestDuration: !1, + deepLinking: !1, + tryItOutEnabled: !1, + requestInterceptor: (s) => ((s.curlOptions = []), s), + responseInterceptor: (s) => s, + showMutatedRequest: !0, + defaultModelRendering: 'example', + defaultModelExpandDepth: 1, + defaultModelsExpandDepth: 1, + showExtensions: !1, + showCommonExtensions: !1, + withCredentials: !1, + requestSnippetsEnabled: !1, + requestSnippets: { + generators: { + curl_bash: { title: 'cURL (bash)', syntax: 'bash' }, + curl_powershell: { title: 'cURL (PowerShell)', syntax: 'powershell' }, + curl_cmd: { title: 'cURL (CMD)', syntax: 'bash' } + }, + defaultExpanded: !0, + languages: null + }, + supportedSubmitMethods: [ + 'get', + 'put', + 'post', + 'delete', + 'options', + 'head', + 'patch', + 'trace' + ], + queryConfigEnabled: !1, + presets: [PresetApis], + plugins: [], + initialState: {}, + fn: {}, + components: {}, + syntaxHighlight: { activated: !0, theme: 'agate' }, + operationsSorter: null, + tagsSorter: null, + onComplete: null, + modelPropertyMacro: null, + parameterMacro: null + }); + var qI = __webpack_require__(61448), + $I = __webpack_require__.n(qI), + VI = __webpack_require__(77731), + UI = __webpack_require__.n(VI); + const type_casters_array = (s, o = []) => (Array.isArray(s) ? s : o), + type_casters_boolean = (s, o = !1) => + !0 === s || + 'true' === s || + 1 === s || + '1' === s || + (!1 !== s && 'false' !== s && 0 !== s && '0' !== s && o), + dom_node = (s) => (null === s || 'null' === s ? null : s), + type_casters_filter = (s) => { + const o = String(s); + return type_casters_boolean(s, o); + }, + type_casters_function = (s, o) => ('function' == typeof s ? s : o), + nullable_array = (s) => (Array.isArray(s) ? s : null), + nullable_function = (s) => ('function' == typeof s ? s : null), + nullable_string = (s) => (null === s || 'null' === s ? null : String(s)), + type_casters_number = (s, o = -1) => { + const i = parseInt(s, 10); + return Number.isNaN(i) ? o : i; + }, + type_casters_object = (s, o = {}) => (cI()(s) ? s : o), + sorter = (s) => ('function' == typeof s || 'string' == typeof s ? s : null), + type_casters_string = (s) => String(s), + syntax_highlight = (s, o) => + cI()(s) ? s : !1 === s || 'false' === s || 0 === s || '0' === s ? { activated: !1 } : o, + undefined_string = (s) => (void 0 === s || 'undefined' === s ? void 0 : String(s)), + zI = { + components: { typeCaster: type_casters_object }, + configs: { typeCaster: type_casters_object }, + configUrl: { typeCaster: nullable_string }, + deepLinking: { typeCaster: type_casters_boolean, defaultValue: FI.deepLinking }, + defaultModelExpandDepth: { + typeCaster: type_casters_number, + defaultValue: FI.defaultModelExpandDepth + }, + defaultModelRendering: { typeCaster: type_casters_string }, + defaultModelsExpandDepth: { + typeCaster: type_casters_number, + defaultValue: FI.defaultModelsExpandDepth + }, + displayOperationId: { + typeCaster: type_casters_boolean, + defaultValue: FI.displayOperationId + }, + displayRequestDuration: { + typeCaster: type_casters_boolean, + defaultValue: FI.displayRequestDuration + }, + docExpansion: { typeCaster: type_casters_string }, + dom_id: { typeCaster: nullable_string }, + domNode: { typeCaster: dom_node }, + filter: { typeCaster: type_casters_filter }, + fn: { typeCaster: type_casters_object }, + initialState: { typeCaster: type_casters_object }, + layout: { typeCaster: type_casters_string }, + maxDisplayedTags: { + typeCaster: type_casters_number, + defaultValue: FI.maxDisplayedTags + }, + modelPropertyMacro: { typeCaster: nullable_function }, + oauth2RedirectUrl: { typeCaster: undefined_string }, + onComplete: { typeCaster: nullable_function }, + operationsSorter: { typeCaster: sorter }, + paramaterMacro: { typeCaster: nullable_function }, + persistAuthorization: { + typeCaster: type_casters_boolean, + defaultValue: FI.persistAuthorization + }, + plugins: { typeCaster: type_casters_array, defaultValue: FI.plugins }, + presets: { typeCaster: type_casters_array, defaultValue: FI.presets }, + requestInterceptor: { + typeCaster: type_casters_function, + defaultValue: FI.requestInterceptor + }, + requestSnippets: { typeCaster: type_casters_object, defaultValue: FI.requestSnippets }, + requestSnippetsEnabled: { + typeCaster: type_casters_boolean, + defaultValue: FI.requestSnippetsEnabled + }, + responseInterceptor: { + typeCaster: type_casters_function, + defaultValue: FI.responseInterceptor + }, + showCommonExtensions: { + typeCaster: type_casters_boolean, + defaultValue: FI.showCommonExtensions + }, + showExtensions: { typeCaster: type_casters_boolean, defaultValue: FI.showExtensions }, + showMutatedRequest: { + typeCaster: type_casters_boolean, + defaultValue: FI.showMutatedRequest + }, + spec: { typeCaster: type_casters_object, defaultValue: FI.spec }, + supportedSubmitMethods: { + typeCaster: type_casters_array, + defaultValue: FI.supportedSubmitMethods + }, + syntaxHighlight: { typeCaster: syntax_highlight, defaultValue: FI.syntaxHighlight }, + 'syntaxHighlight.activated': { + typeCaster: type_casters_boolean, + defaultValue: FI.syntaxHighlight.activated + }, + 'syntaxHighlight.theme': { typeCaster: type_casters_string }, + tagsSorter: { typeCaster: sorter }, + tryItOutEnabled: { typeCaster: type_casters_boolean, defaultValue: FI.tryItOutEnabled }, + url: { typeCaster: type_casters_string }, + urls: { typeCaster: nullable_array }, + 'urls.primaryName': { typeCaster: type_casters_string }, + validatorUrl: { typeCaster: nullable_string }, + withCredentials: { typeCaster: type_casters_boolean, defaultValue: FI.withCredentials } + }, + type_cast = (s) => + Object.entries(zI).reduce( + (s, [o, { typeCaster: i, defaultValue: u }]) => { + if ($I()(s, o)) { + const _ = i(jn()(s, o), u); + s = UI()(o, _, s); + } + return s; + }, + { ...s } + ), + config_merge = (s, ...o) => { + let i = Symbol.for('domNode'), + u = Symbol.for('primaryName'); + const _ = []; + for (const s of o) { + const o = { ...s }; + Object.hasOwn(o, 'domNode') && ((i = o.domNode), delete o.domNode), + Object.hasOwn(o, 'urls.primaryName') + ? ((u = o['urls.primaryName']), delete o['urls.primaryName']) + : Array.isArray(o.urls) && + Object.hasOwn(o.urls, 'primaryName') && + ((u = o.urls.primaryName), delete o.urls.primaryName), + _.push(o); + } + const w = We()(s, ..._); + return ( + i !== Symbol.for('domNode') && (w.domNode = i), + u !== Symbol.for('primaryName') && Array.isArray(w.urls) && (w.urls.primaryName = u), + type_cast(w) + ); + }; + function SwaggerUI(s) { + const o = sources_query()(s), + i = runtime()(), + u = SwaggerUI.config.merge({}, SwaggerUI.config.defaults, i, s, o), + _ = factorization_system(u), + w = inline_plugin(u), + x = new Store(_); + x.register([u.plugins, w]); + const C = x.getSystem(), + persistConfigs = (s) => { + x.setConfigs(s), C.configsActions.loaded(); + }, + updateSpec = (s) => { + !o.url && 'object' == typeof s.spec && Object.keys(s.spec).length > 0 + ? (C.specActions.updateUrl(''), + C.specActions.updateLoadingStatus('success'), + C.specActions.updateSpec(JSON.stringify(s.spec))) + : 'function' == typeof C.specActions.download && + s.url && + !s.urls && + (C.specActions.updateUrl(s.url), C.specActions.download(s.url)); + }, + render = (s) => { + if (s.domNode) C.render(s.domNode, 'App'); + else if (s.dom_id) { + const o = document.querySelector(s.dom_id); + C.render(o, 'App'); + } else + null === s.dom_id || + null === s.domNode || + console.error('Skipped rendering: no `dom_id` or `domNode` was specified'); + }; + return u.configUrl + ? ((async () => { + const { configUrl: s } = u, + i = await sources_url({ url: s, system: C })(u), + _ = SwaggerUI.config.merge({}, u, i, o); + persistConfigs(_), null !== i && updateSpec(_), render(_); + })(), + C) + : (persistConfigs(u), updateSpec(u), render(u), C); + } + (SwaggerUI.System = Store), + (SwaggerUI.config = { + defaults: FI, + merge: config_merge, + typeCast: type_cast, + typeCastMappings: zI + }), + (SwaggerUI.presets = { base, apis: PresetApis }), + (SwaggerUI.plugins = { + Auth: auth, + Configs: configsPlugin, + DeepLining: deep_linking, + Err: err, + Filter: filter, + Icons: icons, + JSONSchema5: json_schema_5, + JSONSchema5Samples: json_schema_5_samples, + JSONSchema202012: json_schema_2020_12, + JSONSchema202012Samples: json_schema_2020_12_samples, + Layout: plugins_layout, + Logs: logs, + OpenAPI30: oas3, + OpenAPI31: oas3, + OnComplete: on_complete, + RequestSnippets: plugins_request_snippets, + Spec: plugins_spec, + SwaggerClient: swagger_client, + Util: util, + View: view, + ViewLegacy: view_legacy, + DownloadUrl: downloadUrlPlugin, + SyntaxHighlighting: syntax_highlighting, + Versions: versions, + SafeRender: safe_render + }); + const WI = SwaggerUI; + })(), + (_ = _.default) + ); + })() +); diff --git a/backend/open_webui/static/swagger-ui/swagger-ui.css b/backend/open_webui/static/swagger-ui/swagger-ui.css new file mode 100644 index 0000000..4efa5ef --- /dev/null +++ b/backend/open_webui/static/swagger-ui/swagger-ui.css @@ -0,0 +1,9310 @@ +.swagger-ui { + color: #3b4151; + font-family: sans-serif; /*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */ +} +.swagger-ui html { + line-height: 1.15; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; +} +.swagger-ui body { + margin: 0; +} +.swagger-ui article, +.swagger-ui aside, +.swagger-ui footer, +.swagger-ui header, +.swagger-ui nav, +.swagger-ui section { + display: block; +} +.swagger-ui h1 { + font-size: 2em; + margin: 0.67em 0; +} +.swagger-ui figcaption, +.swagger-ui figure, +.swagger-ui main { + display: block; +} +.swagger-ui figure { + margin: 1em 40px; +} +.swagger-ui hr { + box-sizing: content-box; + height: 0; + overflow: visible; +} +.swagger-ui pre { + font-family: monospace, monospace; + font-size: 1em; +} +.swagger-ui a { + background-color: transparent; + -webkit-text-decoration-skip: objects; +} +.swagger-ui abbr[title] { + border-bottom: none; + text-decoration: underline; + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; +} +.swagger-ui b, +.swagger-ui strong { + font-weight: inherit; + font-weight: bolder; +} +.swagger-ui code, +.swagger-ui kbd, +.swagger-ui samp { + font-family: monospace, monospace; + font-size: 1em; +} +.swagger-ui dfn { + font-style: italic; +} +.swagger-ui mark { + background-color: #ff0; + color: #000; +} +.swagger-ui small { + font-size: 80%; +} +.swagger-ui sub, +.swagger-ui sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} +.swagger-ui sub { + bottom: -0.25em; +} +.swagger-ui sup { + top: -0.5em; +} +.swagger-ui audio, +.swagger-ui video { + display: inline-block; +} +.swagger-ui audio:not([controls]) { + display: none; + height: 0; +} +.swagger-ui img { + border-style: none; +} +.swagger-ui svg:not(:root) { + overflow: hidden; +} +.swagger-ui button, +.swagger-ui input, +.swagger-ui optgroup, +.swagger-ui select, +.swagger-ui textarea { + font-family: sans-serif; + font-size: 100%; + line-height: 1.15; + margin: 0; +} +.swagger-ui button, +.swagger-ui input { + overflow: visible; +} +.swagger-ui button, +.swagger-ui select { + text-transform: none; +} +.swagger-ui [type='reset'], +.swagger-ui [type='submit'], +.swagger-ui button, +.swagger-ui html [type='button'] { + -webkit-appearance: button; +} +.swagger-ui [type='button']::-moz-focus-inner, +.swagger-ui [type='reset']::-moz-focus-inner, +.swagger-ui [type='submit']::-moz-focus-inner, +.swagger-ui button::-moz-focus-inner { + border-style: none; + padding: 0; +} +.swagger-ui [type='button']:-moz-focusring, +.swagger-ui [type='reset']:-moz-focusring, +.swagger-ui [type='submit']:-moz-focusring, +.swagger-ui button:-moz-focusring { + outline: 1px dotted ButtonText; +} +.swagger-ui fieldset { + padding: 0.35em 0.75em 0.625em; +} +.swagger-ui legend { + box-sizing: border-box; + color: inherit; + display: table; + max-width: 100%; + padding: 0; + white-space: normal; +} +.swagger-ui progress { + display: inline-block; + vertical-align: baseline; +} +.swagger-ui textarea { + overflow: auto; +} +.swagger-ui [type='checkbox'], +.swagger-ui [type='radio'] { + box-sizing: border-box; + padding: 0; +} +.swagger-ui [type='number']::-webkit-inner-spin-button, +.swagger-ui [type='number']::-webkit-outer-spin-button { + height: auto; +} +.swagger-ui [type='search'] { + -webkit-appearance: textfield; + outline-offset: -2px; +} +.swagger-ui [type='search']::-webkit-search-cancel-button, +.swagger-ui [type='search']::-webkit-search-decoration { + -webkit-appearance: none; +} +.swagger-ui ::-webkit-file-upload-button { + -webkit-appearance: button; + font: inherit; +} +.swagger-ui details, +.swagger-ui menu { + display: block; +} +.swagger-ui summary { + display: list-item; +} +.swagger-ui canvas { + display: inline-block; +} +.swagger-ui [hidden], +.swagger-ui template { + display: none; +} +.swagger-ui .debug * { + outline: 1px solid gold; +} +.swagger-ui .debug-white * { + outline: 1px solid #fff; +} +.swagger-ui .debug-black * { + outline: 1px solid #000; +} +.swagger-ui .debug-grid { + background: transparent + url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MTRDOTY4N0U2N0VFMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MTRDOTY4N0Q2N0VFMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NjcyQkQ3NjY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NjcyQkQ3NzY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PsBS+GMAAAAjSURBVHjaYvz//z8DLsD4gcGXiYEAGBIKGBne//fFpwAgwAB98AaF2pjlUQAAAABJRU5ErkJggg==) + repeat 0 0; +} +.swagger-ui .debug-grid-16 { + background: transparent + url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6ODYyRjhERDU2N0YyMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ODYyRjhERDQ2N0YyMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NjcyQkQ3QTY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NjcyQkQ3QjY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PvCS01IAAABMSURBVHjaYmR4/5+BFPBfAMFm/MBgx8RAGWCn1AAmSg34Q6kBDKMGMDCwICeMIemF/5QawEipAWwUhwEjMDvbAWlWkvVBwu8vQIABAEwBCph8U6c0AAAAAElFTkSuQmCC) + repeat 0 0; +} +.swagger-ui .debug-grid-8-solid { + background: #fff + url(data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAAAAAD/4QMxaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzExMSA3OS4xNTgzMjUsIDIwMTUvMDkvMTAtMDE6MTA6MjAgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE1IChNYWNpbnRvc2gpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkIxMjI0OTczNjdCMzExRTZCMkJDRTI0MDgxMDAyMTcxIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkIxMjI0OTc0NjdCMzExRTZCMkJDRTI0MDgxMDAyMTcxIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6QjEyMjQ5NzE2N0IzMTFFNkIyQkNFMjQwODEwMDIxNzEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6QjEyMjQ5NzI2N0IzMTFFNkIyQkNFMjQwODEwMDIxNzEiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7/7gAOQWRvYmUAZMAAAAAB/9sAhAAbGhopHSlBJiZBQi8vL0JHPz4+P0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHAR0pKTQmND8oKD9HPzU/R0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0f/wAARCAAIAAgDASIAAhEBAxEB/8QAWQABAQAAAAAAAAAAAAAAAAAAAAYBAQEAAAAAAAAAAAAAAAAAAAIEEAEBAAMBAAAAAAAAAAAAAAABADECA0ERAAEDBQAAAAAAAAAAAAAAAAARITFBUWESIv/aAAwDAQACEQMRAD8AoOnTV1QTD7JJshP3vSM3P//Z) + repeat 0 0; +} +.swagger-ui .debug-grid-16-solid { + background: #fff + url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NzY3MkJEN0U2N0M1MTFFNkIyQkNFMjQwODEwMDIxNzEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NzY3MkJEN0Y2N0M1MTFFNkIyQkNFMjQwODEwMDIxNzEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NjcyQkQ3QzY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NjcyQkQ3RDY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pve6J3kAAAAzSURBVHjaYvz//z8D0UDsMwMjSRoYP5Gq4SPNbRjVMEQ1fCRDg+in/6+J1AJUxsgAEGAA31BAJMS0GYEAAAAASUVORK5CYII=) + repeat 0 0; +} +.swagger-ui .border-box, +.swagger-ui a, +.swagger-ui article, +.swagger-ui body, +.swagger-ui code, +.swagger-ui dd, +.swagger-ui div, +.swagger-ui dl, +.swagger-ui dt, +.swagger-ui fieldset, +.swagger-ui footer, +.swagger-ui form, +.swagger-ui h1, +.swagger-ui h2, +.swagger-ui h3, +.swagger-ui h4, +.swagger-ui h5, +.swagger-ui h6, +.swagger-ui header, +.swagger-ui html, +.swagger-ui input[type='email'], +.swagger-ui input[type='number'], +.swagger-ui input[type='password'], +.swagger-ui input[type='tel'], +.swagger-ui input[type='text'], +.swagger-ui input[type='url'], +.swagger-ui legend, +.swagger-ui li, +.swagger-ui main, +.swagger-ui ol, +.swagger-ui p, +.swagger-ui pre, +.swagger-ui section, +.swagger-ui table, +.swagger-ui td, +.swagger-ui textarea, +.swagger-ui th, +.swagger-ui tr, +.swagger-ui ul { + box-sizing: border-box; +} +.swagger-ui .aspect-ratio { + height: 0; + position: relative; +} +.swagger-ui .aspect-ratio--16x9 { + padding-bottom: 56.25%; +} +.swagger-ui .aspect-ratio--9x16 { + padding-bottom: 177.77%; +} +.swagger-ui .aspect-ratio--4x3 { + padding-bottom: 75%; +} +.swagger-ui .aspect-ratio--3x4 { + padding-bottom: 133.33%; +} +.swagger-ui .aspect-ratio--6x4 { + padding-bottom: 66.6%; +} +.swagger-ui .aspect-ratio--4x6 { + padding-bottom: 150%; +} +.swagger-ui .aspect-ratio--8x5 { + padding-bottom: 62.5%; +} +.swagger-ui .aspect-ratio--5x8 { + padding-bottom: 160%; +} +.swagger-ui .aspect-ratio--7x5 { + padding-bottom: 71.42%; +} +.swagger-ui .aspect-ratio--5x7 { + padding-bottom: 140%; +} +.swagger-ui .aspect-ratio--1x1 { + padding-bottom: 100%; +} +.swagger-ui .aspect-ratio--object { + bottom: 0; + height: 100%; + left: 0; + position: absolute; + right: 0; + top: 0; + width: 100%; + z-index: 100; +} +@media screen and (min-width: 30em) { + .swagger-ui .aspect-ratio-ns { + height: 0; + position: relative; + } + .swagger-ui .aspect-ratio--16x9-ns { + padding-bottom: 56.25%; + } + .swagger-ui .aspect-ratio--9x16-ns { + padding-bottom: 177.77%; + } + .swagger-ui .aspect-ratio--4x3-ns { + padding-bottom: 75%; + } + .swagger-ui .aspect-ratio--3x4-ns { + padding-bottom: 133.33%; + } + .swagger-ui .aspect-ratio--6x4-ns { + padding-bottom: 66.6%; + } + .swagger-ui .aspect-ratio--4x6-ns { + padding-bottom: 150%; + } + .swagger-ui .aspect-ratio--8x5-ns { + padding-bottom: 62.5%; + } + .swagger-ui .aspect-ratio--5x8-ns { + padding-bottom: 160%; + } + .swagger-ui .aspect-ratio--7x5-ns { + padding-bottom: 71.42%; + } + .swagger-ui .aspect-ratio--5x7-ns { + padding-bottom: 140%; + } + .swagger-ui .aspect-ratio--1x1-ns { + padding-bottom: 100%; + } + .swagger-ui .aspect-ratio--object-ns { + bottom: 0; + height: 100%; + left: 0; + position: absolute; + right: 0; + top: 0; + width: 100%; + z-index: 100; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .aspect-ratio-m { + height: 0; + position: relative; + } + .swagger-ui .aspect-ratio--16x9-m { + padding-bottom: 56.25%; + } + .swagger-ui .aspect-ratio--9x16-m { + padding-bottom: 177.77%; + } + .swagger-ui .aspect-ratio--4x3-m { + padding-bottom: 75%; + } + .swagger-ui .aspect-ratio--3x4-m { + padding-bottom: 133.33%; + } + .swagger-ui .aspect-ratio--6x4-m { + padding-bottom: 66.6%; + } + .swagger-ui .aspect-ratio--4x6-m { + padding-bottom: 150%; + } + .swagger-ui .aspect-ratio--8x5-m { + padding-bottom: 62.5%; + } + .swagger-ui .aspect-ratio--5x8-m { + padding-bottom: 160%; + } + .swagger-ui .aspect-ratio--7x5-m { + padding-bottom: 71.42%; + } + .swagger-ui .aspect-ratio--5x7-m { + padding-bottom: 140%; + } + .swagger-ui .aspect-ratio--1x1-m { + padding-bottom: 100%; + } + .swagger-ui .aspect-ratio--object-m { + bottom: 0; + height: 100%; + left: 0; + position: absolute; + right: 0; + top: 0; + width: 100%; + z-index: 100; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .aspect-ratio-l { + height: 0; + position: relative; + } + .swagger-ui .aspect-ratio--16x9-l { + padding-bottom: 56.25%; + } + .swagger-ui .aspect-ratio--9x16-l { + padding-bottom: 177.77%; + } + .swagger-ui .aspect-ratio--4x3-l { + padding-bottom: 75%; + } + .swagger-ui .aspect-ratio--3x4-l { + padding-bottom: 133.33%; + } + .swagger-ui .aspect-ratio--6x4-l { + padding-bottom: 66.6%; + } + .swagger-ui .aspect-ratio--4x6-l { + padding-bottom: 150%; + } + .swagger-ui .aspect-ratio--8x5-l { + padding-bottom: 62.5%; + } + .swagger-ui .aspect-ratio--5x8-l { + padding-bottom: 160%; + } + .swagger-ui .aspect-ratio--7x5-l { + padding-bottom: 71.42%; + } + .swagger-ui .aspect-ratio--5x7-l { + padding-bottom: 140%; + } + .swagger-ui .aspect-ratio--1x1-l { + padding-bottom: 100%; + } + .swagger-ui .aspect-ratio--object-l { + bottom: 0; + height: 100%; + left: 0; + position: absolute; + right: 0; + top: 0; + width: 100%; + z-index: 100; + } +} +.swagger-ui img { + max-width: 100%; +} +.swagger-ui .cover { + background-size: cover !important; +} +.swagger-ui .contain { + background-size: contain !important; +} +@media screen and (min-width: 30em) { + .swagger-ui .cover-ns { + background-size: cover !important; + } + .swagger-ui .contain-ns { + background-size: contain !important; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .cover-m { + background-size: cover !important; + } + .swagger-ui .contain-m { + background-size: contain !important; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .cover-l { + background-size: cover !important; + } + .swagger-ui .contain-l { + background-size: contain !important; + } +} +.swagger-ui .bg-center { + background-position: 50%; + background-repeat: no-repeat; +} +.swagger-ui .bg-top { + background-position: top; + background-repeat: no-repeat; +} +.swagger-ui .bg-right { + background-position: 100%; + background-repeat: no-repeat; +} +.swagger-ui .bg-bottom { + background-position: bottom; + background-repeat: no-repeat; +} +.swagger-ui .bg-left { + background-position: 0; + background-repeat: no-repeat; +} +@media screen and (min-width: 30em) { + .swagger-ui .bg-center-ns { + background-position: 50%; + background-repeat: no-repeat; + } + .swagger-ui .bg-top-ns { + background-position: top; + background-repeat: no-repeat; + } + .swagger-ui .bg-right-ns { + background-position: 100%; + background-repeat: no-repeat; + } + .swagger-ui .bg-bottom-ns { + background-position: bottom; + background-repeat: no-repeat; + } + .swagger-ui .bg-left-ns { + background-position: 0; + background-repeat: no-repeat; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .bg-center-m { + background-position: 50%; + background-repeat: no-repeat; + } + .swagger-ui .bg-top-m { + background-position: top; + background-repeat: no-repeat; + } + .swagger-ui .bg-right-m { + background-position: 100%; + background-repeat: no-repeat; + } + .swagger-ui .bg-bottom-m { + background-position: bottom; + background-repeat: no-repeat; + } + .swagger-ui .bg-left-m { + background-position: 0; + background-repeat: no-repeat; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .bg-center-l { + background-position: 50%; + background-repeat: no-repeat; + } + .swagger-ui .bg-top-l { + background-position: top; + background-repeat: no-repeat; + } + .swagger-ui .bg-right-l { + background-position: 100%; + background-repeat: no-repeat; + } + .swagger-ui .bg-bottom-l { + background-position: bottom; + background-repeat: no-repeat; + } + .swagger-ui .bg-left-l { + background-position: 0; + background-repeat: no-repeat; + } +} +.swagger-ui .outline { + outline: 1px solid; +} +.swagger-ui .outline-transparent { + outline: 1px solid transparent; +} +.swagger-ui .outline-0 { + outline: 0; +} +@media screen and (min-width: 30em) { + .swagger-ui .outline-ns { + outline: 1px solid; + } + .swagger-ui .outline-transparent-ns { + outline: 1px solid transparent; + } + .swagger-ui .outline-0-ns { + outline: 0; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .outline-m { + outline: 1px solid; + } + .swagger-ui .outline-transparent-m { + outline: 1px solid transparent; + } + .swagger-ui .outline-0-m { + outline: 0; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .outline-l { + outline: 1px solid; + } + .swagger-ui .outline-transparent-l { + outline: 1px solid transparent; + } + .swagger-ui .outline-0-l { + outline: 0; + } +} +.swagger-ui .ba { + border-style: solid; + border-width: 1px; +} +.swagger-ui .bt { + border-top-style: solid; + border-top-width: 1px; +} +.swagger-ui .br { + border-right-style: solid; + border-right-width: 1px; +} +.swagger-ui .bb { + border-bottom-style: solid; + border-bottom-width: 1px; +} +.swagger-ui .bl { + border-left-style: solid; + border-left-width: 1px; +} +.swagger-ui .bn { + border-style: none; + border-width: 0; +} +@media screen and (min-width: 30em) { + .swagger-ui .ba-ns { + border-style: solid; + border-width: 1px; + } + .swagger-ui .bt-ns { + border-top-style: solid; + border-top-width: 1px; + } + .swagger-ui .br-ns { + border-right-style: solid; + border-right-width: 1px; + } + .swagger-ui .bb-ns { + border-bottom-style: solid; + border-bottom-width: 1px; + } + .swagger-ui .bl-ns { + border-left-style: solid; + border-left-width: 1px; + } + .swagger-ui .bn-ns { + border-style: none; + border-width: 0; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .ba-m { + border-style: solid; + border-width: 1px; + } + .swagger-ui .bt-m { + border-top-style: solid; + border-top-width: 1px; + } + .swagger-ui .br-m { + border-right-style: solid; + border-right-width: 1px; + } + .swagger-ui .bb-m { + border-bottom-style: solid; + border-bottom-width: 1px; + } + .swagger-ui .bl-m { + border-left-style: solid; + border-left-width: 1px; + } + .swagger-ui .bn-m { + border-style: none; + border-width: 0; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .ba-l { + border-style: solid; + border-width: 1px; + } + .swagger-ui .bt-l { + border-top-style: solid; + border-top-width: 1px; + } + .swagger-ui .br-l { + border-right-style: solid; + border-right-width: 1px; + } + .swagger-ui .bb-l { + border-bottom-style: solid; + border-bottom-width: 1px; + } + .swagger-ui .bl-l { + border-left-style: solid; + border-left-width: 1px; + } + .swagger-ui .bn-l { + border-style: none; + border-width: 0; + } +} +.swagger-ui .b--black { + border-color: #000; +} +.swagger-ui .b--near-black { + border-color: #111; +} +.swagger-ui .b--dark-gray { + border-color: #333; +} +.swagger-ui .b--mid-gray { + border-color: #555; +} +.swagger-ui .b--gray { + border-color: #777; +} +.swagger-ui .b--silver { + border-color: #999; +} +.swagger-ui .b--light-silver { + border-color: #aaa; +} +.swagger-ui .b--moon-gray { + border-color: #ccc; +} +.swagger-ui .b--light-gray { + border-color: #eee; +} +.swagger-ui .b--near-white { + border-color: #f4f4f4; +} +.swagger-ui .b--white { + border-color: #fff; +} +.swagger-ui .b--white-90 { + border-color: hsla(0, 0%, 100%, 0.9); +} +.swagger-ui .b--white-80 { + border-color: hsla(0, 0%, 100%, 0.8); +} +.swagger-ui .b--white-70 { + border-color: hsla(0, 0%, 100%, 0.7); +} +.swagger-ui .b--white-60 { + border-color: hsla(0, 0%, 100%, 0.6); +} +.swagger-ui .b--white-50 { + border-color: hsla(0, 0%, 100%, 0.5); +} +.swagger-ui .b--white-40 { + border-color: hsla(0, 0%, 100%, 0.4); +} +.swagger-ui .b--white-30 { + border-color: hsla(0, 0%, 100%, 0.3); +} +.swagger-ui .b--white-20 { + border-color: hsla(0, 0%, 100%, 0.2); +} +.swagger-ui .b--white-10 { + border-color: hsla(0, 0%, 100%, 0.1); +} +.swagger-ui .b--white-05 { + border-color: hsla(0, 0%, 100%, 0.05); +} +.swagger-ui .b--white-025 { + border-color: hsla(0, 0%, 100%, 0.025); +} +.swagger-ui .b--white-0125 { + border-color: hsla(0, 0%, 100%, 0.013); +} +.swagger-ui .b--black-90 { + border-color: rgba(0, 0, 0, 0.9); +} +.swagger-ui .b--black-80 { + border-color: rgba(0, 0, 0, 0.8); +} +.swagger-ui .b--black-70 { + border-color: rgba(0, 0, 0, 0.7); +} +.swagger-ui .b--black-60 { + border-color: rgba(0, 0, 0, 0.6); +} +.swagger-ui .b--black-50 { + border-color: rgba(0, 0, 0, 0.5); +} +.swagger-ui .b--black-40 { + border-color: rgba(0, 0, 0, 0.4); +} +.swagger-ui .b--black-30 { + border-color: rgba(0, 0, 0, 0.3); +} +.swagger-ui .b--black-20 { + border-color: rgba(0, 0, 0, 0.2); +} +.swagger-ui .b--black-10 { + border-color: rgba(0, 0, 0, 0.1); +} +.swagger-ui .b--black-05 { + border-color: rgba(0, 0, 0, 0.05); +} +.swagger-ui .b--black-025 { + border-color: rgba(0, 0, 0, 0.025); +} +.swagger-ui .b--black-0125 { + border-color: rgba(0, 0, 0, 0.013); +} +.swagger-ui .b--dark-red { + border-color: #e7040f; +} +.swagger-ui .b--red { + border-color: #ff4136; +} +.swagger-ui .b--light-red { + border-color: #ff725c; +} +.swagger-ui .b--orange { + border-color: #ff6300; +} +.swagger-ui .b--gold { + border-color: #ffb700; +} +.swagger-ui .b--yellow { + border-color: gold; +} +.swagger-ui .b--light-yellow { + border-color: #fbf1a9; +} +.swagger-ui .b--purple { + border-color: #5e2ca5; +} +.swagger-ui .b--light-purple { + border-color: #a463f2; +} +.swagger-ui .b--dark-pink { + border-color: #d5008f; +} +.swagger-ui .b--hot-pink { + border-color: #ff41b4; +} +.swagger-ui .b--pink { + border-color: #ff80cc; +} +.swagger-ui .b--light-pink { + border-color: #ffa3d7; +} +.swagger-ui .b--dark-green { + border-color: #137752; +} +.swagger-ui .b--green { + border-color: #19a974; +} +.swagger-ui .b--light-green { + border-color: #9eebcf; +} +.swagger-ui .b--navy { + border-color: #001b44; +} +.swagger-ui .b--dark-blue { + border-color: #00449e; +} +.swagger-ui .b--blue { + border-color: #357edd; +} +.swagger-ui .b--light-blue { + border-color: #96ccff; +} +.swagger-ui .b--lightest-blue { + border-color: #cdecff; +} +.swagger-ui .b--washed-blue { + border-color: #f6fffe; +} +.swagger-ui .b--washed-green { + border-color: #e8fdf5; +} +.swagger-ui .b--washed-yellow { + border-color: #fffceb; +} +.swagger-ui .b--washed-red { + border-color: #ffdfdf; +} +.swagger-ui .b--transparent { + border-color: transparent; +} +.swagger-ui .b--inherit { + border-color: inherit; +} +.swagger-ui .br0 { + border-radius: 0; +} +.swagger-ui .br1 { + border-radius: 0.125rem; +} +.swagger-ui .br2 { + border-radius: 0.25rem; +} +.swagger-ui .br3 { + border-radius: 0.5rem; +} +.swagger-ui .br4 { + border-radius: 1rem; +} +.swagger-ui .br-100 { + border-radius: 100%; +} +.swagger-ui .br-pill { + border-radius: 9999px; +} +.swagger-ui .br--bottom { + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.swagger-ui .br--top { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} +.swagger-ui .br--right { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.swagger-ui .br--left { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} +@media screen and (min-width: 30em) { + .swagger-ui .br0-ns { + border-radius: 0; + } + .swagger-ui .br1-ns { + border-radius: 0.125rem; + } + .swagger-ui .br2-ns { + border-radius: 0.25rem; + } + .swagger-ui .br3-ns { + border-radius: 0.5rem; + } + .swagger-ui .br4-ns { + border-radius: 1rem; + } + .swagger-ui .br-100-ns { + border-radius: 100%; + } + .swagger-ui .br-pill-ns { + border-radius: 9999px; + } + .swagger-ui .br--bottom-ns { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + .swagger-ui .br--top-ns { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + .swagger-ui .br--right-ns { + border-bottom-left-radius: 0; + border-top-left-radius: 0; + } + .swagger-ui .br--left-ns { + border-bottom-right-radius: 0; + border-top-right-radius: 0; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .br0-m { + border-radius: 0; + } + .swagger-ui .br1-m { + border-radius: 0.125rem; + } + .swagger-ui .br2-m { + border-radius: 0.25rem; + } + .swagger-ui .br3-m { + border-radius: 0.5rem; + } + .swagger-ui .br4-m { + border-radius: 1rem; + } + .swagger-ui .br-100-m { + border-radius: 100%; + } + .swagger-ui .br-pill-m { + border-radius: 9999px; + } + .swagger-ui .br--bottom-m { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + .swagger-ui .br--top-m { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + .swagger-ui .br--right-m { + border-bottom-left-radius: 0; + border-top-left-radius: 0; + } + .swagger-ui .br--left-m { + border-bottom-right-radius: 0; + border-top-right-radius: 0; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .br0-l { + border-radius: 0; + } + .swagger-ui .br1-l { + border-radius: 0.125rem; + } + .swagger-ui .br2-l { + border-radius: 0.25rem; + } + .swagger-ui .br3-l { + border-radius: 0.5rem; + } + .swagger-ui .br4-l { + border-radius: 1rem; + } + .swagger-ui .br-100-l { + border-radius: 100%; + } + .swagger-ui .br-pill-l { + border-radius: 9999px; + } + .swagger-ui .br--bottom-l { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + .swagger-ui .br--top-l { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + .swagger-ui .br--right-l { + border-bottom-left-radius: 0; + border-top-left-radius: 0; + } + .swagger-ui .br--left-l { + border-bottom-right-radius: 0; + border-top-right-radius: 0; + } +} +.swagger-ui .b--dotted { + border-style: dotted; +} +.swagger-ui .b--dashed { + border-style: dashed; +} +.swagger-ui .b--solid { + border-style: solid; +} +.swagger-ui .b--none { + border-style: none; +} +@media screen and (min-width: 30em) { + .swagger-ui .b--dotted-ns { + border-style: dotted; + } + .swagger-ui .b--dashed-ns { + border-style: dashed; + } + .swagger-ui .b--solid-ns { + border-style: solid; + } + .swagger-ui .b--none-ns { + border-style: none; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .b--dotted-m { + border-style: dotted; + } + .swagger-ui .b--dashed-m { + border-style: dashed; + } + .swagger-ui .b--solid-m { + border-style: solid; + } + .swagger-ui .b--none-m { + border-style: none; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .b--dotted-l { + border-style: dotted; + } + .swagger-ui .b--dashed-l { + border-style: dashed; + } + .swagger-ui .b--solid-l { + border-style: solid; + } + .swagger-ui .b--none-l { + border-style: none; + } +} +.swagger-ui .bw0 { + border-width: 0; +} +.swagger-ui .bw1 { + border-width: 0.125rem; +} +.swagger-ui .bw2 { + border-width: 0.25rem; +} +.swagger-ui .bw3 { + border-width: 0.5rem; +} +.swagger-ui .bw4 { + border-width: 1rem; +} +.swagger-ui .bw5 { + border-width: 2rem; +} +.swagger-ui .bt-0 { + border-top-width: 0; +} +.swagger-ui .br-0 { + border-right-width: 0; +} +.swagger-ui .bb-0 { + border-bottom-width: 0; +} +.swagger-ui .bl-0 { + border-left-width: 0; +} +@media screen and (min-width: 30em) { + .swagger-ui .bw0-ns { + border-width: 0; + } + .swagger-ui .bw1-ns { + border-width: 0.125rem; + } + .swagger-ui .bw2-ns { + border-width: 0.25rem; + } + .swagger-ui .bw3-ns { + border-width: 0.5rem; + } + .swagger-ui .bw4-ns { + border-width: 1rem; + } + .swagger-ui .bw5-ns { + border-width: 2rem; + } + .swagger-ui .bt-0-ns { + border-top-width: 0; + } + .swagger-ui .br-0-ns { + border-right-width: 0; + } + .swagger-ui .bb-0-ns { + border-bottom-width: 0; + } + .swagger-ui .bl-0-ns { + border-left-width: 0; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .bw0-m { + border-width: 0; + } + .swagger-ui .bw1-m { + border-width: 0.125rem; + } + .swagger-ui .bw2-m { + border-width: 0.25rem; + } + .swagger-ui .bw3-m { + border-width: 0.5rem; + } + .swagger-ui .bw4-m { + border-width: 1rem; + } + .swagger-ui .bw5-m { + border-width: 2rem; + } + .swagger-ui .bt-0-m { + border-top-width: 0; + } + .swagger-ui .br-0-m { + border-right-width: 0; + } + .swagger-ui .bb-0-m { + border-bottom-width: 0; + } + .swagger-ui .bl-0-m { + border-left-width: 0; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .bw0-l { + border-width: 0; + } + .swagger-ui .bw1-l { + border-width: 0.125rem; + } + .swagger-ui .bw2-l { + border-width: 0.25rem; + } + .swagger-ui .bw3-l { + border-width: 0.5rem; + } + .swagger-ui .bw4-l { + border-width: 1rem; + } + .swagger-ui .bw5-l { + border-width: 2rem; + } + .swagger-ui .bt-0-l { + border-top-width: 0; + } + .swagger-ui .br-0-l { + border-right-width: 0; + } + .swagger-ui .bb-0-l { + border-bottom-width: 0; + } + .swagger-ui .bl-0-l { + border-left-width: 0; + } +} +.swagger-ui .shadow-1 { + box-shadow: 0 0 4px 2px rgba(0, 0, 0, 0.2); +} +.swagger-ui .shadow-2 { + box-shadow: 0 0 8px 2px rgba(0, 0, 0, 0.2); +} +.swagger-ui .shadow-3 { + box-shadow: 2px 2px 4px 2px rgba(0, 0, 0, 0.2); +} +.swagger-ui .shadow-4 { + box-shadow: 2px 2px 8px 0 rgba(0, 0, 0, 0.2); +} +.swagger-ui .shadow-5 { + box-shadow: 4px 4px 8px 0 rgba(0, 0, 0, 0.2); +} +@media screen and (min-width: 30em) { + .swagger-ui .shadow-1-ns { + box-shadow: 0 0 4px 2px rgba(0, 0, 0, 0.2); + } + .swagger-ui .shadow-2-ns { + box-shadow: 0 0 8px 2px rgba(0, 0, 0, 0.2); + } + .swagger-ui .shadow-3-ns { + box-shadow: 2px 2px 4px 2px rgba(0, 0, 0, 0.2); + } + .swagger-ui .shadow-4-ns { + box-shadow: 2px 2px 8px 0 rgba(0, 0, 0, 0.2); + } + .swagger-ui .shadow-5-ns { + box-shadow: 4px 4px 8px 0 rgba(0, 0, 0, 0.2); + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .shadow-1-m { + box-shadow: 0 0 4px 2px rgba(0, 0, 0, 0.2); + } + .swagger-ui .shadow-2-m { + box-shadow: 0 0 8px 2px rgba(0, 0, 0, 0.2); + } + .swagger-ui .shadow-3-m { + box-shadow: 2px 2px 4px 2px rgba(0, 0, 0, 0.2); + } + .swagger-ui .shadow-4-m { + box-shadow: 2px 2px 8px 0 rgba(0, 0, 0, 0.2); + } + .swagger-ui .shadow-5-m { + box-shadow: 4px 4px 8px 0 rgba(0, 0, 0, 0.2); + } +} +@media screen and (min-width: 60em) { + .swagger-ui .shadow-1-l { + box-shadow: 0 0 4px 2px rgba(0, 0, 0, 0.2); + } + .swagger-ui .shadow-2-l { + box-shadow: 0 0 8px 2px rgba(0, 0, 0, 0.2); + } + .swagger-ui .shadow-3-l { + box-shadow: 2px 2px 4px 2px rgba(0, 0, 0, 0.2); + } + .swagger-ui .shadow-4-l { + box-shadow: 2px 2px 8px 0 rgba(0, 0, 0, 0.2); + } + .swagger-ui .shadow-5-l { + box-shadow: 4px 4px 8px 0 rgba(0, 0, 0, 0.2); + } +} +.swagger-ui .pre { + overflow-x: auto; + overflow-y: hidden; + overflow: scroll; +} +.swagger-ui .top-0 { + top: 0; +} +.swagger-ui .right-0 { + right: 0; +} +.swagger-ui .bottom-0 { + bottom: 0; +} +.swagger-ui .left-0 { + left: 0; +} +.swagger-ui .top-1 { + top: 1rem; +} +.swagger-ui .right-1 { + right: 1rem; +} +.swagger-ui .bottom-1 { + bottom: 1rem; +} +.swagger-ui .left-1 { + left: 1rem; +} +.swagger-ui .top-2 { + top: 2rem; +} +.swagger-ui .right-2 { + right: 2rem; +} +.swagger-ui .bottom-2 { + bottom: 2rem; +} +.swagger-ui .left-2 { + left: 2rem; +} +.swagger-ui .top--1 { + top: -1rem; +} +.swagger-ui .right--1 { + right: -1rem; +} +.swagger-ui .bottom--1 { + bottom: -1rem; +} +.swagger-ui .left--1 { + left: -1rem; +} +.swagger-ui .top--2 { + top: -2rem; +} +.swagger-ui .right--2 { + right: -2rem; +} +.swagger-ui .bottom--2 { + bottom: -2rem; +} +.swagger-ui .left--2 { + left: -2rem; +} +.swagger-ui .absolute--fill { + bottom: 0; + left: 0; + right: 0; + top: 0; +} +@media screen and (min-width: 30em) { + .swagger-ui .top-0-ns { + top: 0; + } + .swagger-ui .left-0-ns { + left: 0; + } + .swagger-ui .right-0-ns { + right: 0; + } + .swagger-ui .bottom-0-ns { + bottom: 0; + } + .swagger-ui .top-1-ns { + top: 1rem; + } + .swagger-ui .left-1-ns { + left: 1rem; + } + .swagger-ui .right-1-ns { + right: 1rem; + } + .swagger-ui .bottom-1-ns { + bottom: 1rem; + } + .swagger-ui .top-2-ns { + top: 2rem; + } + .swagger-ui .left-2-ns { + left: 2rem; + } + .swagger-ui .right-2-ns { + right: 2rem; + } + .swagger-ui .bottom-2-ns { + bottom: 2rem; + } + .swagger-ui .top--1-ns { + top: -1rem; + } + .swagger-ui .right--1-ns { + right: -1rem; + } + .swagger-ui .bottom--1-ns { + bottom: -1rem; + } + .swagger-ui .left--1-ns { + left: -1rem; + } + .swagger-ui .top--2-ns { + top: -2rem; + } + .swagger-ui .right--2-ns { + right: -2rem; + } + .swagger-ui .bottom--2-ns { + bottom: -2rem; + } + .swagger-ui .left--2-ns { + left: -2rem; + } + .swagger-ui .absolute--fill-ns { + bottom: 0; + left: 0; + right: 0; + top: 0; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .top-0-m { + top: 0; + } + .swagger-ui .left-0-m { + left: 0; + } + .swagger-ui .right-0-m { + right: 0; + } + .swagger-ui .bottom-0-m { + bottom: 0; + } + .swagger-ui .top-1-m { + top: 1rem; + } + .swagger-ui .left-1-m { + left: 1rem; + } + .swagger-ui .right-1-m { + right: 1rem; + } + .swagger-ui .bottom-1-m { + bottom: 1rem; + } + .swagger-ui .top-2-m { + top: 2rem; + } + .swagger-ui .left-2-m { + left: 2rem; + } + .swagger-ui .right-2-m { + right: 2rem; + } + .swagger-ui .bottom-2-m { + bottom: 2rem; + } + .swagger-ui .top--1-m { + top: -1rem; + } + .swagger-ui .right--1-m { + right: -1rem; + } + .swagger-ui .bottom--1-m { + bottom: -1rem; + } + .swagger-ui .left--1-m { + left: -1rem; + } + .swagger-ui .top--2-m { + top: -2rem; + } + .swagger-ui .right--2-m { + right: -2rem; + } + .swagger-ui .bottom--2-m { + bottom: -2rem; + } + .swagger-ui .left--2-m { + left: -2rem; + } + .swagger-ui .absolute--fill-m { + bottom: 0; + left: 0; + right: 0; + top: 0; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .top-0-l { + top: 0; + } + .swagger-ui .left-0-l { + left: 0; + } + .swagger-ui .right-0-l { + right: 0; + } + .swagger-ui .bottom-0-l { + bottom: 0; + } + .swagger-ui .top-1-l { + top: 1rem; + } + .swagger-ui .left-1-l { + left: 1rem; + } + .swagger-ui .right-1-l { + right: 1rem; + } + .swagger-ui .bottom-1-l { + bottom: 1rem; + } + .swagger-ui .top-2-l { + top: 2rem; + } + .swagger-ui .left-2-l { + left: 2rem; + } + .swagger-ui .right-2-l { + right: 2rem; + } + .swagger-ui .bottom-2-l { + bottom: 2rem; + } + .swagger-ui .top--1-l { + top: -1rem; + } + .swagger-ui .right--1-l { + right: -1rem; + } + .swagger-ui .bottom--1-l { + bottom: -1rem; + } + .swagger-ui .left--1-l { + left: -1rem; + } + .swagger-ui .top--2-l { + top: -2rem; + } + .swagger-ui .right--2-l { + right: -2rem; + } + .swagger-ui .bottom--2-l { + bottom: -2rem; + } + .swagger-ui .left--2-l { + left: -2rem; + } + .swagger-ui .absolute--fill-l { + bottom: 0; + left: 0; + right: 0; + top: 0; + } +} +.swagger-ui .cf:after, +.swagger-ui .cf:before { + content: ' '; + display: table; +} +.swagger-ui .cf:after { + clear: both; +} +.swagger-ui .cf { + zoom: 1; +} +.swagger-ui .cl { + clear: left; +} +.swagger-ui .cr { + clear: right; +} +.swagger-ui .cb { + clear: both; +} +.swagger-ui .cn { + clear: none; +} +@media screen and (min-width: 30em) { + .swagger-ui .cl-ns { + clear: left; + } + .swagger-ui .cr-ns { + clear: right; + } + .swagger-ui .cb-ns { + clear: both; + } + .swagger-ui .cn-ns { + clear: none; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .cl-m { + clear: left; + } + .swagger-ui .cr-m { + clear: right; + } + .swagger-ui .cb-m { + clear: both; + } + .swagger-ui .cn-m { + clear: none; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .cl-l { + clear: left; + } + .swagger-ui .cr-l { + clear: right; + } + .swagger-ui .cb-l { + clear: both; + } + .swagger-ui .cn-l { + clear: none; + } +} +.swagger-ui .flex { + display: flex; +} +.swagger-ui .inline-flex { + display: inline-flex; +} +.swagger-ui .flex-auto { + flex: 1 1 auto; + min-height: 0; + min-width: 0; +} +.swagger-ui .flex-none { + flex: none; +} +.swagger-ui .flex-column { + flex-direction: column; +} +.swagger-ui .flex-row { + flex-direction: row; +} +.swagger-ui .flex-wrap { + flex-wrap: wrap; +} +.swagger-ui .flex-nowrap { + flex-wrap: nowrap; +} +.swagger-ui .flex-wrap-reverse { + flex-wrap: wrap-reverse; +} +.swagger-ui .flex-column-reverse { + flex-direction: column-reverse; +} +.swagger-ui .flex-row-reverse { + flex-direction: row-reverse; +} +.swagger-ui .items-start { + align-items: flex-start; +} +.swagger-ui .items-end { + align-items: flex-end; +} +.swagger-ui .items-center { + align-items: center; +} +.swagger-ui .items-baseline { + align-items: baseline; +} +.swagger-ui .items-stretch { + align-items: stretch; +} +.swagger-ui .self-start { + align-self: flex-start; +} +.swagger-ui .self-end { + align-self: flex-end; +} +.swagger-ui .self-center { + align-self: center; +} +.swagger-ui .self-baseline { + align-self: baseline; +} +.swagger-ui .self-stretch { + align-self: stretch; +} +.swagger-ui .justify-start { + justify-content: flex-start; +} +.swagger-ui .justify-end { + justify-content: flex-end; +} +.swagger-ui .justify-center { + justify-content: center; +} +.swagger-ui .justify-between { + justify-content: space-between; +} +.swagger-ui .justify-around { + justify-content: space-around; +} +.swagger-ui .content-start { + align-content: flex-start; +} +.swagger-ui .content-end { + align-content: flex-end; +} +.swagger-ui .content-center { + align-content: center; +} +.swagger-ui .content-between { + align-content: space-between; +} +.swagger-ui .content-around { + align-content: space-around; +} +.swagger-ui .content-stretch { + align-content: stretch; +} +.swagger-ui .order-0 { + order: 0; +} +.swagger-ui .order-1 { + order: 1; +} +.swagger-ui .order-2 { + order: 2; +} +.swagger-ui .order-3 { + order: 3; +} +.swagger-ui .order-4 { + order: 4; +} +.swagger-ui .order-5 { + order: 5; +} +.swagger-ui .order-6 { + order: 6; +} +.swagger-ui .order-7 { + order: 7; +} +.swagger-ui .order-8 { + order: 8; +} +.swagger-ui .order-last { + order: 99999; +} +.swagger-ui .flex-grow-0 { + flex-grow: 0; +} +.swagger-ui .flex-grow-1 { + flex-grow: 1; +} +.swagger-ui .flex-shrink-0 { + flex-shrink: 0; +} +.swagger-ui .flex-shrink-1 { + flex-shrink: 1; +} +@media screen and (min-width: 30em) { + .swagger-ui .flex-ns { + display: flex; + } + .swagger-ui .inline-flex-ns { + display: inline-flex; + } + .swagger-ui .flex-auto-ns { + flex: 1 1 auto; + min-height: 0; + min-width: 0; + } + .swagger-ui .flex-none-ns { + flex: none; + } + .swagger-ui .flex-column-ns { + flex-direction: column; + } + .swagger-ui .flex-row-ns { + flex-direction: row; + } + .swagger-ui .flex-wrap-ns { + flex-wrap: wrap; + } + .swagger-ui .flex-nowrap-ns { + flex-wrap: nowrap; + } + .swagger-ui .flex-wrap-reverse-ns { + flex-wrap: wrap-reverse; + } + .swagger-ui .flex-column-reverse-ns { + flex-direction: column-reverse; + } + .swagger-ui .flex-row-reverse-ns { + flex-direction: row-reverse; + } + .swagger-ui .items-start-ns { + align-items: flex-start; + } + .swagger-ui .items-end-ns { + align-items: flex-end; + } + .swagger-ui .items-center-ns { + align-items: center; + } + .swagger-ui .items-baseline-ns { + align-items: baseline; + } + .swagger-ui .items-stretch-ns { + align-items: stretch; + } + .swagger-ui .self-start-ns { + align-self: flex-start; + } + .swagger-ui .self-end-ns { + align-self: flex-end; + } + .swagger-ui .self-center-ns { + align-self: center; + } + .swagger-ui .self-baseline-ns { + align-self: baseline; + } + .swagger-ui .self-stretch-ns { + align-self: stretch; + } + .swagger-ui .justify-start-ns { + justify-content: flex-start; + } + .swagger-ui .justify-end-ns { + justify-content: flex-end; + } + .swagger-ui .justify-center-ns { + justify-content: center; + } + .swagger-ui .justify-between-ns { + justify-content: space-between; + } + .swagger-ui .justify-around-ns { + justify-content: space-around; + } + .swagger-ui .content-start-ns { + align-content: flex-start; + } + .swagger-ui .content-end-ns { + align-content: flex-end; + } + .swagger-ui .content-center-ns { + align-content: center; + } + .swagger-ui .content-between-ns { + align-content: space-between; + } + .swagger-ui .content-around-ns { + align-content: space-around; + } + .swagger-ui .content-stretch-ns { + align-content: stretch; + } + .swagger-ui .order-0-ns { + order: 0; + } + .swagger-ui .order-1-ns { + order: 1; + } + .swagger-ui .order-2-ns { + order: 2; + } + .swagger-ui .order-3-ns { + order: 3; + } + .swagger-ui .order-4-ns { + order: 4; + } + .swagger-ui .order-5-ns { + order: 5; + } + .swagger-ui .order-6-ns { + order: 6; + } + .swagger-ui .order-7-ns { + order: 7; + } + .swagger-ui .order-8-ns { + order: 8; + } + .swagger-ui .order-last-ns { + order: 99999; + } + .swagger-ui .flex-grow-0-ns { + flex-grow: 0; + } + .swagger-ui .flex-grow-1-ns { + flex-grow: 1; + } + .swagger-ui .flex-shrink-0-ns { + flex-shrink: 0; + } + .swagger-ui .flex-shrink-1-ns { + flex-shrink: 1; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .flex-m { + display: flex; + } + .swagger-ui .inline-flex-m { + display: inline-flex; + } + .swagger-ui .flex-auto-m { + flex: 1 1 auto; + min-height: 0; + min-width: 0; + } + .swagger-ui .flex-none-m { + flex: none; + } + .swagger-ui .flex-column-m { + flex-direction: column; + } + .swagger-ui .flex-row-m { + flex-direction: row; + } + .swagger-ui .flex-wrap-m { + flex-wrap: wrap; + } + .swagger-ui .flex-nowrap-m { + flex-wrap: nowrap; + } + .swagger-ui .flex-wrap-reverse-m { + flex-wrap: wrap-reverse; + } + .swagger-ui .flex-column-reverse-m { + flex-direction: column-reverse; + } + .swagger-ui .flex-row-reverse-m { + flex-direction: row-reverse; + } + .swagger-ui .items-start-m { + align-items: flex-start; + } + .swagger-ui .items-end-m { + align-items: flex-end; + } + .swagger-ui .items-center-m { + align-items: center; + } + .swagger-ui .items-baseline-m { + align-items: baseline; + } + .swagger-ui .items-stretch-m { + align-items: stretch; + } + .swagger-ui .self-start-m { + align-self: flex-start; + } + .swagger-ui .self-end-m { + align-self: flex-end; + } + .swagger-ui .self-center-m { + align-self: center; + } + .swagger-ui .self-baseline-m { + align-self: baseline; + } + .swagger-ui .self-stretch-m { + align-self: stretch; + } + .swagger-ui .justify-start-m { + justify-content: flex-start; + } + .swagger-ui .justify-end-m { + justify-content: flex-end; + } + .swagger-ui .justify-center-m { + justify-content: center; + } + .swagger-ui .justify-between-m { + justify-content: space-between; + } + .swagger-ui .justify-around-m { + justify-content: space-around; + } + .swagger-ui .content-start-m { + align-content: flex-start; + } + .swagger-ui .content-end-m { + align-content: flex-end; + } + .swagger-ui .content-center-m { + align-content: center; + } + .swagger-ui .content-between-m { + align-content: space-between; + } + .swagger-ui .content-around-m { + align-content: space-around; + } + .swagger-ui .content-stretch-m { + align-content: stretch; + } + .swagger-ui .order-0-m { + order: 0; + } + .swagger-ui .order-1-m { + order: 1; + } + .swagger-ui .order-2-m { + order: 2; + } + .swagger-ui .order-3-m { + order: 3; + } + .swagger-ui .order-4-m { + order: 4; + } + .swagger-ui .order-5-m { + order: 5; + } + .swagger-ui .order-6-m { + order: 6; + } + .swagger-ui .order-7-m { + order: 7; + } + .swagger-ui .order-8-m { + order: 8; + } + .swagger-ui .order-last-m { + order: 99999; + } + .swagger-ui .flex-grow-0-m { + flex-grow: 0; + } + .swagger-ui .flex-grow-1-m { + flex-grow: 1; + } + .swagger-ui .flex-shrink-0-m { + flex-shrink: 0; + } + .swagger-ui .flex-shrink-1-m { + flex-shrink: 1; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .flex-l { + display: flex; + } + .swagger-ui .inline-flex-l { + display: inline-flex; + } + .swagger-ui .flex-auto-l { + flex: 1 1 auto; + min-height: 0; + min-width: 0; + } + .swagger-ui .flex-none-l { + flex: none; + } + .swagger-ui .flex-column-l { + flex-direction: column; + } + .swagger-ui .flex-row-l { + flex-direction: row; + } + .swagger-ui .flex-wrap-l { + flex-wrap: wrap; + } + .swagger-ui .flex-nowrap-l { + flex-wrap: nowrap; + } + .swagger-ui .flex-wrap-reverse-l { + flex-wrap: wrap-reverse; + } + .swagger-ui .flex-column-reverse-l { + flex-direction: column-reverse; + } + .swagger-ui .flex-row-reverse-l { + flex-direction: row-reverse; + } + .swagger-ui .items-start-l { + align-items: flex-start; + } + .swagger-ui .items-end-l { + align-items: flex-end; + } + .swagger-ui .items-center-l { + align-items: center; + } + .swagger-ui .items-baseline-l { + align-items: baseline; + } + .swagger-ui .items-stretch-l { + align-items: stretch; + } + .swagger-ui .self-start-l { + align-self: flex-start; + } + .swagger-ui .self-end-l { + align-self: flex-end; + } + .swagger-ui .self-center-l { + align-self: center; + } + .swagger-ui .self-baseline-l { + align-self: baseline; + } + .swagger-ui .self-stretch-l { + align-self: stretch; + } + .swagger-ui .justify-start-l { + justify-content: flex-start; + } + .swagger-ui .justify-end-l { + justify-content: flex-end; + } + .swagger-ui .justify-center-l { + justify-content: center; + } + .swagger-ui .justify-between-l { + justify-content: space-between; + } + .swagger-ui .justify-around-l { + justify-content: space-around; + } + .swagger-ui .content-start-l { + align-content: flex-start; + } + .swagger-ui .content-end-l { + align-content: flex-end; + } + .swagger-ui .content-center-l { + align-content: center; + } + .swagger-ui .content-between-l { + align-content: space-between; + } + .swagger-ui .content-around-l { + align-content: space-around; + } + .swagger-ui .content-stretch-l { + align-content: stretch; + } + .swagger-ui .order-0-l { + order: 0; + } + .swagger-ui .order-1-l { + order: 1; + } + .swagger-ui .order-2-l { + order: 2; + } + .swagger-ui .order-3-l { + order: 3; + } + .swagger-ui .order-4-l { + order: 4; + } + .swagger-ui .order-5-l { + order: 5; + } + .swagger-ui .order-6-l { + order: 6; + } + .swagger-ui .order-7-l { + order: 7; + } + .swagger-ui .order-8-l { + order: 8; + } + .swagger-ui .order-last-l { + order: 99999; + } + .swagger-ui .flex-grow-0-l { + flex-grow: 0; + } + .swagger-ui .flex-grow-1-l { + flex-grow: 1; + } + .swagger-ui .flex-shrink-0-l { + flex-shrink: 0; + } + .swagger-ui .flex-shrink-1-l { + flex-shrink: 1; + } +} +.swagger-ui .dn { + display: none; +} +.swagger-ui .di { + display: inline; +} +.swagger-ui .db { + display: block; +} +.swagger-ui .dib { + display: inline-block; +} +.swagger-ui .dit { + display: inline-table; +} +.swagger-ui .dt { + display: table; +} +.swagger-ui .dtc { + display: table-cell; +} +.swagger-ui .dt-row { + display: table-row; +} +.swagger-ui .dt-row-group { + display: table-row-group; +} +.swagger-ui .dt-column { + display: table-column; +} +.swagger-ui .dt-column-group { + display: table-column-group; +} +.swagger-ui .dt--fixed { + table-layout: fixed; + width: 100%; +} +@media screen and (min-width: 30em) { + .swagger-ui .dn-ns { + display: none; + } + .swagger-ui .di-ns { + display: inline; + } + .swagger-ui .db-ns { + display: block; + } + .swagger-ui .dib-ns { + display: inline-block; + } + .swagger-ui .dit-ns { + display: inline-table; + } + .swagger-ui .dt-ns { + display: table; + } + .swagger-ui .dtc-ns { + display: table-cell; + } + .swagger-ui .dt-row-ns { + display: table-row; + } + .swagger-ui .dt-row-group-ns { + display: table-row-group; + } + .swagger-ui .dt-column-ns { + display: table-column; + } + .swagger-ui .dt-column-group-ns { + display: table-column-group; + } + .swagger-ui .dt--fixed-ns { + table-layout: fixed; + width: 100%; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .dn-m { + display: none; + } + .swagger-ui .di-m { + display: inline; + } + .swagger-ui .db-m { + display: block; + } + .swagger-ui .dib-m { + display: inline-block; + } + .swagger-ui .dit-m { + display: inline-table; + } + .swagger-ui .dt-m { + display: table; + } + .swagger-ui .dtc-m { + display: table-cell; + } + .swagger-ui .dt-row-m { + display: table-row; + } + .swagger-ui .dt-row-group-m { + display: table-row-group; + } + .swagger-ui .dt-column-m { + display: table-column; + } + .swagger-ui .dt-column-group-m { + display: table-column-group; + } + .swagger-ui .dt--fixed-m { + table-layout: fixed; + width: 100%; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .dn-l { + display: none; + } + .swagger-ui .di-l { + display: inline; + } + .swagger-ui .db-l { + display: block; + } + .swagger-ui .dib-l { + display: inline-block; + } + .swagger-ui .dit-l { + display: inline-table; + } + .swagger-ui .dt-l { + display: table; + } + .swagger-ui .dtc-l { + display: table-cell; + } + .swagger-ui .dt-row-l { + display: table-row; + } + .swagger-ui .dt-row-group-l { + display: table-row-group; + } + .swagger-ui .dt-column-l { + display: table-column; + } + .swagger-ui .dt-column-group-l { + display: table-column-group; + } + .swagger-ui .dt--fixed-l { + table-layout: fixed; + width: 100%; + } +} +.swagger-ui .fl { + _display: inline; + float: left; +} +.swagger-ui .fr { + _display: inline; + float: right; +} +.swagger-ui .fn { + float: none; +} +@media screen and (min-width: 30em) { + .swagger-ui .fl-ns { + _display: inline; + float: left; + } + .swagger-ui .fr-ns { + _display: inline; + float: right; + } + .swagger-ui .fn-ns { + float: none; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .fl-m { + _display: inline; + float: left; + } + .swagger-ui .fr-m { + _display: inline; + float: right; + } + .swagger-ui .fn-m { + float: none; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .fl-l { + _display: inline; + float: left; + } + .swagger-ui .fr-l { + _display: inline; + float: right; + } + .swagger-ui .fn-l { + float: none; + } +} +.swagger-ui .sans-serif { + font-family: + -apple-system, + BlinkMacSystemFont, + avenir next, + avenir, + helvetica, + helvetica neue, + ubuntu, + roboto, + noto, + segoe ui, + arial, + sans-serif; +} +.swagger-ui .serif { + font-family: georgia, serif; +} +.swagger-ui .system-sans-serif { + font-family: sans-serif; +} +.swagger-ui .system-serif { + font-family: serif; +} +.swagger-ui .code, +.swagger-ui code { + font-family: Consolas, monaco, monospace; +} +.swagger-ui .courier { + font-family: + Courier Next, + courier, + monospace; +} +.swagger-ui .helvetica { + font-family: + helvetica neue, + helvetica, + sans-serif; +} +.swagger-ui .avenir { + font-family: + avenir next, + avenir, + sans-serif; +} +.swagger-ui .athelas { + font-family: athelas, georgia, serif; +} +.swagger-ui .georgia { + font-family: georgia, serif; +} +.swagger-ui .times { + font-family: times, serif; +} +.swagger-ui .bodoni { + font-family: + Bodoni MT, + serif; +} +.swagger-ui .calisto { + font-family: + Calisto MT, + serif; +} +.swagger-ui .garamond { + font-family: garamond, serif; +} +.swagger-ui .baskerville { + font-family: baskerville, serif; +} +.swagger-ui .i { + font-style: italic; +} +.swagger-ui .fs-normal { + font-style: normal; +} +@media screen and (min-width: 30em) { + .swagger-ui .i-ns { + font-style: italic; + } + .swagger-ui .fs-normal-ns { + font-style: normal; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .i-m { + font-style: italic; + } + .swagger-ui .fs-normal-m { + font-style: normal; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .i-l { + font-style: italic; + } + .swagger-ui .fs-normal-l { + font-style: normal; + } +} +.swagger-ui .normal { + font-weight: 400; +} +.swagger-ui .b { + font-weight: 700; +} +.swagger-ui .fw1 { + font-weight: 100; +} +.swagger-ui .fw2 { + font-weight: 200; +} +.swagger-ui .fw3 { + font-weight: 300; +} +.swagger-ui .fw4 { + font-weight: 400; +} +.swagger-ui .fw5 { + font-weight: 500; +} +.swagger-ui .fw6 { + font-weight: 600; +} +.swagger-ui .fw7 { + font-weight: 700; +} +.swagger-ui .fw8 { + font-weight: 800; +} +.swagger-ui .fw9 { + font-weight: 900; +} +@media screen and (min-width: 30em) { + .swagger-ui .normal-ns { + font-weight: 400; + } + .swagger-ui .b-ns { + font-weight: 700; + } + .swagger-ui .fw1-ns { + font-weight: 100; + } + .swagger-ui .fw2-ns { + font-weight: 200; + } + .swagger-ui .fw3-ns { + font-weight: 300; + } + .swagger-ui .fw4-ns { + font-weight: 400; + } + .swagger-ui .fw5-ns { + font-weight: 500; + } + .swagger-ui .fw6-ns { + font-weight: 600; + } + .swagger-ui .fw7-ns { + font-weight: 700; + } + .swagger-ui .fw8-ns { + font-weight: 800; + } + .swagger-ui .fw9-ns { + font-weight: 900; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .normal-m { + font-weight: 400; + } + .swagger-ui .b-m { + font-weight: 700; + } + .swagger-ui .fw1-m { + font-weight: 100; + } + .swagger-ui .fw2-m { + font-weight: 200; + } + .swagger-ui .fw3-m { + font-weight: 300; + } + .swagger-ui .fw4-m { + font-weight: 400; + } + .swagger-ui .fw5-m { + font-weight: 500; + } + .swagger-ui .fw6-m { + font-weight: 600; + } + .swagger-ui .fw7-m { + font-weight: 700; + } + .swagger-ui .fw8-m { + font-weight: 800; + } + .swagger-ui .fw9-m { + font-weight: 900; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .normal-l { + font-weight: 400; + } + .swagger-ui .b-l { + font-weight: 700; + } + .swagger-ui .fw1-l { + font-weight: 100; + } + .swagger-ui .fw2-l { + font-weight: 200; + } + .swagger-ui .fw3-l { + font-weight: 300; + } + .swagger-ui .fw4-l { + font-weight: 400; + } + .swagger-ui .fw5-l { + font-weight: 500; + } + .swagger-ui .fw6-l { + font-weight: 600; + } + .swagger-ui .fw7-l { + font-weight: 700; + } + .swagger-ui .fw8-l { + font-weight: 800; + } + .swagger-ui .fw9-l { + font-weight: 900; + } +} +.swagger-ui .input-reset { + -webkit-appearance: none; + -moz-appearance: none; +} +.swagger-ui .button-reset::-moz-focus-inner, +.swagger-ui .input-reset::-moz-focus-inner { + border: 0; + padding: 0; +} +.swagger-ui .h1 { + height: 1rem; +} +.swagger-ui .h2 { + height: 2rem; +} +.swagger-ui .h3 { + height: 4rem; +} +.swagger-ui .h4 { + height: 8rem; +} +.swagger-ui .h5 { + height: 16rem; +} +.swagger-ui .h-25 { + height: 25%; +} +.swagger-ui .h-50 { + height: 50%; +} +.swagger-ui .h-75 { + height: 75%; +} +.swagger-ui .h-100 { + height: 100%; +} +.swagger-ui .min-h-100 { + min-height: 100%; +} +.swagger-ui .vh-25 { + height: 25vh; +} +.swagger-ui .vh-50 { + height: 50vh; +} +.swagger-ui .vh-75 { + height: 75vh; +} +.swagger-ui .vh-100 { + height: 100vh; +} +.swagger-ui .min-vh-100 { + min-height: 100vh; +} +.swagger-ui .h-auto { + height: auto; +} +.swagger-ui .h-inherit { + height: inherit; +} +@media screen and (min-width: 30em) { + .swagger-ui .h1-ns { + height: 1rem; + } + .swagger-ui .h2-ns { + height: 2rem; + } + .swagger-ui .h3-ns { + height: 4rem; + } + .swagger-ui .h4-ns { + height: 8rem; + } + .swagger-ui .h5-ns { + height: 16rem; + } + .swagger-ui .h-25-ns { + height: 25%; + } + .swagger-ui .h-50-ns { + height: 50%; + } + .swagger-ui .h-75-ns { + height: 75%; + } + .swagger-ui .h-100-ns { + height: 100%; + } + .swagger-ui .min-h-100-ns { + min-height: 100%; + } + .swagger-ui .vh-25-ns { + height: 25vh; + } + .swagger-ui .vh-50-ns { + height: 50vh; + } + .swagger-ui .vh-75-ns { + height: 75vh; + } + .swagger-ui .vh-100-ns { + height: 100vh; + } + .swagger-ui .min-vh-100-ns { + min-height: 100vh; + } + .swagger-ui .h-auto-ns { + height: auto; + } + .swagger-ui .h-inherit-ns { + height: inherit; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .h1-m { + height: 1rem; + } + .swagger-ui .h2-m { + height: 2rem; + } + .swagger-ui .h3-m { + height: 4rem; + } + .swagger-ui .h4-m { + height: 8rem; + } + .swagger-ui .h5-m { + height: 16rem; + } + .swagger-ui .h-25-m { + height: 25%; + } + .swagger-ui .h-50-m { + height: 50%; + } + .swagger-ui .h-75-m { + height: 75%; + } + .swagger-ui .h-100-m { + height: 100%; + } + .swagger-ui .min-h-100-m { + min-height: 100%; + } + .swagger-ui .vh-25-m { + height: 25vh; + } + .swagger-ui .vh-50-m { + height: 50vh; + } + .swagger-ui .vh-75-m { + height: 75vh; + } + .swagger-ui .vh-100-m { + height: 100vh; + } + .swagger-ui .min-vh-100-m { + min-height: 100vh; + } + .swagger-ui .h-auto-m { + height: auto; + } + .swagger-ui .h-inherit-m { + height: inherit; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .h1-l { + height: 1rem; + } + .swagger-ui .h2-l { + height: 2rem; + } + .swagger-ui .h3-l { + height: 4rem; + } + .swagger-ui .h4-l { + height: 8rem; + } + .swagger-ui .h5-l { + height: 16rem; + } + .swagger-ui .h-25-l { + height: 25%; + } + .swagger-ui .h-50-l { + height: 50%; + } + .swagger-ui .h-75-l { + height: 75%; + } + .swagger-ui .h-100-l { + height: 100%; + } + .swagger-ui .min-h-100-l { + min-height: 100%; + } + .swagger-ui .vh-25-l { + height: 25vh; + } + .swagger-ui .vh-50-l { + height: 50vh; + } + .swagger-ui .vh-75-l { + height: 75vh; + } + .swagger-ui .vh-100-l { + height: 100vh; + } + .swagger-ui .min-vh-100-l { + min-height: 100vh; + } + .swagger-ui .h-auto-l { + height: auto; + } + .swagger-ui .h-inherit-l { + height: inherit; + } +} +.swagger-ui .tracked { + letter-spacing: 0.1em; +} +.swagger-ui .tracked-tight { + letter-spacing: -0.05em; +} +.swagger-ui .tracked-mega { + letter-spacing: 0.25em; +} +@media screen and (min-width: 30em) { + .swagger-ui .tracked-ns { + letter-spacing: 0.1em; + } + .swagger-ui .tracked-tight-ns { + letter-spacing: -0.05em; + } + .swagger-ui .tracked-mega-ns { + letter-spacing: 0.25em; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .tracked-m { + letter-spacing: 0.1em; + } + .swagger-ui .tracked-tight-m { + letter-spacing: -0.05em; + } + .swagger-ui .tracked-mega-m { + letter-spacing: 0.25em; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .tracked-l { + letter-spacing: 0.1em; + } + .swagger-ui .tracked-tight-l { + letter-spacing: -0.05em; + } + .swagger-ui .tracked-mega-l { + letter-spacing: 0.25em; + } +} +.swagger-ui .lh-solid { + line-height: 1; +} +.swagger-ui .lh-title { + line-height: 1.25; +} +.swagger-ui .lh-copy { + line-height: 1.5; +} +@media screen and (min-width: 30em) { + .swagger-ui .lh-solid-ns { + line-height: 1; + } + .swagger-ui .lh-title-ns { + line-height: 1.25; + } + .swagger-ui .lh-copy-ns { + line-height: 1.5; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .lh-solid-m { + line-height: 1; + } + .swagger-ui .lh-title-m { + line-height: 1.25; + } + .swagger-ui .lh-copy-m { + line-height: 1.5; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .lh-solid-l { + line-height: 1; + } + .swagger-ui .lh-title-l { + line-height: 1.25; + } + .swagger-ui .lh-copy-l { + line-height: 1.5; + } +} +.swagger-ui .link { + -webkit-text-decoration: none; + text-decoration: none; +} +.swagger-ui .link, +.swagger-ui .link:active, +.swagger-ui .link:focus, +.swagger-ui .link:hover, +.swagger-ui .link:link, +.swagger-ui .link:visited { + transition: color 0.15s ease-in; +} +.swagger-ui .link:focus { + outline: 1px dotted currentColor; +} +.swagger-ui .list { + list-style-type: none; +} +.swagger-ui .mw-100 { + max-width: 100%; +} +.swagger-ui .mw1 { + max-width: 1rem; +} +.swagger-ui .mw2 { + max-width: 2rem; +} +.swagger-ui .mw3 { + max-width: 4rem; +} +.swagger-ui .mw4 { + max-width: 8rem; +} +.swagger-ui .mw5 { + max-width: 16rem; +} +.swagger-ui .mw6 { + max-width: 32rem; +} +.swagger-ui .mw7 { + max-width: 48rem; +} +.swagger-ui .mw8 { + max-width: 64rem; +} +.swagger-ui .mw9 { + max-width: 96rem; +} +.swagger-ui .mw-none { + max-width: none; +} +@media screen and (min-width: 30em) { + .swagger-ui .mw-100-ns { + max-width: 100%; + } + .swagger-ui .mw1-ns { + max-width: 1rem; + } + .swagger-ui .mw2-ns { + max-width: 2rem; + } + .swagger-ui .mw3-ns { + max-width: 4rem; + } + .swagger-ui .mw4-ns { + max-width: 8rem; + } + .swagger-ui .mw5-ns { + max-width: 16rem; + } + .swagger-ui .mw6-ns { + max-width: 32rem; + } + .swagger-ui .mw7-ns { + max-width: 48rem; + } + .swagger-ui .mw8-ns { + max-width: 64rem; + } + .swagger-ui .mw9-ns { + max-width: 96rem; + } + .swagger-ui .mw-none-ns { + max-width: none; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .mw-100-m { + max-width: 100%; + } + .swagger-ui .mw1-m { + max-width: 1rem; + } + .swagger-ui .mw2-m { + max-width: 2rem; + } + .swagger-ui .mw3-m { + max-width: 4rem; + } + .swagger-ui .mw4-m { + max-width: 8rem; + } + .swagger-ui .mw5-m { + max-width: 16rem; + } + .swagger-ui .mw6-m { + max-width: 32rem; + } + .swagger-ui .mw7-m { + max-width: 48rem; + } + .swagger-ui .mw8-m { + max-width: 64rem; + } + .swagger-ui .mw9-m { + max-width: 96rem; + } + .swagger-ui .mw-none-m { + max-width: none; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .mw-100-l { + max-width: 100%; + } + .swagger-ui .mw1-l { + max-width: 1rem; + } + .swagger-ui .mw2-l { + max-width: 2rem; + } + .swagger-ui .mw3-l { + max-width: 4rem; + } + .swagger-ui .mw4-l { + max-width: 8rem; + } + .swagger-ui .mw5-l { + max-width: 16rem; + } + .swagger-ui .mw6-l { + max-width: 32rem; + } + .swagger-ui .mw7-l { + max-width: 48rem; + } + .swagger-ui .mw8-l { + max-width: 64rem; + } + .swagger-ui .mw9-l { + max-width: 96rem; + } + .swagger-ui .mw-none-l { + max-width: none; + } +} +.swagger-ui .w1 { + width: 1rem; +} +.swagger-ui .w2 { + width: 2rem; +} +.swagger-ui .w3 { + width: 4rem; +} +.swagger-ui .w4 { + width: 8rem; +} +.swagger-ui .w5 { + width: 16rem; +} +.swagger-ui .w-10 { + width: 10%; +} +.swagger-ui .w-20 { + width: 20%; +} +.swagger-ui .w-25 { + width: 25%; +} +.swagger-ui .w-30 { + width: 30%; +} +.swagger-ui .w-33 { + width: 33%; +} +.swagger-ui .w-34 { + width: 34%; +} +.swagger-ui .w-40 { + width: 40%; +} +.swagger-ui .w-50 { + width: 50%; +} +.swagger-ui .w-60 { + width: 60%; +} +.swagger-ui .w-70 { + width: 70%; +} +.swagger-ui .w-75 { + width: 75%; +} +.swagger-ui .w-80 { + width: 80%; +} +.swagger-ui .w-90 { + width: 90%; +} +.swagger-ui .w-100 { + width: 100%; +} +.swagger-ui .w-third { + width: 33.3333333333%; +} +.swagger-ui .w-two-thirds { + width: 66.6666666667%; +} +.swagger-ui .w-auto { + width: auto; +} +@media screen and (min-width: 30em) { + .swagger-ui .w1-ns { + width: 1rem; + } + .swagger-ui .w2-ns { + width: 2rem; + } + .swagger-ui .w3-ns { + width: 4rem; + } + .swagger-ui .w4-ns { + width: 8rem; + } + .swagger-ui .w5-ns { + width: 16rem; + } + .swagger-ui .w-10-ns { + width: 10%; + } + .swagger-ui .w-20-ns { + width: 20%; + } + .swagger-ui .w-25-ns { + width: 25%; + } + .swagger-ui .w-30-ns { + width: 30%; + } + .swagger-ui .w-33-ns { + width: 33%; + } + .swagger-ui .w-34-ns { + width: 34%; + } + .swagger-ui .w-40-ns { + width: 40%; + } + .swagger-ui .w-50-ns { + width: 50%; + } + .swagger-ui .w-60-ns { + width: 60%; + } + .swagger-ui .w-70-ns { + width: 70%; + } + .swagger-ui .w-75-ns { + width: 75%; + } + .swagger-ui .w-80-ns { + width: 80%; + } + .swagger-ui .w-90-ns { + width: 90%; + } + .swagger-ui .w-100-ns { + width: 100%; + } + .swagger-ui .w-third-ns { + width: 33.3333333333%; + } + .swagger-ui .w-two-thirds-ns { + width: 66.6666666667%; + } + .swagger-ui .w-auto-ns { + width: auto; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .w1-m { + width: 1rem; + } + .swagger-ui .w2-m { + width: 2rem; + } + .swagger-ui .w3-m { + width: 4rem; + } + .swagger-ui .w4-m { + width: 8rem; + } + .swagger-ui .w5-m { + width: 16rem; + } + .swagger-ui .w-10-m { + width: 10%; + } + .swagger-ui .w-20-m { + width: 20%; + } + .swagger-ui .w-25-m { + width: 25%; + } + .swagger-ui .w-30-m { + width: 30%; + } + .swagger-ui .w-33-m { + width: 33%; + } + .swagger-ui .w-34-m { + width: 34%; + } + .swagger-ui .w-40-m { + width: 40%; + } + .swagger-ui .w-50-m { + width: 50%; + } + .swagger-ui .w-60-m { + width: 60%; + } + .swagger-ui .w-70-m { + width: 70%; + } + .swagger-ui .w-75-m { + width: 75%; + } + .swagger-ui .w-80-m { + width: 80%; + } + .swagger-ui .w-90-m { + width: 90%; + } + .swagger-ui .w-100-m { + width: 100%; + } + .swagger-ui .w-third-m { + width: 33.3333333333%; + } + .swagger-ui .w-two-thirds-m { + width: 66.6666666667%; + } + .swagger-ui .w-auto-m { + width: auto; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .w1-l { + width: 1rem; + } + .swagger-ui .w2-l { + width: 2rem; + } + .swagger-ui .w3-l { + width: 4rem; + } + .swagger-ui .w4-l { + width: 8rem; + } + .swagger-ui .w5-l { + width: 16rem; + } + .swagger-ui .w-10-l { + width: 10%; + } + .swagger-ui .w-20-l { + width: 20%; + } + .swagger-ui .w-25-l { + width: 25%; + } + .swagger-ui .w-30-l { + width: 30%; + } + .swagger-ui .w-33-l { + width: 33%; + } + .swagger-ui .w-34-l { + width: 34%; + } + .swagger-ui .w-40-l { + width: 40%; + } + .swagger-ui .w-50-l { + width: 50%; + } + .swagger-ui .w-60-l { + width: 60%; + } + .swagger-ui .w-70-l { + width: 70%; + } + .swagger-ui .w-75-l { + width: 75%; + } + .swagger-ui .w-80-l { + width: 80%; + } + .swagger-ui .w-90-l { + width: 90%; + } + .swagger-ui .w-100-l { + width: 100%; + } + .swagger-ui .w-third-l { + width: 33.3333333333%; + } + .swagger-ui .w-two-thirds-l { + width: 66.6666666667%; + } + .swagger-ui .w-auto-l { + width: auto; + } +} +.swagger-ui .overflow-visible { + overflow: visible; +} +.swagger-ui .overflow-hidden { + overflow: hidden; +} +.swagger-ui .overflow-scroll { + overflow: scroll; +} +.swagger-ui .overflow-auto { + overflow: auto; +} +.swagger-ui .overflow-x-visible { + overflow-x: visible; +} +.swagger-ui .overflow-x-hidden { + overflow-x: hidden; +} +.swagger-ui .overflow-x-scroll { + overflow-x: scroll; +} +.swagger-ui .overflow-x-auto { + overflow-x: auto; +} +.swagger-ui .overflow-y-visible { + overflow-y: visible; +} +.swagger-ui .overflow-y-hidden { + overflow-y: hidden; +} +.swagger-ui .overflow-y-scroll { + overflow-y: scroll; +} +.swagger-ui .overflow-y-auto { + overflow-y: auto; +} +@media screen and (min-width: 30em) { + .swagger-ui .overflow-visible-ns { + overflow: visible; + } + .swagger-ui .overflow-hidden-ns { + overflow: hidden; + } + .swagger-ui .overflow-scroll-ns { + overflow: scroll; + } + .swagger-ui .overflow-auto-ns { + overflow: auto; + } + .swagger-ui .overflow-x-visible-ns { + overflow-x: visible; + } + .swagger-ui .overflow-x-hidden-ns { + overflow-x: hidden; + } + .swagger-ui .overflow-x-scroll-ns { + overflow-x: scroll; + } + .swagger-ui .overflow-x-auto-ns { + overflow-x: auto; + } + .swagger-ui .overflow-y-visible-ns { + overflow-y: visible; + } + .swagger-ui .overflow-y-hidden-ns { + overflow-y: hidden; + } + .swagger-ui .overflow-y-scroll-ns { + overflow-y: scroll; + } + .swagger-ui .overflow-y-auto-ns { + overflow-y: auto; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .overflow-visible-m { + overflow: visible; + } + .swagger-ui .overflow-hidden-m { + overflow: hidden; + } + .swagger-ui .overflow-scroll-m { + overflow: scroll; + } + .swagger-ui .overflow-auto-m { + overflow: auto; + } + .swagger-ui .overflow-x-visible-m { + overflow-x: visible; + } + .swagger-ui .overflow-x-hidden-m { + overflow-x: hidden; + } + .swagger-ui .overflow-x-scroll-m { + overflow-x: scroll; + } + .swagger-ui .overflow-x-auto-m { + overflow-x: auto; + } + .swagger-ui .overflow-y-visible-m { + overflow-y: visible; + } + .swagger-ui .overflow-y-hidden-m { + overflow-y: hidden; + } + .swagger-ui .overflow-y-scroll-m { + overflow-y: scroll; + } + .swagger-ui .overflow-y-auto-m { + overflow-y: auto; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .overflow-visible-l { + overflow: visible; + } + .swagger-ui .overflow-hidden-l { + overflow: hidden; + } + .swagger-ui .overflow-scroll-l { + overflow: scroll; + } + .swagger-ui .overflow-auto-l { + overflow: auto; + } + .swagger-ui .overflow-x-visible-l { + overflow-x: visible; + } + .swagger-ui .overflow-x-hidden-l { + overflow-x: hidden; + } + .swagger-ui .overflow-x-scroll-l { + overflow-x: scroll; + } + .swagger-ui .overflow-x-auto-l { + overflow-x: auto; + } + .swagger-ui .overflow-y-visible-l { + overflow-y: visible; + } + .swagger-ui .overflow-y-hidden-l { + overflow-y: hidden; + } + .swagger-ui .overflow-y-scroll-l { + overflow-y: scroll; + } + .swagger-ui .overflow-y-auto-l { + overflow-y: auto; + } +} +.swagger-ui .static { + position: static; +} +.swagger-ui .relative { + position: relative; +} +.swagger-ui .absolute { + position: absolute; +} +.swagger-ui .fixed { + position: fixed; +} +@media screen and (min-width: 30em) { + .swagger-ui .static-ns { + position: static; + } + .swagger-ui .relative-ns { + position: relative; + } + .swagger-ui .absolute-ns { + position: absolute; + } + .swagger-ui .fixed-ns { + position: fixed; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .static-m { + position: static; + } + .swagger-ui .relative-m { + position: relative; + } + .swagger-ui .absolute-m { + position: absolute; + } + .swagger-ui .fixed-m { + position: fixed; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .static-l { + position: static; + } + .swagger-ui .relative-l { + position: relative; + } + .swagger-ui .absolute-l { + position: absolute; + } + .swagger-ui .fixed-l { + position: fixed; + } +} +.swagger-ui .o-100 { + opacity: 1; +} +.swagger-ui .o-90 { + opacity: 0.9; +} +.swagger-ui .o-80 { + opacity: 0.8; +} +.swagger-ui .o-70 { + opacity: 0.7; +} +.swagger-ui .o-60 { + opacity: 0.6; +} +.swagger-ui .o-50 { + opacity: 0.5; +} +.swagger-ui .o-40 { + opacity: 0.4; +} +.swagger-ui .o-30 { + opacity: 0.3; +} +.swagger-ui .o-20 { + opacity: 0.2; +} +.swagger-ui .o-10 { + opacity: 0.1; +} +.swagger-ui .o-05 { + opacity: 0.05; +} +.swagger-ui .o-025 { + opacity: 0.025; +} +.swagger-ui .o-0 { + opacity: 0; +} +.swagger-ui .rotate-45 { + transform: rotate(45deg); +} +.swagger-ui .rotate-90 { + transform: rotate(90deg); +} +.swagger-ui .rotate-135 { + transform: rotate(135deg); +} +.swagger-ui .rotate-180 { + transform: rotate(180deg); +} +.swagger-ui .rotate-225 { + transform: rotate(225deg); +} +.swagger-ui .rotate-270 { + transform: rotate(270deg); +} +.swagger-ui .rotate-315 { + transform: rotate(315deg); +} +@media screen and (min-width: 30em) { + .swagger-ui .rotate-45-ns { + transform: rotate(45deg); + } + .swagger-ui .rotate-90-ns { + transform: rotate(90deg); + } + .swagger-ui .rotate-135-ns { + transform: rotate(135deg); + } + .swagger-ui .rotate-180-ns { + transform: rotate(180deg); + } + .swagger-ui .rotate-225-ns { + transform: rotate(225deg); + } + .swagger-ui .rotate-270-ns { + transform: rotate(270deg); + } + .swagger-ui .rotate-315-ns { + transform: rotate(315deg); + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .rotate-45-m { + transform: rotate(45deg); + } + .swagger-ui .rotate-90-m { + transform: rotate(90deg); + } + .swagger-ui .rotate-135-m { + transform: rotate(135deg); + } + .swagger-ui .rotate-180-m { + transform: rotate(180deg); + } + .swagger-ui .rotate-225-m { + transform: rotate(225deg); + } + .swagger-ui .rotate-270-m { + transform: rotate(270deg); + } + .swagger-ui .rotate-315-m { + transform: rotate(315deg); + } +} +@media screen and (min-width: 60em) { + .swagger-ui .rotate-45-l { + transform: rotate(45deg); + } + .swagger-ui .rotate-90-l { + transform: rotate(90deg); + } + .swagger-ui .rotate-135-l { + transform: rotate(135deg); + } + .swagger-ui .rotate-180-l { + transform: rotate(180deg); + } + .swagger-ui .rotate-225-l { + transform: rotate(225deg); + } + .swagger-ui .rotate-270-l { + transform: rotate(270deg); + } + .swagger-ui .rotate-315-l { + transform: rotate(315deg); + } +} +.swagger-ui .black-90 { + color: rgba(0, 0, 0, 0.9); +} +.swagger-ui .black-80 { + color: rgba(0, 0, 0, 0.8); +} +.swagger-ui .black-70 { + color: rgba(0, 0, 0, 0.7); +} +.swagger-ui .black-60 { + color: rgba(0, 0, 0, 0.6); +} +.swagger-ui .black-50 { + color: rgba(0, 0, 0, 0.5); +} +.swagger-ui .black-40 { + color: rgba(0, 0, 0, 0.4); +} +.swagger-ui .black-30 { + color: rgba(0, 0, 0, 0.3); +} +.swagger-ui .black-20 { + color: rgba(0, 0, 0, 0.2); +} +.swagger-ui .black-10 { + color: rgba(0, 0, 0, 0.1); +} +.swagger-ui .black-05 { + color: rgba(0, 0, 0, 0.05); +} +.swagger-ui .white-90 { + color: hsla(0, 0%, 100%, 0.9); +} +.swagger-ui .white-80 { + color: hsla(0, 0%, 100%, 0.8); +} +.swagger-ui .white-70 { + color: hsla(0, 0%, 100%, 0.7); +} +.swagger-ui .white-60 { + color: hsla(0, 0%, 100%, 0.6); +} +.swagger-ui .white-50 { + color: hsla(0, 0%, 100%, 0.5); +} +.swagger-ui .white-40 { + color: hsla(0, 0%, 100%, 0.4); +} +.swagger-ui .white-30 { + color: hsla(0, 0%, 100%, 0.3); +} +.swagger-ui .white-20 { + color: hsla(0, 0%, 100%, 0.2); +} +.swagger-ui .white-10 { + color: hsla(0, 0%, 100%, 0.1); +} +.swagger-ui .black { + color: #000; +} +.swagger-ui .near-black { + color: #111; +} +.swagger-ui .dark-gray { + color: #333; +} +.swagger-ui .mid-gray { + color: #555; +} +.swagger-ui .gray { + color: #777; +} +.swagger-ui .silver { + color: #999; +} +.swagger-ui .light-silver { + color: #aaa; +} +.swagger-ui .moon-gray { + color: #ccc; +} +.swagger-ui .light-gray { + color: #eee; +} +.swagger-ui .near-white { + color: #f4f4f4; +} +.swagger-ui .white { + color: #fff; +} +.swagger-ui .dark-red { + color: #e7040f; +} +.swagger-ui .red { + color: #ff4136; +} +.swagger-ui .light-red { + color: #ff725c; +} +.swagger-ui .orange { + color: #ff6300; +} +.swagger-ui .gold { + color: #ffb700; +} +.swagger-ui .yellow { + color: gold; +} +.swagger-ui .light-yellow { + color: #fbf1a9; +} +.swagger-ui .purple { + color: #5e2ca5; +} +.swagger-ui .light-purple { + color: #a463f2; +} +.swagger-ui .dark-pink { + color: #d5008f; +} +.swagger-ui .hot-pink { + color: #ff41b4; +} +.swagger-ui .pink { + color: #ff80cc; +} +.swagger-ui .light-pink { + color: #ffa3d7; +} +.swagger-ui .dark-green { + color: #137752; +} +.swagger-ui .green { + color: #19a974; +} +.swagger-ui .light-green { + color: #9eebcf; +} +.swagger-ui .navy { + color: #001b44; +} +.swagger-ui .dark-blue { + color: #00449e; +} +.swagger-ui .blue { + color: #357edd; +} +.swagger-ui .light-blue { + color: #96ccff; +} +.swagger-ui .lightest-blue { + color: #cdecff; +} +.swagger-ui .washed-blue { + color: #f6fffe; +} +.swagger-ui .washed-green { + color: #e8fdf5; +} +.swagger-ui .washed-yellow { + color: #fffceb; +} +.swagger-ui .washed-red { + color: #ffdfdf; +} +.swagger-ui .color-inherit { + color: inherit; +} +.swagger-ui .bg-black-90 { + background-color: rgba(0, 0, 0, 0.9); +} +.swagger-ui .bg-black-80 { + background-color: rgba(0, 0, 0, 0.8); +} +.swagger-ui .bg-black-70 { + background-color: rgba(0, 0, 0, 0.7); +} +.swagger-ui .bg-black-60 { + background-color: rgba(0, 0, 0, 0.6); +} +.swagger-ui .bg-black-50 { + background-color: rgba(0, 0, 0, 0.5); +} +.swagger-ui .bg-black-40 { + background-color: rgba(0, 0, 0, 0.4); +} +.swagger-ui .bg-black-30 { + background-color: rgba(0, 0, 0, 0.3); +} +.swagger-ui .bg-black-20 { + background-color: rgba(0, 0, 0, 0.2); +} +.swagger-ui .bg-black-10 { + background-color: rgba(0, 0, 0, 0.1); +} +.swagger-ui .bg-black-05 { + background-color: rgba(0, 0, 0, 0.05); +} +.swagger-ui .bg-white-90 { + background-color: hsla(0, 0%, 100%, 0.9); +} +.swagger-ui .bg-white-80 { + background-color: hsla(0, 0%, 100%, 0.8); +} +.swagger-ui .bg-white-70 { + background-color: hsla(0, 0%, 100%, 0.7); +} +.swagger-ui .bg-white-60 { + background-color: hsla(0, 0%, 100%, 0.6); +} +.swagger-ui .bg-white-50 { + background-color: hsla(0, 0%, 100%, 0.5); +} +.swagger-ui .bg-white-40 { + background-color: hsla(0, 0%, 100%, 0.4); +} +.swagger-ui .bg-white-30 { + background-color: hsla(0, 0%, 100%, 0.3); +} +.swagger-ui .bg-white-20 { + background-color: hsla(0, 0%, 100%, 0.2); +} +.swagger-ui .bg-white-10 { + background-color: hsla(0, 0%, 100%, 0.1); +} +.swagger-ui .bg-black { + background-color: #000; +} +.swagger-ui .bg-near-black { + background-color: #111; +} +.swagger-ui .bg-dark-gray { + background-color: #333; +} +.swagger-ui .bg-mid-gray { + background-color: #555; +} +.swagger-ui .bg-gray { + background-color: #777; +} +.swagger-ui .bg-silver { + background-color: #999; +} +.swagger-ui .bg-light-silver { + background-color: #aaa; +} +.swagger-ui .bg-moon-gray { + background-color: #ccc; +} +.swagger-ui .bg-light-gray { + background-color: #eee; +} +.swagger-ui .bg-near-white { + background-color: #f4f4f4; +} +.swagger-ui .bg-white { + background-color: #fff; +} +.swagger-ui .bg-transparent { + background-color: transparent; +} +.swagger-ui .bg-dark-red { + background-color: #e7040f; +} +.swagger-ui .bg-red { + background-color: #ff4136; +} +.swagger-ui .bg-light-red { + background-color: #ff725c; +} +.swagger-ui .bg-orange { + background-color: #ff6300; +} +.swagger-ui .bg-gold { + background-color: #ffb700; +} +.swagger-ui .bg-yellow { + background-color: gold; +} +.swagger-ui .bg-light-yellow { + background-color: #fbf1a9; +} +.swagger-ui .bg-purple { + background-color: #5e2ca5; +} +.swagger-ui .bg-light-purple { + background-color: #a463f2; +} +.swagger-ui .bg-dark-pink { + background-color: #d5008f; +} +.swagger-ui .bg-hot-pink { + background-color: #ff41b4; +} +.swagger-ui .bg-pink { + background-color: #ff80cc; +} +.swagger-ui .bg-light-pink { + background-color: #ffa3d7; +} +.swagger-ui .bg-dark-green { + background-color: #137752; +} +.swagger-ui .bg-green { + background-color: #19a974; +} +.swagger-ui .bg-light-green { + background-color: #9eebcf; +} +.swagger-ui .bg-navy { + background-color: #001b44; +} +.swagger-ui .bg-dark-blue { + background-color: #00449e; +} +.swagger-ui .bg-blue { + background-color: #357edd; +} +.swagger-ui .bg-light-blue { + background-color: #96ccff; +} +.swagger-ui .bg-lightest-blue { + background-color: #cdecff; +} +.swagger-ui .bg-washed-blue { + background-color: #f6fffe; +} +.swagger-ui .bg-washed-green { + background-color: #e8fdf5; +} +.swagger-ui .bg-washed-yellow { + background-color: #fffceb; +} +.swagger-ui .bg-washed-red { + background-color: #ffdfdf; +} +.swagger-ui .bg-inherit { + background-color: inherit; +} +.swagger-ui .hover-black:focus, +.swagger-ui .hover-black:hover { + color: #000; +} +.swagger-ui .hover-near-black:focus, +.swagger-ui .hover-near-black:hover { + color: #111; +} +.swagger-ui .hover-dark-gray:focus, +.swagger-ui .hover-dark-gray:hover { + color: #333; +} +.swagger-ui .hover-mid-gray:focus, +.swagger-ui .hover-mid-gray:hover { + color: #555; +} +.swagger-ui .hover-gray:focus, +.swagger-ui .hover-gray:hover { + color: #777; +} +.swagger-ui .hover-silver:focus, +.swagger-ui .hover-silver:hover { + color: #999; +} +.swagger-ui .hover-light-silver:focus, +.swagger-ui .hover-light-silver:hover { + color: #aaa; +} +.swagger-ui .hover-moon-gray:focus, +.swagger-ui .hover-moon-gray:hover { + color: #ccc; +} +.swagger-ui .hover-light-gray:focus, +.swagger-ui .hover-light-gray:hover { + color: #eee; +} +.swagger-ui .hover-near-white:focus, +.swagger-ui .hover-near-white:hover { + color: #f4f4f4; +} +.swagger-ui .hover-white:focus, +.swagger-ui .hover-white:hover { + color: #fff; +} +.swagger-ui .hover-black-90:focus, +.swagger-ui .hover-black-90:hover { + color: rgba(0, 0, 0, 0.9); +} +.swagger-ui .hover-black-80:focus, +.swagger-ui .hover-black-80:hover { + color: rgba(0, 0, 0, 0.8); +} +.swagger-ui .hover-black-70:focus, +.swagger-ui .hover-black-70:hover { + color: rgba(0, 0, 0, 0.7); +} +.swagger-ui .hover-black-60:focus, +.swagger-ui .hover-black-60:hover { + color: rgba(0, 0, 0, 0.6); +} +.swagger-ui .hover-black-50:focus, +.swagger-ui .hover-black-50:hover { + color: rgba(0, 0, 0, 0.5); +} +.swagger-ui .hover-black-40:focus, +.swagger-ui .hover-black-40:hover { + color: rgba(0, 0, 0, 0.4); +} +.swagger-ui .hover-black-30:focus, +.swagger-ui .hover-black-30:hover { + color: rgba(0, 0, 0, 0.3); +} +.swagger-ui .hover-black-20:focus, +.swagger-ui .hover-black-20:hover { + color: rgba(0, 0, 0, 0.2); +} +.swagger-ui .hover-black-10:focus, +.swagger-ui .hover-black-10:hover { + color: rgba(0, 0, 0, 0.1); +} +.swagger-ui .hover-white-90:focus, +.swagger-ui .hover-white-90:hover { + color: hsla(0, 0%, 100%, 0.9); +} +.swagger-ui .hover-white-80:focus, +.swagger-ui .hover-white-80:hover { + color: hsla(0, 0%, 100%, 0.8); +} +.swagger-ui .hover-white-70:focus, +.swagger-ui .hover-white-70:hover { + color: hsla(0, 0%, 100%, 0.7); +} +.swagger-ui .hover-white-60:focus, +.swagger-ui .hover-white-60:hover { + color: hsla(0, 0%, 100%, 0.6); +} +.swagger-ui .hover-white-50:focus, +.swagger-ui .hover-white-50:hover { + color: hsla(0, 0%, 100%, 0.5); +} +.swagger-ui .hover-white-40:focus, +.swagger-ui .hover-white-40:hover { + color: hsla(0, 0%, 100%, 0.4); +} +.swagger-ui .hover-white-30:focus, +.swagger-ui .hover-white-30:hover { + color: hsla(0, 0%, 100%, 0.3); +} +.swagger-ui .hover-white-20:focus, +.swagger-ui .hover-white-20:hover { + color: hsla(0, 0%, 100%, 0.2); +} +.swagger-ui .hover-white-10:focus, +.swagger-ui .hover-white-10:hover { + color: hsla(0, 0%, 100%, 0.1); +} +.swagger-ui .hover-inherit:focus, +.swagger-ui .hover-inherit:hover { + color: inherit; +} +.swagger-ui .hover-bg-black:focus, +.swagger-ui .hover-bg-black:hover { + background-color: #000; +} +.swagger-ui .hover-bg-near-black:focus, +.swagger-ui .hover-bg-near-black:hover { + background-color: #111; +} +.swagger-ui .hover-bg-dark-gray:focus, +.swagger-ui .hover-bg-dark-gray:hover { + background-color: #333; +} +.swagger-ui .hover-bg-mid-gray:focus, +.swagger-ui .hover-bg-mid-gray:hover { + background-color: #555; +} +.swagger-ui .hover-bg-gray:focus, +.swagger-ui .hover-bg-gray:hover { + background-color: #777; +} +.swagger-ui .hover-bg-silver:focus, +.swagger-ui .hover-bg-silver:hover { + background-color: #999; +} +.swagger-ui .hover-bg-light-silver:focus, +.swagger-ui .hover-bg-light-silver:hover { + background-color: #aaa; +} +.swagger-ui .hover-bg-moon-gray:focus, +.swagger-ui .hover-bg-moon-gray:hover { + background-color: #ccc; +} +.swagger-ui .hover-bg-light-gray:focus, +.swagger-ui .hover-bg-light-gray:hover { + background-color: #eee; +} +.swagger-ui .hover-bg-near-white:focus, +.swagger-ui .hover-bg-near-white:hover { + background-color: #f4f4f4; +} +.swagger-ui .hover-bg-white:focus, +.swagger-ui .hover-bg-white:hover { + background-color: #fff; +} +.swagger-ui .hover-bg-transparent:focus, +.swagger-ui .hover-bg-transparent:hover { + background-color: transparent; +} +.swagger-ui .hover-bg-black-90:focus, +.swagger-ui .hover-bg-black-90:hover { + background-color: rgba(0, 0, 0, 0.9); +} +.swagger-ui .hover-bg-black-80:focus, +.swagger-ui .hover-bg-black-80:hover { + background-color: rgba(0, 0, 0, 0.8); +} +.swagger-ui .hover-bg-black-70:focus, +.swagger-ui .hover-bg-black-70:hover { + background-color: rgba(0, 0, 0, 0.7); +} +.swagger-ui .hover-bg-black-60:focus, +.swagger-ui .hover-bg-black-60:hover { + background-color: rgba(0, 0, 0, 0.6); +} +.swagger-ui .hover-bg-black-50:focus, +.swagger-ui .hover-bg-black-50:hover { + background-color: rgba(0, 0, 0, 0.5); +} +.swagger-ui .hover-bg-black-40:focus, +.swagger-ui .hover-bg-black-40:hover { + background-color: rgba(0, 0, 0, 0.4); +} +.swagger-ui .hover-bg-black-30:focus, +.swagger-ui .hover-bg-black-30:hover { + background-color: rgba(0, 0, 0, 0.3); +} +.swagger-ui .hover-bg-black-20:focus, +.swagger-ui .hover-bg-black-20:hover { + background-color: rgba(0, 0, 0, 0.2); +} +.swagger-ui .hover-bg-black-10:focus, +.swagger-ui .hover-bg-black-10:hover { + background-color: rgba(0, 0, 0, 0.1); +} +.swagger-ui .hover-bg-white-90:focus, +.swagger-ui .hover-bg-white-90:hover { + background-color: hsla(0, 0%, 100%, 0.9); +} +.swagger-ui .hover-bg-white-80:focus, +.swagger-ui .hover-bg-white-80:hover { + background-color: hsla(0, 0%, 100%, 0.8); +} +.swagger-ui .hover-bg-white-70:focus, +.swagger-ui .hover-bg-white-70:hover { + background-color: hsla(0, 0%, 100%, 0.7); +} +.swagger-ui .hover-bg-white-60:focus, +.swagger-ui .hover-bg-white-60:hover { + background-color: hsla(0, 0%, 100%, 0.6); +} +.swagger-ui .hover-bg-white-50:focus, +.swagger-ui .hover-bg-white-50:hover { + background-color: hsla(0, 0%, 100%, 0.5); +} +.swagger-ui .hover-bg-white-40:focus, +.swagger-ui .hover-bg-white-40:hover { + background-color: hsla(0, 0%, 100%, 0.4); +} +.swagger-ui .hover-bg-white-30:focus, +.swagger-ui .hover-bg-white-30:hover { + background-color: hsla(0, 0%, 100%, 0.3); +} +.swagger-ui .hover-bg-white-20:focus, +.swagger-ui .hover-bg-white-20:hover { + background-color: hsla(0, 0%, 100%, 0.2); +} +.swagger-ui .hover-bg-white-10:focus, +.swagger-ui .hover-bg-white-10:hover { + background-color: hsla(0, 0%, 100%, 0.1); +} +.swagger-ui .hover-dark-red:focus, +.swagger-ui .hover-dark-red:hover { + color: #e7040f; +} +.swagger-ui .hover-red:focus, +.swagger-ui .hover-red:hover { + color: #ff4136; +} +.swagger-ui .hover-light-red:focus, +.swagger-ui .hover-light-red:hover { + color: #ff725c; +} +.swagger-ui .hover-orange:focus, +.swagger-ui .hover-orange:hover { + color: #ff6300; +} +.swagger-ui .hover-gold:focus, +.swagger-ui .hover-gold:hover { + color: #ffb700; +} +.swagger-ui .hover-yellow:focus, +.swagger-ui .hover-yellow:hover { + color: gold; +} +.swagger-ui .hover-light-yellow:focus, +.swagger-ui .hover-light-yellow:hover { + color: #fbf1a9; +} +.swagger-ui .hover-purple:focus, +.swagger-ui .hover-purple:hover { + color: #5e2ca5; +} +.swagger-ui .hover-light-purple:focus, +.swagger-ui .hover-light-purple:hover { + color: #a463f2; +} +.swagger-ui .hover-dark-pink:focus, +.swagger-ui .hover-dark-pink:hover { + color: #d5008f; +} +.swagger-ui .hover-hot-pink:focus, +.swagger-ui .hover-hot-pink:hover { + color: #ff41b4; +} +.swagger-ui .hover-pink:focus, +.swagger-ui .hover-pink:hover { + color: #ff80cc; +} +.swagger-ui .hover-light-pink:focus, +.swagger-ui .hover-light-pink:hover { + color: #ffa3d7; +} +.swagger-ui .hover-dark-green:focus, +.swagger-ui .hover-dark-green:hover { + color: #137752; +} +.swagger-ui .hover-green:focus, +.swagger-ui .hover-green:hover { + color: #19a974; +} +.swagger-ui .hover-light-green:focus, +.swagger-ui .hover-light-green:hover { + color: #9eebcf; +} +.swagger-ui .hover-navy:focus, +.swagger-ui .hover-navy:hover { + color: #001b44; +} +.swagger-ui .hover-dark-blue:focus, +.swagger-ui .hover-dark-blue:hover { + color: #00449e; +} +.swagger-ui .hover-blue:focus, +.swagger-ui .hover-blue:hover { + color: #357edd; +} +.swagger-ui .hover-light-blue:focus, +.swagger-ui .hover-light-blue:hover { + color: #96ccff; +} +.swagger-ui .hover-lightest-blue:focus, +.swagger-ui .hover-lightest-blue:hover { + color: #cdecff; +} +.swagger-ui .hover-washed-blue:focus, +.swagger-ui .hover-washed-blue:hover { + color: #f6fffe; +} +.swagger-ui .hover-washed-green:focus, +.swagger-ui .hover-washed-green:hover { + color: #e8fdf5; +} +.swagger-ui .hover-washed-yellow:focus, +.swagger-ui .hover-washed-yellow:hover { + color: #fffceb; +} +.swagger-ui .hover-washed-red:focus, +.swagger-ui .hover-washed-red:hover { + color: #ffdfdf; +} +.swagger-ui .hover-bg-dark-red:focus, +.swagger-ui .hover-bg-dark-red:hover { + background-color: #e7040f; +} +.swagger-ui .hover-bg-red:focus, +.swagger-ui .hover-bg-red:hover { + background-color: #ff4136; +} +.swagger-ui .hover-bg-light-red:focus, +.swagger-ui .hover-bg-light-red:hover { + background-color: #ff725c; +} +.swagger-ui .hover-bg-orange:focus, +.swagger-ui .hover-bg-orange:hover { + background-color: #ff6300; +} +.swagger-ui .hover-bg-gold:focus, +.swagger-ui .hover-bg-gold:hover { + background-color: #ffb700; +} +.swagger-ui .hover-bg-yellow:focus, +.swagger-ui .hover-bg-yellow:hover { + background-color: gold; +} +.swagger-ui .hover-bg-light-yellow:focus, +.swagger-ui .hover-bg-light-yellow:hover { + background-color: #fbf1a9; +} +.swagger-ui .hover-bg-purple:focus, +.swagger-ui .hover-bg-purple:hover { + background-color: #5e2ca5; +} +.swagger-ui .hover-bg-light-purple:focus, +.swagger-ui .hover-bg-light-purple:hover { + background-color: #a463f2; +} +.swagger-ui .hover-bg-dark-pink:focus, +.swagger-ui .hover-bg-dark-pink:hover { + background-color: #d5008f; +} +.swagger-ui .hover-bg-hot-pink:focus, +.swagger-ui .hover-bg-hot-pink:hover { + background-color: #ff41b4; +} +.swagger-ui .hover-bg-pink:focus, +.swagger-ui .hover-bg-pink:hover { + background-color: #ff80cc; +} +.swagger-ui .hover-bg-light-pink:focus, +.swagger-ui .hover-bg-light-pink:hover { + background-color: #ffa3d7; +} +.swagger-ui .hover-bg-dark-green:focus, +.swagger-ui .hover-bg-dark-green:hover { + background-color: #137752; +} +.swagger-ui .hover-bg-green:focus, +.swagger-ui .hover-bg-green:hover { + background-color: #19a974; +} +.swagger-ui .hover-bg-light-green:focus, +.swagger-ui .hover-bg-light-green:hover { + background-color: #9eebcf; +} +.swagger-ui .hover-bg-navy:focus, +.swagger-ui .hover-bg-navy:hover { + background-color: #001b44; +} +.swagger-ui .hover-bg-dark-blue:focus, +.swagger-ui .hover-bg-dark-blue:hover { + background-color: #00449e; +} +.swagger-ui .hover-bg-blue:focus, +.swagger-ui .hover-bg-blue:hover { + background-color: #357edd; +} +.swagger-ui .hover-bg-light-blue:focus, +.swagger-ui .hover-bg-light-blue:hover { + background-color: #96ccff; +} +.swagger-ui .hover-bg-lightest-blue:focus, +.swagger-ui .hover-bg-lightest-blue:hover { + background-color: #cdecff; +} +.swagger-ui .hover-bg-washed-blue:focus, +.swagger-ui .hover-bg-washed-blue:hover { + background-color: #f6fffe; +} +.swagger-ui .hover-bg-washed-green:focus, +.swagger-ui .hover-bg-washed-green:hover { + background-color: #e8fdf5; +} +.swagger-ui .hover-bg-washed-yellow:focus, +.swagger-ui .hover-bg-washed-yellow:hover { + background-color: #fffceb; +} +.swagger-ui .hover-bg-washed-red:focus, +.swagger-ui .hover-bg-washed-red:hover { + background-color: #ffdfdf; +} +.swagger-ui .hover-bg-inherit:focus, +.swagger-ui .hover-bg-inherit:hover { + background-color: inherit; +} +.swagger-ui .pa0 { + padding: 0; +} +.swagger-ui .pa1 { + padding: 0.25rem; +} +.swagger-ui .pa2 { + padding: 0.5rem; +} +.swagger-ui .pa3 { + padding: 1rem; +} +.swagger-ui .pa4 { + padding: 2rem; +} +.swagger-ui .pa5 { + padding: 4rem; +} +.swagger-ui .pa6 { + padding: 8rem; +} +.swagger-ui .pa7 { + padding: 16rem; +} +.swagger-ui .pl0 { + padding-left: 0; +} +.swagger-ui .pl1 { + padding-left: 0.25rem; +} +.swagger-ui .pl2 { + padding-left: 0.5rem; +} +.swagger-ui .pl3 { + padding-left: 1rem; +} +.swagger-ui .pl4 { + padding-left: 2rem; +} +.swagger-ui .pl5 { + padding-left: 4rem; +} +.swagger-ui .pl6 { + padding-left: 8rem; +} +.swagger-ui .pl7 { + padding-left: 16rem; +} +.swagger-ui .pr0 { + padding-right: 0; +} +.swagger-ui .pr1 { + padding-right: 0.25rem; +} +.swagger-ui .pr2 { + padding-right: 0.5rem; +} +.swagger-ui .pr3 { + padding-right: 1rem; +} +.swagger-ui .pr4 { + padding-right: 2rem; +} +.swagger-ui .pr5 { + padding-right: 4rem; +} +.swagger-ui .pr6 { + padding-right: 8rem; +} +.swagger-ui .pr7 { + padding-right: 16rem; +} +.swagger-ui .pb0 { + padding-bottom: 0; +} +.swagger-ui .pb1 { + padding-bottom: 0.25rem; +} +.swagger-ui .pb2 { + padding-bottom: 0.5rem; +} +.swagger-ui .pb3 { + padding-bottom: 1rem; +} +.swagger-ui .pb4 { + padding-bottom: 2rem; +} +.swagger-ui .pb5 { + padding-bottom: 4rem; +} +.swagger-ui .pb6 { + padding-bottom: 8rem; +} +.swagger-ui .pb7 { + padding-bottom: 16rem; +} +.swagger-ui .pt0 { + padding-top: 0; +} +.swagger-ui .pt1 { + padding-top: 0.25rem; +} +.swagger-ui .pt2 { + padding-top: 0.5rem; +} +.swagger-ui .pt3 { + padding-top: 1rem; +} +.swagger-ui .pt4 { + padding-top: 2rem; +} +.swagger-ui .pt5 { + padding-top: 4rem; +} +.swagger-ui .pt6 { + padding-top: 8rem; +} +.swagger-ui .pt7 { + padding-top: 16rem; +} +.swagger-ui .pv0 { + padding-bottom: 0; + padding-top: 0; +} +.swagger-ui .pv1 { + padding-bottom: 0.25rem; + padding-top: 0.25rem; +} +.swagger-ui .pv2 { + padding-bottom: 0.5rem; + padding-top: 0.5rem; +} +.swagger-ui .pv3 { + padding-bottom: 1rem; + padding-top: 1rem; +} +.swagger-ui .pv4 { + padding-bottom: 2rem; + padding-top: 2rem; +} +.swagger-ui .pv5 { + padding-bottom: 4rem; + padding-top: 4rem; +} +.swagger-ui .pv6 { + padding-bottom: 8rem; + padding-top: 8rem; +} +.swagger-ui .pv7 { + padding-bottom: 16rem; + padding-top: 16rem; +} +.swagger-ui .ph0 { + padding-left: 0; + padding-right: 0; +} +.swagger-ui .ph1 { + padding-left: 0.25rem; + padding-right: 0.25rem; +} +.swagger-ui .ph2 { + padding-left: 0.5rem; + padding-right: 0.5rem; +} +.swagger-ui .ph3 { + padding-left: 1rem; + padding-right: 1rem; +} +.swagger-ui .ph4 { + padding-left: 2rem; + padding-right: 2rem; +} +.swagger-ui .ph5 { + padding-left: 4rem; + padding-right: 4rem; +} +.swagger-ui .ph6 { + padding-left: 8rem; + padding-right: 8rem; +} +.swagger-ui .ph7 { + padding-left: 16rem; + padding-right: 16rem; +} +.swagger-ui .ma0 { + margin: 0; +} +.swagger-ui .ma1 { + margin: 0.25rem; +} +.swagger-ui .ma2 { + margin: 0.5rem; +} +.swagger-ui .ma3 { + margin: 1rem; +} +.swagger-ui .ma4 { + margin: 2rem; +} +.swagger-ui .ma5 { + margin: 4rem; +} +.swagger-ui .ma6 { + margin: 8rem; +} +.swagger-ui .ma7 { + margin: 16rem; +} +.swagger-ui .ml0 { + margin-left: 0; +} +.swagger-ui .ml1 { + margin-left: 0.25rem; +} +.swagger-ui .ml2 { + margin-left: 0.5rem; +} +.swagger-ui .ml3 { + margin-left: 1rem; +} +.swagger-ui .ml4 { + margin-left: 2rem; +} +.swagger-ui .ml5 { + margin-left: 4rem; +} +.swagger-ui .ml6 { + margin-left: 8rem; +} +.swagger-ui .ml7 { + margin-left: 16rem; +} +.swagger-ui .mr0 { + margin-right: 0; +} +.swagger-ui .mr1 { + margin-right: 0.25rem; +} +.swagger-ui .mr2 { + margin-right: 0.5rem; +} +.swagger-ui .mr3 { + margin-right: 1rem; +} +.swagger-ui .mr4 { + margin-right: 2rem; +} +.swagger-ui .mr5 { + margin-right: 4rem; +} +.swagger-ui .mr6 { + margin-right: 8rem; +} +.swagger-ui .mr7 { + margin-right: 16rem; +} +.swagger-ui .mb0 { + margin-bottom: 0; +} +.swagger-ui .mb1 { + margin-bottom: 0.25rem; +} +.swagger-ui .mb2 { + margin-bottom: 0.5rem; +} +.swagger-ui .mb3 { + margin-bottom: 1rem; +} +.swagger-ui .mb4 { + margin-bottom: 2rem; +} +.swagger-ui .mb5 { + margin-bottom: 4rem; +} +.swagger-ui .mb6 { + margin-bottom: 8rem; +} +.swagger-ui .mb7 { + margin-bottom: 16rem; +} +.swagger-ui .mt0 { + margin-top: 0; +} +.swagger-ui .mt1 { + margin-top: 0.25rem; +} +.swagger-ui .mt2 { + margin-top: 0.5rem; +} +.swagger-ui .mt3 { + margin-top: 1rem; +} +.swagger-ui .mt4 { + margin-top: 2rem; +} +.swagger-ui .mt5 { + margin-top: 4rem; +} +.swagger-ui .mt6 { + margin-top: 8rem; +} +.swagger-ui .mt7 { + margin-top: 16rem; +} +.swagger-ui .mv0 { + margin-bottom: 0; + margin-top: 0; +} +.swagger-ui .mv1 { + margin-bottom: 0.25rem; + margin-top: 0.25rem; +} +.swagger-ui .mv2 { + margin-bottom: 0.5rem; + margin-top: 0.5rem; +} +.swagger-ui .mv3 { + margin-bottom: 1rem; + margin-top: 1rem; +} +.swagger-ui .mv4 { + margin-bottom: 2rem; + margin-top: 2rem; +} +.swagger-ui .mv5 { + margin-bottom: 4rem; + margin-top: 4rem; +} +.swagger-ui .mv6 { + margin-bottom: 8rem; + margin-top: 8rem; +} +.swagger-ui .mv7 { + margin-bottom: 16rem; + margin-top: 16rem; +} +.swagger-ui .mh0 { + margin-left: 0; + margin-right: 0; +} +.swagger-ui .mh1 { + margin-left: 0.25rem; + margin-right: 0.25rem; +} +.swagger-ui .mh2 { + margin-left: 0.5rem; + margin-right: 0.5rem; +} +.swagger-ui .mh3 { + margin-left: 1rem; + margin-right: 1rem; +} +.swagger-ui .mh4 { + margin-left: 2rem; + margin-right: 2rem; +} +.swagger-ui .mh5 { + margin-left: 4rem; + margin-right: 4rem; +} +.swagger-ui .mh6 { + margin-left: 8rem; + margin-right: 8rem; +} +.swagger-ui .mh7 { + margin-left: 16rem; + margin-right: 16rem; +} +@media screen and (min-width: 30em) { + .swagger-ui .pa0-ns { + padding: 0; + } + .swagger-ui .pa1-ns { + padding: 0.25rem; + } + .swagger-ui .pa2-ns { + padding: 0.5rem; + } + .swagger-ui .pa3-ns { + padding: 1rem; + } + .swagger-ui .pa4-ns { + padding: 2rem; + } + .swagger-ui .pa5-ns { + padding: 4rem; + } + .swagger-ui .pa6-ns { + padding: 8rem; + } + .swagger-ui .pa7-ns { + padding: 16rem; + } + .swagger-ui .pl0-ns { + padding-left: 0; + } + .swagger-ui .pl1-ns { + padding-left: 0.25rem; + } + .swagger-ui .pl2-ns { + padding-left: 0.5rem; + } + .swagger-ui .pl3-ns { + padding-left: 1rem; + } + .swagger-ui .pl4-ns { + padding-left: 2rem; + } + .swagger-ui .pl5-ns { + padding-left: 4rem; + } + .swagger-ui .pl6-ns { + padding-left: 8rem; + } + .swagger-ui .pl7-ns { + padding-left: 16rem; + } + .swagger-ui .pr0-ns { + padding-right: 0; + } + .swagger-ui .pr1-ns { + padding-right: 0.25rem; + } + .swagger-ui .pr2-ns { + padding-right: 0.5rem; + } + .swagger-ui .pr3-ns { + padding-right: 1rem; + } + .swagger-ui .pr4-ns { + padding-right: 2rem; + } + .swagger-ui .pr5-ns { + padding-right: 4rem; + } + .swagger-ui .pr6-ns { + padding-right: 8rem; + } + .swagger-ui .pr7-ns { + padding-right: 16rem; + } + .swagger-ui .pb0-ns { + padding-bottom: 0; + } + .swagger-ui .pb1-ns { + padding-bottom: 0.25rem; + } + .swagger-ui .pb2-ns { + padding-bottom: 0.5rem; + } + .swagger-ui .pb3-ns { + padding-bottom: 1rem; + } + .swagger-ui .pb4-ns { + padding-bottom: 2rem; + } + .swagger-ui .pb5-ns { + padding-bottom: 4rem; + } + .swagger-ui .pb6-ns { + padding-bottom: 8rem; + } + .swagger-ui .pb7-ns { + padding-bottom: 16rem; + } + .swagger-ui .pt0-ns { + padding-top: 0; + } + .swagger-ui .pt1-ns { + padding-top: 0.25rem; + } + .swagger-ui .pt2-ns { + padding-top: 0.5rem; + } + .swagger-ui .pt3-ns { + padding-top: 1rem; + } + .swagger-ui .pt4-ns { + padding-top: 2rem; + } + .swagger-ui .pt5-ns { + padding-top: 4rem; + } + .swagger-ui .pt6-ns { + padding-top: 8rem; + } + .swagger-ui .pt7-ns { + padding-top: 16rem; + } + .swagger-ui .pv0-ns { + padding-bottom: 0; + padding-top: 0; + } + .swagger-ui .pv1-ns { + padding-bottom: 0.25rem; + padding-top: 0.25rem; + } + .swagger-ui .pv2-ns { + padding-bottom: 0.5rem; + padding-top: 0.5rem; + } + .swagger-ui .pv3-ns { + padding-bottom: 1rem; + padding-top: 1rem; + } + .swagger-ui .pv4-ns { + padding-bottom: 2rem; + padding-top: 2rem; + } + .swagger-ui .pv5-ns { + padding-bottom: 4rem; + padding-top: 4rem; + } + .swagger-ui .pv6-ns { + padding-bottom: 8rem; + padding-top: 8rem; + } + .swagger-ui .pv7-ns { + padding-bottom: 16rem; + padding-top: 16rem; + } + .swagger-ui .ph0-ns { + padding-left: 0; + padding-right: 0; + } + .swagger-ui .ph1-ns { + padding-left: 0.25rem; + padding-right: 0.25rem; + } + .swagger-ui .ph2-ns { + padding-left: 0.5rem; + padding-right: 0.5rem; + } + .swagger-ui .ph3-ns { + padding-left: 1rem; + padding-right: 1rem; + } + .swagger-ui .ph4-ns { + padding-left: 2rem; + padding-right: 2rem; + } + .swagger-ui .ph5-ns { + padding-left: 4rem; + padding-right: 4rem; + } + .swagger-ui .ph6-ns { + padding-left: 8rem; + padding-right: 8rem; + } + .swagger-ui .ph7-ns { + padding-left: 16rem; + padding-right: 16rem; + } + .swagger-ui .ma0-ns { + margin: 0; + } + .swagger-ui .ma1-ns { + margin: 0.25rem; + } + .swagger-ui .ma2-ns { + margin: 0.5rem; + } + .swagger-ui .ma3-ns { + margin: 1rem; + } + .swagger-ui .ma4-ns { + margin: 2rem; + } + .swagger-ui .ma5-ns { + margin: 4rem; + } + .swagger-ui .ma6-ns { + margin: 8rem; + } + .swagger-ui .ma7-ns { + margin: 16rem; + } + .swagger-ui .ml0-ns { + margin-left: 0; + } + .swagger-ui .ml1-ns { + margin-left: 0.25rem; + } + .swagger-ui .ml2-ns { + margin-left: 0.5rem; + } + .swagger-ui .ml3-ns { + margin-left: 1rem; + } + .swagger-ui .ml4-ns { + margin-left: 2rem; + } + .swagger-ui .ml5-ns { + margin-left: 4rem; + } + .swagger-ui .ml6-ns { + margin-left: 8rem; + } + .swagger-ui .ml7-ns { + margin-left: 16rem; + } + .swagger-ui .mr0-ns { + margin-right: 0; + } + .swagger-ui .mr1-ns { + margin-right: 0.25rem; + } + .swagger-ui .mr2-ns { + margin-right: 0.5rem; + } + .swagger-ui .mr3-ns { + margin-right: 1rem; + } + .swagger-ui .mr4-ns { + margin-right: 2rem; + } + .swagger-ui .mr5-ns { + margin-right: 4rem; + } + .swagger-ui .mr6-ns { + margin-right: 8rem; + } + .swagger-ui .mr7-ns { + margin-right: 16rem; + } + .swagger-ui .mb0-ns { + margin-bottom: 0; + } + .swagger-ui .mb1-ns { + margin-bottom: 0.25rem; + } + .swagger-ui .mb2-ns { + margin-bottom: 0.5rem; + } + .swagger-ui .mb3-ns { + margin-bottom: 1rem; + } + .swagger-ui .mb4-ns { + margin-bottom: 2rem; + } + .swagger-ui .mb5-ns { + margin-bottom: 4rem; + } + .swagger-ui .mb6-ns { + margin-bottom: 8rem; + } + .swagger-ui .mb7-ns { + margin-bottom: 16rem; + } + .swagger-ui .mt0-ns { + margin-top: 0; + } + .swagger-ui .mt1-ns { + margin-top: 0.25rem; + } + .swagger-ui .mt2-ns { + margin-top: 0.5rem; + } + .swagger-ui .mt3-ns { + margin-top: 1rem; + } + .swagger-ui .mt4-ns { + margin-top: 2rem; + } + .swagger-ui .mt5-ns { + margin-top: 4rem; + } + .swagger-ui .mt6-ns { + margin-top: 8rem; + } + .swagger-ui .mt7-ns { + margin-top: 16rem; + } + .swagger-ui .mv0-ns { + margin-bottom: 0; + margin-top: 0; + } + .swagger-ui .mv1-ns { + margin-bottom: 0.25rem; + margin-top: 0.25rem; + } + .swagger-ui .mv2-ns { + margin-bottom: 0.5rem; + margin-top: 0.5rem; + } + .swagger-ui .mv3-ns { + margin-bottom: 1rem; + margin-top: 1rem; + } + .swagger-ui .mv4-ns { + margin-bottom: 2rem; + margin-top: 2rem; + } + .swagger-ui .mv5-ns { + margin-bottom: 4rem; + margin-top: 4rem; + } + .swagger-ui .mv6-ns { + margin-bottom: 8rem; + margin-top: 8rem; + } + .swagger-ui .mv7-ns { + margin-bottom: 16rem; + margin-top: 16rem; + } + .swagger-ui .mh0-ns { + margin-left: 0; + margin-right: 0; + } + .swagger-ui .mh1-ns { + margin-left: 0.25rem; + margin-right: 0.25rem; + } + .swagger-ui .mh2-ns { + margin-left: 0.5rem; + margin-right: 0.5rem; + } + .swagger-ui .mh3-ns { + margin-left: 1rem; + margin-right: 1rem; + } + .swagger-ui .mh4-ns { + margin-left: 2rem; + margin-right: 2rem; + } + .swagger-ui .mh5-ns { + margin-left: 4rem; + margin-right: 4rem; + } + .swagger-ui .mh6-ns { + margin-left: 8rem; + margin-right: 8rem; + } + .swagger-ui .mh7-ns { + margin-left: 16rem; + margin-right: 16rem; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .pa0-m { + padding: 0; + } + .swagger-ui .pa1-m { + padding: 0.25rem; + } + .swagger-ui .pa2-m { + padding: 0.5rem; + } + .swagger-ui .pa3-m { + padding: 1rem; + } + .swagger-ui .pa4-m { + padding: 2rem; + } + .swagger-ui .pa5-m { + padding: 4rem; + } + .swagger-ui .pa6-m { + padding: 8rem; + } + .swagger-ui .pa7-m { + padding: 16rem; + } + .swagger-ui .pl0-m { + padding-left: 0; + } + .swagger-ui .pl1-m { + padding-left: 0.25rem; + } + .swagger-ui .pl2-m { + padding-left: 0.5rem; + } + .swagger-ui .pl3-m { + padding-left: 1rem; + } + .swagger-ui .pl4-m { + padding-left: 2rem; + } + .swagger-ui .pl5-m { + padding-left: 4rem; + } + .swagger-ui .pl6-m { + padding-left: 8rem; + } + .swagger-ui .pl7-m { + padding-left: 16rem; + } + .swagger-ui .pr0-m { + padding-right: 0; + } + .swagger-ui .pr1-m { + padding-right: 0.25rem; + } + .swagger-ui .pr2-m { + padding-right: 0.5rem; + } + .swagger-ui .pr3-m { + padding-right: 1rem; + } + .swagger-ui .pr4-m { + padding-right: 2rem; + } + .swagger-ui .pr5-m { + padding-right: 4rem; + } + .swagger-ui .pr6-m { + padding-right: 8rem; + } + .swagger-ui .pr7-m { + padding-right: 16rem; + } + .swagger-ui .pb0-m { + padding-bottom: 0; + } + .swagger-ui .pb1-m { + padding-bottom: 0.25rem; + } + .swagger-ui .pb2-m { + padding-bottom: 0.5rem; + } + .swagger-ui .pb3-m { + padding-bottom: 1rem; + } + .swagger-ui .pb4-m { + padding-bottom: 2rem; + } + .swagger-ui .pb5-m { + padding-bottom: 4rem; + } + .swagger-ui .pb6-m { + padding-bottom: 8rem; + } + .swagger-ui .pb7-m { + padding-bottom: 16rem; + } + .swagger-ui .pt0-m { + padding-top: 0; + } + .swagger-ui .pt1-m { + padding-top: 0.25rem; + } + .swagger-ui .pt2-m { + padding-top: 0.5rem; + } + .swagger-ui .pt3-m { + padding-top: 1rem; + } + .swagger-ui .pt4-m { + padding-top: 2rem; + } + .swagger-ui .pt5-m { + padding-top: 4rem; + } + .swagger-ui .pt6-m { + padding-top: 8rem; + } + .swagger-ui .pt7-m { + padding-top: 16rem; + } + .swagger-ui .pv0-m { + padding-bottom: 0; + padding-top: 0; + } + .swagger-ui .pv1-m { + padding-bottom: 0.25rem; + padding-top: 0.25rem; + } + .swagger-ui .pv2-m { + padding-bottom: 0.5rem; + padding-top: 0.5rem; + } + .swagger-ui .pv3-m { + padding-bottom: 1rem; + padding-top: 1rem; + } + .swagger-ui .pv4-m { + padding-bottom: 2rem; + padding-top: 2rem; + } + .swagger-ui .pv5-m { + padding-bottom: 4rem; + padding-top: 4rem; + } + .swagger-ui .pv6-m { + padding-bottom: 8rem; + padding-top: 8rem; + } + .swagger-ui .pv7-m { + padding-bottom: 16rem; + padding-top: 16rem; + } + .swagger-ui .ph0-m { + padding-left: 0; + padding-right: 0; + } + .swagger-ui .ph1-m { + padding-left: 0.25rem; + padding-right: 0.25rem; + } + .swagger-ui .ph2-m { + padding-left: 0.5rem; + padding-right: 0.5rem; + } + .swagger-ui .ph3-m { + padding-left: 1rem; + padding-right: 1rem; + } + .swagger-ui .ph4-m { + padding-left: 2rem; + padding-right: 2rem; + } + .swagger-ui .ph5-m { + padding-left: 4rem; + padding-right: 4rem; + } + .swagger-ui .ph6-m { + padding-left: 8rem; + padding-right: 8rem; + } + .swagger-ui .ph7-m { + padding-left: 16rem; + padding-right: 16rem; + } + .swagger-ui .ma0-m { + margin: 0; + } + .swagger-ui .ma1-m { + margin: 0.25rem; + } + .swagger-ui .ma2-m { + margin: 0.5rem; + } + .swagger-ui .ma3-m { + margin: 1rem; + } + .swagger-ui .ma4-m { + margin: 2rem; + } + .swagger-ui .ma5-m { + margin: 4rem; + } + .swagger-ui .ma6-m { + margin: 8rem; + } + .swagger-ui .ma7-m { + margin: 16rem; + } + .swagger-ui .ml0-m { + margin-left: 0; + } + .swagger-ui .ml1-m { + margin-left: 0.25rem; + } + .swagger-ui .ml2-m { + margin-left: 0.5rem; + } + .swagger-ui .ml3-m { + margin-left: 1rem; + } + .swagger-ui .ml4-m { + margin-left: 2rem; + } + .swagger-ui .ml5-m { + margin-left: 4rem; + } + .swagger-ui .ml6-m { + margin-left: 8rem; + } + .swagger-ui .ml7-m { + margin-left: 16rem; + } + .swagger-ui .mr0-m { + margin-right: 0; + } + .swagger-ui .mr1-m { + margin-right: 0.25rem; + } + .swagger-ui .mr2-m { + margin-right: 0.5rem; + } + .swagger-ui .mr3-m { + margin-right: 1rem; + } + .swagger-ui .mr4-m { + margin-right: 2rem; + } + .swagger-ui .mr5-m { + margin-right: 4rem; + } + .swagger-ui .mr6-m { + margin-right: 8rem; + } + .swagger-ui .mr7-m { + margin-right: 16rem; + } + .swagger-ui .mb0-m { + margin-bottom: 0; + } + .swagger-ui .mb1-m { + margin-bottom: 0.25rem; + } + .swagger-ui .mb2-m { + margin-bottom: 0.5rem; + } + .swagger-ui .mb3-m { + margin-bottom: 1rem; + } + .swagger-ui .mb4-m { + margin-bottom: 2rem; + } + .swagger-ui .mb5-m { + margin-bottom: 4rem; + } + .swagger-ui .mb6-m { + margin-bottom: 8rem; + } + .swagger-ui .mb7-m { + margin-bottom: 16rem; + } + .swagger-ui .mt0-m { + margin-top: 0; + } + .swagger-ui .mt1-m { + margin-top: 0.25rem; + } + .swagger-ui .mt2-m { + margin-top: 0.5rem; + } + .swagger-ui .mt3-m { + margin-top: 1rem; + } + .swagger-ui .mt4-m { + margin-top: 2rem; + } + .swagger-ui .mt5-m { + margin-top: 4rem; + } + .swagger-ui .mt6-m { + margin-top: 8rem; + } + .swagger-ui .mt7-m { + margin-top: 16rem; + } + .swagger-ui .mv0-m { + margin-bottom: 0; + margin-top: 0; + } + .swagger-ui .mv1-m { + margin-bottom: 0.25rem; + margin-top: 0.25rem; + } + .swagger-ui .mv2-m { + margin-bottom: 0.5rem; + margin-top: 0.5rem; + } + .swagger-ui .mv3-m { + margin-bottom: 1rem; + margin-top: 1rem; + } + .swagger-ui .mv4-m { + margin-bottom: 2rem; + margin-top: 2rem; + } + .swagger-ui .mv5-m { + margin-bottom: 4rem; + margin-top: 4rem; + } + .swagger-ui .mv6-m { + margin-bottom: 8rem; + margin-top: 8rem; + } + .swagger-ui .mv7-m { + margin-bottom: 16rem; + margin-top: 16rem; + } + .swagger-ui .mh0-m { + margin-left: 0; + margin-right: 0; + } + .swagger-ui .mh1-m { + margin-left: 0.25rem; + margin-right: 0.25rem; + } + .swagger-ui .mh2-m { + margin-left: 0.5rem; + margin-right: 0.5rem; + } + .swagger-ui .mh3-m { + margin-left: 1rem; + margin-right: 1rem; + } + .swagger-ui .mh4-m { + margin-left: 2rem; + margin-right: 2rem; + } + .swagger-ui .mh5-m { + margin-left: 4rem; + margin-right: 4rem; + } + .swagger-ui .mh6-m { + margin-left: 8rem; + margin-right: 8rem; + } + .swagger-ui .mh7-m { + margin-left: 16rem; + margin-right: 16rem; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .pa0-l { + padding: 0; + } + .swagger-ui .pa1-l { + padding: 0.25rem; + } + .swagger-ui .pa2-l { + padding: 0.5rem; + } + .swagger-ui .pa3-l { + padding: 1rem; + } + .swagger-ui .pa4-l { + padding: 2rem; + } + .swagger-ui .pa5-l { + padding: 4rem; + } + .swagger-ui .pa6-l { + padding: 8rem; + } + .swagger-ui .pa7-l { + padding: 16rem; + } + .swagger-ui .pl0-l { + padding-left: 0; + } + .swagger-ui .pl1-l { + padding-left: 0.25rem; + } + .swagger-ui .pl2-l { + padding-left: 0.5rem; + } + .swagger-ui .pl3-l { + padding-left: 1rem; + } + .swagger-ui .pl4-l { + padding-left: 2rem; + } + .swagger-ui .pl5-l { + padding-left: 4rem; + } + .swagger-ui .pl6-l { + padding-left: 8rem; + } + .swagger-ui .pl7-l { + padding-left: 16rem; + } + .swagger-ui .pr0-l { + padding-right: 0; + } + .swagger-ui .pr1-l { + padding-right: 0.25rem; + } + .swagger-ui .pr2-l { + padding-right: 0.5rem; + } + .swagger-ui .pr3-l { + padding-right: 1rem; + } + .swagger-ui .pr4-l { + padding-right: 2rem; + } + .swagger-ui .pr5-l { + padding-right: 4rem; + } + .swagger-ui .pr6-l { + padding-right: 8rem; + } + .swagger-ui .pr7-l { + padding-right: 16rem; + } + .swagger-ui .pb0-l { + padding-bottom: 0; + } + .swagger-ui .pb1-l { + padding-bottom: 0.25rem; + } + .swagger-ui .pb2-l { + padding-bottom: 0.5rem; + } + .swagger-ui .pb3-l { + padding-bottom: 1rem; + } + .swagger-ui .pb4-l { + padding-bottom: 2rem; + } + .swagger-ui .pb5-l { + padding-bottom: 4rem; + } + .swagger-ui .pb6-l { + padding-bottom: 8rem; + } + .swagger-ui .pb7-l { + padding-bottom: 16rem; + } + .swagger-ui .pt0-l { + padding-top: 0; + } + .swagger-ui .pt1-l { + padding-top: 0.25rem; + } + .swagger-ui .pt2-l { + padding-top: 0.5rem; + } + .swagger-ui .pt3-l { + padding-top: 1rem; + } + .swagger-ui .pt4-l { + padding-top: 2rem; + } + .swagger-ui .pt5-l { + padding-top: 4rem; + } + .swagger-ui .pt6-l { + padding-top: 8rem; + } + .swagger-ui .pt7-l { + padding-top: 16rem; + } + .swagger-ui .pv0-l { + padding-bottom: 0; + padding-top: 0; + } + .swagger-ui .pv1-l { + padding-bottom: 0.25rem; + padding-top: 0.25rem; + } + .swagger-ui .pv2-l { + padding-bottom: 0.5rem; + padding-top: 0.5rem; + } + .swagger-ui .pv3-l { + padding-bottom: 1rem; + padding-top: 1rem; + } + .swagger-ui .pv4-l { + padding-bottom: 2rem; + padding-top: 2rem; + } + .swagger-ui .pv5-l { + padding-bottom: 4rem; + padding-top: 4rem; + } + .swagger-ui .pv6-l { + padding-bottom: 8rem; + padding-top: 8rem; + } + .swagger-ui .pv7-l { + padding-bottom: 16rem; + padding-top: 16rem; + } + .swagger-ui .ph0-l { + padding-left: 0; + padding-right: 0; + } + .swagger-ui .ph1-l { + padding-left: 0.25rem; + padding-right: 0.25rem; + } + .swagger-ui .ph2-l { + padding-left: 0.5rem; + padding-right: 0.5rem; + } + .swagger-ui .ph3-l { + padding-left: 1rem; + padding-right: 1rem; + } + .swagger-ui .ph4-l { + padding-left: 2rem; + padding-right: 2rem; + } + .swagger-ui .ph5-l { + padding-left: 4rem; + padding-right: 4rem; + } + .swagger-ui .ph6-l { + padding-left: 8rem; + padding-right: 8rem; + } + .swagger-ui .ph7-l { + padding-left: 16rem; + padding-right: 16rem; + } + .swagger-ui .ma0-l { + margin: 0; + } + .swagger-ui .ma1-l { + margin: 0.25rem; + } + .swagger-ui .ma2-l { + margin: 0.5rem; + } + .swagger-ui .ma3-l { + margin: 1rem; + } + .swagger-ui .ma4-l { + margin: 2rem; + } + .swagger-ui .ma5-l { + margin: 4rem; + } + .swagger-ui .ma6-l { + margin: 8rem; + } + .swagger-ui .ma7-l { + margin: 16rem; + } + .swagger-ui .ml0-l { + margin-left: 0; + } + .swagger-ui .ml1-l { + margin-left: 0.25rem; + } + .swagger-ui .ml2-l { + margin-left: 0.5rem; + } + .swagger-ui .ml3-l { + margin-left: 1rem; + } + .swagger-ui .ml4-l { + margin-left: 2rem; + } + .swagger-ui .ml5-l { + margin-left: 4rem; + } + .swagger-ui .ml6-l { + margin-left: 8rem; + } + .swagger-ui .ml7-l { + margin-left: 16rem; + } + .swagger-ui .mr0-l { + margin-right: 0; + } + .swagger-ui .mr1-l { + margin-right: 0.25rem; + } + .swagger-ui .mr2-l { + margin-right: 0.5rem; + } + .swagger-ui .mr3-l { + margin-right: 1rem; + } + .swagger-ui .mr4-l { + margin-right: 2rem; + } + .swagger-ui .mr5-l { + margin-right: 4rem; + } + .swagger-ui .mr6-l { + margin-right: 8rem; + } + .swagger-ui .mr7-l { + margin-right: 16rem; + } + .swagger-ui .mb0-l { + margin-bottom: 0; + } + .swagger-ui .mb1-l { + margin-bottom: 0.25rem; + } + .swagger-ui .mb2-l { + margin-bottom: 0.5rem; + } + .swagger-ui .mb3-l { + margin-bottom: 1rem; + } + .swagger-ui .mb4-l { + margin-bottom: 2rem; + } + .swagger-ui .mb5-l { + margin-bottom: 4rem; + } + .swagger-ui .mb6-l { + margin-bottom: 8rem; + } + .swagger-ui .mb7-l { + margin-bottom: 16rem; + } + .swagger-ui .mt0-l { + margin-top: 0; + } + .swagger-ui .mt1-l { + margin-top: 0.25rem; + } + .swagger-ui .mt2-l { + margin-top: 0.5rem; + } + .swagger-ui .mt3-l { + margin-top: 1rem; + } + .swagger-ui .mt4-l { + margin-top: 2rem; + } + .swagger-ui .mt5-l { + margin-top: 4rem; + } + .swagger-ui .mt6-l { + margin-top: 8rem; + } + .swagger-ui .mt7-l { + margin-top: 16rem; + } + .swagger-ui .mv0-l { + margin-bottom: 0; + margin-top: 0; + } + .swagger-ui .mv1-l { + margin-bottom: 0.25rem; + margin-top: 0.25rem; + } + .swagger-ui .mv2-l { + margin-bottom: 0.5rem; + margin-top: 0.5rem; + } + .swagger-ui .mv3-l { + margin-bottom: 1rem; + margin-top: 1rem; + } + .swagger-ui .mv4-l { + margin-bottom: 2rem; + margin-top: 2rem; + } + .swagger-ui .mv5-l { + margin-bottom: 4rem; + margin-top: 4rem; + } + .swagger-ui .mv6-l { + margin-bottom: 8rem; + margin-top: 8rem; + } + .swagger-ui .mv7-l { + margin-bottom: 16rem; + margin-top: 16rem; + } + .swagger-ui .mh0-l { + margin-left: 0; + margin-right: 0; + } + .swagger-ui .mh1-l { + margin-left: 0.25rem; + margin-right: 0.25rem; + } + .swagger-ui .mh2-l { + margin-left: 0.5rem; + margin-right: 0.5rem; + } + .swagger-ui .mh3-l { + margin-left: 1rem; + margin-right: 1rem; + } + .swagger-ui .mh4-l { + margin-left: 2rem; + margin-right: 2rem; + } + .swagger-ui .mh5-l { + margin-left: 4rem; + margin-right: 4rem; + } + .swagger-ui .mh6-l { + margin-left: 8rem; + margin-right: 8rem; + } + .swagger-ui .mh7-l { + margin-left: 16rem; + margin-right: 16rem; + } +} +.swagger-ui .na1 { + margin: -0.25rem; +} +.swagger-ui .na2 { + margin: -0.5rem; +} +.swagger-ui .na3 { + margin: -1rem; +} +.swagger-ui .na4 { + margin: -2rem; +} +.swagger-ui .na5 { + margin: -4rem; +} +.swagger-ui .na6 { + margin: -8rem; +} +.swagger-ui .na7 { + margin: -16rem; +} +.swagger-ui .nl1 { + margin-left: -0.25rem; +} +.swagger-ui .nl2 { + margin-left: -0.5rem; +} +.swagger-ui .nl3 { + margin-left: -1rem; +} +.swagger-ui .nl4 { + margin-left: -2rem; +} +.swagger-ui .nl5 { + margin-left: -4rem; +} +.swagger-ui .nl6 { + margin-left: -8rem; +} +.swagger-ui .nl7 { + margin-left: -16rem; +} +.swagger-ui .nr1 { + margin-right: -0.25rem; +} +.swagger-ui .nr2 { + margin-right: -0.5rem; +} +.swagger-ui .nr3 { + margin-right: -1rem; +} +.swagger-ui .nr4 { + margin-right: -2rem; +} +.swagger-ui .nr5 { + margin-right: -4rem; +} +.swagger-ui .nr6 { + margin-right: -8rem; +} +.swagger-ui .nr7 { + margin-right: -16rem; +} +.swagger-ui .nb1 { + margin-bottom: -0.25rem; +} +.swagger-ui .nb2 { + margin-bottom: -0.5rem; +} +.swagger-ui .nb3 { + margin-bottom: -1rem; +} +.swagger-ui .nb4 { + margin-bottom: -2rem; +} +.swagger-ui .nb5 { + margin-bottom: -4rem; +} +.swagger-ui .nb6 { + margin-bottom: -8rem; +} +.swagger-ui .nb7 { + margin-bottom: -16rem; +} +.swagger-ui .nt1 { + margin-top: -0.25rem; +} +.swagger-ui .nt2 { + margin-top: -0.5rem; +} +.swagger-ui .nt3 { + margin-top: -1rem; +} +.swagger-ui .nt4 { + margin-top: -2rem; +} +.swagger-ui .nt5 { + margin-top: -4rem; +} +.swagger-ui .nt6 { + margin-top: -8rem; +} +.swagger-ui .nt7 { + margin-top: -16rem; +} +@media screen and (min-width: 30em) { + .swagger-ui .na1-ns { + margin: -0.25rem; + } + .swagger-ui .na2-ns { + margin: -0.5rem; + } + .swagger-ui .na3-ns { + margin: -1rem; + } + .swagger-ui .na4-ns { + margin: -2rem; + } + .swagger-ui .na5-ns { + margin: -4rem; + } + .swagger-ui .na6-ns { + margin: -8rem; + } + .swagger-ui .na7-ns { + margin: -16rem; + } + .swagger-ui .nl1-ns { + margin-left: -0.25rem; + } + .swagger-ui .nl2-ns { + margin-left: -0.5rem; + } + .swagger-ui .nl3-ns { + margin-left: -1rem; + } + .swagger-ui .nl4-ns { + margin-left: -2rem; + } + .swagger-ui .nl5-ns { + margin-left: -4rem; + } + .swagger-ui .nl6-ns { + margin-left: -8rem; + } + .swagger-ui .nl7-ns { + margin-left: -16rem; + } + .swagger-ui .nr1-ns { + margin-right: -0.25rem; + } + .swagger-ui .nr2-ns { + margin-right: -0.5rem; + } + .swagger-ui .nr3-ns { + margin-right: -1rem; + } + .swagger-ui .nr4-ns { + margin-right: -2rem; + } + .swagger-ui .nr5-ns { + margin-right: -4rem; + } + .swagger-ui .nr6-ns { + margin-right: -8rem; + } + .swagger-ui .nr7-ns { + margin-right: -16rem; + } + .swagger-ui .nb1-ns { + margin-bottom: -0.25rem; + } + .swagger-ui .nb2-ns { + margin-bottom: -0.5rem; + } + .swagger-ui .nb3-ns { + margin-bottom: -1rem; + } + .swagger-ui .nb4-ns { + margin-bottom: -2rem; + } + .swagger-ui .nb5-ns { + margin-bottom: -4rem; + } + .swagger-ui .nb6-ns { + margin-bottom: -8rem; + } + .swagger-ui .nb7-ns { + margin-bottom: -16rem; + } + .swagger-ui .nt1-ns { + margin-top: -0.25rem; + } + .swagger-ui .nt2-ns { + margin-top: -0.5rem; + } + .swagger-ui .nt3-ns { + margin-top: -1rem; + } + .swagger-ui .nt4-ns { + margin-top: -2rem; + } + .swagger-ui .nt5-ns { + margin-top: -4rem; + } + .swagger-ui .nt6-ns { + margin-top: -8rem; + } + .swagger-ui .nt7-ns { + margin-top: -16rem; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .na1-m { + margin: -0.25rem; + } + .swagger-ui .na2-m { + margin: -0.5rem; + } + .swagger-ui .na3-m { + margin: -1rem; + } + .swagger-ui .na4-m { + margin: -2rem; + } + .swagger-ui .na5-m { + margin: -4rem; + } + .swagger-ui .na6-m { + margin: -8rem; + } + .swagger-ui .na7-m { + margin: -16rem; + } + .swagger-ui .nl1-m { + margin-left: -0.25rem; + } + .swagger-ui .nl2-m { + margin-left: -0.5rem; + } + .swagger-ui .nl3-m { + margin-left: -1rem; + } + .swagger-ui .nl4-m { + margin-left: -2rem; + } + .swagger-ui .nl5-m { + margin-left: -4rem; + } + .swagger-ui .nl6-m { + margin-left: -8rem; + } + .swagger-ui .nl7-m { + margin-left: -16rem; + } + .swagger-ui .nr1-m { + margin-right: -0.25rem; + } + .swagger-ui .nr2-m { + margin-right: -0.5rem; + } + .swagger-ui .nr3-m { + margin-right: -1rem; + } + .swagger-ui .nr4-m { + margin-right: -2rem; + } + .swagger-ui .nr5-m { + margin-right: -4rem; + } + .swagger-ui .nr6-m { + margin-right: -8rem; + } + .swagger-ui .nr7-m { + margin-right: -16rem; + } + .swagger-ui .nb1-m { + margin-bottom: -0.25rem; + } + .swagger-ui .nb2-m { + margin-bottom: -0.5rem; + } + .swagger-ui .nb3-m { + margin-bottom: -1rem; + } + .swagger-ui .nb4-m { + margin-bottom: -2rem; + } + .swagger-ui .nb5-m { + margin-bottom: -4rem; + } + .swagger-ui .nb6-m { + margin-bottom: -8rem; + } + .swagger-ui .nb7-m { + margin-bottom: -16rem; + } + .swagger-ui .nt1-m { + margin-top: -0.25rem; + } + .swagger-ui .nt2-m { + margin-top: -0.5rem; + } + .swagger-ui .nt3-m { + margin-top: -1rem; + } + .swagger-ui .nt4-m { + margin-top: -2rem; + } + .swagger-ui .nt5-m { + margin-top: -4rem; + } + .swagger-ui .nt6-m { + margin-top: -8rem; + } + .swagger-ui .nt7-m { + margin-top: -16rem; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .na1-l { + margin: -0.25rem; + } + .swagger-ui .na2-l { + margin: -0.5rem; + } + .swagger-ui .na3-l { + margin: -1rem; + } + .swagger-ui .na4-l { + margin: -2rem; + } + .swagger-ui .na5-l { + margin: -4rem; + } + .swagger-ui .na6-l { + margin: -8rem; + } + .swagger-ui .na7-l { + margin: -16rem; + } + .swagger-ui .nl1-l { + margin-left: -0.25rem; + } + .swagger-ui .nl2-l { + margin-left: -0.5rem; + } + .swagger-ui .nl3-l { + margin-left: -1rem; + } + .swagger-ui .nl4-l { + margin-left: -2rem; + } + .swagger-ui .nl5-l { + margin-left: -4rem; + } + .swagger-ui .nl6-l { + margin-left: -8rem; + } + .swagger-ui .nl7-l { + margin-left: -16rem; + } + .swagger-ui .nr1-l { + margin-right: -0.25rem; + } + .swagger-ui .nr2-l { + margin-right: -0.5rem; + } + .swagger-ui .nr3-l { + margin-right: -1rem; + } + .swagger-ui .nr4-l { + margin-right: -2rem; + } + .swagger-ui .nr5-l { + margin-right: -4rem; + } + .swagger-ui .nr6-l { + margin-right: -8rem; + } + .swagger-ui .nr7-l { + margin-right: -16rem; + } + .swagger-ui .nb1-l { + margin-bottom: -0.25rem; + } + .swagger-ui .nb2-l { + margin-bottom: -0.5rem; + } + .swagger-ui .nb3-l { + margin-bottom: -1rem; + } + .swagger-ui .nb4-l { + margin-bottom: -2rem; + } + .swagger-ui .nb5-l { + margin-bottom: -4rem; + } + .swagger-ui .nb6-l { + margin-bottom: -8rem; + } + .swagger-ui .nb7-l { + margin-bottom: -16rem; + } + .swagger-ui .nt1-l { + margin-top: -0.25rem; + } + .swagger-ui .nt2-l { + margin-top: -0.5rem; + } + .swagger-ui .nt3-l { + margin-top: -1rem; + } + .swagger-ui .nt4-l { + margin-top: -2rem; + } + .swagger-ui .nt5-l { + margin-top: -4rem; + } + .swagger-ui .nt6-l { + margin-top: -8rem; + } + .swagger-ui .nt7-l { + margin-top: -16rem; + } +} +.swagger-ui .collapse { + border-collapse: collapse; + border-spacing: 0; +} +.swagger-ui .striped--light-silver:nth-child(odd) { + background-color: #aaa; +} +.swagger-ui .striped--moon-gray:nth-child(odd) { + background-color: #ccc; +} +.swagger-ui .striped--light-gray:nth-child(odd) { + background-color: #eee; +} +.swagger-ui .striped--near-white:nth-child(odd) { + background-color: #f4f4f4; +} +.swagger-ui .stripe-light:nth-child(odd) { + background-color: hsla(0, 0%, 100%, 0.1); +} +.swagger-ui .stripe-dark:nth-child(odd) { + background-color: rgba(0, 0, 0, 0.1); +} +.swagger-ui .strike { + -webkit-text-decoration: line-through; + text-decoration: line-through; +} +.swagger-ui .underline { + -webkit-text-decoration: underline; + text-decoration: underline; +} +.swagger-ui .no-underline { + -webkit-text-decoration: none; + text-decoration: none; +} +@media screen and (min-width: 30em) { + .swagger-ui .strike-ns { + -webkit-text-decoration: line-through; + text-decoration: line-through; + } + .swagger-ui .underline-ns { + -webkit-text-decoration: underline; + text-decoration: underline; + } + .swagger-ui .no-underline-ns { + -webkit-text-decoration: none; + text-decoration: none; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .strike-m { + -webkit-text-decoration: line-through; + text-decoration: line-through; + } + .swagger-ui .underline-m { + -webkit-text-decoration: underline; + text-decoration: underline; + } + .swagger-ui .no-underline-m { + -webkit-text-decoration: none; + text-decoration: none; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .strike-l { + -webkit-text-decoration: line-through; + text-decoration: line-through; + } + .swagger-ui .underline-l { + -webkit-text-decoration: underline; + text-decoration: underline; + } + .swagger-ui .no-underline-l { + -webkit-text-decoration: none; + text-decoration: none; + } +} +.swagger-ui .tl { + text-align: left; +} +.swagger-ui .tr { + text-align: right; +} +.swagger-ui .tc { + text-align: center; +} +.swagger-ui .tj { + text-align: justify; +} +@media screen and (min-width: 30em) { + .swagger-ui .tl-ns { + text-align: left; + } + .swagger-ui .tr-ns { + text-align: right; + } + .swagger-ui .tc-ns { + text-align: center; + } + .swagger-ui .tj-ns { + text-align: justify; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .tl-m { + text-align: left; + } + .swagger-ui .tr-m { + text-align: right; + } + .swagger-ui .tc-m { + text-align: center; + } + .swagger-ui .tj-m { + text-align: justify; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .tl-l { + text-align: left; + } + .swagger-ui .tr-l { + text-align: right; + } + .swagger-ui .tc-l { + text-align: center; + } + .swagger-ui .tj-l { + text-align: justify; + } +} +.swagger-ui .ttc { + text-transform: capitalize; +} +.swagger-ui .ttl { + text-transform: lowercase; +} +.swagger-ui .ttu { + text-transform: uppercase; +} +.swagger-ui .ttn { + text-transform: none; +} +@media screen and (min-width: 30em) { + .swagger-ui .ttc-ns { + text-transform: capitalize; + } + .swagger-ui .ttl-ns { + text-transform: lowercase; + } + .swagger-ui .ttu-ns { + text-transform: uppercase; + } + .swagger-ui .ttn-ns { + text-transform: none; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .ttc-m { + text-transform: capitalize; + } + .swagger-ui .ttl-m { + text-transform: lowercase; + } + .swagger-ui .ttu-m { + text-transform: uppercase; + } + .swagger-ui .ttn-m { + text-transform: none; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .ttc-l { + text-transform: capitalize; + } + .swagger-ui .ttl-l { + text-transform: lowercase; + } + .swagger-ui .ttu-l { + text-transform: uppercase; + } + .swagger-ui .ttn-l { + text-transform: none; + } +} +.swagger-ui .f-6, +.swagger-ui .f-headline { + font-size: 6rem; +} +.swagger-ui .f-5, +.swagger-ui .f-subheadline { + font-size: 5rem; +} +.swagger-ui .f1 { + font-size: 3rem; +} +.swagger-ui .f2 { + font-size: 2.25rem; +} +.swagger-ui .f3 { + font-size: 1.5rem; +} +.swagger-ui .f4 { + font-size: 1.25rem; +} +.swagger-ui .f5 { + font-size: 1rem; +} +.swagger-ui .f6 { + font-size: 0.875rem; +} +.swagger-ui .f7 { + font-size: 0.75rem; +} +@media screen and (min-width: 30em) { + .swagger-ui .f-6-ns, + .swagger-ui .f-headline-ns { + font-size: 6rem; + } + .swagger-ui .f-5-ns, + .swagger-ui .f-subheadline-ns { + font-size: 5rem; + } + .swagger-ui .f1-ns { + font-size: 3rem; + } + .swagger-ui .f2-ns { + font-size: 2.25rem; + } + .swagger-ui .f3-ns { + font-size: 1.5rem; + } + .swagger-ui .f4-ns { + font-size: 1.25rem; + } + .swagger-ui .f5-ns { + font-size: 1rem; + } + .swagger-ui .f6-ns { + font-size: 0.875rem; + } + .swagger-ui .f7-ns { + font-size: 0.75rem; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .f-6-m, + .swagger-ui .f-headline-m { + font-size: 6rem; + } + .swagger-ui .f-5-m, + .swagger-ui .f-subheadline-m { + font-size: 5rem; + } + .swagger-ui .f1-m { + font-size: 3rem; + } + .swagger-ui .f2-m { + font-size: 2.25rem; + } + .swagger-ui .f3-m { + font-size: 1.5rem; + } + .swagger-ui .f4-m { + font-size: 1.25rem; + } + .swagger-ui .f5-m { + font-size: 1rem; + } + .swagger-ui .f6-m { + font-size: 0.875rem; + } + .swagger-ui .f7-m { + font-size: 0.75rem; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .f-6-l, + .swagger-ui .f-headline-l { + font-size: 6rem; + } + .swagger-ui .f-5-l, + .swagger-ui .f-subheadline-l { + font-size: 5rem; + } + .swagger-ui .f1-l { + font-size: 3rem; + } + .swagger-ui .f2-l { + font-size: 2.25rem; + } + .swagger-ui .f3-l { + font-size: 1.5rem; + } + .swagger-ui .f4-l { + font-size: 1.25rem; + } + .swagger-ui .f5-l { + font-size: 1rem; + } + .swagger-ui .f6-l { + font-size: 0.875rem; + } + .swagger-ui .f7-l { + font-size: 0.75rem; + } +} +.swagger-ui .measure { + max-width: 30em; +} +.swagger-ui .measure-wide { + max-width: 34em; +} +.swagger-ui .measure-narrow { + max-width: 20em; +} +.swagger-ui .indent { + margin-bottom: 0; + margin-top: 0; + text-indent: 1em; +} +.swagger-ui .small-caps { + font-feature-settings: 'smcp'; + font-variant: small-caps; +} +.swagger-ui .truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +@media screen and (min-width: 30em) { + .swagger-ui .measure-ns { + max-width: 30em; + } + .swagger-ui .measure-wide-ns { + max-width: 34em; + } + .swagger-ui .measure-narrow-ns { + max-width: 20em; + } + .swagger-ui .indent-ns { + margin-bottom: 0; + margin-top: 0; + text-indent: 1em; + } + .swagger-ui .small-caps-ns { + font-feature-settings: 'smcp'; + font-variant: small-caps; + } + .swagger-ui .truncate-ns { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .measure-m { + max-width: 30em; + } + .swagger-ui .measure-wide-m { + max-width: 34em; + } + .swagger-ui .measure-narrow-m { + max-width: 20em; + } + .swagger-ui .indent-m { + margin-bottom: 0; + margin-top: 0; + text-indent: 1em; + } + .swagger-ui .small-caps-m { + font-feature-settings: 'smcp'; + font-variant: small-caps; + } + .swagger-ui .truncate-m { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .measure-l { + max-width: 30em; + } + .swagger-ui .measure-wide-l { + max-width: 34em; + } + .swagger-ui .measure-narrow-l { + max-width: 20em; + } + .swagger-ui .indent-l { + margin-bottom: 0; + margin-top: 0; + text-indent: 1em; + } + .swagger-ui .small-caps-l { + font-feature-settings: 'smcp'; + font-variant: small-caps; + } + .swagger-ui .truncate-l { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } +} +.swagger-ui .overflow-container { + overflow-y: scroll; +} +.swagger-ui .center { + margin-left: auto; + margin-right: auto; +} +.swagger-ui .mr-auto { + margin-right: auto; +} +.swagger-ui .ml-auto { + margin-left: auto; +} +@media screen and (min-width: 30em) { + .swagger-ui .center-ns { + margin-left: auto; + margin-right: auto; + } + .swagger-ui .mr-auto-ns { + margin-right: auto; + } + .swagger-ui .ml-auto-ns { + margin-left: auto; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .center-m { + margin-left: auto; + margin-right: auto; + } + .swagger-ui .mr-auto-m { + margin-right: auto; + } + .swagger-ui .ml-auto-m { + margin-left: auto; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .center-l { + margin-left: auto; + margin-right: auto; + } + .swagger-ui .mr-auto-l { + margin-right: auto; + } + .swagger-ui .ml-auto-l { + margin-left: auto; + } +} +.swagger-ui .clip { + position: fixed !important; + _position: absolute !important; + clip: rect(1px 1px 1px 1px); + clip: rect(1px, 1px, 1px, 1px); +} +@media screen and (min-width: 30em) { + .swagger-ui .clip-ns { + position: fixed !important; + _position: absolute !important; + clip: rect(1px 1px 1px 1px); + clip: rect(1px, 1px, 1px, 1px); + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .clip-m { + position: fixed !important; + _position: absolute !important; + clip: rect(1px 1px 1px 1px); + clip: rect(1px, 1px, 1px, 1px); + } +} +@media screen and (min-width: 60em) { + .swagger-ui .clip-l { + position: fixed !important; + _position: absolute !important; + clip: rect(1px 1px 1px 1px); + clip: rect(1px, 1px, 1px, 1px); + } +} +.swagger-ui .ws-normal { + white-space: normal; +} +.swagger-ui .nowrap { + white-space: nowrap; +} +.swagger-ui .pre { + white-space: pre; +} +@media screen and (min-width: 30em) { + .swagger-ui .ws-normal-ns { + white-space: normal; + } + .swagger-ui .nowrap-ns { + white-space: nowrap; + } + .swagger-ui .pre-ns { + white-space: pre; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .ws-normal-m { + white-space: normal; + } + .swagger-ui .nowrap-m { + white-space: nowrap; + } + .swagger-ui .pre-m { + white-space: pre; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .ws-normal-l { + white-space: normal; + } + .swagger-ui .nowrap-l { + white-space: nowrap; + } + .swagger-ui .pre-l { + white-space: pre; + } +} +.swagger-ui .v-base { + vertical-align: baseline; +} +.swagger-ui .v-mid { + vertical-align: middle; +} +.swagger-ui .v-top { + vertical-align: top; +} +.swagger-ui .v-btm { + vertical-align: bottom; +} +@media screen and (min-width: 30em) { + .swagger-ui .v-base-ns { + vertical-align: baseline; + } + .swagger-ui .v-mid-ns { + vertical-align: middle; + } + .swagger-ui .v-top-ns { + vertical-align: top; + } + .swagger-ui .v-btm-ns { + vertical-align: bottom; + } +} +@media screen and (min-width: 30em) and (max-width: 60em) { + .swagger-ui .v-base-m { + vertical-align: baseline; + } + .swagger-ui .v-mid-m { + vertical-align: middle; + } + .swagger-ui .v-top-m { + vertical-align: top; + } + .swagger-ui .v-btm-m { + vertical-align: bottom; + } +} +@media screen and (min-width: 60em) { + .swagger-ui .v-base-l { + vertical-align: baseline; + } + .swagger-ui .v-mid-l { + vertical-align: middle; + } + .swagger-ui .v-top-l { + vertical-align: top; + } + .swagger-ui .v-btm-l { + vertical-align: bottom; + } +} +.swagger-ui .dim { + opacity: 1; + transition: opacity 0.15s ease-in; +} +.swagger-ui .dim:focus, +.swagger-ui .dim:hover { + opacity: 0.5; + transition: opacity 0.15s ease-in; +} +.swagger-ui .dim:active { + opacity: 0.8; + transition: opacity 0.15s ease-out; +} +.swagger-ui .glow { + transition: opacity 0.15s ease-in; +} +.swagger-ui .glow:focus, +.swagger-ui .glow:hover { + opacity: 1; + transition: opacity 0.15s ease-in; +} +.swagger-ui .hide-child .child { + opacity: 0; + transition: opacity 0.15s ease-in; +} +.swagger-ui .hide-child:active .child, +.swagger-ui .hide-child:focus .child, +.swagger-ui .hide-child:hover .child { + opacity: 1; + transition: opacity 0.15s ease-in; +} +.swagger-ui .underline-hover:focus, +.swagger-ui .underline-hover:hover { + -webkit-text-decoration: underline; + text-decoration: underline; +} +.swagger-ui .grow { + -moz-osx-font-smoothing: grayscale; + backface-visibility: hidden; + transform: translateZ(0); + transition: transform 0.25s ease-out; +} +.swagger-ui .grow:focus, +.swagger-ui .grow:hover { + transform: scale(1.05); +} +.swagger-ui .grow:active { + transform: scale(0.9); +} +.swagger-ui .grow-large { + -moz-osx-font-smoothing: grayscale; + backface-visibility: hidden; + transform: translateZ(0); + transition: transform 0.25s ease-in-out; +} +.swagger-ui .grow-large:focus, +.swagger-ui .grow-large:hover { + transform: scale(1.2); +} +.swagger-ui .grow-large:active { + transform: scale(0.95); +} +.swagger-ui .pointer:hover { + cursor: pointer; +} +.swagger-ui .shadow-hover { + cursor: pointer; + position: relative; + transition: all 0.5s cubic-bezier(0.165, 0.84, 0.44, 1); +} +.swagger-ui .shadow-hover:after { + border-radius: inherit; + box-shadow: 0 0 16px 2px rgba(0, 0, 0, 0.2); + content: ''; + height: 100%; + left: 0; + opacity: 0; + position: absolute; + top: 0; + transition: opacity 0.5s cubic-bezier(0.165, 0.84, 0.44, 1); + width: 100%; + z-index: -1; +} +.swagger-ui .shadow-hover:focus:after, +.swagger-ui .shadow-hover:hover:after { + opacity: 1; +} +.swagger-ui .bg-animate, +.swagger-ui .bg-animate:focus, +.swagger-ui .bg-animate:hover { + transition: background-color 0.15s ease-in-out; +} +.swagger-ui .z-0 { + z-index: 0; +} +.swagger-ui .z-1 { + z-index: 1; +} +.swagger-ui .z-2 { + z-index: 2; +} +.swagger-ui .z-3 { + z-index: 3; +} +.swagger-ui .z-4 { + z-index: 4; +} +.swagger-ui .z-5 { + z-index: 5; +} +.swagger-ui .z-999 { + z-index: 999; +} +.swagger-ui .z-9999 { + z-index: 9999; +} +.swagger-ui .z-max { + z-index: 2147483647; +} +.swagger-ui .z-inherit { + z-index: inherit; +} +.swagger-ui .z-initial, +.swagger-ui .z-unset { + z-index: auto; +} +.swagger-ui .nested-copy-line-height ol, +.swagger-ui .nested-copy-line-height p, +.swagger-ui .nested-copy-line-height ul { + line-height: 1.5; +} +.swagger-ui .nested-headline-line-height h1, +.swagger-ui .nested-headline-line-height h2, +.swagger-ui .nested-headline-line-height h3, +.swagger-ui .nested-headline-line-height h4, +.swagger-ui .nested-headline-line-height h5, +.swagger-ui .nested-headline-line-height h6 { + line-height: 1.25; +} +.swagger-ui .nested-list-reset ol, +.swagger-ui .nested-list-reset ul { + list-style-type: none; + margin-left: 0; + padding-left: 0; +} +.swagger-ui .nested-copy-indent p + p { + margin-bottom: 0; + margin-top: 0; + text-indent: 0.1em; +} +.swagger-ui .nested-copy-seperator p + p { + margin-top: 1.5em; +} +.swagger-ui .nested-img img { + display: block; + max-width: 100%; + width: 100%; +} +.swagger-ui .nested-links a { + color: #357edd; + transition: color 0.15s ease-in; +} +.swagger-ui .nested-links a:focus, +.swagger-ui .nested-links a:hover { + color: #96ccff; + transition: color 0.15s ease-in; +} +.swagger-ui .wrapper { + box-sizing: border-box; + margin: 0 auto; + max-width: 1460px; + padding: 0 20px; + width: 100%; +} +.swagger-ui .opblock-tag-section { + display: flex; + flex-direction: column; +} +.swagger-ui .try-out.btn-group { + display: flex; + flex: 0.1 2 auto; + padding: 0; +} +.swagger-ui .try-out__btn { + margin-left: 1.25rem; +} +.swagger-ui .opblock-tag { + align-items: center; + border-bottom: 1px solid rgba(59, 65, 81, 0.3); + cursor: pointer; + display: flex; + padding: 10px 20px 10px 10px; + transition: all 0.2s; +} +.swagger-ui .opblock-tag:hover { + background: rgba(0, 0, 0, 0.02); +} +.swagger-ui .opblock-tag { + color: #3b4151; + font-family: sans-serif; + font-size: 24px; + margin: 0 0 5px; +} +.swagger-ui .opblock-tag.no-desc span { + flex: 1; +} +.swagger-ui .opblock-tag svg { + transition: all 0.4s; +} +.swagger-ui .opblock-tag small { + color: #3b4151; + flex: 2; + font-family: sans-serif; + font-size: 14px; + font-weight: 400; + padding: 0 10px; +} +.swagger-ui .opblock-tag > div { + flex: 1 1 150px; + font-weight: 400; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +@media (max-width: 640px) { + .swagger-ui .opblock-tag small, + .swagger-ui .opblock-tag > div { + flex: 1; + } +} +.swagger-ui .opblock-tag .info__externaldocs { + text-align: right; +} +.swagger-ui .parameter__type { + color: #3b4151; + font-family: monospace; + font-size: 12px; + font-weight: 600; + padding: 5px 0; +} +.swagger-ui .parameter-controls { + margin-top: 0.75em; +} +.swagger-ui .examples__title { + display: block; + font-size: 1.1em; + font-weight: 700; + margin-bottom: 0.75em; +} +.swagger-ui .examples__section { + margin-top: 1.5em; +} +.swagger-ui .examples__section-header { + font-size: 0.9rem; + font-weight: 700; + margin-bottom: 0.5rem; +} +.swagger-ui .examples-select { + display: inline-block; + margin-bottom: 0.75em; +} +.swagger-ui .examples-select .examples-select-element { + width: 100%; +} +.swagger-ui .examples-select__section-label { + font-size: 0.9rem; + font-weight: 700; + margin-right: 0.5rem; +} +.swagger-ui .example__section { + margin-top: 1.5em; +} +.swagger-ui .example__section-header { + font-size: 0.9rem; + font-weight: 700; + margin-bottom: 0.5rem; +} +.swagger-ui .view-line-link { + cursor: pointer; + margin: 0 5px; + position: relative; + top: 3px; + transition: all 0.5s; + width: 20px; +} +.swagger-ui .opblock { + border: 1px solid #000; + border-radius: 4px; + box-shadow: 0 0 3px rgba(0, 0, 0, 0.19); + margin: 0 0 15px; +} +.swagger-ui .opblock .tab-header { + display: flex; + flex: 1; +} +.swagger-ui .opblock .tab-header .tab-item { + cursor: pointer; + padding: 0 40px; +} +.swagger-ui .opblock .tab-header .tab-item:first-of-type { + padding: 0 40px 0 0; +} +.swagger-ui .opblock .tab-header .tab-item.active h4 span { + position: relative; +} +.swagger-ui .opblock .tab-header .tab-item.active h4 span:after { + background: grey; + bottom: -15px; + content: ''; + height: 4px; + left: 50%; + position: absolute; + transform: translateX(-50%); + width: 120%; +} +.swagger-ui .opblock.is-open .opblock-summary { + border-bottom: 1px solid #000; +} +.swagger-ui .opblock .opblock-section-header { + align-items: center; + background: hsla(0, 0%, 100%, 0.8); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); + display: flex; + min-height: 50px; + padding: 8px 20px; +} +.swagger-ui .opblock .opblock-section-header > label { + align-items: center; + color: #3b4151; + display: flex; + font-family: sans-serif; + font-size: 12px; + font-weight: 700; + margin: 0 0 0 auto; +} +.swagger-ui .opblock .opblock-section-header > label > span { + padding: 0 10px 0 0; +} +.swagger-ui .opblock .opblock-section-header h4 { + color: #3b4151; + flex: 1; + font-family: sans-serif; + font-size: 14px; + margin: 0; +} +.swagger-ui .opblock .opblock-summary-method { + background: #000; + border-radius: 3px; + color: #fff; + font-family: sans-serif; + font-size: 14px; + font-weight: 700; + min-width: 80px; + padding: 6px 0; + text-align: center; + text-shadow: 0 1px 0 rgba(0, 0, 0, 0.1); +} +@media (max-width: 768px) { + .swagger-ui .opblock .opblock-summary-method { + font-size: 12px; + } +} +.swagger-ui .opblock .opblock-summary-operation-id, +.swagger-ui .opblock .opblock-summary-path, +.swagger-ui .opblock .opblock-summary-path__deprecated { + align-items: center; + color: #3b4151; + display: flex; + font-family: monospace; + font-size: 16px; + font-weight: 600; + word-break: break-word; +} +@media (max-width: 768px) { + .swagger-ui .opblock .opblock-summary-operation-id, + .swagger-ui .opblock .opblock-summary-path, + .swagger-ui .opblock .opblock-summary-path__deprecated { + font-size: 12px; + } +} +.swagger-ui .opblock .opblock-summary-path { + flex-shrink: 1; +} +@media (max-width: 640px) { + .swagger-ui .opblock .opblock-summary-path { + max-width: 100%; + } +} +.swagger-ui .opblock .opblock-summary-path__deprecated { + -webkit-text-decoration: line-through; + text-decoration: line-through; +} +.swagger-ui .opblock .opblock-summary-operation-id { + font-size: 14px; +} +.swagger-ui .opblock .opblock-summary-description { + color: #3b4151; + font-family: sans-serif; + font-size: 13px; + word-break: break-word; +} +.swagger-ui .opblock .opblock-summary-path-description-wrapper { + align-items: center; + display: flex; + flex-direction: row; + flex-wrap: wrap; + gap: 0 10px; + padding: 0 10px; + width: 100%; +} +@media (max-width: 550px) { + .swagger-ui .opblock .opblock-summary-path-description-wrapper { + align-items: flex-start; + flex-direction: column; + } +} +.swagger-ui .opblock .opblock-summary { + align-items: center; + cursor: pointer; + display: flex; + padding: 5px; +} +.swagger-ui .opblock .opblock-summary .view-line-link { + cursor: pointer; + margin: 0; + position: relative; + top: 2px; + transition: all 0.5s; + width: 0; +} +.swagger-ui .opblock .opblock-summary:hover .view-line-link { + margin: 0 5px; + width: 18px; +} +.swagger-ui .opblock .opblock-summary:hover .view-line-link.copy-to-clipboard { + width: 24px; +} +.swagger-ui .opblock.opblock-post { + background: rgba(73, 204, 144, 0.1); + border-color: #49cc90; +} +.swagger-ui .opblock.opblock-post .opblock-summary-method { + background: #49cc90; +} +.swagger-ui .opblock.opblock-post .opblock-summary { + border-color: #49cc90; +} +.swagger-ui .opblock.opblock-post .tab-header .tab-item.active h4 span:after { + background: #49cc90; +} +.swagger-ui .opblock.opblock-put { + background: rgba(252, 161, 48, 0.1); + border-color: #fca130; +} +.swagger-ui .opblock.opblock-put .opblock-summary-method { + background: #fca130; +} +.swagger-ui .opblock.opblock-put .opblock-summary { + border-color: #fca130; +} +.swagger-ui .opblock.opblock-put .tab-header .tab-item.active h4 span:after { + background: #fca130; +} +.swagger-ui .opblock.opblock-delete { + background: rgba(249, 62, 62, 0.1); + border-color: #f93e3e; +} +.swagger-ui .opblock.opblock-delete .opblock-summary-method { + background: #f93e3e; +} +.swagger-ui .opblock.opblock-delete .opblock-summary { + border-color: #f93e3e; +} +.swagger-ui .opblock.opblock-delete .tab-header .tab-item.active h4 span:after { + background: #f93e3e; +} +.swagger-ui .opblock.opblock-get { + background: rgba(97, 175, 254, 0.1); + border-color: #61affe; +} +.swagger-ui .opblock.opblock-get .opblock-summary-method { + background: #61affe; +} +.swagger-ui .opblock.opblock-get .opblock-summary { + border-color: #61affe; +} +.swagger-ui .opblock.opblock-get .tab-header .tab-item.active h4 span:after { + background: #61affe; +} +.swagger-ui .opblock.opblock-patch { + background: rgba(80, 227, 194, 0.1); + border-color: #50e3c2; +} +.swagger-ui .opblock.opblock-patch .opblock-summary-method { + background: #50e3c2; +} +.swagger-ui .opblock.opblock-patch .opblock-summary { + border-color: #50e3c2; +} +.swagger-ui .opblock.opblock-patch .tab-header .tab-item.active h4 span:after { + background: #50e3c2; +} +.swagger-ui .opblock.opblock-head { + background: rgba(144, 18, 254, 0.1); + border-color: #9012fe; +} +.swagger-ui .opblock.opblock-head .opblock-summary-method { + background: #9012fe; +} +.swagger-ui .opblock.opblock-head .opblock-summary { + border-color: #9012fe; +} +.swagger-ui .opblock.opblock-head .tab-header .tab-item.active h4 span:after { + background: #9012fe; +} +.swagger-ui .opblock.opblock-options { + background: rgba(13, 90, 167, 0.1); + border-color: #0d5aa7; +} +.swagger-ui .opblock.opblock-options .opblock-summary-method { + background: #0d5aa7; +} +.swagger-ui .opblock.opblock-options .opblock-summary { + border-color: #0d5aa7; +} +.swagger-ui .opblock.opblock-options .tab-header .tab-item.active h4 span:after { + background: #0d5aa7; +} +.swagger-ui .opblock.opblock-deprecated { + background: hsla(0, 0%, 92%, 0.1); + border-color: #ebebeb; + opacity: 0.6; +} +.swagger-ui .opblock.opblock-deprecated .opblock-summary-method { + background: #ebebeb; +} +.swagger-ui .opblock.opblock-deprecated .opblock-summary { + border-color: #ebebeb; +} +.swagger-ui .opblock.opblock-deprecated .tab-header .tab-item.active h4 span:after { + background: #ebebeb; +} +.swagger-ui .opblock .opblock-schemes { + padding: 8px 20px; +} +.swagger-ui .opblock .opblock-schemes .schemes-title { + padding: 0 10px 0 0; +} +.swagger-ui .filter .operation-filter-input { + border: 2px solid #d8dde7; + margin: 20px 0; + padding: 10px; + width: 100%; +} +.swagger-ui .download-url-wrapper .failed, +.swagger-ui .filter .failed { + color: red; +} +.swagger-ui .download-url-wrapper .loading, +.swagger-ui .filter .loading { + color: #aaa; +} +.swagger-ui .model-example { + margin-top: 1em; +} +.swagger-ui .tab { + display: flex; + list-style: none; + padding: 0; +} +.swagger-ui .tab li { + color: #3b4151; + cursor: pointer; + font-family: sans-serif; + font-size: 12px; + min-width: 60px; + padding: 0; +} +.swagger-ui .tab li:first-of-type { + padding-left: 0; + padding-right: 12px; + position: relative; +} +.swagger-ui .tab li:first-of-type:after { + background: rgba(0, 0, 0, 0.2); + content: ''; + height: 100%; + position: absolute; + right: 6px; + top: 0; + width: 1px; +} +.swagger-ui .tab li.active { + font-weight: 700; +} +.swagger-ui .tab li button.tablinks { + background: none; + border: 0; + color: inherit; + font-family: inherit; + font-weight: inherit; + padding: 0; +} +.swagger-ui .opblock-description-wrapper, +.swagger-ui .opblock-external-docs-wrapper, +.swagger-ui .opblock-title_normal { + color: #3b4151; + font-family: sans-serif; + font-size: 12px; + margin: 0 0 5px; + padding: 15px 20px; +} +.swagger-ui .opblock-description-wrapper h4, +.swagger-ui .opblock-external-docs-wrapper h4, +.swagger-ui .opblock-title_normal h4 { + color: #3b4151; + font-family: sans-serif; + font-size: 12px; + margin: 0 0 5px; +} +.swagger-ui .opblock-description-wrapper p, +.swagger-ui .opblock-external-docs-wrapper p, +.swagger-ui .opblock-title_normal p { + color: #3b4151; + font-family: sans-serif; + font-size: 14px; + margin: 0; +} +.swagger-ui .opblock-external-docs-wrapper h4 { + padding-left: 0; +} +.swagger-ui .execute-wrapper { + padding: 20px; + text-align: right; +} +.swagger-ui .execute-wrapper .btn { + padding: 8px 40px; + width: 100%; +} +.swagger-ui .body-param-options { + display: flex; + flex-direction: column; +} +.swagger-ui .body-param-options .body-param-edit { + padding: 10px 0; +} +.swagger-ui .body-param-options label { + padding: 8px 0; +} +.swagger-ui .body-param-options label select { + margin: 3px 0 0; +} +.swagger-ui .responses-inner { + padding: 20px; +} +.swagger-ui .responses-inner h4, +.swagger-ui .responses-inner h5 { + color: #3b4151; + font-family: sans-serif; + font-size: 12px; + margin: 10px 0 5px; +} +.swagger-ui .responses-inner .curl { + max-height: 400px; + min-height: 6em; + overflow-y: auto; +} +.swagger-ui .response-col_status { + color: #3b4151; + font-family: sans-serif; + font-size: 14px; +} +.swagger-ui .response-col_status .response-undocumented { + color: #909090; + font-family: monospace; + font-size: 11px; + font-weight: 600; +} +.swagger-ui .response-col_links { + color: #3b4151; + font-family: sans-serif; + font-size: 14px; + max-width: 40em; + padding-left: 2em; +} +.swagger-ui .response-col_links .response-undocumented { + color: #909090; + font-family: monospace; + font-size: 11px; + font-weight: 600; +} +.swagger-ui .response-col_links .operation-link { + margin-bottom: 1.5em; +} +.swagger-ui .response-col_links .operation-link .description { + margin-bottom: 0.5em; +} +.swagger-ui .opblock-body .opblock-loading-animation { + display: block; + margin: 3em auto; +} +.swagger-ui .opblock-body pre.microlight { + background: #333; + border-radius: 4px; + font-size: 12px; + hyphens: auto; + margin: 0; + padding: 10px; + white-space: pre-wrap; + word-break: break-all; + word-break: break-word; + word-wrap: break-word; + color: #fff; + font-family: monospace; + font-weight: 600; +} +.swagger-ui .opblock-body pre.microlight .headerline { + display: block; +} +.swagger-ui .highlight-code { + position: relative; +} +.swagger-ui .highlight-code > .microlight { + max-height: 400px; + min-height: 6em; + overflow-y: auto; +} +.swagger-ui .highlight-code > .microlight code { + white-space: pre-wrap !important; + word-break: break-all; +} +.swagger-ui .curl-command { + position: relative; +} +.swagger-ui .download-contents { + align-items: center; + background: #7d8293; + border: none; + border-radius: 4px; + bottom: 10px; + color: #fff; + display: flex; + font-family: sans-serif; + font-size: 14px; + font-weight: 600; + height: 30px; + justify-content: center; + padding: 5px; + position: absolute; + right: 10px; + text-align: center; +} +.swagger-ui .scheme-container { + background: #fff; + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.15); + margin: 0 0 20px; + padding: 30px 0; +} +.swagger-ui .scheme-container .schemes { + align-items: flex-end; + display: flex; + flex-wrap: wrap; + gap: 10px; + justify-content: space-between; +} +.swagger-ui .scheme-container .schemes > .schemes-server-container { + display: flex; + flex-wrap: wrap; + gap: 10px; +} +.swagger-ui .scheme-container .schemes > .schemes-server-container > label { + color: #3b4151; + display: flex; + flex-direction: column; + font-family: sans-serif; + font-size: 12px; + font-weight: 700; + margin: -20px 15px 0 0; +} +.swagger-ui .scheme-container .schemes > .schemes-server-container > label select { + min-width: 130px; + text-transform: uppercase; +} +.swagger-ui .scheme-container .schemes:not(:has(.schemes-server-container)) { + justify-content: flex-end; +} +.swagger-ui .scheme-container .schemes .auth-wrapper { + flex: none; + justify-content: start; +} +.swagger-ui .scheme-container .schemes .auth-wrapper .authorize { + display: flex; + flex-wrap: nowrap; + margin: 0; + padding-right: 20px; +} +.swagger-ui .loading-container { + align-items: center; + display: flex; + flex-direction: column; + justify-content: center; + margin-top: 1em; + min-height: 1px; + padding: 40px 0 60px; +} +.swagger-ui .loading-container .loading { + position: relative; +} +.swagger-ui .loading-container .loading:after { + color: #3b4151; + content: 'loading'; + font-family: sans-serif; + font-size: 10px; + font-weight: 700; + left: 50%; + position: absolute; + text-transform: uppercase; + top: 50%; + transform: translate(-50%, -50%); +} +.swagger-ui .loading-container .loading:before { + animation: + rotation 1s linear infinite, + opacity 0.5s; + backface-visibility: hidden; + border: 2px solid rgba(85, 85, 85, 0.1); + border-radius: 100%; + border-top-color: rgba(0, 0, 0, 0.6); + content: ''; + display: block; + height: 60px; + left: 50%; + margin: -30px; + opacity: 1; + position: absolute; + top: 50%; + width: 60px; +} +@keyframes rotation { + to { + transform: rotate(1turn); + } +} +.swagger-ui .response-controls { + display: flex; + padding-top: 1em; +} +.swagger-ui .response-control-media-type { + margin-right: 1em; +} +.swagger-ui .response-control-media-type--accept-controller select { + border-color: green; +} +.swagger-ui .response-control-media-type__accept-message { + color: green; + font-size: 0.7em; +} +.swagger-ui .response-control-examples__title, +.swagger-ui .response-control-media-type__title { + display: block; + font-size: 0.7em; + margin-bottom: 0.2em; +} +@keyframes blinker { + 50% { + opacity: 0; + } +} +.swagger-ui .hidden { + display: none; +} +.swagger-ui .no-margin { + border: none; + height: auto; + margin: 0; + padding: 0; +} +.swagger-ui .float-right { + float: right; +} +.swagger-ui .svg-assets { + height: 0; + position: absolute; + width: 0; +} +.swagger-ui section h3 { + color: #3b4151; + font-family: sans-serif; +} +.swagger-ui a.nostyle { + display: inline; +} +.swagger-ui a.nostyle, +.swagger-ui a.nostyle:visited { + color: inherit; + cursor: pointer; + text-decoration: inherit; +} +.swagger-ui .fallback { + color: #aaa; + padding: 1em; +} +.swagger-ui .version-pragma { + height: 100%; + padding: 5em 0; +} +.swagger-ui .version-pragma__message { + display: flex; + font-size: 1.2em; + height: 100%; + justify-content: center; + line-height: 1.5em; + padding: 0 0.6em; + text-align: center; +} +.swagger-ui .version-pragma__message > div { + flex: 1; + max-width: 55ch; +} +.swagger-ui .version-pragma__message code { + background-color: #dedede; + padding: 4px 4px 2px; + white-space: pre; +} +.swagger-ui .opblock-link { + font-weight: 400; +} +.swagger-ui .opblock-link.shown { + font-weight: 700; +} +.swagger-ui span.token-string { + color: #555; +} +.swagger-ui span.token-not-formatted { + color: #555; + font-weight: 700; +} +.swagger-ui .btn { + background: transparent; + border: 2px solid grey; + border-radius: 4px; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); + color: #3b4151; + font-family: sans-serif; + font-size: 14px; + font-weight: 700; + padding: 5px 23px; + transition: all 0.3s; +} +.swagger-ui .btn.btn-sm { + font-size: 12px; + padding: 4px 23px; +} +.swagger-ui .btn[disabled] { + cursor: not-allowed; + opacity: 0.3; +} +.swagger-ui .btn:hover { + box-shadow: 0 0 5px rgba(0, 0, 0, 0.3); +} +.swagger-ui .btn.cancel { + background-color: transparent; + border-color: #ff6060; + color: #ff6060; + font-family: sans-serif; +} +.swagger-ui .btn.authorize { + background-color: transparent; + border-color: #49cc90; + color: #49cc90; + display: inline; + line-height: 1; +} +.swagger-ui .btn.authorize span { + float: left; + padding: 4px 20px 0 0; +} +.swagger-ui .btn.authorize svg { + fill: #49cc90; +} +.swagger-ui .btn.execute { + background-color: #4990e2; + border-color: #4990e2; + color: #fff; +} +.swagger-ui .btn-group { + display: flex; + padding: 30px; +} +.swagger-ui .btn-group .btn { + flex: 1; +} +.swagger-ui .btn-group .btn:first-child { + border-radius: 4px 0 0 4px; +} +.swagger-ui .btn-group .btn:last-child { + border-radius: 0 4px 4px 0; +} +.swagger-ui .authorization__btn { + background: none; + border: none; + padding: 0 0 0 10px; +} +.swagger-ui .authorization__btn .locked { + opacity: 1; +} +.swagger-ui .authorization__btn .unlocked { + opacity: 0.4; +} +.swagger-ui .model-box-control, +.swagger-ui .models-control, +.swagger-ui .opblock-summary-control { + all: inherit; + border-bottom: 0; + cursor: pointer; + flex: 1; + padding: 0; +} +.swagger-ui .model-box-control:focus, +.swagger-ui .models-control:focus, +.swagger-ui .opblock-summary-control:focus { + outline: auto; +} +.swagger-ui .expand-methods, +.swagger-ui .expand-operation { + background: none; + border: none; +} +.swagger-ui .expand-methods svg, +.swagger-ui .expand-operation svg { + height: 20px; + width: 20px; +} +.swagger-ui .expand-methods { + padding: 0 10px; +} +.swagger-ui .expand-methods:hover svg { + fill: #404040; +} +.swagger-ui .expand-methods svg { + transition: all 0.3s; + fill: #707070; +} +.swagger-ui button { + cursor: pointer; +} +.swagger-ui button.invalid { + animation: shake 0.4s 1; + background: #feebeb; + border-color: #f93e3e; +} +.swagger-ui .copy-to-clipboard { + align-items: center; + background: #7d8293; + border: none; + border-radius: 4px; + bottom: 10px; + display: flex; + height: 30px; + justify-content: center; + position: absolute; + right: 100px; + width: 30px; +} +.swagger-ui .copy-to-clipboard button { + background: url('data:image/svg+xml;charset=utf-8,') + 50% no-repeat; + border: none; + flex-grow: 1; + flex-shrink: 1; + height: 25px; +} +.swagger-ui .copy-to-clipboard:active { + background: #5e626f; +} +.swagger-ui .opblock-control-arrow { + background: none; + border: none; + text-align: center; +} +.swagger-ui .curl-command .copy-to-clipboard { + bottom: 5px; + height: 20px; + right: 10px; + width: 20px; +} +.swagger-ui .curl-command .copy-to-clipboard button { + height: 18px; +} +.swagger-ui .opblock .opblock-summary .view-line-link.copy-to-clipboard { + height: 26px; + position: static; +} +.swagger-ui select { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background: #f7f7f7 + url('data:image/svg+xml;charset=utf-8,') + right 10px center no-repeat; + background-size: 20px; + border: 2px solid #41444e; + border-radius: 4px; + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.25); + color: #3b4151; + font-family: sans-serif; + font-size: 14px; + font-weight: 700; + padding: 5px 40px 5px 10px; +} +.swagger-ui select[multiple] { + background: #f7f7f7; + margin: 5px 0; + padding: 5px; +} +.swagger-ui select.invalid { + animation: shake 0.4s 1; + background: #feebeb; + border-color: #f93e3e; +} +.swagger-ui .opblock-body select { + min-width: 230px; +} +@media (max-width: 768px) { + .swagger-ui .opblock-body select { + min-width: 180px; + } +} +@media (max-width: 640px) { + .swagger-ui .opblock-body select { + min-width: 100%; + width: 100%; + } +} +.swagger-ui label { + color: #3b4151; + font-family: sans-serif; + font-size: 12px; + font-weight: 700; + margin: 0 0 5px; +} +.swagger-ui input[type='email'], +.swagger-ui input[type='file'], +.swagger-ui input[type='password'], +.swagger-ui input[type='search'], +.swagger-ui input[type='text'] { + line-height: 1; +} +@media (max-width: 768px) { + .swagger-ui input[type='email'], + .swagger-ui input[type='file'], + .swagger-ui input[type='password'], + .swagger-ui input[type='search'], + .swagger-ui input[type='text'] { + max-width: 175px; + } +} +.swagger-ui input[type='email'], +.swagger-ui input[type='file'], +.swagger-ui input[type='password'], +.swagger-ui input[type='search'], +.swagger-ui input[type='text'], +.swagger-ui textarea { + background: #fff; + border: 1px solid #d9d9d9; + border-radius: 4px; + margin: 5px 0; + min-width: 100px; + padding: 8px 10px; +} +.swagger-ui input[type='email'].invalid, +.swagger-ui input[type='file'].invalid, +.swagger-ui input[type='password'].invalid, +.swagger-ui input[type='search'].invalid, +.swagger-ui input[type='text'].invalid, +.swagger-ui textarea.invalid { + animation: shake 0.4s 1; + background: #feebeb; + border-color: #f93e3e; +} +.swagger-ui input[disabled], +.swagger-ui select[disabled], +.swagger-ui textarea[disabled] { + background-color: #fafafa; + color: #888; + cursor: not-allowed; +} +.swagger-ui select[disabled] { + border-color: #888; +} +.swagger-ui textarea[disabled] { + background-color: #41444e; + color: #fff; +} +@keyframes shake { + 10%, + 90% { + transform: translate3d(-1px, 0, 0); + } + 20%, + 80% { + transform: translate3d(2px, 0, 0); + } + 30%, + 50%, + 70% { + transform: translate3d(-4px, 0, 0); + } + 40%, + 60% { + transform: translate3d(4px, 0, 0); + } +} +.swagger-ui textarea { + background: hsla(0, 0%, 100%, 0.8); + border: none; + border-radius: 4px; + color: #3b4151; + font-family: monospace; + font-size: 12px; + font-weight: 600; + min-height: 280px; + outline: none; + padding: 10px; + width: 100%; +} +.swagger-ui textarea:focus { + border: 2px solid #61affe; +} +.swagger-ui textarea.curl { + background: #41444e; + border-radius: 4px; + color: #fff; + font-family: monospace; + font-size: 12px; + font-weight: 600; + margin: 0; + min-height: 100px; + padding: 10px; + resize: none; +} +.swagger-ui .checkbox { + color: #303030; + padding: 5px 0 10px; + transition: opacity 0.5s; +} +.swagger-ui .checkbox label { + display: flex; +} +.swagger-ui .checkbox p { + color: #3b4151; + font-family: monospace; + font-style: italic; + font-weight: 400 !important; + font-weight: 600; + margin: 0 !important; +} +.swagger-ui .checkbox input[type='checkbox'] { + display: none; +} +.swagger-ui .checkbox input[type='checkbox'] + label > .item { + background: #e8e8e8; + border-radius: 1px; + box-shadow: 0 0 0 2px #e8e8e8; + cursor: pointer; + display: inline-block; + flex: none; + height: 16px; + margin: 0 8px 0 0; + padding: 5px; + position: relative; + top: 3px; + width: 16px; +} +.swagger-ui .checkbox input[type='checkbox'] + label > .item:active { + transform: scale(0.9); +} +.swagger-ui .checkbox input[type='checkbox']:checked + label > .item { + background: #e8e8e8 + url('data:image/svg+xml;charset=utf-8,') + 50% no-repeat; +} +.swagger-ui .dialog-ux { + bottom: 0; + left: 0; + position: fixed; + right: 0; + top: 0; + z-index: 9999; +} +.swagger-ui .dialog-ux .backdrop-ux { + background: rgba(0, 0, 0, 0.8); + bottom: 0; + left: 0; + position: fixed; + right: 0; + top: 0; +} +.swagger-ui .dialog-ux .modal-ux { + background: #fff; + border: 1px solid #ebebeb; + border-radius: 4px; + box-shadow: 0 10px 30px 0 rgba(0, 0, 0, 0.2); + left: 50%; + max-width: 650px; + min-width: 300px; + position: absolute; + top: 50%; + transform: translate(-50%, -50%); + width: 100%; + z-index: 9999; +} +.swagger-ui .dialog-ux .modal-ux-content { + max-height: 540px; + overflow-y: auto; + padding: 20px; +} +.swagger-ui .dialog-ux .modal-ux-content p { + color: #41444e; + color: #3b4151; + font-family: sans-serif; + font-size: 12px; + margin: 0 0 5px; +} +.swagger-ui .dialog-ux .modal-ux-content h4 { + color: #3b4151; + font-family: sans-serif; + font-size: 18px; + font-weight: 600; + margin: 15px 0 0; +} +.swagger-ui .dialog-ux .modal-ux-header { + align-items: center; + border-bottom: 1px solid #ebebeb; + display: flex; + padding: 12px 0; +} +.swagger-ui .dialog-ux .modal-ux-header .close-modal { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background: none; + border: none; + padding: 0 10px; +} +.swagger-ui .dialog-ux .modal-ux-header h3 { + color: #3b4151; + flex: 1; + font-family: sans-serif; + font-size: 20px; + font-weight: 600; + margin: 0; + padding: 0 20px; +} +.swagger-ui .model { + color: #3b4151; + font-family: monospace; + font-size: 12px; + font-weight: 300; + font-weight: 600; +} +.swagger-ui .model .deprecated span, +.swagger-ui .model .deprecated td { + color: #a0a0a0 !important; +} +.swagger-ui .model .deprecated > td:first-of-type { + -webkit-text-decoration: line-through; + text-decoration: line-through; +} +.swagger-ui .model-toggle { + cursor: pointer; + display: inline-block; + font-size: 10px; + margin: auto 0.3em; + position: relative; + top: 6px; + transform: rotate(90deg); + transform-origin: 50% 50%; + transition: transform 0.15s ease-in; +} +.swagger-ui .model-toggle.collapsed { + transform: rotate(0deg); +} +.swagger-ui .model-toggle:after { + background: url('data:image/svg+xml;charset=utf-8,') + 50% no-repeat; + background-size: 100%; + content: ''; + display: block; + height: 20px; + width: 20px; +} +.swagger-ui .model-jump-to-path { + cursor: pointer; + position: relative; +} +.swagger-ui .model-jump-to-path .view-line-link { + cursor: pointer; + position: absolute; + top: -0.4em; +} +.swagger-ui .model-title { + position: relative; +} +.swagger-ui .model-title:hover .model-hint { + visibility: visible; +} +.swagger-ui .model-hint { + background: rgba(0, 0, 0, 0.7); + border-radius: 4px; + color: #ebebeb; + padding: 0.1em 0.5em; + position: absolute; + top: -1.8em; + visibility: hidden; + white-space: nowrap; +} +.swagger-ui .model p { + margin: 0 0 1em; +} +.swagger-ui .model .property { + color: #999; + font-style: italic; +} +.swagger-ui .model .property.primitive { + color: #6b6b6b; +} +.swagger-ui .model .external-docs, +.swagger-ui table.model tr.description { + color: #666; + font-weight: 400; +} +.swagger-ui table.model tr.description td:first-child, +.swagger-ui table.model tr.property-row.required td:first-child { + font-weight: 700; +} +.swagger-ui table.model tr.property-row td { + vertical-align: top; +} +.swagger-ui table.model tr.property-row td:first-child { + padding-right: 0.2em; +} +.swagger-ui table.model tr.property-row .star { + color: red; +} +.swagger-ui table.model tr.extension { + color: #777; +} +.swagger-ui table.model tr.extension td:last-child { + vertical-align: top; +} +.swagger-ui table.model tr.external-docs td:first-child { + font-weight: 700; +} +.swagger-ui table.model tr .renderedMarkdown p:first-child { + margin-top: 0; +} +.swagger-ui section.models { + border: 1px solid rgba(59, 65, 81, 0.3); + border-radius: 4px; + margin: 30px 0; +} +.swagger-ui section.models .pointer { + cursor: pointer; +} +.swagger-ui section.models.is-open { + padding: 0 0 20px; +} +.swagger-ui section.models.is-open h4 { + border-bottom: 1px solid rgba(59, 65, 81, 0.3); + margin: 0 0 5px; +} +.swagger-ui section.models h4 { + align-items: center; + color: #606060; + cursor: pointer; + display: flex; + font-family: sans-serif; + font-size: 16px; + margin: 0; + padding: 10px 20px 10px 10px; + transition: all 0.2s; +} +.swagger-ui section.models h4 svg { + transition: all 0.4s; +} +.swagger-ui section.models h4 span { + flex: 1; +} +.swagger-ui section.models h4:hover { + background: rgba(0, 0, 0, 0.02); +} +.swagger-ui section.models h5 { + color: #707070; + font-family: sans-serif; + font-size: 16px; + margin: 0 0 10px; +} +.swagger-ui section.models .model-jump-to-path { + position: relative; + top: 5px; +} +.swagger-ui section.models .model-container { + background: rgba(0, 0, 0, 0.05); + border-radius: 4px; + margin: 0 20px 15px; + position: relative; + transition: all 0.5s; +} +.swagger-ui section.models .model-container:hover { + background: rgba(0, 0, 0, 0.07); +} +.swagger-ui section.models .model-container:first-of-type { + margin: 20px; +} +.swagger-ui section.models .model-container:last-of-type { + margin: 0 20px; +} +.swagger-ui section.models .model-container .models-jump-to-path { + opacity: 0.65; + position: absolute; + right: 5px; + top: 8px; +} +.swagger-ui section.models .model-box { + background: none; +} +.swagger-ui .model-box { + background: rgba(0, 0, 0, 0.1); + border-radius: 4px; + display: inline-block; + padding: 10px; +} +.swagger-ui .model-box .model-jump-to-path { + position: relative; + top: 4px; +} +.swagger-ui .model-box.deprecated { + opacity: 0.5; +} +.swagger-ui .model-title { + color: #505050; + font-family: sans-serif; + font-size: 16px; +} +.swagger-ui .model-title img { + bottom: 0; + margin-left: 1em; + position: relative; +} +.swagger-ui .model-deprecated-warning { + color: #f93e3e; + font-family: sans-serif; + font-size: 16px; + font-weight: 600; + margin-right: 1em; +} +.swagger-ui span > span.model .brace-close { + padding: 0 0 0 10px; +} +.swagger-ui .prop-name { + display: inline-block; + margin-right: 1em; +} +.swagger-ui .prop-type { + color: #55a; +} +.swagger-ui .prop-enum { + display: block; +} +.swagger-ui .prop-format { + color: #606060; +} +.swagger-ui .servers > label { + color: #3b4151; + font-family: sans-serif; + font-size: 12px; + margin: -20px 15px 0 0; +} +.swagger-ui .servers > label select { + max-width: 100%; + min-width: 130px; + width: 100%; +} +.swagger-ui .servers h4.message { + padding-bottom: 2em; +} +.swagger-ui .servers table tr { + width: 30em; +} +.swagger-ui .servers table td { + display: inline-block; + max-width: 15em; + padding-bottom: 10px; + padding-top: 10px; + vertical-align: middle; +} +.swagger-ui .servers table td:first-of-type { + padding-right: 1em; +} +.swagger-ui .servers table td input { + height: 100%; + width: 100%; +} +.swagger-ui .servers .computed-url { + margin: 2em 0; +} +.swagger-ui .servers .computed-url code { + display: inline-block; + font-size: 16px; + margin: 0 1em; + padding: 4px; +} +.swagger-ui .servers-title { + font-size: 12px; + font-weight: 700; +} +.swagger-ui .operation-servers h4.message { + margin-bottom: 2em; +} +.swagger-ui table { + border-collapse: collapse; + padding: 0 10px; + width: 100%; +} +.swagger-ui table.model tbody tr td { + padding: 0; + vertical-align: top; +} +.swagger-ui table.model tbody tr td:first-of-type { + padding: 0 0 0 2em; + width: 174px; +} +.swagger-ui table.headers td { + color: #3b4151; + font-family: monospace; + font-size: 12px; + font-weight: 300; + font-weight: 600; + vertical-align: middle; +} +.swagger-ui table.headers .header-example { + color: #999; + font-style: italic; +} +.swagger-ui table tbody tr td { + padding: 10px 0 0; + vertical-align: top; +} +.swagger-ui table tbody tr td:first-of-type { + min-width: 6em; + padding: 10px 0; +} +.swagger-ui table thead tr td, +.swagger-ui table thead tr th { + border-bottom: 1px solid rgba(59, 65, 81, 0.2); + color: #3b4151; + font-family: sans-serif; + font-size: 12px; + font-weight: 700; + padding: 12px 0; + text-align: left; +} +.swagger-ui .parameters-col_description { + margin-bottom: 2em; + width: 99%; +} +.swagger-ui .parameters-col_description input { + max-width: 340px; + width: 100%; +} +.swagger-ui .parameters-col_description select { + border-width: 1px; +} +.swagger-ui .parameters-col_description .markdown p, +.swagger-ui .parameters-col_description .renderedMarkdown p { + margin: 0; +} +.swagger-ui .parameter__name { + color: #3b4151; + font-family: sans-serif; + font-size: 16px; + font-weight: 400; + margin-right: 0.75em; +} +.swagger-ui .parameter__name.required { + font-weight: 700; +} +.swagger-ui .parameter__name.required span { + color: red; +} +.swagger-ui .parameter__name.required:after { + color: rgba(255, 0, 0, 0.6); + content: 'required'; + font-size: 10px; + padding: 5px; + position: relative; + top: -6px; +} +.swagger-ui .parameter__extension, +.swagger-ui .parameter__in { + color: grey; + font-family: monospace; + font-size: 12px; + font-style: italic; + font-weight: 600; +} +.swagger-ui .parameter__deprecated { + color: red; + font-family: monospace; + font-size: 12px; + font-style: italic; + font-weight: 600; +} +.swagger-ui .parameter__empty_value_toggle { + display: block; + font-size: 13px; + padding-bottom: 12px; + padding-top: 5px; +} +.swagger-ui .parameter__empty_value_toggle input { + margin-right: 7px; + width: auto; +} +.swagger-ui .parameter__empty_value_toggle.disabled { + opacity: 0.7; +} +.swagger-ui .table-container { + padding: 20px; +} +.swagger-ui .response-col_description { + width: 99%; +} +.swagger-ui .response-col_description .markdown p, +.swagger-ui .response-col_description .renderedMarkdown p { + margin: 0; +} +.swagger-ui .response-col_links { + min-width: 6em; +} +.swagger-ui .response__extension { + color: grey; + font-family: monospace; + font-size: 12px; + font-style: italic; + font-weight: 600; +} +.swagger-ui .topbar { + background-color: #1b1b1b; + padding: 10px 0; +} +.swagger-ui .topbar .topbar-wrapper { + align-items: center; + display: flex; + flex-wrap: wrap; + gap: 10px; +} +@media (max-width: 550px) { + .swagger-ui .topbar .topbar-wrapper { + align-items: start; + flex-direction: column; + } +} +.swagger-ui .topbar a { + align-items: center; + color: #fff; + display: flex; + flex: 1; + font-family: sans-serif; + font-size: 1.5em; + font-weight: 700; + max-width: 300px; + -webkit-text-decoration: none; + text-decoration: none; +} +.swagger-ui .topbar a span { + margin: 0; + padding: 0 10px; +} +.swagger-ui .topbar .download-url-wrapper { + display: flex; + flex: 3; + justify-content: flex-end; +} +.swagger-ui .topbar .download-url-wrapper input[type='text'] { + border: 2px solid #62a03f; + border-radius: 4px 0 0 4px; + margin: 0; + max-width: 100%; + outline: none; + width: 100%; +} +.swagger-ui .topbar .download-url-wrapper .select-label { + align-items: center; + color: #f0f0f0; + display: flex; + margin: 0; + max-width: 600px; + width: 100%; +} +.swagger-ui .topbar .download-url-wrapper .select-label span { + flex: 1; + font-size: 16px; + padding: 0 10px 0 0; + text-align: right; +} +.swagger-ui .topbar .download-url-wrapper .select-label select { + border: 2px solid #62a03f; + box-shadow: none; + flex: 2; + outline: none; + width: 100%; +} +.swagger-ui .topbar .download-url-wrapper .download-url-button { + background: #62a03f; + border: none; + border-radius: 0 4px 4px 0; + color: #fff; + font-family: sans-serif; + font-size: 16px; + font-weight: 700; + padding: 4px 30px; +} +@media (max-width: 550px) { + .swagger-ui .topbar .download-url-wrapper { + width: 100%; + } +} +.swagger-ui .info { + margin: 50px 0; +} +.swagger-ui .info.failed-config { + margin-left: auto; + margin-right: auto; + max-width: 880px; + text-align: center; +} +.swagger-ui .info hgroup.main { + margin: 0 0 20px; +} +.swagger-ui .info hgroup.main a { + font-size: 12px; +} +.swagger-ui .info pre { + font-size: 14px; +} +.swagger-ui .info li, +.swagger-ui .info p, +.swagger-ui .info table { + color: #3b4151; + font-family: sans-serif; + font-size: 14px; +} +.swagger-ui .info h1, +.swagger-ui .info h2, +.swagger-ui .info h3, +.swagger-ui .info h4, +.swagger-ui .info h5 { + color: #3b4151; + font-family: sans-serif; +} +.swagger-ui .info a { + color: #4990e2; + font-family: sans-serif; + font-size: 14px; + transition: all 0.4s; +} +.swagger-ui .info a:hover { + color: #1f69c0; +} +.swagger-ui .info > div { + margin: 0 0 5px; +} +.swagger-ui .info .base-url { + color: #3b4151; + font-family: monospace; + font-size: 12px; + font-weight: 300 !important; + font-weight: 600; + margin: 0; +} +.swagger-ui .info .title { + color: #3b4151; + font-family: sans-serif; + font-size: 36px; + margin: 0; +} +.swagger-ui .info .title small { + background: #7d8492; + border-radius: 57px; + display: inline-block; + font-size: 10px; + margin: 0 0 0 5px; + padding: 2px 4px; + position: relative; + top: -5px; + vertical-align: super; +} +.swagger-ui .info .title small.version-stamp { + background-color: #89bf04; +} +.swagger-ui .info .title small pre { + color: #fff; + font-family: sans-serif; + margin: 0; + padding: 0; +} +.swagger-ui .auth-btn-wrapper { + display: flex; + justify-content: center; + padding: 10px 0; +} +.swagger-ui .auth-btn-wrapper .btn-done { + margin-right: 1em; +} +.swagger-ui .auth-wrapper { + display: flex; + flex: 1; + justify-content: flex-end; +} +.swagger-ui .auth-wrapper .authorize { + margin-left: 10px; + margin-right: 10px; + padding-right: 20px; +} +.swagger-ui .auth-container { + border-bottom: 1px solid #ebebeb; + margin: 0 0 10px; + padding: 10px 20px; +} +.swagger-ui .auth-container:last-of-type { + border: 0; + margin: 0; + padding: 10px 20px; +} +.swagger-ui .auth-container h4 { + margin: 5px 0 15px !important; +} +.swagger-ui .auth-container .wrapper { + margin: 0; + padding: 0; +} +.swagger-ui .auth-container input[type='password'], +.swagger-ui .auth-container input[type='text'] { + min-width: 230px; +} +.swagger-ui .auth-container .errors { + background-color: #fee; + border-radius: 4px; + color: red; + color: #3b4151; + font-family: monospace; + font-size: 12px; + font-weight: 600; + margin: 1em; + padding: 10px; +} +.swagger-ui .auth-container .errors b { + margin-right: 1em; + text-transform: capitalize; +} +.swagger-ui .scopes h2 { + color: #3b4151; + font-family: sans-serif; + font-size: 14px; +} +.swagger-ui .scopes h2 a { + color: #4990e2; + cursor: pointer; + font-size: 12px; + padding-left: 10px; + -webkit-text-decoration: underline; + text-decoration: underline; +} +.swagger-ui .scope-def { + padding: 0 0 20px; +} +.swagger-ui .errors-wrapper { + animation: scaleUp 0.5s; + background: rgba(249, 62, 62, 0.1); + border: 2px solid #f93e3e; + border-radius: 4px; + margin: 20px; + padding: 10px 20px; +} +.swagger-ui .errors-wrapper .error-wrapper { + margin: 0 0 10px; +} +.swagger-ui .errors-wrapper .errors h4 { + color: #3b4151; + font-family: monospace; + font-size: 14px; + font-weight: 600; + margin: 0; +} +.swagger-ui .errors-wrapper .errors small { + color: #606060; +} +.swagger-ui .errors-wrapper .errors .message { + white-space: pre-line; +} +.swagger-ui .errors-wrapper .errors .message.thrown { + max-width: 100%; +} +.swagger-ui .errors-wrapper .errors .error-line { + cursor: pointer; + -webkit-text-decoration: underline; + text-decoration: underline; +} +.swagger-ui .errors-wrapper hgroup { + align-items: center; + display: flex; +} +.swagger-ui .errors-wrapper hgroup h4 { + color: #3b4151; + flex: 1; + font-family: sans-serif; + font-size: 20px; + margin: 0; +} +@keyframes scaleUp { + 0% { + opacity: 0; + transform: scale(0.8); + } + to { + opacity: 1; + transform: scale(1); + } +} +.swagger-ui .Resizer.vertical.disabled { + display: none; +} +.swagger-ui .markdown p, +.swagger-ui .markdown pre, +.swagger-ui .renderedMarkdown p, +.swagger-ui .renderedMarkdown pre { + margin: 1em auto; + word-break: break-all; + word-break: break-word; +} +.swagger-ui .markdown pre, +.swagger-ui .renderedMarkdown pre { + background: none; + color: #000; + font-weight: 400; + padding: 0; + white-space: pre-wrap; +} +.swagger-ui .markdown code, +.swagger-ui .renderedMarkdown code { + background: rgba(0, 0, 0, 0.05); + border-radius: 4px; + color: #9012fe; + font-family: monospace; + font-size: 14px; + font-weight: 600; + padding: 5px 7px; +} +.swagger-ui .markdown pre > code, +.swagger-ui .renderedMarkdown pre > code { + display: block; +} +.swagger-ui .json-schema-2020-12 { + background-color: rgba(0, 0, 0, 0.05); + border-radius: 4px; + margin: 0 20px 15px; + padding: 12px 0 12px 20px; +} +.swagger-ui .json-schema-2020-12:first-of-type { + margin: 20px; +} +.swagger-ui .json-schema-2020-12:last-of-type { + margin: 0 20px; +} +.swagger-ui .json-schema-2020-12--embedded { + background-color: inherit; + padding-bottom: 0; + padding-left: inherit; + padding-right: inherit; + padding-top: 0; +} +.swagger-ui .json-schema-2020-12-body { + border-left: 1px dashed rgba(0, 0, 0, 0.1); + margin: 2px 0; +} +.swagger-ui .json-schema-2020-12-body--collapsed { + display: none; +} +.swagger-ui .json-schema-2020-12-accordion { + border: none; + outline: none; + padding-left: 0; +} +.swagger-ui .json-schema-2020-12-accordion__children { + display: inline-block; +} +.swagger-ui .json-schema-2020-12-accordion__icon { + display: inline-block; + height: 18px; + vertical-align: bottom; + width: 18px; +} +.swagger-ui .json-schema-2020-12-accordion__icon--expanded { + transform: rotate(-90deg); + transform-origin: 50% 50%; + transition: transform 0.15s ease-in; +} +.swagger-ui .json-schema-2020-12-accordion__icon--collapsed { + transform: rotate(0deg); + transform-origin: 50% 50%; + transition: transform 0.15s ease-in; +} +.swagger-ui .json-schema-2020-12-accordion__icon svg { + height: 20px; + width: 20px; +} +.swagger-ui .json-schema-2020-12-expand-deep-button { + border: none; + color: #505050; + color: #afaeae; + font-family: sans-serif; + font-size: 12px; + padding-right: 0; +} +.swagger-ui .json-schema-2020-12-keyword { + margin: 5px 0; +} +.swagger-ui .json-schema-2020-12-keyword__children { + border-left: 1px dashed rgba(0, 0, 0, 0.1); + margin: 0 0 0 20px; + padding: 0; +} +.swagger-ui .json-schema-2020-12-keyword__children--collapsed { + display: none; +} +.swagger-ui .json-schema-2020-12-keyword__name { + font-size: 12px; + font-weight: 700; + margin-left: 20px; +} +.swagger-ui .json-schema-2020-12-keyword__name--primary { + color: #3b4151; + font-style: normal; +} +.swagger-ui .json-schema-2020-12-keyword__name--secondary { + color: #6b6b6b; + font-style: italic; +} +.swagger-ui .json-schema-2020-12-keyword__value { + color: #6b6b6b; + font-size: 12px; + font-style: italic; + font-weight: 400; +} +.swagger-ui .json-schema-2020-12-keyword__value--primary { + color: #3b4151; + font-style: normal; +} +.swagger-ui .json-schema-2020-12-keyword__value--secondary { + color: #6b6b6b; + font-style: italic; +} +.swagger-ui .json-schema-2020-12-keyword__value--const, +.swagger-ui .json-schema-2020-12-keyword__value--warning { + border: 1px dashed #6b6b6b; + border-radius: 4px; + color: #3b4151; + color: #6b6b6b; + display: inline-block; + font-family: monospace; + font-style: normal; + font-weight: 600; + line-height: 1.5; + margin-left: 10px; + padding: 1px 4px; +} +.swagger-ui .json-schema-2020-12-keyword__value--warning { + border: 1px dashed red; + color: red; +} +.swagger-ui + .json-schema-2020-12-keyword__name--secondary + + .json-schema-2020-12-keyword__value--secondary:before { + content: '='; +} +.swagger-ui .json-schema-2020-12__attribute { + color: #3b4151; + font-family: monospace; + font-size: 12px; + padding-left: 10px; + text-transform: lowercase; +} +.swagger-ui .json-schema-2020-12__attribute--primary { + color: #55a; +} +.swagger-ui .json-schema-2020-12__attribute--muted { + color: gray; +} +.swagger-ui .json-schema-2020-12__attribute--warning { + color: red; +} +.swagger-ui .json-schema-2020-12-keyword--\$vocabulary ul { + border-left: 1px dashed rgba(0, 0, 0, 0.1); + margin: 0 0 0 20px; +} +.swagger-ui .json-schema-2020-12-\$vocabulary-uri { + margin-left: 35px; +} +.swagger-ui .json-schema-2020-12-\$vocabulary-uri--disabled { + -webkit-text-decoration: line-through; + text-decoration: line-through; +} +.swagger-ui .json-schema-2020-12-keyword--description { + color: #6b6b6b; + font-size: 12px; + margin-left: 20px; +} +.swagger-ui .json-schema-2020-12-keyword--description p { + margin: 0; +} +.swagger-ui .json-schema-2020-12__title { + color: #505050; + display: inline-block; + font-family: sans-serif; + font-size: 12px; + font-weight: 700; + line-height: normal; +} +.swagger-ui .json-schema-2020-12__title .json-schema-2020-12-keyword__name { + margin: 0; +} +.swagger-ui .json-schema-2020-12-property { + margin: 7px 0; +} +.swagger-ui .json-schema-2020-12-property .json-schema-2020-12__title { + color: #3b4151; + font-family: monospace; + font-size: 12px; + font-weight: 600; + vertical-align: middle; +} +.swagger-ui .json-schema-2020-12-keyword--properties > ul { + border: none; + margin: 0; + padding: 0; +} +.swagger-ui .json-schema-2020-12-property { + list-style-type: none; +} +.swagger-ui + .json-schema-2020-12-property--required + > .json-schema-2020-12:first-of-type + > .json-schema-2020-12-head + .json-schema-2020-12__title:after { + color: red; + content: '*'; + font-weight: 700; +} +.swagger-ui .json-schema-2020-12-keyword--patternProperties ul { + border: none; + margin: 0; + padding: 0; +} +.swagger-ui + .json-schema-2020-12-keyword--patternProperties + .json-schema-2020-12__title:first-of-type:after, +.swagger-ui + .json-schema-2020-12-keyword--patternProperties + .json-schema-2020-12__title:first-of-type:before { + color: #55a; + content: '/'; +} +.swagger-ui .json-schema-2020-12-keyword--enum > ul { + display: inline-block; + margin: 0; + padding: 0; +} +.swagger-ui .json-schema-2020-12-keyword--enum > ul li { + display: inline; + list-style-type: none; +} +.swagger-ui .json-schema-2020-12__constraint { + background-color: #805ad5; + border-radius: 4px; + color: #3b4151; + color: #fff; + font-family: monospace; + font-weight: 600; + line-height: 1.5; + margin-left: 10px; + padding: 1px 3px; +} +.swagger-ui .json-schema-2020-12__constraint--string { + background-color: #d69e2e; + color: #fff; +} +.swagger-ui .json-schema-2020-12-keyword--dependentRequired > ul { + display: inline-block; + margin: 0; + padding: 0; +} +.swagger-ui .json-schema-2020-12-keyword--dependentRequired > ul li { + display: inline; + list-style-type: none; +} +.swagger-ui + .model-box + .json-schema-2020-12:not(.json-schema-2020-12--embedded) + > .json-schema-2020-12-head + .json-schema-2020-12__title:first-of-type { + font-size: 16px; +} +.swagger-ui .model-box > .json-schema-2020-12 { + margin: 0; +} +.swagger-ui .model-box .json-schema-2020-12 { + background-color: transparent; + padding: 0; +} +.swagger-ui .model-box .json-schema-2020-12-accordion, +.swagger-ui .model-box .json-schema-2020-12-expand-deep-button { + background-color: transparent; +} +.swagger-ui + .models + .json-schema-2020-12:not(.json-schema-2020-12--embedded) + > .json-schema-2020-12-head + .json-schema-2020-12__title:first-of-type { + font-size: 16px; +} diff --git a/backend/open_webui/static/user-import.csv b/backend/open_webui/static/user-import.csv new file mode 100644 index 0000000..918a92a --- /dev/null +++ b/backend/open_webui/static/user-import.csv @@ -0,0 +1 @@ +Name,Email,Password,Role diff --git a/backend/open_webui/storage/provider.py b/backend/open_webui/storage/provider.py new file mode 100644 index 0000000..2f31cbd --- /dev/null +++ b/backend/open_webui/storage/provider.py @@ -0,0 +1,327 @@ +import os +import shutil +import json +import logging +from abc import ABC, abstractmethod +from typing import BinaryIO, Tuple + +import boto3 +from botocore.config import Config +from botocore.exceptions import ClientError +from open_webui.config import ( + S3_ACCESS_KEY_ID, + S3_BUCKET_NAME, + S3_ENDPOINT_URL, + S3_KEY_PREFIX, + S3_REGION_NAME, + S3_SECRET_ACCESS_KEY, + S3_USE_ACCELERATE_ENDPOINT, + S3_ADDRESSING_STYLE, + GCS_BUCKET_NAME, + GOOGLE_APPLICATION_CREDENTIALS_JSON, + AZURE_STORAGE_ENDPOINT, + AZURE_STORAGE_CONTAINER_NAME, + AZURE_STORAGE_KEY, + STORAGE_PROVIDER, + UPLOAD_DIR, +) +from google.cloud import storage +from google.cloud.exceptions import GoogleCloudError, NotFound +from open_webui.constants import ERROR_MESSAGES +from azure.identity import DefaultAzureCredential +from azure.storage.blob import BlobServiceClient +from azure.core.exceptions import ResourceNotFoundError +from open_webui.env import SRC_LOG_LEVELS + + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MAIN"]) + + +class StorageProvider(ABC): + @abstractmethod + def get_file(self, file_path: str) -> str: + pass + + @abstractmethod + def upload_file(self, file: BinaryIO, filename: str) -> Tuple[bytes, str]: + pass + + @abstractmethod + def delete_all_files(self) -> None: + pass + + @abstractmethod + def delete_file(self, file_path: str) -> None: + pass + + +class LocalStorageProvider(StorageProvider): + @staticmethod + def upload_file(file: BinaryIO, filename: str) -> Tuple[bytes, str]: + contents = file.read() + if not contents: + raise ValueError(ERROR_MESSAGES.EMPTY_CONTENT) + file_path = f"{UPLOAD_DIR}/{filename}" + with open(file_path, "wb") as f: + f.write(contents) + return contents, file_path + + @staticmethod + def get_file(file_path: str) -> str: + """Handles downloading of the file from local storage.""" + return file_path + + @staticmethod + def delete_file(file_path: str) -> None: + """Handles deletion of the file from local storage.""" + filename = file_path.split("/")[-1] + file_path = f"{UPLOAD_DIR}/{filename}" + if os.path.isfile(file_path): + os.remove(file_path) + else: + log.warning(f"File {file_path} not found in local storage.") + + @staticmethod + def delete_all_files() -> None: + """Handles deletion of all files from local storage.""" + if os.path.exists(UPLOAD_DIR): + for filename in os.listdir(UPLOAD_DIR): + file_path = os.path.join(UPLOAD_DIR, filename) + try: + if os.path.isfile(file_path) or os.path.islink(file_path): + os.unlink(file_path) # Remove the file or link + elif os.path.isdir(file_path): + shutil.rmtree(file_path) # Remove the directory + except Exception as e: + log.exception(f"Failed to delete {file_path}. Reason: {e}") + else: + log.warning(f"Directory {UPLOAD_DIR} not found in local storage.") + + +class S3StorageProvider(StorageProvider): + def __init__(self): + self.s3_client = boto3.client( + "s3", + region_name=S3_REGION_NAME, + endpoint_url=S3_ENDPOINT_URL, + aws_access_key_id=S3_ACCESS_KEY_ID, + aws_secret_access_key=S3_SECRET_ACCESS_KEY, + config=Config( + s3={ + "use_accelerate_endpoint": S3_USE_ACCELERATE_ENDPOINT, + "addressing_style": S3_ADDRESSING_STYLE, + }, + ), + ) + self.bucket_name = S3_BUCKET_NAME + self.key_prefix = S3_KEY_PREFIX if S3_KEY_PREFIX else "" + + def upload_file(self, file: BinaryIO, filename: str) -> Tuple[bytes, str]: + """Handles uploading of the file to S3 storage.""" + _, file_path = LocalStorageProvider.upload_file(file, filename) + try: + s3_key = os.path.join(self.key_prefix, filename) + self.s3_client.upload_file(file_path, self.bucket_name, s3_key) + return ( + open(file_path, "rb").read(), + "s3://" + self.bucket_name + "/" + s3_key, + ) + except ClientError as e: + raise RuntimeError(f"Error uploading file to S3: {e}") + + def get_file(self, file_path: str) -> str: + """Handles downloading of the file from S3 storage.""" + try: + s3_key = self._extract_s3_key(file_path) + local_file_path = self._get_local_file_path(s3_key) + self.s3_client.download_file(self.bucket_name, s3_key, local_file_path) + return local_file_path + except ClientError as e: + raise RuntimeError(f"Error downloading file from S3: {e}") + + def delete_file(self, file_path: str) -> None: + """Handles deletion of the file from S3 storage.""" + try: + s3_key = self._extract_s3_key(file_path) + self.s3_client.delete_object(Bucket=self.bucket_name, Key=s3_key) + except ClientError as e: + raise RuntimeError(f"Error deleting file from S3: {e}") + + # Always delete from local storage + LocalStorageProvider.delete_file(file_path) + + def delete_all_files(self) -> None: + """Handles deletion of all files from S3 storage.""" + try: + response = self.s3_client.list_objects_v2(Bucket=self.bucket_name) + if "Contents" in response: + for content in response["Contents"]: + # Skip objects that were not uploaded from open-webui in the first place + if not content["Key"].startswith(self.key_prefix): + continue + + self.s3_client.delete_object( + Bucket=self.bucket_name, Key=content["Key"] + ) + except ClientError as e: + raise RuntimeError(f"Error deleting all files from S3: {e}") + + # Always delete from local storage + LocalStorageProvider.delete_all_files() + + # The s3 key is the name assigned to an object. It excludes the bucket name, but includes the internal path and the file name. + def _extract_s3_key(self, full_file_path: str) -> str: + return "/".join(full_file_path.split("//")[1].split("/")[1:]) + + def _get_local_file_path(self, s3_key: str) -> str: + return f"{UPLOAD_DIR}/{s3_key.split('/')[-1]}" + + +class GCSStorageProvider(StorageProvider): + def __init__(self): + self.bucket_name = GCS_BUCKET_NAME + + if GOOGLE_APPLICATION_CREDENTIALS_JSON: + self.gcs_client = storage.Client.from_service_account_info( + info=json.loads(GOOGLE_APPLICATION_CREDENTIALS_JSON) + ) + else: + # if no credentials json is provided, credentials will be picked up from the environment + # if running on local environment, credentials would be user credentials + # if running on a Compute Engine instance, credentials would be from Google Metadata server + self.gcs_client = storage.Client() + self.bucket = self.gcs_client.bucket(GCS_BUCKET_NAME) + + def upload_file(self, file: BinaryIO, filename: str) -> Tuple[bytes, str]: + """Handles uploading of the file to GCS storage.""" + contents, file_path = LocalStorageProvider.upload_file(file, filename) + try: + blob = self.bucket.blob(filename) + blob.upload_from_filename(file_path) + return contents, "gs://" + self.bucket_name + "/" + filename + except GoogleCloudError as e: + raise RuntimeError(f"Error uploading file to GCS: {e}") + + def get_file(self, file_path: str) -> str: + """Handles downloading of the file from GCS storage.""" + try: + filename = file_path.removeprefix("gs://").split("/")[1] + local_file_path = f"{UPLOAD_DIR}/{filename}" + blob = self.bucket.get_blob(filename) + blob.download_to_filename(local_file_path) + + return local_file_path + except NotFound as e: + raise RuntimeError(f"Error downloading file from GCS: {e}") + + def delete_file(self, file_path: str) -> None: + """Handles deletion of the file from GCS storage.""" + try: + filename = file_path.removeprefix("gs://").split("/")[1] + blob = self.bucket.get_blob(filename) + blob.delete() + except NotFound as e: + raise RuntimeError(f"Error deleting file from GCS: {e}") + + # Always delete from local storage + LocalStorageProvider.delete_file(file_path) + + def delete_all_files(self) -> None: + """Handles deletion of all files from GCS storage.""" + try: + blobs = self.bucket.list_blobs() + + for blob in blobs: + blob.delete() + + except NotFound as e: + raise RuntimeError(f"Error deleting all files from GCS: {e}") + + # Always delete from local storage + LocalStorageProvider.delete_all_files() + + +class AzureStorageProvider(StorageProvider): + def __init__(self): + self.endpoint = AZURE_STORAGE_ENDPOINT + self.container_name = AZURE_STORAGE_CONTAINER_NAME + storage_key = AZURE_STORAGE_KEY + + if storage_key: + # Configure using the Azure Storage Account Endpoint and Key + self.blob_service_client = BlobServiceClient( + account_url=self.endpoint, credential=storage_key + ) + else: + # Configure using the Azure Storage Account Endpoint and DefaultAzureCredential + # If the key is not configured, then the DefaultAzureCredential will be used to support Managed Identity authentication + self.blob_service_client = BlobServiceClient( + account_url=self.endpoint, credential=DefaultAzureCredential() + ) + self.container_client = self.blob_service_client.get_container_client( + self.container_name + ) + + def upload_file(self, file: BinaryIO, filename: str) -> Tuple[bytes, str]: + """Handles uploading of the file to Azure Blob Storage.""" + contents, file_path = LocalStorageProvider.upload_file(file, filename) + try: + blob_client = self.container_client.get_blob_client(filename) + blob_client.upload_blob(contents, overwrite=True) + return contents, f"{self.endpoint}/{self.container_name}/{filename}" + except Exception as e: + raise RuntimeError(f"Error uploading file to Azure Blob Storage: {e}") + + def get_file(self, file_path: str) -> str: + """Handles downloading of the file from Azure Blob Storage.""" + try: + filename = file_path.split("/")[-1] + local_file_path = f"{UPLOAD_DIR}/{filename}" + blob_client = self.container_client.get_blob_client(filename) + with open(local_file_path, "wb") as download_file: + download_file.write(blob_client.download_blob().readall()) + return local_file_path + except ResourceNotFoundError as e: + raise RuntimeError(f"Error downloading file from Azure Blob Storage: {e}") + + def delete_file(self, file_path: str) -> None: + """Handles deletion of the file from Azure Blob Storage.""" + try: + filename = file_path.split("/")[-1] + blob_client = self.container_client.get_blob_client(filename) + blob_client.delete_blob() + except ResourceNotFoundError as e: + raise RuntimeError(f"Error deleting file from Azure Blob Storage: {e}") + + # Always delete from local storage + LocalStorageProvider.delete_file(file_path) + + def delete_all_files(self) -> None: + """Handles deletion of all files from Azure Blob Storage.""" + try: + blobs = self.container_client.list_blobs() + for blob in blobs: + self.container_client.delete_blob(blob.name) + except Exception as e: + raise RuntimeError(f"Error deleting all files from Azure Blob Storage: {e}") + + # Always delete from local storage + LocalStorageProvider.delete_all_files() + + +def get_storage_provider(storage_provider: str): + if storage_provider == "local": + Storage = LocalStorageProvider() + elif storage_provider == "s3": + Storage = S3StorageProvider() + elif storage_provider == "gcs": + Storage = GCSStorageProvider() + elif storage_provider == "azure": + Storage = AzureStorageProvider() + else: + raise RuntimeError(f"Unsupported storage provider: {storage_provider}") + return Storage + + +Storage = get_storage_provider(STORAGE_PROVIDER) diff --git a/backend/open_webui/tasks.py b/backend/open_webui/tasks.py new file mode 100644 index 0000000..2740ecb --- /dev/null +++ b/backend/open_webui/tasks.py @@ -0,0 +1,61 @@ +# tasks.py +import asyncio +from typing import Dict +from uuid import uuid4 + +# A dictionary to keep track of active tasks +tasks: Dict[str, asyncio.Task] = {} + + +def cleanup_task(task_id: str): + """ + Remove a completed or canceled task from the global `tasks` dictionary. + """ + tasks.pop(task_id, None) # Remove the task if it exists + + +def create_task(coroutine): + """ + Create a new asyncio task and add it to the global task dictionary. + """ + task_id = str(uuid4()) # Generate a unique ID for the task + task = asyncio.create_task(coroutine) # Create the task + + # Add a done callback for cleanup + task.add_done_callback(lambda t: cleanup_task(task_id)) + + tasks[task_id] = task + return task_id, task + + +def get_task(task_id: str): + """ + Retrieve a task by its task ID. + """ + return tasks.get(task_id) + + +def list_tasks(): + """ + List all currently active task IDs. + """ + return list(tasks.keys()) + + +async def stop_task(task_id: str): + """ + Cancel a running task and remove it from the global task list. + """ + task = tasks.get(task_id) + if not task: + raise ValueError(f"Task with ID {task_id} not found.") + + task.cancel() # Request task cancellation + try: + await task # Wait for the task to handle the cancellation + except asyncio.CancelledError: + # Task successfully canceled + tasks.pop(task_id, None) # Remove it from the dictionary + return {"status": True, "message": f"Task {task_id} successfully stopped."} + + return {"status": False, "message": f"Failed to stop task {task_id}."} diff --git a/backend/open_webui/test/__init__.py b/backend/open_webui/test/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/open_webui/test/apps/webui/routers/test_auths.py b/backend/open_webui/test/apps/webui/routers/test_auths.py new file mode 100644 index 0000000..f0f69e2 --- /dev/null +++ b/backend/open_webui/test/apps/webui/routers/test_auths.py @@ -0,0 +1,200 @@ +from test.util.abstract_integration_test import AbstractPostgresTest +from test.util.mock_user import mock_webui_user + + +class TestAuths(AbstractPostgresTest): + BASE_PATH = "/api/v1/auths" + + def setup_class(cls): + super().setup_class() + from open_webui.models.auths import Auths + from open_webui.models.users import Users + + cls.users = Users + cls.auths = Auths + + def test_get_session_user(self): + with mock_webui_user(): + response = self.fast_api_client.get(self.create_url("")) + assert response.status_code == 200 + assert response.json() == { + "id": "1", + "name": "John Doe", + "email": "john.doe@openwebui.com", + "role": "user", + "profile_image_url": "/user.png", + } + + def test_update_profile(self): + from open_webui.utils.auth import get_password_hash + + user = self.auths.insert_new_auth( + email="john.doe@openwebui.com", + password=get_password_hash("old_password"), + name="John Doe", + profile_image_url="/user.png", + role="user", + ) + + with mock_webui_user(id=user.id): + response = self.fast_api_client.post( + self.create_url("/update/profile"), + json={"name": "John Doe 2", "profile_image_url": "/user2.png"}, + ) + assert response.status_code == 200 + db_user = self.users.get_user_by_id(user.id) + assert db_user.name == "John Doe 2" + assert db_user.profile_image_url == "/user2.png" + + def test_update_password(self): + from open_webui.utils.auth import get_password_hash + + user = self.auths.insert_new_auth( + email="john.doe@openwebui.com", + password=get_password_hash("old_password"), + name="John Doe", + profile_image_url="/user.png", + role="user", + ) + + with mock_webui_user(id=user.id): + response = self.fast_api_client.post( + self.create_url("/update/password"), + json={"password": "old_password", "new_password": "new_password"}, + ) + assert response.status_code == 200 + + old_auth = self.auths.authenticate_user( + "john.doe@openwebui.com", "old_password" + ) + assert old_auth is None + new_auth = self.auths.authenticate_user( + "john.doe@openwebui.com", "new_password" + ) + assert new_auth is not None + + def test_signin(self): + from open_webui.utils.auth import get_password_hash + + user = self.auths.insert_new_auth( + email="john.doe@openwebui.com", + password=get_password_hash("password"), + name="John Doe", + profile_image_url="/user.png", + role="user", + ) + response = self.fast_api_client.post( + self.create_url("/signin"), + json={"email": "john.doe@openwebui.com", "password": "password"}, + ) + assert response.status_code == 200 + data = response.json() + assert data["id"] == user.id + assert data["name"] == "John Doe" + assert data["email"] == "john.doe@openwebui.com" + assert data["role"] == "user" + assert data["profile_image_url"] == "/user.png" + assert data["token"] is not None and len(data["token"]) > 0 + assert data["token_type"] == "Bearer" + + def test_signup(self): + response = self.fast_api_client.post( + self.create_url("/signup"), + json={ + "name": "John Doe", + "email": "john.doe@openwebui.com", + "password": "password", + }, + ) + assert response.status_code == 200 + data = response.json() + assert data["id"] is not None and len(data["id"]) > 0 + assert data["name"] == "John Doe" + assert data["email"] == "john.doe@openwebui.com" + assert data["role"] in ["admin", "user", "pending"] + assert data["profile_image_url"] == "/user.png" + assert data["token"] is not None and len(data["token"]) > 0 + assert data["token_type"] == "Bearer" + + def test_add_user(self): + with mock_webui_user(): + response = self.fast_api_client.post( + self.create_url("/add"), + json={ + "name": "John Doe 2", + "email": "john.doe2@openwebui.com", + "password": "password2", + "role": "admin", + }, + ) + assert response.status_code == 200 + data = response.json() + assert data["id"] is not None and len(data["id"]) > 0 + assert data["name"] == "John Doe 2" + assert data["email"] == "john.doe2@openwebui.com" + assert data["role"] == "admin" + assert data["profile_image_url"] == "/user.png" + assert data["token"] is not None and len(data["token"]) > 0 + assert data["token_type"] == "Bearer" + + def test_get_admin_details(self): + self.auths.insert_new_auth( + email="john.doe@openwebui.com", + password="password", + name="John Doe", + profile_image_url="/user.png", + role="admin", + ) + with mock_webui_user(): + response = self.fast_api_client.get(self.create_url("/admin/details")) + + assert response.status_code == 200 + assert response.json() == { + "name": "John Doe", + "email": "john.doe@openwebui.com", + } + + def test_create_api_key_(self): + user = self.auths.insert_new_auth( + email="john.doe@openwebui.com", + password="password", + name="John Doe", + profile_image_url="/user.png", + role="admin", + ) + with mock_webui_user(id=user.id): + response = self.fast_api_client.post(self.create_url("/api_key")) + assert response.status_code == 200 + data = response.json() + assert data["api_key"] is not None + assert len(data["api_key"]) > 0 + + def test_delete_api_key(self): + user = self.auths.insert_new_auth( + email="john.doe@openwebui.com", + password="password", + name="John Doe", + profile_image_url="/user.png", + role="admin", + ) + self.users.update_user_api_key_by_id(user.id, "abc") + with mock_webui_user(id=user.id): + response = self.fast_api_client.delete(self.create_url("/api_key")) + assert response.status_code == 200 + assert response.json() == True + db_user = self.users.get_user_by_id(user.id) + assert db_user.api_key is None + + def test_get_api_key(self): + user = self.auths.insert_new_auth( + email="john.doe@openwebui.com", + password="password", + name="John Doe", + profile_image_url="/user.png", + role="admin", + ) + self.users.update_user_api_key_by_id(user.id, "abc") + with mock_webui_user(id=user.id): + response = self.fast_api_client.get(self.create_url("/api_key")) + assert response.status_code == 200 + assert response.json() == {"api_key": "abc"} diff --git a/backend/open_webui/test/apps/webui/routers/test_chats.py b/backend/open_webui/test/apps/webui/routers/test_chats.py new file mode 100644 index 0000000..a36a01f --- /dev/null +++ b/backend/open_webui/test/apps/webui/routers/test_chats.py @@ -0,0 +1,236 @@ +import uuid + +from test.util.abstract_integration_test import AbstractPostgresTest +from test.util.mock_user import mock_webui_user + + +class TestChats(AbstractPostgresTest): + BASE_PATH = "/api/v1/chats" + + def setup_class(cls): + super().setup_class() + + def setup_method(self): + super().setup_method() + from open_webui.models.chats import ChatForm, Chats + + self.chats = Chats + self.chats.insert_new_chat( + "2", + ChatForm( + **{ + "chat": { + "name": "chat1", + "description": "chat1 description", + "tags": ["tag1", "tag2"], + "history": {"currentId": "1", "messages": []}, + } + } + ), + ) + + def test_get_session_user_chat_list(self): + with mock_webui_user(id="2"): + response = self.fast_api_client.get(self.create_url("/")) + assert response.status_code == 200 + first_chat = response.json()[0] + assert first_chat["id"] is not None + assert first_chat["title"] == "New Chat" + assert first_chat["created_at"] is not None + assert first_chat["updated_at"] is not None + + def test_delete_all_user_chats(self): + with mock_webui_user(id="2"): + response = self.fast_api_client.delete(self.create_url("/")) + assert response.status_code == 200 + assert len(self.chats.get_chats()) == 0 + + def test_get_user_chat_list_by_user_id(self): + with mock_webui_user(id="3"): + response = self.fast_api_client.get(self.create_url("/list/user/2")) + assert response.status_code == 200 + first_chat = response.json()[0] + assert first_chat["id"] is not None + assert first_chat["title"] == "New Chat" + assert first_chat["created_at"] is not None + assert first_chat["updated_at"] is not None + + def test_create_new_chat(self): + with mock_webui_user(id="2"): + response = self.fast_api_client.post( + self.create_url("/new"), + json={ + "chat": { + "name": "chat2", + "description": "chat2 description", + "tags": ["tag1", "tag2"], + } + }, + ) + assert response.status_code == 200 + data = response.json() + assert data["archived"] is False + assert data["chat"] == { + "name": "chat2", + "description": "chat2 description", + "tags": ["tag1", "tag2"], + } + assert data["user_id"] == "2" + assert data["id"] is not None + assert data["share_id"] is None + assert data["title"] == "New Chat" + assert data["updated_at"] is not None + assert data["created_at"] is not None + assert len(self.chats.get_chats()) == 2 + + def test_get_user_chats(self): + self.test_get_session_user_chat_list() + + def test_get_user_archived_chats(self): + self.chats.archive_all_chats_by_user_id("2") + from open_webui.internal.db import Session + + Session.commit() + with mock_webui_user(id="2"): + response = self.fast_api_client.get(self.create_url("/all/archived")) + assert response.status_code == 200 + first_chat = response.json()[0] + assert first_chat["id"] is not None + assert first_chat["title"] == "New Chat" + assert first_chat["created_at"] is not None + assert first_chat["updated_at"] is not None + + def test_get_all_user_chats_in_db(self): + with mock_webui_user(id="4"): + response = self.fast_api_client.get(self.create_url("/all/db")) + assert response.status_code == 200 + assert len(response.json()) == 1 + + def test_get_archived_session_user_chat_list(self): + self.test_get_user_archived_chats() + + def test_archive_all_chats(self): + with mock_webui_user(id="2"): + response = self.fast_api_client.post(self.create_url("/archive/all")) + assert response.status_code == 200 + assert len(self.chats.get_archived_chats_by_user_id("2")) == 1 + + def test_get_shared_chat_by_id(self): + chat_id = self.chats.get_chats()[0].id + self.chats.update_chat_share_id_by_id(chat_id, chat_id) + with mock_webui_user(id="2"): + response = self.fast_api_client.get(self.create_url(f"/share/{chat_id}")) + assert response.status_code == 200 + data = response.json() + assert data["id"] == chat_id + assert data["chat"] == { + "name": "chat1", + "description": "chat1 description", + "tags": ["tag1", "tag2"], + "history": {"currentId": "1", "messages": []}, + } + assert data["id"] == chat_id + assert data["share_id"] == chat_id + assert data["title"] == "New Chat" + + def test_get_chat_by_id(self): + chat_id = self.chats.get_chats()[0].id + with mock_webui_user(id="2"): + response = self.fast_api_client.get(self.create_url(f"/{chat_id}")) + assert response.status_code == 200 + data = response.json() + assert data["id"] == chat_id + assert data["chat"] == { + "name": "chat1", + "description": "chat1 description", + "tags": ["tag1", "tag2"], + "history": {"currentId": "1", "messages": []}, + } + assert data["share_id"] is None + assert data["title"] == "New Chat" + assert data["user_id"] == "2" + + def test_update_chat_by_id(self): + chat_id = self.chats.get_chats()[0].id + with mock_webui_user(id="2"): + response = self.fast_api_client.post( + self.create_url(f"/{chat_id}"), + json={ + "chat": { + "name": "chat2", + "description": "chat2 description", + "tags": ["tag2", "tag4"], + "title": "Just another title", + } + }, + ) + assert response.status_code == 200 + data = response.json() + assert data["id"] == chat_id + assert data["chat"] == { + "name": "chat2", + "title": "Just another title", + "description": "chat2 description", + "tags": ["tag2", "tag4"], + "history": {"currentId": "1", "messages": []}, + } + assert data["share_id"] is None + assert data["title"] == "Just another title" + assert data["user_id"] == "2" + + def test_delete_chat_by_id(self): + chat_id = self.chats.get_chats()[0].id + with mock_webui_user(id="2"): + response = self.fast_api_client.delete(self.create_url(f"/{chat_id}")) + assert response.status_code == 200 + assert response.json() is True + + def test_clone_chat_by_id(self): + chat_id = self.chats.get_chats()[0].id + with mock_webui_user(id="2"): + response = self.fast_api_client.get(self.create_url(f"/{chat_id}/clone")) + + assert response.status_code == 200 + data = response.json() + assert data["id"] != chat_id + assert data["chat"] == { + "branchPointMessageId": "1", + "description": "chat1 description", + "history": {"currentId": "1", "messages": []}, + "name": "chat1", + "originalChatId": chat_id, + "tags": ["tag1", "tag2"], + "title": "Clone of New Chat", + } + assert data["share_id"] is None + assert data["title"] == "Clone of New Chat" + assert data["user_id"] == "2" + + def test_archive_chat_by_id(self): + chat_id = self.chats.get_chats()[0].id + with mock_webui_user(id="2"): + response = self.fast_api_client.get(self.create_url(f"/{chat_id}/archive")) + assert response.status_code == 200 + + chat = self.chats.get_chat_by_id(chat_id) + assert chat.archived is True + + def test_share_chat_by_id(self): + chat_id = self.chats.get_chats()[0].id + with mock_webui_user(id="2"): + response = self.fast_api_client.post(self.create_url(f"/{chat_id}/share")) + assert response.status_code == 200 + + chat = self.chats.get_chat_by_id(chat_id) + assert chat.share_id is not None + + def test_delete_shared_chat_by_id(self): + chat_id = self.chats.get_chats()[0].id + share_id = str(uuid.uuid4()) + self.chats.update_chat_share_id_by_id(chat_id, share_id) + with mock_webui_user(id="2"): + response = self.fast_api_client.delete(self.create_url(f"/{chat_id}/share")) + assert response.status_code + + chat = self.chats.get_chat_by_id(chat_id) + assert chat.share_id is None diff --git a/backend/open_webui/test/apps/webui/routers/test_models.py b/backend/open_webui/test/apps/webui/routers/test_models.py new file mode 100644 index 0000000..c16ca9d --- /dev/null +++ b/backend/open_webui/test/apps/webui/routers/test_models.py @@ -0,0 +1,61 @@ +from test.util.abstract_integration_test import AbstractPostgresTest +from test.util.mock_user import mock_webui_user + + +class TestModels(AbstractPostgresTest): + BASE_PATH = "/api/v1/models" + + def setup_class(cls): + super().setup_class() + from open_webui.models.models import Model + + cls.models = Model + + def test_models(self): + with mock_webui_user(id="2"): + response = self.fast_api_client.get(self.create_url("/")) + assert response.status_code == 200 + assert len(response.json()) == 0 + + with mock_webui_user(id="2"): + response = self.fast_api_client.post( + self.create_url("/add"), + json={ + "id": "my-model", + "base_model_id": "base-model-id", + "name": "Hello World", + "meta": { + "profile_image_url": "/static/favicon.png", + "description": "description", + "capabilities": None, + "model_config": {}, + }, + "params": {}, + }, + ) + assert response.status_code == 200 + + with mock_webui_user(id="2"): + response = self.fast_api_client.get(self.create_url("/")) + assert response.status_code == 200 + assert len(response.json()) == 1 + + with mock_webui_user(id="2"): + response = self.fast_api_client.get( + self.create_url(query_params={"id": "my-model"}) + ) + assert response.status_code == 200 + data = response.json()[0] + assert data["id"] == "my-model" + assert data["name"] == "Hello World" + + with mock_webui_user(id="2"): + response = self.fast_api_client.delete( + self.create_url("/delete?id=my-model") + ) + assert response.status_code == 200 + + with mock_webui_user(id="2"): + response = self.fast_api_client.get(self.create_url("/")) + assert response.status_code == 200 + assert len(response.json()) == 0 diff --git a/backend/open_webui/test/apps/webui/routers/test_prompts.py b/backend/open_webui/test/apps/webui/routers/test_prompts.py new file mode 100644 index 0000000..d91bf77 --- /dev/null +++ b/backend/open_webui/test/apps/webui/routers/test_prompts.py @@ -0,0 +1,91 @@ +from test.util.abstract_integration_test import AbstractPostgresTest +from test.util.mock_user import mock_webui_user + + +class TestPrompts(AbstractPostgresTest): + BASE_PATH = "/api/v1/prompts" + + def test_prompts(self): + # Get all prompts + with mock_webui_user(id="2"): + response = self.fast_api_client.get(self.create_url("/")) + assert response.status_code == 200 + assert len(response.json()) == 0 + + # Create a two new prompts + with mock_webui_user(id="2"): + response = self.fast_api_client.post( + self.create_url("/create"), + json={ + "command": "/my-command", + "title": "Hello World", + "content": "description", + }, + ) + assert response.status_code == 200 + with mock_webui_user(id="3"): + response = self.fast_api_client.post( + self.create_url("/create"), + json={ + "command": "/my-command2", + "title": "Hello World 2", + "content": "description 2", + }, + ) + assert response.status_code == 200 + + # Get all prompts + with mock_webui_user(id="2"): + response = self.fast_api_client.get(self.create_url("/")) + assert response.status_code == 200 + assert len(response.json()) == 2 + + # Get prompt by command + with mock_webui_user(id="2"): + response = self.fast_api_client.get(self.create_url("/command/my-command")) + assert response.status_code == 200 + data = response.json() + assert data["command"] == "/my-command" + assert data["title"] == "Hello World" + assert data["content"] == "description" + assert data["user_id"] == "2" + + # Update prompt + with mock_webui_user(id="2"): + response = self.fast_api_client.post( + self.create_url("/command/my-command2/update"), + json={ + "command": "irrelevant for request", + "title": "Hello World Updated", + "content": "description Updated", + }, + ) + assert response.status_code == 200 + data = response.json() + assert data["command"] == "/my-command2" + assert data["title"] == "Hello World Updated" + assert data["content"] == "description Updated" + assert data["user_id"] == "3" + + # Get prompt by command + with mock_webui_user(id="2"): + response = self.fast_api_client.get(self.create_url("/command/my-command2")) + assert response.status_code == 200 + data = response.json() + assert data["command"] == "/my-command2" + assert data["title"] == "Hello World Updated" + assert data["content"] == "description Updated" + assert data["user_id"] == "3" + + # Delete prompt + with mock_webui_user(id="2"): + response = self.fast_api_client.delete( + self.create_url("/command/my-command/delete") + ) + assert response.status_code == 200 + + # Get all prompts + with mock_webui_user(id="2"): + response = self.fast_api_client.get(self.create_url("/")) + assert response.status_code == 200 + assert len(response.json()) == 1 diff --git a/backend/open_webui/test/apps/webui/routers/test_users.py b/backend/open_webui/test/apps/webui/routers/test_users.py new file mode 100644 index 0000000..1a58ab1 --- /dev/null +++ b/backend/open_webui/test/apps/webui/routers/test_users.py @@ -0,0 +1,167 @@ +from test.util.abstract_integration_test import AbstractPostgresTest +from test.util.mock_user import mock_webui_user + + +def _get_user_by_id(data, param): + return next((item for item in data if item["id"] == param), None) + + +def _assert_user(data, id, **kwargs): + user = _get_user_by_id(data, id) + assert user is not None + comparison_data = { + "name": f"user {id}", + "email": f"user{id}@openwebui.com", + "profile_image_url": f"/user{id}.png", + "role": "user", + **kwargs, + } + for key, value in comparison_data.items(): + assert user[key] == value + + +class TestUsers(AbstractPostgresTest): + BASE_PATH = "/api/v1/users" + + def setup_class(cls): + super().setup_class() + from open_webui.models.users import Users + + cls.users = Users + + def setup_method(self): + super().setup_method() + self.users.insert_new_user( + id="1", + name="user 1", + email="user1@openwebui.com", + profile_image_url="/user1.png", + role="user", + ) + self.users.insert_new_user( + id="2", + name="user 2", + email="user2@openwebui.com", + profile_image_url="/user2.png", + role="user", + ) + + def test_users(self): + # Get all users + with mock_webui_user(id="3"): + response = self.fast_api_client.get(self.create_url("")) + assert response.status_code == 200 + assert len(response.json()) == 2 + data = response.json() + _assert_user(data, "1") + _assert_user(data, "2") + + # update role + with mock_webui_user(id="3"): + response = self.fast_api_client.post( + self.create_url("/update/role"), json={"id": "2", "role": "admin"} + ) + assert response.status_code == 200 + _assert_user([response.json()], "2", role="admin") + + # Get all users + with mock_webui_user(id="3"): + response = self.fast_api_client.get(self.create_url("")) + assert response.status_code == 200 + assert len(response.json()) == 2 + data = response.json() + _assert_user(data, "1") + _assert_user(data, "2", role="admin") + + # Get (empty) user settings + with mock_webui_user(id="2"): + response = self.fast_api_client.get(self.create_url("/user/settings")) + assert response.status_code == 200 + assert response.json() is None + + # Update user settings + with mock_webui_user(id="2"): + response = self.fast_api_client.post( + self.create_url("/user/settings/update"), + json={ + "ui": {"attr1": "value1", "attr2": "value2"}, + "model_config": {"attr3": "value3", "attr4": "value4"}, + }, + ) + assert response.status_code == 200 + + # Get user settings + with mock_webui_user(id="2"): + response = self.fast_api_client.get(self.create_url("/user/settings")) + assert response.status_code == 200 + assert response.json() == { + "ui": {"attr1": "value1", "attr2": "value2"}, + "model_config": {"attr3": "value3", "attr4": "value4"}, + } + + # Get (empty) user info + with mock_webui_user(id="1"): + response = self.fast_api_client.get(self.create_url("/user/info")) + assert response.status_code == 200 + assert response.json() is None + + # Update user info + with mock_webui_user(id="1"): + response = self.fast_api_client.post( + self.create_url("/user/info/update"), + json={"attr1": "value1", "attr2": "value2"}, + ) + assert response.status_code == 200 + + # Get user info + with mock_webui_user(id="1"): + response = self.fast_api_client.get(self.create_url("/user/info")) + assert response.status_code == 200 + assert response.json() == {"attr1": "value1", "attr2": "value2"} + + # Get user by id + with mock_webui_user(id="1"): + response = self.fast_api_client.get(self.create_url("/2")) + assert response.status_code == 200 + assert response.json() == {"name": "user 2", "profile_image_url": "/user2.png"} + + # Update user by id + with mock_webui_user(id="1"): + response = self.fast_api_client.post( + self.create_url("/2/update"), + json={ + "name": "user 2 updated", + "email": "user2-updated@openwebui.com", + "profile_image_url": "/user2-updated.png", + }, + ) + assert response.status_code == 200 + + # Get all users + with mock_webui_user(id="3"): + response = self.fast_api_client.get(self.create_url("")) + assert response.status_code == 200 + assert len(response.json()) == 2 + data = response.json() + _assert_user(data, "1") + _assert_user( + data, + "2", + role="admin", + name="user 2 updated", + email="user2-updated@openwebui.com", + profile_image_url="/user2-updated.png", + ) + + # Delete user by id + with mock_webui_user(id="1"): + response = self.fast_api_client.delete(self.create_url("/2")) + assert response.status_code == 200 + + # Get all users + with mock_webui_user(id="3"): + response = self.fast_api_client.get(self.create_url("")) + assert response.status_code == 200 + assert len(response.json()) == 1 + data = response.json() + _assert_user(data, "1") diff --git a/backend/open_webui/test/apps/webui/storage/test_provider.py b/backend/open_webui/test/apps/webui/storage/test_provider.py new file mode 100644 index 0000000..a5ef135 --- /dev/null +++ b/backend/open_webui/test/apps/webui/storage/test_provider.py @@ -0,0 +1,424 @@ +import io +import os +import boto3 +import pytest +from botocore.exceptions import ClientError +from moto import mock_aws +from open_webui.storage import provider +from gcp_storage_emulator.server import create_server +from google.cloud import storage +from azure.storage.blob import BlobServiceClient, ContainerClient, BlobClient +from unittest.mock import MagicMock + + +def mock_upload_dir(monkeypatch, tmp_path): + """Fixture to monkey-patch the UPLOAD_DIR and create a temporary directory.""" + directory = tmp_path / "uploads" + directory.mkdir() + monkeypatch.setattr(provider, "UPLOAD_DIR", str(directory)) + return directory + + +def test_imports(): + provider.StorageProvider + provider.LocalStorageProvider + provider.S3StorageProvider + provider.GCSStorageProvider + provider.AzureStorageProvider + provider.Storage + + +def test_get_storage_provider(): + Storage = provider.get_storage_provider("local") + assert isinstance(Storage, provider.LocalStorageProvider) + Storage = provider.get_storage_provider("s3") + assert isinstance(Storage, provider.S3StorageProvider) + Storage = provider.get_storage_provider("gcs") + assert isinstance(Storage, provider.GCSStorageProvider) + Storage = provider.get_storage_provider("azure") + assert isinstance(Storage, provider.AzureStorageProvider) + with pytest.raises(RuntimeError): + provider.get_storage_provider("invalid") + + +def test_class_instantiation(): + with pytest.raises(TypeError): + provider.StorageProvider() + with pytest.raises(TypeError): + + class Test(provider.StorageProvider): + pass + + Test() + provider.LocalStorageProvider() + provider.S3StorageProvider() + provider.GCSStorageProvider() + provider.AzureStorageProvider() + + +class TestLocalStorageProvider: + Storage = provider.LocalStorageProvider() + file_content = b"test content" + file_bytesio = io.BytesIO(file_content) + filename = "test.txt" + filename_extra = "test_exyta.txt" + file_bytesio_empty = io.BytesIO() + + def test_upload_file(self, monkeypatch, tmp_path): + upload_dir = mock_upload_dir(monkeypatch, tmp_path) + contents, file_path = self.Storage.upload_file(self.file_bytesio, self.filename) + assert (upload_dir / self.filename).exists() + assert (upload_dir / self.filename).read_bytes() == self.file_content + assert contents == self.file_content + assert file_path == str(upload_dir / self.filename) + with pytest.raises(ValueError): + self.Storage.upload_file(self.file_bytesio_empty, self.filename) + + def test_get_file(self, monkeypatch, tmp_path): + upload_dir = mock_upload_dir(monkeypatch, tmp_path) + file_path = str(upload_dir / self.filename) + file_path_return = self.Storage.get_file(file_path) + assert file_path == file_path_return + + def test_delete_file(self, monkeypatch, tmp_path): + upload_dir = mock_upload_dir(monkeypatch, tmp_path) + (upload_dir / self.filename).write_bytes(self.file_content) + assert (upload_dir / self.filename).exists() + file_path = str(upload_dir / self.filename) + self.Storage.delete_file(file_path) + assert not (upload_dir / self.filename).exists() + + def test_delete_all_files(self, monkeypatch, tmp_path): + upload_dir = mock_upload_dir(monkeypatch, tmp_path) + (upload_dir / self.filename).write_bytes(self.file_content) + (upload_dir / self.filename_extra).write_bytes(self.file_content) + self.Storage.delete_all_files() + assert not (upload_dir / self.filename).exists() + assert not (upload_dir / self.filename_extra).exists() + + +@mock_aws +class TestS3StorageProvider: + + def __init__(self): + self.Storage = provider.S3StorageProvider() + self.Storage.bucket_name = "my-bucket" + self.s3_client = boto3.resource("s3", region_name="us-east-1") + self.file_content = b"test content" + self.filename = "test.txt" + self.filename_extra = "test_exyta.txt" + self.file_bytesio_empty = io.BytesIO() + super().__init__() + + def test_upload_file(self, monkeypatch, tmp_path): + upload_dir = mock_upload_dir(monkeypatch, tmp_path) + # S3 checks + with pytest.raises(Exception): + self.Storage.upload_file(io.BytesIO(self.file_content), self.filename) + self.s3_client.create_bucket(Bucket=self.Storage.bucket_name) + contents, s3_file_path = self.Storage.upload_file( + io.BytesIO(self.file_content), self.filename + ) + object = self.s3_client.Object(self.Storage.bucket_name, self.filename) + assert self.file_content == object.get()["Body"].read() + # local checks + assert (upload_dir / self.filename).exists() + assert (upload_dir / self.filename).read_bytes() == self.file_content + assert contents == self.file_content + assert s3_file_path == "s3://" + self.Storage.bucket_name + "/" + self.filename + with pytest.raises(ValueError): + self.Storage.upload_file(self.file_bytesio_empty, self.filename) + + def test_get_file(self, monkeypatch, tmp_path): + upload_dir = mock_upload_dir(monkeypatch, tmp_path) + self.s3_client.create_bucket(Bucket=self.Storage.bucket_name) + contents, s3_file_path = self.Storage.upload_file( + io.BytesIO(self.file_content), self.filename + ) + file_path = self.Storage.get_file(s3_file_path) + assert file_path == str(upload_dir / self.filename) + assert (upload_dir / self.filename).exists() + + def test_delete_file(self, monkeypatch, tmp_path): + upload_dir = mock_upload_dir(monkeypatch, tmp_path) + self.s3_client.create_bucket(Bucket=self.Storage.bucket_name) + contents, s3_file_path = self.Storage.upload_file( + io.BytesIO(self.file_content), self.filename + ) + assert (upload_dir / self.filename).exists() + self.Storage.delete_file(s3_file_path) + assert not (upload_dir / self.filename).exists() + with pytest.raises(ClientError) as exc: + self.s3_client.Object(self.Storage.bucket_name, self.filename).load() + error = exc.value.response["Error"] + assert error["Code"] == "404" + assert error["Message"] == "Not Found" + + def test_delete_all_files(self, monkeypatch, tmp_path): + upload_dir = mock_upload_dir(monkeypatch, tmp_path) + # create 2 files + self.s3_client.create_bucket(Bucket=self.Storage.bucket_name) + self.Storage.upload_file(io.BytesIO(self.file_content), self.filename) + object = self.s3_client.Object(self.Storage.bucket_name, self.filename) + assert self.file_content == object.get()["Body"].read() + assert (upload_dir / self.filename).exists() + assert (upload_dir / self.filename).read_bytes() == self.file_content + self.Storage.upload_file(io.BytesIO(self.file_content), self.filename_extra) + object = self.s3_client.Object(self.Storage.bucket_name, self.filename_extra) + assert self.file_content == object.get()["Body"].read() + assert (upload_dir / self.filename).exists() + assert (upload_dir / self.filename).read_bytes() == self.file_content + + self.Storage.delete_all_files() + assert not (upload_dir / self.filename).exists() + with pytest.raises(ClientError) as exc: + self.s3_client.Object(self.Storage.bucket_name, self.filename).load() + error = exc.value.response["Error"] + assert error["Code"] == "404" + assert error["Message"] == "Not Found" + assert not (upload_dir / self.filename_extra).exists() + with pytest.raises(ClientError) as exc: + self.s3_client.Object(self.Storage.bucket_name, self.filename_extra).load() + error = exc.value.response["Error"] + assert error["Code"] == "404" + assert error["Message"] == "Not Found" + + self.Storage.delete_all_files() + assert not (upload_dir / self.filename).exists() + assert not (upload_dir / self.filename_extra).exists() + + +class TestGCSStorageProvider: + Storage = provider.GCSStorageProvider() + Storage.bucket_name = "my-bucket" + file_content = b"test content" + filename = "test.txt" + filename_extra = "test_exyta.txt" + file_bytesio_empty = io.BytesIO() + + @pytest.fixture(scope="class") + def setup(self): + host, port = "localhost", 9023 + + server = create_server(host, port, in_memory=True) + server.start() + os.environ["STORAGE_EMULATOR_HOST"] = f"http://{host}:{port}" + + gcs_client = storage.Client() + bucket = gcs_client.bucket(self.Storage.bucket_name) + bucket.create() + self.Storage.gcs_client, self.Storage.bucket = gcs_client, bucket + yield + bucket.delete(force=True) + server.stop() + + def test_upload_file(self, monkeypatch, tmp_path, setup): + upload_dir = mock_upload_dir(monkeypatch, tmp_path) + # catch error if bucket does not exist + with pytest.raises(Exception): + self.Storage.bucket = monkeypatch(self.Storage, "bucket", None) + self.Storage.upload_file(io.BytesIO(self.file_content), self.filename) + contents, gcs_file_path = self.Storage.upload_file( + io.BytesIO(self.file_content), self.filename + ) + object = self.Storage.bucket.get_blob(self.filename) + assert self.file_content == object.download_as_bytes() + # local checks + assert (upload_dir / self.filename).exists() + assert (upload_dir / self.filename).read_bytes() == self.file_content + assert contents == self.file_content + assert gcs_file_path == "gs://" + self.Storage.bucket_name + "/" + self.filename + # test error if file is empty + with pytest.raises(ValueError): + self.Storage.upload_file(self.file_bytesio_empty, self.filename) + + def test_get_file(self, monkeypatch, tmp_path, setup): + upload_dir = mock_upload_dir(monkeypatch, tmp_path) + contents, gcs_file_path = self.Storage.upload_file( + io.BytesIO(self.file_content), self.filename + ) + file_path = self.Storage.get_file(gcs_file_path) + assert file_path == str(upload_dir / self.filename) + assert (upload_dir / self.filename).exists() + + def test_delete_file(self, monkeypatch, tmp_path, setup): + upload_dir = mock_upload_dir(monkeypatch, tmp_path) + contents, gcs_file_path = self.Storage.upload_file( + io.BytesIO(self.file_content), self.filename + ) + # ensure that local directory has the uploaded file as well + assert (upload_dir / self.filename).exists() + assert self.Storage.bucket.get_blob(self.filename).name == self.filename + self.Storage.delete_file(gcs_file_path) + # check that deleting file from gcs will delete the local file as well + assert not (upload_dir / self.filename).exists() + assert self.Storage.bucket.get_blob(self.filename) == None + + def test_delete_all_files(self, monkeypatch, tmp_path, setup): + upload_dir = mock_upload_dir(monkeypatch, tmp_path) + # create 2 files + self.Storage.upload_file(io.BytesIO(self.file_content), self.filename) + object = self.Storage.bucket.get_blob(self.filename) + assert (upload_dir / self.filename).exists() + assert (upload_dir / self.filename).read_bytes() == self.file_content + assert self.Storage.bucket.get_blob(self.filename).name == self.filename + assert self.file_content == object.download_as_bytes() + self.Storage.upload_file(io.BytesIO(self.file_content), self.filename_extra) + object = self.Storage.bucket.get_blob(self.filename_extra) + assert (upload_dir / self.filename_extra).exists() + assert (upload_dir / self.filename_extra).read_bytes() == self.file_content + assert ( + self.Storage.bucket.get_blob(self.filename_extra).name + == self.filename_extra + ) + assert self.file_content == object.download_as_bytes() + + self.Storage.delete_all_files() + assert not (upload_dir / self.filename).exists() + assert not (upload_dir / self.filename_extra).exists() + assert self.Storage.bucket.get_blob(self.filename) == None + assert self.Storage.bucket.get_blob(self.filename_extra) == None + + +class TestAzureStorageProvider: + def __init__(self): + super().__init__() + + @pytest.fixture(scope="class") + def setup_storage(self, monkeypatch): + # Create mock Blob Service Client and related clients + mock_blob_service_client = MagicMock() + mock_container_client = MagicMock() + mock_blob_client = MagicMock() + + # Set up return values for the mock + mock_blob_service_client.get_container_client.return_value = ( + mock_container_client + ) + mock_container_client.get_blob_client.return_value = mock_blob_client + + # Monkeypatch the Azure classes to return our mocks + monkeypatch.setattr( + azure.storage.blob, + "BlobServiceClient", + lambda *args, **kwargs: mock_blob_service_client, + ) + monkeypatch.setattr( + azure.storage.blob, + "ContainerClient", + lambda *args, **kwargs: mock_container_client, + ) + monkeypatch.setattr( + azure.storage.blob, "BlobClient", lambda *args, **kwargs: mock_blob_client + ) + + self.Storage = provider.AzureStorageProvider() + self.Storage.endpoint = "https://myaccount.blob.core.windows.net" + self.Storage.container_name = "my-container" + self.file_content = b"test content" + self.filename = "test.txt" + self.filename_extra = "test_extra.txt" + self.file_bytesio_empty = io.BytesIO() + + # Apply mocks to the Storage instance + self.Storage.blob_service_client = mock_blob_service_client + self.Storage.container_client = mock_container_client + + def test_upload_file(self, monkeypatch, tmp_path): + upload_dir = mock_upload_dir(monkeypatch, tmp_path) + + # Simulate an error when container does not exist + self.Storage.container_client.get_blob_client.side_effect = Exception( + "Container does not exist" + ) + with pytest.raises(Exception): + self.Storage.upload_file(io.BytesIO(self.file_content), self.filename) + + # Reset side effect and create container + self.Storage.container_client.get_blob_client.side_effect = None + self.Storage.create_container() + contents, azure_file_path = self.Storage.upload_file( + io.BytesIO(self.file_content), self.filename + ) + + # Assertions + self.Storage.container_client.get_blob_client.assert_called_with(self.filename) + self.Storage.container_client.get_blob_client().upload_blob.assert_called_once_with( + self.file_content, overwrite=True + ) + assert contents == self.file_content + assert ( + azure_file_path + == f"https://myaccount.blob.core.windows.net/{self.Storage.container_name}/{self.filename}" + ) + assert (upload_dir / self.filename).exists() + assert (upload_dir / self.filename).read_bytes() == self.file_content + + with pytest.raises(ValueError): + self.Storage.upload_file(self.file_bytesio_empty, self.filename) + + def test_get_file(self, monkeypatch, tmp_path): + upload_dir = mock_upload_dir(monkeypatch, tmp_path) + self.Storage.create_container() + + # Mock upload behavior + self.Storage.upload_file(io.BytesIO(self.file_content), self.filename) + # Mock blob download behavior + self.Storage.container_client.get_blob_client().download_blob().readall.return_value = ( + self.file_content + ) + + file_url = f"https://myaccount.blob.core.windows.net/{self.Storage.container_name}/{self.filename}" + file_path = self.Storage.get_file(file_url) + + assert file_path == str(upload_dir / self.filename) + assert (upload_dir / self.filename).exists() + assert (upload_dir / self.filename).read_bytes() == self.file_content + + def test_delete_file(self, monkeypatch, tmp_path): + upload_dir = mock_upload_dir(monkeypatch, tmp_path) + self.Storage.create_container() + + # Mock file upload + self.Storage.upload_file(io.BytesIO(self.file_content), self.filename) + # Mock deletion + self.Storage.container_client.get_blob_client().delete_blob.return_value = None + + file_url = f"https://myaccount.blob.core.windows.net/{self.Storage.container_name}/{self.filename}" + self.Storage.delete_file(file_url) + + self.Storage.container_client.get_blob_client().delete_blob.assert_called_once() + assert not (upload_dir / self.filename).exists() + + def test_delete_all_files(self, monkeypatch, tmp_path): + upload_dir = mock_upload_dir(monkeypatch, tmp_path) + self.Storage.create_container() + + # Mock file uploads + self.Storage.upload_file(io.BytesIO(self.file_content), self.filename) + self.Storage.upload_file(io.BytesIO(self.file_content), self.filename_extra) + + # Mock listing and deletion behavior + self.Storage.container_client.list_blobs.return_value = [ + {"name": self.filename}, + {"name": self.filename_extra}, + ] + self.Storage.container_client.get_blob_client().delete_blob.return_value = None + + self.Storage.delete_all_files() + + self.Storage.container_client.list_blobs.assert_called_once() + self.Storage.container_client.get_blob_client().delete_blob.assert_any_call() + assert not (upload_dir / self.filename).exists() + assert not (upload_dir / self.filename_extra).exists() + + def test_get_file_not_found(self, monkeypatch): + self.Storage.create_container() + + file_url = f"https://myaccount.blob.core.windows.net/{self.Storage.container_name}/{self.filename}" + # Mock behavior to raise an error for missing blobs + self.Storage.container_client.get_blob_client().download_blob.side_effect = ( + Exception("Blob not found") + ) + with pytest.raises(Exception, match="Blob not found"): + self.Storage.get_file(file_url) diff --git a/backend/open_webui/test/util/abstract_integration_test.py b/backend/open_webui/test/util/abstract_integration_test.py new file mode 100644 index 0000000..e8492be --- /dev/null +++ b/backend/open_webui/test/util/abstract_integration_test.py @@ -0,0 +1,161 @@ +import logging +import os +import time + +import docker +import pytest +from docker import DockerClient +from pytest_docker.plugin import get_docker_ip +from fastapi.testclient import TestClient +from sqlalchemy import text, create_engine + + +log = logging.getLogger(__name__) + + +def get_fast_api_client(): + from main import app + + with TestClient(app) as c: + return c + + +class AbstractIntegrationTest: + BASE_PATH = None + + def create_url(self, path="", query_params=None): + if self.BASE_PATH is None: + raise Exception("BASE_PATH is not set") + parts = self.BASE_PATH.split("/") + parts = [part.strip() for part in parts if part.strip() != ""] + path_parts = path.split("/") + path_parts = [part.strip() for part in path_parts if part.strip() != ""] + query_parts = "" + if query_params: + query_parts = "&".join( + [f"{key}={value}" for key, value in query_params.items()] + ) + query_parts = f"?{query_parts}" + return "/".join(parts + path_parts) + query_parts + + @classmethod + def setup_class(cls): + pass + + def setup_method(self): + pass + + @classmethod + def teardown_class(cls): + pass + + def teardown_method(self): + pass + + +class AbstractPostgresTest(AbstractIntegrationTest): + DOCKER_CONTAINER_NAME = "postgres-test-container-will-get-deleted" + docker_client: DockerClient + + @classmethod + def _create_db_url(cls, env_vars_postgres: dict) -> str: + host = get_docker_ip() + user = env_vars_postgres["POSTGRES_USER"] + pw = env_vars_postgres["POSTGRES_PASSWORD"] + port = 8081 + db = env_vars_postgres["POSTGRES_DB"] + return f"postgresql://{user}:{pw}@{host}:{port}/{db}" + + @classmethod + def setup_class(cls): + super().setup_class() + try: + env_vars_postgres = { + "POSTGRES_USER": "user", + "POSTGRES_PASSWORD": "example", + "POSTGRES_DB": "openwebui", + } + cls.docker_client = docker.from_env() + cls.docker_client.containers.run( + "postgres:16.2", + detach=True, + environment=env_vars_postgres, + name=cls.DOCKER_CONTAINER_NAME, + ports={5432: ("0.0.0.0", 8081)}, + command="postgres -c log_statement=all", + ) + time.sleep(0.5) + + database_url = cls._create_db_url(env_vars_postgres) + os.environ["DATABASE_URL"] = database_url + retries = 10 + db = None + while retries > 0: + try: + from open_webui.config import OPEN_WEBUI_DIR + + db = create_engine(database_url, pool_pre_ping=True) + db = db.connect() + log.info("postgres is ready!") + break + except Exception as e: + log.warning(e) + time.sleep(3) + retries -= 1 + + if db: + # import must be after setting env! + cls.fast_api_client = get_fast_api_client() + db.close() + else: + raise Exception("Could not connect to Postgres") + except Exception as ex: + log.error(ex) + cls.teardown_class() + pytest.fail(f"Could not setup test environment: {ex}") + + def _check_db_connection(self): + from open_webui.internal.db import Session + + retries = 10 + while retries > 0: + try: + Session.execute(text("SELECT 1")) + Session.commit() + break + except Exception as e: + Session.rollback() + log.warning(e) + time.sleep(3) + retries -= 1 + + def setup_method(self): + super().setup_method() + self._check_db_connection() + + @classmethod + def teardown_class(cls) -> None: + super().teardown_class() + cls.docker_client.containers.get(cls.DOCKER_CONTAINER_NAME).remove(force=True) + + def teardown_method(self): + from open_webui.internal.db import Session + + # rollback everything not yet committed + Session.commit() + + # truncate all tables + tables = [ + "auth", + "chat", + "chatidtag", + "document", + "memory", + "model", + "prompt", + "tag", + '"user"', + ] + for table in tables: + Session.execute(text(f"TRUNCATE TABLE {table}")) + Session.commit() diff --git a/backend/open_webui/test/util/mock_user.py b/backend/open_webui/test/util/mock_user.py new file mode 100644 index 0000000..7ce64df --- /dev/null +++ b/backend/open_webui/test/util/mock_user.py @@ -0,0 +1,45 @@ +from contextlib import contextmanager + +from fastapi import FastAPI + + +@contextmanager +def mock_webui_user(**kwargs): + from open_webui.routers.webui import app + + with mock_user(app, **kwargs): + yield + + +@contextmanager +def mock_user(app: FastAPI, **kwargs): + from open_webui.utils.auth import ( + get_current_user, + get_verified_user, + get_admin_user, + get_current_user_by_api_key, + ) + from open_webui.models.users import User + + def create_user(): + user_parameters = { + "id": "1", + "name": "John Doe", + "email": "john.doe@openwebui.com", + "role": "user", + "profile_image_url": "/user.png", + "last_active_at": 1627351200, + "updated_at": 1627351200, + "created_at": 162735120, + **kwargs, + } + return User(**user_parameters) + + app.dependency_overrides = { + get_current_user: create_user, + get_verified_user: create_user, + get_admin_user: create_user, + get_current_user_by_api_key: create_user, + } + yield + app.dependency_overrides = {} diff --git a/backend/open_webui/utils/access_control.py b/backend/open_webui/utils/access_control.py new file mode 100644 index 0000000..1699cfa --- /dev/null +++ b/backend/open_webui/utils/access_control.py @@ -0,0 +1,147 @@ +from typing import Optional, Union, List, Dict, Any +from open_webui.models.users import Users, UserModel +from open_webui.models.groups import Groups + + +from open_webui.config import DEFAULT_USER_PERMISSIONS +import json + + +def fill_missing_permissions( + permissions: Dict[str, Any], default_permissions: Dict[str, Any] +) -> Dict[str, Any]: + """ + Recursively fills in missing properties in the permissions dictionary + using the default permissions as a template. + """ + for key, value in default_permissions.items(): + if key not in permissions: + permissions[key] = value + elif isinstance(value, dict) and isinstance( + permissions[key], dict + ): # Both are nested dictionaries + permissions[key] = fill_missing_permissions(permissions[key], value) + + return permissions + + +def get_permissions( + user_id: str, + default_permissions: Dict[str, Any], +) -> Dict[str, Any]: + """ + Get all permissions for a user by combining the permissions of all groups the user is a member of. + If a permission is defined in multiple groups, the most permissive value is used (True > False). + Permissions are nested in a dict with the permission key as the key and a boolean as the value. + """ + + def combine_permissions( + permissions: Dict[str, Any], group_permissions: Dict[str, Any] + ) -> Dict[str, Any]: + """Combine permissions from multiple groups by taking the most permissive value.""" + for key, value in group_permissions.items(): + if isinstance(value, dict): + if key not in permissions: + permissions[key] = {} + permissions[key] = combine_permissions(permissions[key], value) + else: + if key not in permissions: + permissions[key] = value + else: + permissions[key] = ( + permissions[key] or value + ) # Use the most permissive value (True > False) + return permissions + + user_groups = Groups.get_groups_by_member_id(user_id) + + # Deep copy default permissions to avoid modifying the original dict + permissions = json.loads(json.dumps(default_permissions)) + + # Combine permissions from all user groups + for group in user_groups: + group_permissions = group.permissions + permissions = combine_permissions(permissions, group_permissions) + + # Ensure all fields from default_permissions are present and filled in + permissions = fill_missing_permissions(permissions, default_permissions) + + return permissions + + +def has_permission( + user_id: str, + permission_key: str, + default_permissions: Dict[str, Any] = {}, +) -> bool: + """ + Check if a user has a specific permission by checking the group permissions + and fall back to default permissions if not found in any group. + + Permission keys can be hierarchical and separated by dots ('.'). + """ + + def get_permission(permissions: Dict[str, Any], keys: List[str]) -> bool: + """Traverse permissions dict using a list of keys (from dot-split permission_key).""" + for key in keys: + if key not in permissions: + return False # If any part of the hierarchy is missing, deny access + permissions = permissions[key] # Traverse one level deeper + + return bool(permissions) # Return the boolean at the final level + + permission_hierarchy = permission_key.split(".") + + # Retrieve user group permissions + user_groups = Groups.get_groups_by_member_id(user_id) + + for group in user_groups: + group_permissions = group.permissions + if get_permission(group_permissions, permission_hierarchy): + return True + + # Check default permissions afterward if the group permissions don't allow it + default_permissions = fill_missing_permissions( + default_permissions, DEFAULT_USER_PERMISSIONS + ) + return get_permission(default_permissions, permission_hierarchy) + + +def has_access( + user_id: str, + type: str = "write", + access_control: Optional[dict] = None, +) -> bool: + if access_control is None: + return type == "read" + + user_groups = Groups.get_groups_by_member_id(user_id) + user_group_ids = [group.id for group in user_groups] + permission_access = access_control.get(type, {}) + permitted_group_ids = permission_access.get("group_ids", []) + permitted_user_ids = permission_access.get("user_ids", []) + + return user_id in permitted_user_ids or any( + group_id in permitted_group_ids for group_id in user_group_ids + ) + + +# Get all users with access to a resource +def get_users_with_access( + type: str = "write", access_control: Optional[dict] = None +) -> List[UserModel]: + if access_control is None: + return Users.get_users() + + permission_access = access_control.get(type, {}) + permitted_group_ids = permission_access.get("group_ids", []) + permitted_user_ids = permission_access.get("user_ids", []) + + user_ids_with_access = set(permitted_user_ids) + + for group_id in permitted_group_ids: + group_user_ids = Groups.get_group_user_ids_by_id(group_id) + if group_user_ids: + user_ids_with_access.update(group_user_ids) + + return Users.get_users_by_user_ids(list(user_ids_with_access)) diff --git a/backend/open_webui/utils/audit.py b/backend/open_webui/utils/audit.py new file mode 100644 index 0000000..2d7ceab --- /dev/null +++ b/backend/open_webui/utils/audit.py @@ -0,0 +1,249 @@ +from contextlib import asynccontextmanager +from dataclasses import asdict, dataclass +from enum import Enum +import re +from typing import ( + TYPE_CHECKING, + Any, + AsyncGenerator, + Dict, + MutableMapping, + Optional, + cast, +) +import uuid + +from asgiref.typing import ( + ASGI3Application, + ASGIReceiveCallable, + ASGIReceiveEvent, + ASGISendCallable, + ASGISendEvent, + Scope as ASGIScope, +) +from loguru import logger +from starlette.requests import Request + +from open_webui.env import AUDIT_LOG_LEVEL, MAX_BODY_LOG_SIZE +from open_webui.utils.auth import get_current_user, get_http_authorization_cred +from open_webui.models.users import UserModel + + +if TYPE_CHECKING: + from loguru import Logger + + +@dataclass(frozen=True) +class AuditLogEntry: + # `Metadata` audit level properties + id: str + user: dict[str, Any] + audit_level: str + verb: str + request_uri: str + user_agent: Optional[str] = None + source_ip: Optional[str] = None + # `Request` audit level properties + request_object: Any = None + # `Request Response` level + response_object: Any = None + response_status_code: Optional[int] = None + + +class AuditLevel(str, Enum): + NONE = "NONE" + METADATA = "METADATA" + REQUEST = "REQUEST" + REQUEST_RESPONSE = "REQUEST_RESPONSE" + + +class AuditLogger: + """ + A helper class that encapsulates audit logging functionality. It uses Loguru’s logger with an auditable binding to ensure that audit log entries are filtered correctly. + + Parameters: + logger (Logger): An instance of Loguru’s logger. + """ + + def __init__(self, logger: "Logger"): + self.logger = logger.bind(auditable=True) + + def write( + self, + audit_entry: AuditLogEntry, + *, + log_level: str = "INFO", + extra: Optional[dict] = None, + ): + + entry = asdict(audit_entry) + + if extra: + entry["extra"] = extra + + self.logger.log( + log_level, + "", + **entry, + ) + + +class AuditContext: + """ + Captures and aggregates the HTTP request and response bodies during the processing of a request. It ensures that only a configurable maximum amount of data is stored to prevent excessive memory usage. + + Attributes: + request_body (bytearray): Accumulated request payload. + response_body (bytearray): Accumulated response payload. + max_body_size (int): Maximum number of bytes to capture. + metadata (Dict[str, Any]): A dictionary to store additional audit metadata (user, http verb, user agent, etc.). + """ + + def __init__(self, max_body_size: int = MAX_BODY_LOG_SIZE): + self.request_body = bytearray() + self.response_body = bytearray() + self.max_body_size = max_body_size + self.metadata: Dict[str, Any] = {} + + def add_request_chunk(self, chunk: bytes): + if len(self.request_body) < self.max_body_size: + self.request_body.extend( + chunk[: self.max_body_size - len(self.request_body)] + ) + + def add_response_chunk(self, chunk: bytes): + if len(self.response_body) < self.max_body_size: + self.response_body.extend( + chunk[: self.max_body_size - len(self.response_body)] + ) + + +class AuditLoggingMiddleware: + """ + ASGI middleware that intercepts HTTP requests and responses to perform audit logging. It captures request/response bodies (depending on audit level), headers, HTTP methods, and user information, then logs a structured audit entry at the end of the request cycle. + """ + + AUDITED_METHODS = {"PUT", "PATCH", "DELETE", "POST"} + + def __init__( + self, + app: ASGI3Application, + *, + excluded_paths: Optional[list[str]] = None, + max_body_size: int = MAX_BODY_LOG_SIZE, + audit_level: AuditLevel = AuditLevel.NONE, + ) -> None: + self.app = app + self.audit_logger = AuditLogger(logger) + self.excluded_paths = excluded_paths or [] + self.max_body_size = max_body_size + self.audit_level = audit_level + + async def __call__( + self, + scope: ASGIScope, + receive: ASGIReceiveCallable, + send: ASGISendCallable, + ) -> None: + if scope["type"] != "http": + return await self.app(scope, receive, send) + + request = Request(scope=cast(MutableMapping, scope)) + + if self._should_skip_auditing(request): + return await self.app(scope, receive, send) + + async with self._audit_context(request) as context: + + async def send_wrapper(message: ASGISendEvent) -> None: + if self.audit_level == AuditLevel.REQUEST_RESPONSE: + await self._capture_response(message, context) + + await send(message) + + original_receive = receive + + async def receive_wrapper() -> ASGIReceiveEvent: + nonlocal original_receive + message = await original_receive() + + if self.audit_level in ( + AuditLevel.REQUEST, + AuditLevel.REQUEST_RESPONSE, + ): + await self._capture_request(message, context) + + return message + + await self.app(scope, receive_wrapper, send_wrapper) + + @asynccontextmanager + async def _audit_context( + self, request: Request + ) -> AsyncGenerator[AuditContext, None]: + """ + async context manager that ensures that an audit log entry is recorded after the request is processed. + """ + context = AuditContext() + try: + yield context + finally: + await self._log_audit_entry(request, context) + + async def _get_authenticated_user(self, request: Request) -> UserModel: + + auth_header = request.headers.get("Authorization") + assert auth_header + user = get_current_user(request, None, get_http_authorization_cred(auth_header)) + + return user + + def _should_skip_auditing(self, request: Request) -> bool: + if ( + request.method not in {"POST", "PUT", "PATCH", "DELETE"} + or AUDIT_LOG_LEVEL == "NONE" + or not request.headers.get("authorization") + ): + return True + # match either /api//...(for the endpoint /api/chat case) or /api/v1//... + pattern = re.compile( + r"^/api(?:/v1)?/(" + "|".join(self.excluded_paths) + r")\b" + ) + if pattern.match(request.url.path): + return True + + return False + + async def _capture_request(self, message: ASGIReceiveEvent, context: AuditContext): + if message["type"] == "http.request": + body = message.get("body", b"") + context.add_request_chunk(body) + + async def _capture_response(self, message: ASGISendEvent, context: AuditContext): + if message["type"] == "http.response.start": + context.metadata["response_status_code"] = message["status"] + + elif message["type"] == "http.response.body": + body = message.get("body", b"") + context.add_response_chunk(body) + + async def _log_audit_entry(self, request: Request, context: AuditContext): + try: + user = await self._get_authenticated_user(request) + + entry = AuditLogEntry( + id=str(uuid.uuid4()), + user=user.model_dump(include={"id", "name", "email", "role"}), + audit_level=self.audit_level.value, + verb=request.method, + request_uri=str(request.url), + response_status_code=context.metadata.get("response_status_code", None), + source_ip=request.client.host if request.client else None, + user_agent=request.headers.get("user-agent"), + request_object=context.request_body.decode("utf-8", errors="replace"), + response_object=context.response_body.decode("utf-8", errors="replace"), + ) + + self.audit_logger.write(entry) + except Exception as e: + logger.error(f"Failed to log audit entry: {str(e)}") diff --git a/backend/open_webui/utils/auth.py b/backend/open_webui/utils/auth.py new file mode 100644 index 0000000..cbc8b15 --- /dev/null +++ b/backend/open_webui/utils/auth.py @@ -0,0 +1,247 @@ +import logging +import uuid +import jwt +import base64 +import hmac +import hashlib +import requests +import os + + +from datetime import UTC, datetime, timedelta +from typing import Optional, Union, List, Dict + +from open_webui.models.users import Users + +from open_webui.constants import ERROR_MESSAGES +from open_webui.env import ( + WEBUI_SECRET_KEY, + TRUSTED_SIGNATURE_KEY, + STATIC_DIR, + SRC_LOG_LEVELS, +) + +from fastapi import BackgroundTasks, Depends, HTTPException, Request, Response, status +from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer +from passlib.context import CryptContext + + +logging.getLogger("passlib").setLevel(logging.ERROR) + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["OAUTH"]) + +SESSION_SECRET = WEBUI_SECRET_KEY +ALGORITHM = "HS256" + +############## +# Auth Utils +############## + + +def verify_signature(payload: str, signature: str) -> bool: + """ + Verifies the HMAC signature of the received payload. + """ + try: + expected_signature = base64.b64encode( + hmac.new(TRUSTED_SIGNATURE_KEY, payload.encode(), hashlib.sha256).digest() + ).decode() + + # Compare securely to prevent timing attacks + return hmac.compare_digest(expected_signature, signature) + + except Exception: + return False + + +def override_static(path: str, content: str): + # Ensure path is safe + if "/" in path or ".." in path: + log.error(f"Invalid path: {path}") + return + + file_path = os.path.join(STATIC_DIR, path) + os.makedirs(os.path.dirname(file_path), exist_ok=True) + + with open(file_path, "wb") as f: + f.write(base64.b64decode(content)) # Convert Base64 back to raw binary + + +def get_license_data(app, key): + if key: + try: + res = requests.post( + "https://api.openwebui.com/api/v1/license", + json={"key": key, "version": "1"}, + timeout=5, + ) + + if getattr(res, "ok", False): + payload = getattr(res, "json", lambda: {})() + for k, v in payload.items(): + if k == "resources": + for p, c in v.items(): + globals().get("override_static", lambda a, b: None)(p, c) + elif k == "user_count": + setattr(app.state, "USER_COUNT", v) + elif k == "webui_name": + setattr(app.state, "WEBUI_NAME", v) + + return True + else: + log.error( + f"License: retrieval issue: {getattr(res, 'text', 'unknown error')}" + ) + except Exception as ex: + log.exception(f"License: Uncaught Exception: {ex}") + return False + + +bearer_security = HTTPBearer(auto_error=False) +pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") + + +def verify_password(plain_password, hashed_password): + return ( + pwd_context.verify(plain_password, hashed_password) if hashed_password else None + ) + + +def get_password_hash(password): + return pwd_context.hash(password) + + +def create_token(data: dict, expires_delta: Union[timedelta, None] = None) -> str: + payload = data.copy() + + if expires_delta: + expire = datetime.now(UTC) + expires_delta + payload.update({"exp": expire}) + + encoded_jwt = jwt.encode(payload, SESSION_SECRET, algorithm=ALGORITHM) + return encoded_jwt + + +def decode_token(token: str) -> Optional[dict]: + try: + decoded = jwt.decode(token, SESSION_SECRET, algorithms=[ALGORITHM]) + return decoded + except Exception: + return None + + +def extract_token_from_auth_header(auth_header: str): + return auth_header[len("Bearer ") :] + + +def create_api_key(): + key = str(uuid.uuid4()).replace("-", "") + return f"sk-{key}" + + +def get_http_authorization_cred(auth_header: str): + try: + scheme, credentials = auth_header.split(" ") + return HTTPAuthorizationCredentials(scheme=scheme, credentials=credentials) + except Exception: + raise ValueError(ERROR_MESSAGES.INVALID_TOKEN) + + +def get_current_user( + request: Request, + background_tasks: BackgroundTasks, + auth_token: HTTPAuthorizationCredentials = Depends(bearer_security), +): + token = None + + if auth_token is not None: + token = auth_token.credentials + + if token is None and "token" in request.cookies: + token = request.cookies.get("token") + + if token is None: + raise HTTPException(status_code=403, detail="Not authenticated") + + # auth by api key + if token.startswith("sk-"): + if not request.state.enable_api_key: + raise HTTPException( + status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.API_KEY_NOT_ALLOWED + ) + + if request.app.state.config.ENABLE_API_KEY_ENDPOINT_RESTRICTIONS: + allowed_paths = [ + path.strip() + for path in str( + request.app.state.config.API_KEY_ALLOWED_ENDPOINTS + ).split(",") + ] + + if request.url.path not in allowed_paths: + raise HTTPException( + status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.API_KEY_NOT_ALLOWED + ) + + return get_current_user_by_api_key(token) + + # auth by jwt token + try: + data = decode_token(token) + except Exception as e: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="Invalid token", + ) + + if data is not None and "id" in data: + user = Users.get_user_by_id(data["id"]) + if user is None: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.INVALID_TOKEN, + ) + else: + # Refresh the user's last active timestamp asynchronously + # to prevent blocking the request + if background_tasks: + background_tasks.add_task(Users.update_user_last_active_by_id, user.id) + return user + else: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.UNAUTHORIZED, + ) + + +def get_current_user_by_api_key(api_key: str): + user = Users.get_user_by_api_key(api_key) + + if user is None: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.INVALID_TOKEN, + ) + else: + Users.update_user_last_active_by_id(user.id) + + return user + + +def get_verified_user(user=Depends(get_current_user)): + if user.role not in {"user", "admin"}: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + ) + return user + + +def get_admin_user(user=Depends(get_current_user)): + if user.role != "admin": + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + ) + return user diff --git a/backend/open_webui/utils/chat.py b/backend/open_webui/utils/chat.py new file mode 100644 index 0000000..74d0af4 --- /dev/null +++ b/backend/open_webui/utils/chat.py @@ -0,0 +1,447 @@ +import time +import logging +import sys + +from aiocache import cached +from typing import Any, Optional +import random +import json +import inspect +import uuid +import asyncio + +from fastapi import Request, status +from starlette.responses import Response, StreamingResponse, JSONResponse + + +from open_webui.models.users import UserModel + +from open_webui.socket.main import ( + sio, + get_event_call, + get_event_emitter, +) +from open_webui.functions import generate_function_chat_completion + +from open_webui.routers.openai import ( + generate_chat_completion as generate_openai_chat_completion, +) + +from open_webui.routers.ollama import ( + generate_chat_completion as generate_ollama_chat_completion, +) + +from open_webui.routers.pipelines import ( + process_pipeline_inlet_filter, + process_pipeline_outlet_filter, +) + +from open_webui.models.functions import Functions +from open_webui.models.models import Models + + +from open_webui.utils.plugin import load_function_module_by_id +from open_webui.utils.models import get_all_models, check_model_access +from open_webui.utils.payload import convert_payload_openai_to_ollama +from open_webui.utils.response import ( + convert_response_ollama_to_openai, + convert_streaming_response_ollama_to_openai, +) +from open_webui.utils.filter import ( + get_sorted_filter_ids, + process_filter_functions, +) + +from open_webui.env import SRC_LOG_LEVELS, GLOBAL_LOG_LEVEL, BYPASS_MODEL_ACCESS_CONTROL + + +logging.basicConfig(stream=sys.stdout, level=GLOBAL_LOG_LEVEL) +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MAIN"]) + + +async def generate_direct_chat_completion( + request: Request, + form_data: dict, + user: Any, + models: dict, +): + log.info("generate_direct_chat_completion") + + metadata = form_data.pop("metadata", {}) + + user_id = metadata.get("user_id") + session_id = metadata.get("session_id") + request_id = str(uuid.uuid4()) # Generate a unique request ID + + event_caller = get_event_call(metadata) + + channel = f"{user_id}:{session_id}:{request_id}" + + if form_data.get("stream"): + q = asyncio.Queue() + + async def message_listener(sid, data): + """ + Handle received socket messages and push them into the queue. + """ + await q.put(data) + + # Register the listener + sio.on(channel, message_listener) + + # Start processing chat completion in background + res = await event_caller( + { + "type": "request:chat:completion", + "data": { + "form_data": form_data, + "model": models[form_data["model"]], + "channel": channel, + "session_id": session_id, + }, + } + ) + + log.info(f"res: {res}") + + if res.get("status", False): + # Define a generator to stream responses + async def event_generator(): + nonlocal q + try: + while True: + data = await q.get() # Wait for new messages + if isinstance(data, dict): + if "done" in data and data["done"]: + break # Stop streaming when 'done' is received + + yield f"data: {json.dumps(data)}\n\n" + elif isinstance(data, str): + yield data + except Exception as e: + log.debug(f"Error in event generator: {e}") + pass + + # Define a background task to run the event generator + async def background(): + try: + del sio.handlers["/"][channel] + except Exception as e: + pass + + # Return the streaming response + return StreamingResponse( + event_generator(), media_type="text/event-stream", background=background + ) + else: + raise Exception(str(res)) + else: + res = await event_caller( + { + "type": "request:chat:completion", + "data": { + "form_data": form_data, + "model": models[form_data["model"]], + "channel": channel, + "session_id": session_id, + }, + } + ) + + if "error" in res: + raise Exception(res["error"]) + + return res + + +async def generate_chat_completion( + request: Request, + form_data: dict, + user: Any, + bypass_filter: bool = False, +): + log.debug(f"generate_chat_completion: {form_data}") + if BYPASS_MODEL_ACCESS_CONTROL: + bypass_filter = True + + if hasattr(request.state, "metadata"): + if "metadata" not in form_data: + form_data["metadata"] = request.state.metadata + else: + form_data["metadata"] = { + **form_data["metadata"], + **request.state.metadata, + } + + if getattr(request.state, "direct", False) and hasattr(request.state, "model"): + models = { + request.state.model["id"]: request.state.model, + } + log.debug(f"direct connection to model: {models}") + else: + models = request.app.state.MODELS + + model_id = form_data["model"] + if model_id not in models: + raise Exception("Model not found") + + model = models[model_id] + + if getattr(request.state, "direct", False): + return await generate_direct_chat_completion( + request, form_data, user=user, models=models + ) + else: + # Check if user has access to the model + if not bypass_filter and user.role == "user": + try: + check_model_access(user, model) + except Exception as e: + raise e + + if model.get("owned_by") == "arena": + model_ids = model.get("info", {}).get("meta", {}).get("model_ids") + filter_mode = model.get("info", {}).get("meta", {}).get("filter_mode") + if model_ids and filter_mode == "exclude": + model_ids = [ + model["id"] + for model in list(request.app.state.MODELS.values()) + if model.get("owned_by") != "arena" and model["id"] not in model_ids + ] + + selected_model_id = None + if isinstance(model_ids, list) and model_ids: + selected_model_id = random.choice(model_ids) + else: + model_ids = [ + model["id"] + for model in list(request.app.state.MODELS.values()) + if model.get("owned_by") != "arena" + ] + selected_model_id = random.choice(model_ids) + + form_data["model"] = selected_model_id + + if form_data.get("stream") == True: + + async def stream_wrapper(stream): + yield f"data: {json.dumps({'selected_model_id': selected_model_id})}\n\n" + async for chunk in stream: + yield chunk + + response = await generate_chat_completion( + request, form_data, user, bypass_filter=True + ) + return StreamingResponse( + stream_wrapper(response.body_iterator), + media_type="text/event-stream", + background=response.background, + ) + else: + return { + **( + await generate_chat_completion( + request, form_data, user, bypass_filter=True + ) + ), + "selected_model_id": selected_model_id, + } + + if model.get("pipe"): + # Below does not require bypass_filter because this is the only route the uses this function and it is already bypassing the filter + return await generate_function_chat_completion( + request, form_data, user=user, models=models + ) + if model.get("owned_by") == "ollama": + # Using /ollama/api/chat endpoint + form_data = convert_payload_openai_to_ollama(form_data) + response = await generate_ollama_chat_completion( + request=request, + form_data=form_data, + user=user, + bypass_filter=bypass_filter, + ) + if form_data.get("stream"): + response.headers["content-type"] = "text/event-stream" + return StreamingResponse( + convert_streaming_response_ollama_to_openai(response), + headers=dict(response.headers), + background=response.background, + ) + else: + return convert_response_ollama_to_openai(response) + else: + return await generate_openai_chat_completion( + request=request, + form_data=form_data, + user=user, + bypass_filter=bypass_filter, + ) + + +chat_completion = generate_chat_completion + + +async def chat_completed(request: Request, form_data: dict, user: Any): + if not request.app.state.MODELS: + await get_all_models(request, user=user) + + if getattr(request.state, "direct", False) and hasattr(request.state, "model"): + models = { + request.state.model["id"]: request.state.model, + } + else: + models = request.app.state.MODELS + + data = form_data + model_id = data["model"] + if model_id not in models: + raise Exception("Model not found") + + model = models[model_id] + + try: + data = await process_pipeline_outlet_filter(request, data, user, models) + except Exception as e: + return Exception(f"Error: {e}") + + metadata = { + "chat_id": data["chat_id"], + "message_id": data["id"], + "session_id": data["session_id"], + "user_id": user.id, + } + + extra_params = { + "__event_emitter__": get_event_emitter(metadata), + "__event_call__": get_event_call(metadata), + "__user__": { + "id": user.id, + "email": user.email, + "name": user.name, + "role": user.role, + }, + "__metadata__": metadata, + "__request__": request, + "__model__": model, + } + + try: + result, _ = await process_filter_functions( + request=request, + filter_ids=get_sorted_filter_ids(model), + filter_type="outlet", + form_data=data, + extra_params=extra_params, + ) + return result + except Exception as e: + return Exception(f"Error: {e}") + + +async def chat_action(request: Request, action_id: str, form_data: dict, user: Any): + if "." in action_id: + action_id, sub_action_id = action_id.split(".") + else: + sub_action_id = None + + action = Functions.get_function_by_id(action_id) + if not action: + raise Exception(f"Action not found: {action_id}") + + if not request.app.state.MODELS: + await get_all_models(request, user=user) + + if getattr(request.state, "direct", False) and hasattr(request.state, "model"): + models = { + request.state.model["id"]: request.state.model, + } + else: + models = request.app.state.MODELS + + data = form_data + model_id = data["model"] + + if model_id not in models: + raise Exception("Model not found") + model = models[model_id] + + __event_emitter__ = get_event_emitter( + { + "chat_id": data["chat_id"], + "message_id": data["id"], + "session_id": data["session_id"], + "user_id": user.id, + } + ) + __event_call__ = get_event_call( + { + "chat_id": data["chat_id"], + "message_id": data["id"], + "session_id": data["session_id"], + "user_id": user.id, + } + ) + + if action_id in request.app.state.FUNCTIONS: + function_module = request.app.state.FUNCTIONS[action_id] + else: + function_module, _, _ = load_function_module_by_id(action_id) + request.app.state.FUNCTIONS[action_id] = function_module + + if hasattr(function_module, "valves") and hasattr(function_module, "Valves"): + valves = Functions.get_function_valves_by_id(action_id) + function_module.valves = function_module.Valves(**(valves if valves else {})) + + if hasattr(function_module, "action"): + try: + action = function_module.action + + # Get the signature of the function + sig = inspect.signature(action) + params = {"body": data} + + # Extra parameters to be passed to the function + extra_params = { + "__model__": model, + "__id__": sub_action_id if sub_action_id is not None else action_id, + "__event_emitter__": __event_emitter__, + "__event_call__": __event_call__, + "__request__": request, + } + + # Add extra params in contained in function signature + for key, value in extra_params.items(): + if key in sig.parameters: + params[key] = value + + if "__user__" in sig.parameters: + __user__ = { + "id": user.id, + "email": user.email, + "name": user.name, + "role": user.role, + } + + try: + if hasattr(function_module, "UserValves"): + __user__["valves"] = function_module.UserValves( + **Functions.get_user_valves_by_id_and_user_id( + action_id, user.id + ) + ) + except Exception as e: + log.exception(f"Failed to get user values: {e}") + + params = {**params, "__user__": __user__} + + if inspect.iscoroutinefunction(action): + data = await action(**params) + else: + data = action(**params) + + except Exception as e: + return Exception(f"Error: {e}") + + return data diff --git a/backend/open_webui/utils/code_interpreter.py b/backend/open_webui/utils/code_interpreter.py new file mode 100644 index 0000000..0a74da9 --- /dev/null +++ b/backend/open_webui/utils/code_interpreter.py @@ -0,0 +1,148 @@ +import asyncio +import json +import uuid +import websockets +import requests +from urllib.parse import urljoin + + +async def execute_code_jupyter( + jupyter_url, code, token=None, password=None, timeout=10 +): + """ + Executes Python code in a Jupyter kernel. + Supports authentication with a token or password. + :param jupyter_url: Jupyter server URL (e.g., "http://localhost:8888") + :param code: Code to execute + :param token: Jupyter authentication token (optional) + :param password: Jupyter password (optional) + :param timeout: WebSocket timeout in seconds (default: 10s) + :return: Dictionary with stdout, stderr, and result + - Images are prefixed with "base64:image/png," and separated by newlines if multiple. + """ + session = requests.Session() # Maintain cookies + headers = {} # Headers for requests + + # Authenticate using password + if password and not token: + try: + login_url = urljoin(jupyter_url, "/login") + response = session.get(login_url) + response.raise_for_status() + xsrf_token = session.cookies.get("_xsrf") + if not xsrf_token: + raise ValueError("Failed to fetch _xsrf token") + + login_data = {"_xsrf": xsrf_token, "password": password} + login_response = session.post( + login_url, data=login_data, cookies=session.cookies + ) + login_response.raise_for_status() + headers["X-XSRFToken"] = xsrf_token + except Exception as e: + return { + "stdout": "", + "stderr": f"Authentication Error: {str(e)}", + "result": "", + } + + # Construct API URLs with authentication token if provided + params = f"?token={token}" if token else "" + kernel_url = urljoin(jupyter_url, f"/api/kernels{params}") + + try: + response = session.post(kernel_url, headers=headers, cookies=session.cookies) + response.raise_for_status() + kernel_id = response.json()["id"] + + websocket_url = urljoin( + jupyter_url.replace("http", "ws"), + f"/api/kernels/{kernel_id}/channels{params}", + ) + + ws_headers = {} + if password and not token: + ws_headers["X-XSRFToken"] = session.cookies.get("_xsrf") + cookies = {name: value for name, value in session.cookies.items()} + ws_headers["Cookie"] = "; ".join( + [f"{name}={value}" for name, value in cookies.items()] + ) + + async with websockets.connect( + websocket_url, additional_headers=ws_headers + ) as ws: + msg_id = str(uuid.uuid4()) + execute_request = { + "header": { + "msg_id": msg_id, + "msg_type": "execute_request", + "username": "user", + "session": str(uuid.uuid4()), + "date": "", + "version": "5.3", + }, + "parent_header": {}, + "metadata": {}, + "content": { + "code": code, + "silent": False, + "store_history": True, + "user_expressions": {}, + "allow_stdin": False, + "stop_on_error": True, + }, + "channel": "shell", + } + await ws.send(json.dumps(execute_request)) + + stdout, stderr, result = "", "", [] + + while True: + try: + message = await asyncio.wait_for(ws.recv(), timeout) + message_data = json.loads(message) + if message_data.get("parent_header", {}).get("msg_id") == msg_id: + msg_type = message_data.get("msg_type") + + if msg_type == "stream": + if message_data["content"]["name"] == "stdout": + stdout += message_data["content"]["text"] + elif message_data["content"]["name"] == "stderr": + stderr += message_data["content"]["text"] + + elif msg_type in ("execute_result", "display_data"): + data = message_data["content"]["data"] + if "image/png" in data: + result.append( + f"data:image/png;base64,{data['image/png']}" + ) + elif "text/plain" in data: + result.append(data["text/plain"]) + + elif msg_type == "error": + stderr += "\n".join(message_data["content"]["traceback"]) + + elif ( + msg_type == "status" + and message_data["content"]["execution_state"] == "idle" + ): + break + + except asyncio.TimeoutError: + stderr += "\nExecution timed out." + break + + except Exception as e: + return {"stdout": "", "stderr": f"Error: {str(e)}", "result": ""} + + finally: + if kernel_id: + requests.delete( + f"{kernel_url}/{kernel_id}", headers=headers, cookies=session.cookies + ) + + return { + "stdout": stdout.strip(), + "stderr": stderr.strip(), + "result": "\n".join(result).strip() if result else "", + } diff --git a/backend/open_webui/utils/filter.py b/backend/open_webui/utils/filter.py new file mode 100644 index 0000000..0ca754e --- /dev/null +++ b/backend/open_webui/utils/filter.py @@ -0,0 +1,110 @@ +import inspect +import logging + +from open_webui.utils.plugin import load_function_module_by_id +from open_webui.models.functions import Functions +from open_webui.env import SRC_LOG_LEVELS + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MAIN"]) + + +def get_sorted_filter_ids(model): + def get_priority(function_id): + function = Functions.get_function_by_id(function_id) + if function is not None and hasattr(function, "valves"): + # TODO: Fix FunctionModel to include vavles + return (function.valves if function.valves else {}).get("priority", 0) + return 0 + + filter_ids = [function.id for function in Functions.get_global_filter_functions()] + if "info" in model and "meta" in model["info"]: + filter_ids.extend(model["info"]["meta"].get("filterIds", [])) + filter_ids = list(set(filter_ids)) + + enabled_filter_ids = [ + function.id + for function in Functions.get_functions_by_type("filter", active_only=True) + ] + + filter_ids = [fid for fid in filter_ids if fid in enabled_filter_ids] + filter_ids.sort(key=get_priority) + return filter_ids + + +async def process_filter_functions( + request, filter_ids, filter_type, form_data, extra_params +): + skip_files = None + + for filter_id in filter_ids: + filter = Functions.get_function_by_id(filter_id) + if not filter: + continue + + if filter_id in request.app.state.FUNCTIONS: + function_module = request.app.state.FUNCTIONS[filter_id] + else: + function_module, _, _ = load_function_module_by_id(filter_id) + request.app.state.FUNCTIONS[filter_id] = function_module + + # Check if the function has a file_handler variable + if filter_type == "inlet" and hasattr(function_module, "file_handler"): + skip_files = function_module.file_handler + + # Apply valves to the function + if hasattr(function_module, "valves") and hasattr(function_module, "Valves"): + valves = Functions.get_function_valves_by_id(filter_id) + function_module.valves = function_module.Valves( + **(valves if valves else {}) + ) + + # Prepare handler function + handler = getattr(function_module, filter_type, None) + if not handler: + continue + + try: + # Prepare parameters + sig = inspect.signature(handler) + + params = {"body": form_data} + if filter_type == "stream": + params = {"event": form_data} + + params = params | { + k: v + for k, v in { + **extra_params, + "__id__": filter_id, + }.items() + if k in sig.parameters + } + + # Handle user parameters + if "__user__" in sig.parameters: + if hasattr(function_module, "UserValves"): + try: + params["__user__"]["valves"] = function_module.UserValves( + **Functions.get_user_valves_by_id_and_user_id( + filter_id, params["__user__"]["id"] + ) + ) + except Exception as e: + log.exception(f"Failed to get user values: {e}") + + # Execute handler + if inspect.iscoroutinefunction(handler): + form_data = await handler(**params) + else: + form_data = handler(**params) + + except Exception as e: + log.exception(f"Error in {filter_type} handler {filter_id}: {e}") + raise e + + # Handle file cleanup for inlet + if skip_files and "files" in form_data.get("metadata", {}): + del form_data["metadata"]["files"] + + return form_data, {} diff --git a/backend/open_webui/utils/images/comfyui.py b/backend/open_webui/utils/images/comfyui.py new file mode 100644 index 0000000..b86c257 --- /dev/null +++ b/backend/open_webui/utils/images/comfyui.py @@ -0,0 +1,193 @@ +import asyncio +import json +import logging +import random +import urllib.parse +import urllib.request +from typing import Optional + +import websocket # NOTE: websocket-client (https://github.com/websocket-client/websocket-client) +from open_webui.env import SRC_LOG_LEVELS +from pydantic import BaseModel + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["COMFYUI"]) + +default_headers = {"User-Agent": "Mozilla/5.0"} + + +def queue_prompt(prompt, client_id, base_url, api_key): + log.info("queue_prompt") + p = {"prompt": prompt, "client_id": client_id} + data = json.dumps(p).encode("utf-8") + log.debug(f"queue_prompt data: {data}") + try: + req = urllib.request.Request( + f"{base_url}/prompt", + data=data, + headers={**default_headers, "Authorization": f"Bearer {api_key}"}, + ) + response = urllib.request.urlopen(req).read() + return json.loads(response) + except Exception as e: + log.exception(f"Error while queuing prompt: {e}") + raise e + + +def get_image(filename, subfolder, folder_type, base_url, api_key): + log.info("get_image") + data = {"filename": filename, "subfolder": subfolder, "type": folder_type} + url_values = urllib.parse.urlencode(data) + req = urllib.request.Request( + f"{base_url}/view?{url_values}", + headers={**default_headers, "Authorization": f"Bearer {api_key}"}, + ) + with urllib.request.urlopen(req) as response: + return response.read() + + +def get_image_url(filename, subfolder, folder_type, base_url): + log.info("get_image") + data = {"filename": filename, "subfolder": subfolder, "type": folder_type} + url_values = urllib.parse.urlencode(data) + return f"{base_url}/view?{url_values}" + + +def get_history(prompt_id, base_url, api_key): + log.info("get_history") + + req = urllib.request.Request( + f"{base_url}/history/{prompt_id}", + headers={**default_headers, "Authorization": f"Bearer {api_key}"}, + ) + with urllib.request.urlopen(req) as response: + return json.loads(response.read()) + + +def get_images(ws, prompt, client_id, base_url, api_key): + prompt_id = queue_prompt(prompt, client_id, base_url, api_key)["prompt_id"] + output_images = [] + while True: + out = ws.recv() + if isinstance(out, str): + message = json.loads(out) + if message["type"] == "executing": + data = message["data"] + if data["node"] is None and data["prompt_id"] == prompt_id: + break # Execution is done + else: + continue # previews are binary data + + history = get_history(prompt_id, base_url, api_key)[prompt_id] + for o in history["outputs"]: + for node_id in history["outputs"]: + node_output = history["outputs"][node_id] + if "images" in node_output: + for image in node_output["images"]: + url = get_image_url( + image["filename"], image["subfolder"], image["type"], base_url + ) + output_images.append({"url": url}) + return {"data": output_images} + + +class ComfyUINodeInput(BaseModel): + type: Optional[str] = None + node_ids: list[str] = [] + key: Optional[str] = "text" + value: Optional[str] = None + + +class ComfyUIWorkflow(BaseModel): + workflow: str + nodes: list[ComfyUINodeInput] + + +class ComfyUIGenerateImageForm(BaseModel): + workflow: ComfyUIWorkflow + + prompt: str + negative_prompt: Optional[str] = None + width: int + height: int + n: int = 1 + + steps: Optional[int] = None + seed: Optional[int] = None + + +async def comfyui_generate_image( + model: str, payload: ComfyUIGenerateImageForm, client_id, base_url, api_key +): + ws_url = base_url.replace("http://", "ws://").replace("https://", "wss://") + workflow = json.loads(payload.workflow.workflow) + + for node in payload.workflow.nodes: + if node.type: + if node.type == "model": + for node_id in node.node_ids: + workflow[node_id]["inputs"][node.key] = model + elif node.type == "prompt": + for node_id in node.node_ids: + workflow[node_id]["inputs"][ + node.key if node.key else "text" + ] = payload.prompt + elif node.type == "negative_prompt": + for node_id in node.node_ids: + workflow[node_id]["inputs"][ + node.key if node.key else "text" + ] = payload.negative_prompt + elif node.type == "width": + for node_id in node.node_ids: + workflow[node_id]["inputs"][ + node.key if node.key else "width" + ] = payload.width + elif node.type == "height": + for node_id in node.node_ids: + workflow[node_id]["inputs"][ + node.key if node.key else "height" + ] = payload.height + elif node.type == "n": + for node_id in node.node_ids: + workflow[node_id]["inputs"][ + node.key if node.key else "batch_size" + ] = payload.n + elif node.type == "steps": + for node_id in node.node_ids: + workflow[node_id]["inputs"][ + node.key if node.key else "steps" + ] = payload.steps + elif node.type == "seed": + seed = ( + payload.seed + if payload.seed + else random.randint(0, 1125899906842624) + ) + for node_id in node.node_ids: + workflow[node_id]["inputs"][node.key] = seed + else: + for node_id in node.node_ids: + workflow[node_id]["inputs"][node.key] = node.value + + try: + ws = websocket.WebSocket() + headers = {"Authorization": f"Bearer {api_key}"} + ws.connect(f"{ws_url}/ws?clientId={client_id}", header=headers) + log.info("WebSocket connection established.") + except Exception as e: + log.exception(f"Failed to connect to WebSocket server: {e}") + return None + + try: + log.info("Sending workflow to WebSocket server.") + log.info(f"Workflow: {workflow}") + images = await asyncio.to_thread( + get_images, ws, workflow, client_id, base_url, api_key + ) + except Exception as e: + log.exception(f"Error while receiving images: {e}") + images = None + + ws.close() + + return images diff --git a/backend/open_webui/utils/logger.py b/backend/open_webui/utils/logger.py new file mode 100644 index 0000000..2557610 --- /dev/null +++ b/backend/open_webui/utils/logger.py @@ -0,0 +1,140 @@ +import json +import logging +import sys +from typing import TYPE_CHECKING + +from loguru import logger + +from open_webui.env import ( + AUDIT_LOG_FILE_ROTATION_SIZE, + AUDIT_LOG_LEVEL, + AUDIT_LOGS_FILE_PATH, + GLOBAL_LOG_LEVEL, +) + + +if TYPE_CHECKING: + from loguru import Record + + +def stdout_format(record: "Record") -> str: + """ + Generates a formatted string for log records that are output to the console. This format includes a timestamp, log level, source location (module, function, and line), the log message, and any extra data (serialized as JSON). + + Parameters: + record (Record): A Loguru record that contains logging details including time, level, name, function, line, message, and any extra context. + Returns: + str: A formatted log string intended for stdout. + """ + record["extra"]["extra_json"] = json.dumps(record["extra"]) + return ( + "{time:YYYY-MM-DD HH:mm:ss.SSS} | " + "{level: <8} | " + "{name}:{function}:{line} - " + "{message} - {extra[extra_json]}" + "\n{exception}" + ) + + +class InterceptHandler(logging.Handler): + """ + Intercepts log records from Python's standard logging module + and redirects them to Loguru's logger. + """ + + def emit(self, record): + """ + Called by the standard logging module for each log event. + It transforms the standard `LogRecord` into a format compatible with Loguru + and passes it to Loguru's logger. + """ + try: + level = logger.level(record.levelname).name + except ValueError: + level = record.levelno + + frame, depth = sys._getframe(6), 6 + while frame and frame.f_code.co_filename == logging.__file__: + frame = frame.f_back + depth += 1 + + logger.opt(depth=depth, exception=record.exc_info).log( + level, record.getMessage() + ) + + +def file_format(record: "Record"): + """ + Formats audit log records into a structured JSON string for file output. + + Parameters: + record (Record): A Loguru record containing extra audit data. + Returns: + str: A JSON-formatted string representing the audit data. + """ + + audit_data = { + "id": record["extra"].get("id", ""), + "timestamp": int(record["time"].timestamp()), + "user": record["extra"].get("user", dict()), + "audit_level": record["extra"].get("audit_level", ""), + "verb": record["extra"].get("verb", ""), + "request_uri": record["extra"].get("request_uri", ""), + "response_status_code": record["extra"].get("response_status_code", 0), + "source_ip": record["extra"].get("source_ip", ""), + "user_agent": record["extra"].get("user_agent", ""), + "request_object": record["extra"].get("request_object", b""), + "response_object": record["extra"].get("response_object", b""), + "extra": record["extra"].get("extra", {}), + } + + record["extra"]["file_extra"] = json.dumps(audit_data, default=str) + return "{extra[file_extra]}\n" + + +def start_logger(): + """ + Initializes and configures Loguru's logger with distinct handlers: + + A console (stdout) handler for general log messages (excluding those marked as auditable). + An optional file handler for audit logs if audit logging is enabled. + Additionally, this function reconfigures Python’s standard logging to route through Loguru and adjusts logging levels for Uvicorn. + + Parameters: + enable_audit_logging (bool): Determines whether audit-specific log entries should be recorded to file. + """ + logger.remove() + + logger.add( + sys.stdout, + level=GLOBAL_LOG_LEVEL, + format=stdout_format, + filter=lambda record: "auditable" not in record["extra"], + ) + + if AUDIT_LOG_LEVEL != "NONE": + try: + logger.add( + AUDIT_LOGS_FILE_PATH, + level="INFO", + rotation=AUDIT_LOG_FILE_ROTATION_SIZE, + compression="zip", + format=file_format, + filter=lambda record: record["extra"].get("auditable") is True, + ) + except Exception as e: + logger.error(f"Failed to initialize audit log file handler: {str(e)}") + + logging.basicConfig( + handlers=[InterceptHandler()], level=GLOBAL_LOG_LEVEL, force=True + ) + for uvicorn_logger_name in ["uvicorn", "uvicorn.error"]: + uvicorn_logger = logging.getLogger(uvicorn_logger_name) + uvicorn_logger.setLevel(GLOBAL_LOG_LEVEL) + uvicorn_logger.handlers = [] + for uvicorn_logger_name in ["uvicorn.access"]: + uvicorn_logger = logging.getLogger(uvicorn_logger_name) + uvicorn_logger.setLevel(GLOBAL_LOG_LEVEL) + uvicorn_logger.handlers = [InterceptHandler()] + + logger.info(f"GLOBAL_LOG_LEVEL: {GLOBAL_LOG_LEVEL}") diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py new file mode 100644 index 0000000..43fd0d4 --- /dev/null +++ b/backend/open_webui/utils/middleware.py @@ -0,0 +1,2045 @@ +import time +import logging +import sys +import os +import base64 + +import asyncio +from aiocache import cached +from typing import Any, Optional +import random +import json +import html +import inspect +import re +import ast + +from uuid import uuid4 +from concurrent.futures import ThreadPoolExecutor + + +from fastapi import Request +from fastapi import BackgroundTasks + +from starlette.responses import Response, StreamingResponse + + +from open_webui.models.chats import Chats +from open_webui.models.users import Users +from open_webui.socket.main import ( + get_event_call, + get_event_emitter, + get_active_status_by_user_id, +) +from open_webui.routers.tasks import ( + generate_queries, + generate_title, + generate_image_prompt, + generate_chat_tags, +) +from open_webui.routers.retrieval import process_web_search, SearchForm +from open_webui.routers.images import image_generations, GenerateImageForm +from open_webui.routers.pipelines import ( + process_pipeline_inlet_filter, + process_pipeline_outlet_filter, +) + +from open_webui.utils.webhook import post_webhook + + +from open_webui.models.users import UserModel +from open_webui.models.functions import Functions +from open_webui.models.models import Models + +from open_webui.retrieval.utils import get_sources_from_files + + +from open_webui.utils.chat import generate_chat_completion +from open_webui.utils.task import ( + get_task_model_id, + rag_template, + tools_function_calling_generation_template, +) +from open_webui.utils.misc import ( + deep_update, + get_message_list, + add_or_update_system_message, + add_or_update_user_message, + get_last_user_message, + get_last_assistant_message, + prepend_to_first_user_message_content, +) +from open_webui.utils.tools import get_tools +from open_webui.utils.plugin import load_function_module_by_id +from open_webui.utils.filter import ( + get_sorted_filter_ids, + process_filter_functions, +) +from open_webui.utils.code_interpreter import execute_code_jupyter + +from open_webui.tasks import create_task + +from open_webui.config import ( + CACHE_DIR, + DEFAULT_TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE, + DEFAULT_CODE_INTERPRETER_PROMPT, +) +from open_webui.env import ( + SRC_LOG_LEVELS, + GLOBAL_LOG_LEVEL, + BYPASS_MODEL_ACCESS_CONTROL, + ENABLE_REALTIME_CHAT_SAVE, +) +from open_webui.constants import TASKS + + +logging.basicConfig(stream=sys.stdout, level=GLOBAL_LOG_LEVEL) +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MAIN"]) + + +async def chat_completion_tools_handler( + request: Request, body: dict, user: UserModel, models, tools +) -> tuple[dict, dict]: + async def get_content_from_response(response) -> Optional[str]: + content = None + if hasattr(response, "body_iterator"): + async for chunk in response.body_iterator: + data = json.loads(chunk.decode("utf-8")) + content = data["choices"][0]["message"]["content"] + + # Cleanup any remaining background tasks if necessary + if response.background is not None: + await response.background() + else: + content = response["choices"][0]["message"]["content"] + return content + + def get_tools_function_calling_payload(messages, task_model_id, content): + user_message = get_last_user_message(messages) + history = "\n".join( + f"{message['role'].upper()}: \"\"\"{message['content']}\"\"\"" + for message in messages[::-1][:4] + ) + + prompt = f"History:\n{history}\nQuery: {user_message}" + + return { + "model": task_model_id, + "messages": [ + {"role": "system", "content": content}, + {"role": "user", "content": f"Query: {prompt}"}, + ], + "stream": False, + "metadata": {"task": str(TASKS.FUNCTION_CALLING)}, + } + + task_model_id = get_task_model_id( + body["model"], + request.app.state.config.TASK_MODEL, + request.app.state.config.TASK_MODEL_EXTERNAL, + models, + ) + + skip_files = False + sources = [] + + specs = [tool["spec"] for tool in tools.values()] + tools_specs = json.dumps(specs) + + if request.app.state.config.TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE != "": + template = request.app.state.config.TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE + else: + template = DEFAULT_TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE + + tools_function_calling_prompt = tools_function_calling_generation_template( + template, tools_specs + ) + log.info(f"{tools_function_calling_prompt=}") + payload = get_tools_function_calling_payload( + body["messages"], task_model_id, tools_function_calling_prompt + ) + + try: + response = await generate_chat_completion(request, form_data=payload, user=user) + log.debug(f"{response=}") + content = await get_content_from_response(response) + log.debug(f"{content=}") + + if not content: + return body, {} + + try: + content = content[content.find("{") : content.rfind("}") + 1] + if not content: + raise Exception("No JSON object found in the response") + + result = json.loads(content) + + async def tool_call_handler(tool_call): + nonlocal skip_files + + log.debug(f"{tool_call=}") + + tool_function_name = tool_call.get("name", None) + if tool_function_name not in tools: + return body, {} + + tool_function_params = tool_call.get("parameters", {}) + + try: + required_params = ( + tools[tool_function_name] + .get("spec", {}) + .get("parameters", {}) + .get("required", []) + ) + tool_function = tools[tool_function_name]["callable"] + tool_function_params = { + k: v + for k, v in tool_function_params.items() + if k in required_params + } + tool_output = await tool_function(**tool_function_params) + + except Exception as e: + tool_output = str(e) + + if isinstance(tool_output, str): + if tools[tool_function_name]["citation"]: + sources.append( + { + "source": { + "name": f"TOOL:{tools[tool_function_name]['toolkit_id']}/{tool_function_name}" + }, + "document": [tool_output], + "metadata": [ + { + "source": f"TOOL:{tools[tool_function_name]['toolkit_id']}/{tool_function_name}" + } + ], + } + ) + else: + sources.append( + { + "source": {}, + "document": [tool_output], + "metadata": [ + { + "source": f"TOOL:{tools[tool_function_name]['toolkit_id']}/{tool_function_name}" + } + ], + } + ) + + if tools[tool_function_name]["file_handler"]: + skip_files = True + + # check if "tool_calls" in result + if result.get("tool_calls"): + for tool_call in result.get("tool_calls"): + await tool_call_handler(tool_call) + else: + await tool_call_handler(result) + + except Exception as e: + log.exception(f"Error: {e}") + content = None + except Exception as e: + log.exception(f"Error: {e}") + content = None + + log.debug(f"tool_contexts: {sources}") + + if skip_files and "files" in body.get("metadata", {}): + del body["metadata"]["files"] + + return body, {"sources": sources} + + +async def chat_web_search_handler( + request: Request, form_data: dict, extra_params: dict, user +): + event_emitter = extra_params["__event_emitter__"] + await event_emitter( + { + "type": "status", + "data": { + "action": "web_search", + "description": "Generating search query", + "done": False, + }, + } + ) + + messages = form_data["messages"] + user_message = get_last_user_message(messages) + + queries = [] + try: + res = await generate_queries( + request, + { + "model": form_data["model"], + "messages": messages, + "prompt": user_message, + "type": "web_search", + }, + user, + ) + + response = res["choices"][0]["message"]["content"] + + try: + bracket_start = response.find("{") + bracket_end = response.rfind("}") + 1 + + if bracket_start == -1 or bracket_end == -1: + raise Exception("No JSON object found in the response") + + response = response[bracket_start:bracket_end] + queries = json.loads(response) + queries = queries.get("queries", []) + except Exception as e: + queries = [response] + + except Exception as e: + log.exception(e) + queries = [user_message] + + if len(queries) == 0: + await event_emitter( + { + "type": "status", + "data": { + "action": "web_search", + "description": "No search query generated", + "done": True, + }, + } + ) + return form_data + + all_results = [] + + for searchQuery in queries: + await event_emitter( + { + "type": "status", + "data": { + "action": "web_search", + "description": 'Searching "{{searchQuery}}"', + "query": searchQuery, + "done": False, + }, + } + ) + + try: + results = await process_web_search( + request, + SearchForm( + **{ + "query": searchQuery, + } + ), + user=user, + ) + + if results: + all_results.append(results) + files = form_data.get("files", []) + + if results.get("collection_name"): + files.append( + { + "collection_name": results["collection_name"], + "name": searchQuery, + "type": "web_search", + "urls": results["filenames"], + } + ) + elif results.get("docs"): + files.append( + { + "docs": results.get("docs", []), + "name": searchQuery, + "type": "web_search", + "urls": results["filenames"], + } + ) + + form_data["files"] = files + except Exception as e: + log.exception(e) + await event_emitter( + { + "type": "status", + "data": { + "action": "web_search", + "description": 'Error searching "{{searchQuery}}"', + "query": searchQuery, + "done": True, + "error": True, + }, + } + ) + + if all_results: + urls = [] + for results in all_results: + if "filenames" in results: + urls.extend(results["filenames"]) + + await event_emitter( + { + "type": "status", + "data": { + "action": "web_search", + "description": "Searched {{count}} sites", + "urls": urls, + "done": True, + }, + } + ) + else: + await event_emitter( + { + "type": "status", + "data": { + "action": "web_search", + "description": "No search results found", + "done": True, + "error": True, + }, + } + ) + + return form_data + + +async def chat_image_generation_handler( + request: Request, form_data: dict, extra_params: dict, user +): + __event_emitter__ = extra_params["__event_emitter__"] + await __event_emitter__( + { + "type": "status", + "data": {"description": "Generating an image", "done": False}, + } + ) + + messages = form_data["messages"] + user_message = get_last_user_message(messages) + + prompt = user_message + negative_prompt = "" + + if request.app.state.config.ENABLE_IMAGE_PROMPT_GENERATION: + try: + res = await generate_image_prompt( + request, + { + "model": form_data["model"], + "messages": messages, + }, + user, + ) + + response = res["choices"][0]["message"]["content"] + + try: + bracket_start = response.find("{") + bracket_end = response.rfind("}") + 1 + + if bracket_start == -1 or bracket_end == -1: + raise Exception("No JSON object found in the response") + + response = response[bracket_start:bracket_end] + response = json.loads(response) + prompt = response.get("prompt", []) + except Exception as e: + prompt = user_message + + except Exception as e: + log.exception(e) + prompt = user_message + + system_message_content = "" + + try: + images = await image_generations( + request=request, + form_data=GenerateImageForm(**{"prompt": prompt}), + user=user, + ) + + await __event_emitter__( + { + "type": "status", + "data": {"description": "Generated an image", "done": True}, + } + ) + + for image in images: + await __event_emitter__( + { + "type": "message", + "data": {"content": f"![Generated Image]({image['url']})\n"}, + } + ) + + system_message_content = "User is shown the generated image, tell the user that the image has been generated" + except Exception as e: + log.exception(e) + await __event_emitter__( + { + "type": "status", + "data": { + "description": f"An error occurred while generating an image", + "done": True, + }, + } + ) + + system_message_content = "Unable to generate an image, tell the user that an error occurred" + + if system_message_content: + form_data["messages"] = add_or_update_system_message( + system_message_content, form_data["messages"] + ) + + return form_data + + +async def chat_completion_files_handler( + request: Request, body: dict, user: UserModel +) -> tuple[dict, dict[str, list]]: + sources = [] + + if files := body.get("metadata", {}).get("files", None): + queries = [] + try: + queries_response = await generate_queries( + request, + { + "model": body["model"], + "messages": body["messages"], + "type": "retrieval", + }, + user, + ) + queries_response = queries_response["choices"][0]["message"]["content"] + + try: + bracket_start = queries_response.find("{") + bracket_end = queries_response.rfind("}") + 1 + + if bracket_start == -1 or bracket_end == -1: + raise Exception("No JSON object found in the response") + + queries_response = queries_response[bracket_start:bracket_end] + queries_response = json.loads(queries_response) + except Exception as e: + queries_response = {"queries": [queries_response]} + + queries = queries_response.get("queries", []) + except: + pass + + if len(queries) == 0: + queries = [get_last_user_message(body["messages"])] + + try: + # Offload get_sources_from_files to a separate thread + loop = asyncio.get_running_loop() + with ThreadPoolExecutor() as executor: + sources = await loop.run_in_executor( + executor, + lambda: get_sources_from_files( + request=request, + files=files, + queries=queries, + embedding_function=lambda query: request.app.state.EMBEDDING_FUNCTION( + query, user=user + ), + k=request.app.state.config.TOP_K, + reranking_function=request.app.state.rf, + r=request.app.state.config.RELEVANCE_THRESHOLD, + hybrid_search=request.app.state.config.ENABLE_RAG_HYBRID_SEARCH, + full_context=request.app.state.config.RAG_FULL_CONTEXT, + ), + ) + except Exception as e: + log.exception(e) + + log.debug(f"rag_contexts:sources: {sources}") + + return body, {"sources": sources} + + +def apply_params_to_form_data(form_data, model): + params = form_data.pop("params", {}) + if model.get("ollama"): + form_data["options"] = params + + if "format" in params: + form_data["format"] = params["format"] + + if "keep_alive" in params: + form_data["keep_alive"] = params["keep_alive"] + else: + if "seed" in params: + form_data["seed"] = params["seed"] + + if "stop" in params: + form_data["stop"] = params["stop"] + + if "temperature" in params: + form_data["temperature"] = params["temperature"] + + if "max_tokens" in params: + form_data["max_tokens"] = params["max_tokens"] + + if "top_p" in params: + form_data["top_p"] = params["top_p"] + + if "frequency_penalty" in params: + form_data["frequency_penalty"] = params["frequency_penalty"] + + if "reasoning_effort" in params: + form_data["reasoning_effort"] = params["reasoning_effort"] + + return form_data + + +async def process_chat_payload(request, form_data, metadata, user, model): + + form_data = apply_params_to_form_data(form_data, model) + log.debug(f"form_data: {form_data}") + + event_emitter = get_event_emitter(metadata) + event_call = get_event_call(metadata) + + extra_params = { + "__event_emitter__": event_emitter, + "__event_call__": event_call, + "__user__": { + "id": user.id, + "email": user.email, + "name": user.name, + "role": user.role, + }, + "__metadata__": metadata, + "__request__": request, + "__model__": model, + } + + # Initialize events to store additional event to be sent to the client + # Initialize contexts and citation + if getattr(request.state, "direct", False) and hasattr(request.state, "model"): + models = { + request.state.model["id"]: request.state.model, + } + else: + models = request.app.state.MODELS + + task_model_id = get_task_model_id( + form_data["model"], + request.app.state.config.TASK_MODEL, + request.app.state.config.TASK_MODEL_EXTERNAL, + models, + ) + + events = [] + sources = [] + + user_message = get_last_user_message(form_data["messages"]) + model_knowledge = model.get("info", {}).get("meta", {}).get("knowledge", False) + + if model_knowledge: + await event_emitter( + { + "type": "status", + "data": { + "action": "knowledge_search", + "query": user_message, + "done": False, + }, + } + ) + + knowledge_files = [] + for item in model_knowledge: + if item.get("collection_name"): + knowledge_files.append( + { + "id": item.get("collection_name"), + "name": item.get("name"), + "legacy": True, + } + ) + elif item.get("collection_names"): + knowledge_files.append( + { + "name": item.get("name"), + "type": "collection", + "collection_names": item.get("collection_names"), + "legacy": True, + } + ) + else: + knowledge_files.append(item) + + files = form_data.get("files", []) + files.extend(knowledge_files) + form_data["files"] = files + + variables = form_data.pop("variables", None) + + # Process the form_data through the pipeline + try: + form_data = await process_pipeline_inlet_filter( + request, form_data, user, models + ) + except Exception as e: + raise e + + try: + form_data, flags = await process_filter_functions( + request=request, + filter_ids=get_sorted_filter_ids(model), + filter_type="inlet", + form_data=form_data, + extra_params=extra_params, + ) + except Exception as e: + raise Exception(f"Error: {e}") + + features = form_data.pop("features", None) + if features: + if "web_search" in features and features["web_search"]: + form_data = await chat_web_search_handler( + request, form_data, extra_params, user + ) + + if "image_generation" in features and features["image_generation"]: + form_data = await chat_image_generation_handler( + request, form_data, extra_params, user + ) + + if "code_interpreter" in features and features["code_interpreter"]: + form_data["messages"] = add_or_update_user_message( + ( + request.app.state.config.CODE_INTERPRETER_PROMPT_TEMPLATE + if request.app.state.config.CODE_INTERPRETER_PROMPT_TEMPLATE != "" + else DEFAULT_CODE_INTERPRETER_PROMPT + ), + form_data["messages"], + ) + + tool_ids = form_data.pop("tool_ids", None) + files = form_data.pop("files", None) + + # Remove files duplicates + if files: + files = list({json.dumps(f, sort_keys=True): f for f in files}.values()) + + metadata = { + **metadata, + "tool_ids": tool_ids, + "files": files, + } + form_data["metadata"] = metadata + + tool_ids = metadata.get("tool_ids", None) + log.debug(f"{tool_ids=}") + + if tool_ids: + # If tool_ids field is present, then get the tools + tools = get_tools( + request, + tool_ids, + user, + { + **extra_params, + "__model__": models[task_model_id], + "__messages__": form_data["messages"], + "__files__": metadata.get("files", []), + }, + ) + log.info(f"{tools=}") + + if metadata.get("function_calling") == "native": + # If the function calling is native, then call the tools function calling handler + metadata["tools"] = tools + form_data["tools"] = [ + {"type": "function", "function": tool.get("spec", {})} + for tool in tools.values() + ] + else: + # If the function calling is not native, then call the tools function calling handler + try: + form_data, flags = await chat_completion_tools_handler( + request, form_data, user, models, tools + ) + sources.extend(flags.get("sources", [])) + + except Exception as e: + log.exception(e) + + try: + form_data, flags = await chat_completion_files_handler(request, form_data, user) + sources.extend(flags.get("sources", [])) + except Exception as e: + log.exception(e) + + # If context is not empty, insert it into the messages + if len(sources) > 0: + context_string = "" + for source_idx, source in enumerate(sources): + if "document" in source: + for doc_idx, doc_context in enumerate(source["document"]): + context_string += f"{source_idx}{doc_context}\n" + + context_string = context_string.strip() + prompt = get_last_user_message(form_data["messages"]) + + if prompt is None: + raise Exception("No user message found") + if ( + request.app.state.config.RELEVANCE_THRESHOLD == 0 + and context_string.strip() == "" + ): + log.debug( + f"With a 0 relevancy threshold for RAG, the context cannot be empty" + ) + + # Workaround for Ollama 2.0+ system prompt issue + # TODO: replace with add_or_update_system_message + if model.get("owned_by") == "ollama": + form_data["messages"] = prepend_to_first_user_message_content( + rag_template( + request.app.state.config.RAG_TEMPLATE, context_string, prompt + ), + form_data["messages"], + ) + else: + form_data["messages"] = add_or_update_system_message( + rag_template( + request.app.state.config.RAG_TEMPLATE, context_string, prompt + ), + form_data["messages"], + ) + + # If there are citations, add them to the data_items + sources = [source for source in sources if source.get("source", {}).get("name", "")] + + if len(sources) > 0: + events.append({"sources": sources}) + + if model_knowledge: + await event_emitter( + { + "type": "status", + "data": { + "action": "knowledge_search", + "query": user_message, + "done": True, + "hidden": True, + }, + } + ) + + return form_data, metadata, events + + +async def process_chat_response( + request, response, form_data, user, events, metadata, tasks +): + async def background_tasks_handler(): + message_map = Chats.get_messages_by_chat_id(metadata["chat_id"]) + message = message_map.get(metadata["message_id"]) if message_map else None + + if message: + messages = get_message_list(message_map, message.get("id")) + + if tasks and messages: + if TASKS.TITLE_GENERATION in tasks: + if tasks[TASKS.TITLE_GENERATION]: + res = await generate_title( + request, + { + "model": message["model"], + "messages": messages, + "chat_id": metadata["chat_id"], + }, + user, + ) + + if res and isinstance(res, dict): + if len(res.get("choices", [])) == 1: + title_string = ( + res.get("choices", [])[0] + .get("message", {}) + .get("content", message.get("content", "New Chat")) + ) + else: + title_string = "" + + title_string = title_string[ + title_string.find("{") : title_string.rfind("}") + 1 + ] + + try: + title = json.loads(title_string).get( + "title", "New Chat" + ) + except Exception as e: + title = "" + + if not title: + title = messages[0].get("content", "New Chat") + + Chats.update_chat_title_by_id(metadata["chat_id"], title) + + await event_emitter( + { + "type": "chat:title", + "data": title, + } + ) + elif len(messages) == 2: + title = messages[0].get("content", "New Chat") + + Chats.update_chat_title_by_id(metadata["chat_id"], title) + + await event_emitter( + { + "type": "chat:title", + "data": message.get("content", "New Chat"), + } + ) + + if TASKS.TAGS_GENERATION in tasks and tasks[TASKS.TAGS_GENERATION]: + res = await generate_chat_tags( + request, + { + "model": message["model"], + "messages": messages, + "chat_id": metadata["chat_id"], + }, + user, + ) + + if res and isinstance(res, dict): + if len(res.get("choices", [])) == 1: + tags_string = ( + res.get("choices", [])[0] + .get("message", {}) + .get("content", "") + ) + else: + tags_string = "" + + tags_string = tags_string[ + tags_string.find("{") : tags_string.rfind("}") + 1 + ] + + try: + tags = json.loads(tags_string).get("tags", []) + Chats.update_chat_tags_by_id( + metadata["chat_id"], tags, user + ) + + await event_emitter( + { + "type": "chat:tags", + "data": tags, + } + ) + except Exception as e: + pass + + event_emitter = None + event_caller = None + if ( + "session_id" in metadata + and metadata["session_id"] + and "chat_id" in metadata + and metadata["chat_id"] + and "message_id" in metadata + and metadata["message_id"] + ): + event_emitter = get_event_emitter(metadata) + event_caller = get_event_call(metadata) + + # Non-streaming response + if not isinstance(response, StreamingResponse): + if event_emitter: + if "selected_model_id" in response: + Chats.upsert_message_to_chat_by_id_and_message_id( + metadata["chat_id"], + metadata["message_id"], + { + "selectedModelId": response["selected_model_id"], + }, + ) + + if response.get("choices", [])[0].get("message", {}).get("content"): + content = response["choices"][0]["message"]["content"] + + if content: + + await event_emitter( + { + "type": "chat:completion", + "data": response, + } + ) + + title = Chats.get_chat_title_by_id(metadata["chat_id"]) + + await event_emitter( + { + "type": "chat:completion", + "data": { + "done": True, + "content": content, + "title": title, + }, + } + ) + + # Save message in the database + Chats.upsert_message_to_chat_by_id_and_message_id( + metadata["chat_id"], + metadata["message_id"], + { + "content": content, + }, + ) + + # Send a webhook notification if the user is not active + if get_active_status_by_user_id(user.id) is None: + webhook_url = Users.get_user_webhook_url_by_id(user.id) + if webhook_url: + post_webhook( + request.app.state.WEBUI_NAME, + webhook_url, + f"{title} - {request.app.state.config.WEBUI_URL}/c/{metadata['chat_id']}\n\n{content}", + { + "action": "chat", + "message": content, + "title": title, + "url": f"{request.app.state.config.WEBUI_URL}/c/{metadata['chat_id']}", + }, + ) + + await background_tasks_handler() + + return response + else: + return response + + # Non standard response + if not any( + content_type in response.headers["Content-Type"] + for content_type in ["text/event-stream", "application/x-ndjson"] + ): + return response + + extra_params = { + "__event_emitter__": event_emitter, + "__event_call__": event_caller, + "__user__": { + "id": user.id, + "email": user.email, + "name": user.name, + "role": user.role, + }, + "__metadata__": metadata, + "__request__": request, + "__model__": metadata.get("model"), + } + filter_ids = get_sorted_filter_ids(form_data.get("model")) + + # Streaming response + if event_emitter and event_caller: + task_id = str(uuid4()) # Create a unique task ID. + model_id = form_data.get("model", "") + + Chats.upsert_message_to_chat_by_id_and_message_id( + metadata["chat_id"], + metadata["message_id"], + { + "model": model_id, + }, + ) + + def split_content_and_whitespace(content): + content_stripped = content.rstrip() + original_whitespace = ( + content[len(content_stripped) :] + if len(content) > len(content_stripped) + else "" + ) + return content_stripped, original_whitespace + + def is_opening_code_block(content): + backtick_segments = content.split("```") + # Even number of segments means the last backticks are opening a new block + return len(backtick_segments) > 1 and len(backtick_segments) % 2 == 0 + + # Handle as a background task + async def post_response_handler(response, events): + def serialize_content_blocks(content_blocks, raw=False): + content = "" + + for block in content_blocks: + if block["type"] == "text": + content = f"{content}{block['content'].strip()}\n" + elif block["type"] == "tool_calls": + attributes = block.get("attributes", {}) + + block_content = block.get("content", []) + results = block.get("results", []) + + if results: + + result_display_content = "" + + for result in results: + tool_call_id = result.get("tool_call_id", "") + tool_name = "" + + for tool_call in block_content: + if tool_call.get("id", "") == tool_call_id: + tool_name = tool_call.get("function", {}).get( + "name", "" + ) + break + + result_display_content = f"{result_display_content}\n> {tool_name}: {result.get('content', '')}" + + if not raw: + content = f'{content}\n
        \nTool Executed\n{result_display_content}\n
        \n' + else: + tool_calls_display_content = "" + + for tool_call in block_content: + tool_calls_display_content = f"{tool_calls_display_content}\n> Executing {tool_call.get('function', {}).get('name', '')}" + + if not raw: + content = f'{content}\n
        \nTool Executing...\n{tool_calls_display_content}\n
        \n' + + elif block["type"] == "reasoning": + reasoning_display_content = "\n".join( + (f"> {line}" if not line.startswith(">") else line) + for line in block["content"].splitlines() + ) + + reasoning_duration = block.get("duration", None) + + if reasoning_duration is not None: + if raw: + content = f'{content}\n<{block["start_tag"]}>{block["content"]}<{block["end_tag"]}>\n' + else: + content = f'{content}\n
        \nThought for {reasoning_duration} seconds\n{reasoning_display_content}\n
        \n' + else: + if raw: + content = f'{content}\n<{block["start_tag"]}>{block["content"]}<{block["end_tag"]}>\n' + else: + content = f'{content}\n
        \nThinking…\n{reasoning_display_content}\n
        \n' + + elif block["type"] == "code_interpreter": + attributes = block.get("attributes", {}) + output = block.get("output", None) + lang = attributes.get("lang", "") + + content_stripped, original_whitespace = ( + split_content_and_whitespace(content) + ) + if is_opening_code_block(content_stripped): + # Remove trailing backticks that would open a new block + content = ( + content_stripped.rstrip("`").rstrip() + + original_whitespace + ) + else: + # Keep content as is - either closing backticks or no backticks + content = content_stripped + original_whitespace + + if output: + output = html.escape(json.dumps(output)) + + if raw: + content = f'{content}\n\n{block["content"]}\n\n```output\n{output}\n```\n' + else: + content = f'{content}\n
        \nAnalyzed\n```{lang}\n{block["content"]}\n```\n
        \n' + else: + if raw: + content = f'{content}\n\n{block["content"]}\n\n' + else: + content = f'{content}\n
        \nAnalyzing...\n```{lang}\n{block["content"]}\n```\n
        \n' + + else: + block_content = str(block["content"]).strip() + content = f"{content}{block['type']}: {block_content}\n" + + return content.strip() + + def convert_content_blocks_to_messages(content_blocks): + messages = [] + + temp_blocks = [] + for idx, block in enumerate(content_blocks): + if block["type"] == "tool_calls": + messages.append( + { + "role": "assistant", + "content": serialize_content_blocks(temp_blocks), + "tool_calls": block.get("content"), + } + ) + + results = block.get("results", []) + + for result in results: + messages.append( + { + "role": "tool", + "tool_call_id": result["tool_call_id"], + "content": result["content"], + } + ) + temp_blocks = [] + else: + temp_blocks.append(block) + + if temp_blocks: + content = serialize_content_blocks(temp_blocks) + if content: + messages.append( + { + "role": "assistant", + "content": content, + } + ) + + return messages + + def tag_content_handler(content_type, tags, content, content_blocks): + end_flag = False + + def extract_attributes(tag_content): + """Extract attributes from a tag if they exist.""" + attributes = {} + if not tag_content: # Ensure tag_content is not None + return attributes + # Match attributes in the format: key="value" (ignores single quotes for simplicity) + matches = re.findall(r'(\w+)\s*=\s*"([^"]+)"', tag_content) + for key, value in matches: + attributes[key] = value + return attributes + + if content_blocks[-1]["type"] == "text": + for start_tag, end_tag in tags: + # Match start tag e.g., or + start_tag_pattern = rf"<{re.escape(start_tag)}(\s.*?)?>" + match = re.search(start_tag_pattern, content) + if match: + attr_content = ( + match.group(1) if match.group(1) else "" + ) # Ensure it's not None + attributes = extract_attributes( + attr_content + ) # Extract attributes safely + + # Capture everything before and after the matched tag + before_tag = content[ + : match.start() + ] # Content before opening tag + after_tag = content[ + match.end() : + ] # Content after opening tag + + # Remove the start tag and after from the currently handling text block + content_blocks[-1]["content"] = content_blocks[-1][ + "content" + ].replace(match.group(0) + after_tag, "") + + if before_tag: + content_blocks[-1]["content"] = before_tag + + if not content_blocks[-1]["content"]: + content_blocks.pop() + + # Append the new block + content_blocks.append( + { + "type": content_type, + "start_tag": start_tag, + "end_tag": end_tag, + "attributes": attributes, + "content": "", + "started_at": time.time(), + } + ) + + if after_tag: + content_blocks[-1]["content"] = after_tag + + break + elif content_blocks[-1]["type"] == content_type: + start_tag = content_blocks[-1]["start_tag"] + end_tag = content_blocks[-1]["end_tag"] + # Match end tag e.g., + end_tag_pattern = rf"<{re.escape(end_tag)}>" + + # Check if the content has the end tag + if re.search(end_tag_pattern, content): + end_flag = True + + block_content = content_blocks[-1]["content"] + # Strip start and end tags from the content + start_tag_pattern = rf"<{re.escape(start_tag)}(.*?)>" + block_content = re.sub( + start_tag_pattern, "", block_content + ).strip() + + end_tag_regex = re.compile(end_tag_pattern, re.DOTALL) + split_content = end_tag_regex.split(block_content, maxsplit=1) + + # Content inside the tag + block_content = ( + split_content[0].strip() if split_content else "" + ) + + # Leftover content (everything after ``) + leftover_content = ( + split_content[1].strip() if len(split_content) > 1 else "" + ) + + if block_content: + content_blocks[-1]["content"] = block_content + content_blocks[-1]["ended_at"] = time.time() + content_blocks[-1]["duration"] = int( + content_blocks[-1]["ended_at"] + - content_blocks[-1]["started_at"] + ) + + # Reset the content_blocks by appending a new text block + if content_type != "code_interpreter": + if leftover_content: + + content_blocks.append( + { + "type": "text", + "content": leftover_content, + } + ) + else: + content_blocks.append( + { + "type": "text", + "content": "", + } + ) + + else: + # Remove the block if content is empty + content_blocks.pop() + + if leftover_content: + content_blocks.append( + { + "type": "text", + "content": leftover_content, + } + ) + else: + content_blocks.append( + { + "type": "text", + "content": "", + } + ) + + # Clean processed content + content = re.sub( + rf"<{re.escape(start_tag)}(.*?)>(.|\n)*?<{re.escape(end_tag)}>", + "", + content, + flags=re.DOTALL, + ) + + return content, content_blocks, end_flag + + message = Chats.get_message_by_id_and_message_id( + metadata["chat_id"], metadata["message_id"] + ) + + tool_calls = [] + + last_assistant_message = None + try: + if form_data["messages"][-1]["role"] == "assistant": + last_assistant_message = get_last_assistant_message( + form_data["messages"] + ) + except Exception as e: + pass + + content = ( + message.get("content", "") + if message + else last_assistant_message if last_assistant_message else "" + ) + + content_blocks = [ + { + "type": "text", + "content": content, + } + ] + + # We might want to disable this by default + DETECT_REASONING = True + DETECT_SOLUTION = True + DETECT_CODE_INTERPRETER = metadata.get("features", {}).get( + "code_interpreter", False + ) + + reasoning_tags = [ + ("think", "/think"), + ("thinking", "/thinking"), + ("reason", "/reason"), + ("reasoning", "/reasoning"), + ("thought", "/thought"), + ("Thought", "/Thought"), + ("|begin_of_thought|", "|end_of_thought|"), + ] + + code_interpreter_tags = [("code_interpreter", "/code_interpreter")] + + solution_tags = [("|begin_of_solution|", "|end_of_solution|")] + + try: + for event in events: + await event_emitter( + { + "type": "chat:completion", + "data": event, + } + ) + + # Save message in the database + Chats.upsert_message_to_chat_by_id_and_message_id( + metadata["chat_id"], + metadata["message_id"], + { + **event, + }, + ) + + async def stream_body_handler(response): + nonlocal content + nonlocal content_blocks + + response_tool_calls = [] + + async for line in response.body_iterator: + line = line.decode("utf-8") if isinstance(line, bytes) else line + data = line + + # Skip empty lines + if not data.strip(): + continue + + # "data:" is the prefix for each event + if not data.startswith("data:"): + continue + + # Remove the prefix + data = data[len("data:") :].strip() + + try: + data = json.loads(data) + + data, _ = await process_filter_functions( + request=request, + filter_ids=filter_ids, + filter_type="stream", + form_data=data, + extra_params=extra_params, + ) + + if data: + if "selected_model_id" in data: + model_id = data["selected_model_id"] + Chats.upsert_message_to_chat_by_id_and_message_id( + metadata["chat_id"], + metadata["message_id"], + { + "selectedModelId": model_id, + }, + ) + else: + choices = data.get("choices", []) + if not choices: + usage = data.get("usage", {}) + if usage: + await event_emitter( + { + "type": "chat:completion", + "data": { + "usage": usage, + }, + } + ) + continue + + delta = choices[0].get("delta", {}) + delta_tool_calls = delta.get("tool_calls", None) + + if delta_tool_calls: + for delta_tool_call in delta_tool_calls: + tool_call_index = delta_tool_call.get( + "index" + ) + + if tool_call_index is not None: + if ( + len(response_tool_calls) + <= tool_call_index + ): + response_tool_calls.append( + delta_tool_call + ) + else: + delta_name = delta_tool_call.get( + "function", {} + ).get("name") + delta_arguments = ( + delta_tool_call.get( + "function", {} + ).get("arguments") + ) + + if delta_name: + response_tool_calls[ + tool_call_index + ]["function"][ + "name" + ] += delta_name + + if delta_arguments: + response_tool_calls[ + tool_call_index + ]["function"][ + "arguments" + ] += delta_arguments + + value = delta.get("content") + + if value: + content = f"{content}{value}" + + if not content_blocks: + content_blocks.append( + { + "type": "text", + "content": "", + } + ) + + content_blocks[-1]["content"] = ( + content_blocks[-1]["content"] + value + ) + + if DETECT_REASONING: + content, content_blocks, _ = ( + tag_content_handler( + "reasoning", + reasoning_tags, + content, + content_blocks, + ) + ) + + if DETECT_CODE_INTERPRETER: + content, content_blocks, end = ( + tag_content_handler( + "code_interpreter", + code_interpreter_tags, + content, + content_blocks, + ) + ) + + if end: + break + + if DETECT_SOLUTION: + content, content_blocks, _ = ( + tag_content_handler( + "solution", + solution_tags, + content, + content_blocks, + ) + ) + + if ENABLE_REALTIME_CHAT_SAVE: + # Save message in the database + Chats.upsert_message_to_chat_by_id_and_message_id( + metadata["chat_id"], + metadata["message_id"], + { + "content": serialize_content_blocks( + content_blocks + ), + }, + ) + else: + data = { + "content": serialize_content_blocks( + content_blocks + ), + } + + await event_emitter( + { + "type": "chat:completion", + "data": data, + } + ) + except Exception as e: + done = "data: [DONE]" in line + if done: + pass + else: + log.debug("Error: ", e) + continue + + if content_blocks: + # Clean up the last text block + if content_blocks[-1]["type"] == "text": + content_blocks[-1]["content"] = content_blocks[-1][ + "content" + ].strip() + + if not content_blocks[-1]["content"]: + content_blocks.pop() + + if not content_blocks: + content_blocks.append( + { + "type": "text", + "content": "", + } + ) + + if response_tool_calls: + tool_calls.append(response_tool_calls) + + if response.background: + await response.background() + + await stream_body_handler(response) + + MAX_TOOL_CALL_RETRIES = 5 + tool_call_retries = 0 + + while len(tool_calls) > 0 and tool_call_retries < MAX_TOOL_CALL_RETRIES: + tool_call_retries += 1 + + response_tool_calls = tool_calls.pop(0) + + content_blocks.append( + { + "type": "tool_calls", + "content": response_tool_calls, + } + ) + + await event_emitter( + { + "type": "chat:completion", + "data": { + "content": serialize_content_blocks(content_blocks), + }, + } + ) + + tools = metadata.get("tools", {}) + + results = [] + for tool_call in response_tool_calls: + tool_call_id = tool_call.get("id", "") + tool_name = tool_call.get("function", {}).get("name", "") + + tool_function_params = {} + try: + # json.loads cannot be used because some models do not produce valid JSON + tool_function_params = ast.literal_eval( + tool_call.get("function", {}).get("arguments", "{}") + ) + except Exception as e: + log.debug(e) + + tool_result = None + + if tool_name in tools: + tool = tools[tool_name] + spec = tool.get("spec", {}) + + try: + required_params = spec.get("parameters", {}).get( + "required", [] + ) + tool_function = tool["callable"] + tool_function_params = { + k: v + for k, v in tool_function_params.items() + if k in required_params + } + tool_result = await tool_function( + **tool_function_params + ) + except Exception as e: + tool_result = str(e) + + results.append( + { + "tool_call_id": tool_call_id, + "content": tool_result, + } + ) + + content_blocks[-1]["results"] = results + + content_blocks.append( + { + "type": "text", + "content": "", + } + ) + + await event_emitter( + { + "type": "chat:completion", + "data": { + "content": serialize_content_blocks(content_blocks), + }, + } + ) + + try: + res = await generate_chat_completion( + request, + { + "model": model_id, + "stream": True, + "tools": form_data["tools"], + "messages": [ + *form_data["messages"], + *convert_content_blocks_to_messages(content_blocks), + ], + }, + user, + ) + + if isinstance(res, StreamingResponse): + await stream_body_handler(res) + else: + break + except Exception as e: + log.debug(e) + break + + if DETECT_CODE_INTERPRETER: + MAX_RETRIES = 5 + retries = 0 + + while ( + content_blocks[-1]["type"] == "code_interpreter" + and retries < MAX_RETRIES + ): + await event_emitter( + { + "type": "chat:completion", + "data": { + "content": serialize_content_blocks(content_blocks), + }, + } + ) + + retries += 1 + log.debug(f"Attempt count: {retries}") + + output = "" + try: + if content_blocks[-1]["attributes"].get("type") == "code": + code = content_blocks[-1]["content"] + + if ( + request.app.state.config.CODE_INTERPRETER_ENGINE + == "pyodide" + ): + output = await event_caller( + { + "type": "execute:python", + "data": { + "id": str(uuid4()), + "code": code, + "session_id": metadata.get( + "session_id", None + ), + }, + } + ) + elif ( + request.app.state.config.CODE_INTERPRETER_ENGINE + == "jupyter" + ): + output = await execute_code_jupyter( + request.app.state.config.CODE_INTERPRETER_JUPYTER_URL, + code, + ( + request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_TOKEN + if request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH + == "token" + else None + ), + ( + request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD + if request.app.state.config.CODE_INTERPRETER_JUPYTER_AUTH + == "password" + else None + ), + request.app.state.config.CODE_INTERPRETER_JUPYTER_TIMEOUT, + ) + else: + output = { + "stdout": "Code interpreter engine not configured." + } + + log.debug(f"Code interpreter output: {output}") + + if isinstance(output, dict): + stdout = output.get("stdout", "") + + if isinstance(stdout, str): + stdoutLines = stdout.split("\n") + for idx, line in enumerate(stdoutLines): + if "data:image/png;base64" in line: + id = str(uuid4()) + + # ensure the path exists + os.makedirs( + os.path.join(CACHE_DIR, "images"), + exist_ok=True, + ) + + image_path = os.path.join( + CACHE_DIR, + f"images/{id}.png", + ) + + with open(image_path, "wb") as f: + f.write( + base64.b64decode( + line.split(",")[1] + ) + ) + + stdoutLines[idx] = ( + f"![Output Image {idx}](/cache/images/{id}.png)" + ) + + output["stdout"] = "\n".join(stdoutLines) + + result = output.get("result", "") + + if isinstance(result, str): + resultLines = result.split("\n") + for idx, line in enumerate(resultLines): + if "data:image/png;base64" in line: + id = str(uuid4()) + + # ensure the path exists + os.makedirs( + os.path.join(CACHE_DIR, "images"), + exist_ok=True, + ) + + image_path = os.path.join( + CACHE_DIR, + f"images/{id}.png", + ) + + with open(image_path, "wb") as f: + f.write( + base64.b64decode( + line.split(",")[1] + ) + ) + + resultLines[idx] = ( + f"![Output Image {idx}](/cache/images/{id}.png)" + ) + + output["result"] = "\n".join(resultLines) + except Exception as e: + output = str(e) + + content_blocks[-1]["output"] = output + + content_blocks.append( + { + "type": "text", + "content": "", + } + ) + + await event_emitter( + { + "type": "chat:completion", + "data": { + "content": serialize_content_blocks(content_blocks), + }, + } + ) + + log.info(f"content_blocks={content_blocks}") + log.info( + f"serialize_content_blocks={serialize_content_blocks(content_blocks)}" + ) + + try: + res = await generate_chat_completion( + request, + { + "model": model_id, + "stream": True, + "messages": [ + *form_data["messages"], + { + "role": "assistant", + "content": serialize_content_blocks( + content_blocks, raw=True + ), + }, + ], + }, + user, + ) + + if isinstance(res, StreamingResponse): + await stream_body_handler(res) + else: + break + except Exception as e: + log.debug(e) + break + + title = Chats.get_chat_title_by_id(metadata["chat_id"]) + data = { + "done": True, + "content": serialize_content_blocks(content_blocks), + "title": title, + } + + if not ENABLE_REALTIME_CHAT_SAVE: + # Save message in the database + Chats.upsert_message_to_chat_by_id_and_message_id( + metadata["chat_id"], + metadata["message_id"], + { + "content": serialize_content_blocks(content_blocks), + }, + ) + + # Send a webhook notification if the user is not active + if get_active_status_by_user_id(user.id) is None: + webhook_url = Users.get_user_webhook_url_by_id(user.id) + if webhook_url: + post_webhook( + request.app.state.WEBUI_NAME, + webhook_url, + f"{title} - {request.app.state.config.WEBUI_URL}/c/{metadata['chat_id']}\n\n{content}", + { + "action": "chat", + "message": content, + "title": title, + "url": f"{request.app.state.config.WEBUI_URL}/c/{metadata['chat_id']}", + }, + ) + + await event_emitter( + { + "type": "chat:completion", + "data": data, + } + ) + + await background_tasks_handler() + except asyncio.CancelledError: + log.warning("Task was cancelled!") + await event_emitter({"type": "task-cancelled"}) + + if not ENABLE_REALTIME_CHAT_SAVE: + # Save message in the database + Chats.upsert_message_to_chat_by_id_and_message_id( + metadata["chat_id"], + metadata["message_id"], + { + "content": serialize_content_blocks(content_blocks), + }, + ) + + if response.background is not None: + await response.background() + + # background_tasks.add_task(post_response_handler, response, events) + task_id, _ = create_task(post_response_handler(response, events)) + return {"status": True, "task_id": task_id} + + else: + # Fallback to the original response + async def stream_wrapper(original_generator, events): + def wrap_item(item): + return f"data: {item}\n\n" + + for event in events: + event, _ = await process_filter_functions( + request=request, + filter_ids=filter_ids, + filter_type="stream", + form_data=event, + extra_params=extra_params, + ) + + if event: + yield wrap_item(json.dumps(event)) + + async for data in original_generator: + data, _ = await process_filter_functions( + request=request, + filter_ids=filter_ids, + filter_type="stream", + form_data=data, + extra_params=extra_params, + ) + + if data: + yield data + + return StreamingResponse( + stream_wrapper(response.body_iterator, events), + headers=dict(response.headers), + background=response.background, + ) diff --git a/backend/open_webui/utils/misc.py b/backend/open_webui/utils/misc.py new file mode 100644 index 0000000..8f867ba --- /dev/null +++ b/backend/open_webui/utils/misc.py @@ -0,0 +1,452 @@ +import hashlib +import re +import time +import uuid +import logging +from datetime import timedelta +from pathlib import Path +from typing import Callable, Optional + + +import collections.abc +from open_webui.env import SRC_LOG_LEVELS + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MAIN"]) + + +def deep_update(d, u): + for k, v in u.items(): + if isinstance(v, collections.abc.Mapping): + d[k] = deep_update(d.get(k, {}), v) + else: + d[k] = v + return d + + +def get_message_list(messages, message_id): + """ + Reconstructs a list of messages in order up to the specified message_id. + + :param message_id: ID of the message to reconstruct the chain + :param messages: Message history dict containing all messages + :return: List of ordered messages starting from the root to the given message + """ + + # Find the message by its id + current_message = messages.get(message_id) + + if not current_message: + return None + + # Reconstruct the chain by following the parentId links + message_list = [] + + while current_message: + message_list.insert( + 0, current_message + ) # Insert the message at the beginning of the list + parent_id = current_message["parentId"] + current_message = messages.get(parent_id) if parent_id else None + + return message_list + + +def get_messages_content(messages: list[dict]) -> str: + return "\n".join( + [ + f"{message['role'].upper()}: {get_content_from_message(message)}" + for message in messages + ] + ) + + +def get_last_user_message_item(messages: list[dict]) -> Optional[dict]: + for message in reversed(messages): + if message["role"] == "user": + return message + return None + + +def get_content_from_message(message: dict) -> Optional[str]: + if isinstance(message["content"], list): + for item in message["content"]: + if item["type"] == "text": + return item["text"] + else: + return message["content"] + return None + + +def get_last_user_message(messages: list[dict]) -> Optional[str]: + message = get_last_user_message_item(messages) + if message is None: + return None + return get_content_from_message(message) + + +def get_last_assistant_message_item(messages: list[dict]) -> Optional[dict]: + for message in reversed(messages): + if message["role"] == "assistant": + return message + return None + + +def get_last_assistant_message(messages: list[dict]) -> Optional[str]: + for message in reversed(messages): + if message["role"] == "assistant": + return get_content_from_message(message) + return None + + +def get_system_message(messages: list[dict]) -> Optional[dict]: + for message in messages: + if message["role"] == "system": + return message + return None + + +def remove_system_message(messages: list[dict]) -> list[dict]: + return [message for message in messages if message["role"] != "system"] + + +def pop_system_message(messages: list[dict]) -> tuple[Optional[dict], list[dict]]: + return get_system_message(messages), remove_system_message(messages) + + +def prepend_to_first_user_message_content( + content: str, messages: list[dict] +) -> list[dict]: + for message in messages: + if message["role"] == "user": + if isinstance(message["content"], list): + for item in message["content"]: + if item["type"] == "text": + item["text"] = f"{content}\n{item['text']}" + else: + message["content"] = f"{content}\n{message['content']}" + break + return messages + + +def add_or_update_system_message(content: str, messages: list[dict]): + """ + Adds a new system message at the beginning of the messages list + or updates the existing system message at the beginning. + + :param msg: The message to be added or appended. + :param messages: The list of message dictionaries. + :return: The updated list of message dictionaries. + """ + + if messages and messages[0].get("role") == "system": + messages[0]["content"] = f"{content}\n{messages[0]['content']}" + else: + # Insert at the beginning + messages.insert(0, {"role": "system", "content": content}) + + return messages + + +def add_or_update_user_message(content: str, messages: list[dict]): + """ + Adds a new user message at the end of the messages list + or updates the existing user message at the end. + + :param msg: The message to be added or appended. + :param messages: The list of message dictionaries. + :return: The updated list of message dictionaries. + """ + + if messages and messages[-1].get("role") == "user": + messages[-1]["content"] = f"{messages[-1]['content']}\n{content}" + else: + # Insert at the end + messages.append({"role": "user", "content": content}) + + return messages + + +def append_or_update_assistant_message(content: str, messages: list[dict]): + """ + Adds a new assistant message at the end of the messages list + or updates the existing assistant message at the end. + + :param msg: The message to be added or appended. + :param messages: The list of message dictionaries. + :return: The updated list of message dictionaries. + """ + + if messages and messages[-1].get("role") == "assistant": + messages[-1]["content"] = f"{messages[-1]['content']}\n{content}" + else: + # Insert at the end + messages.append({"role": "assistant", "content": content}) + + return messages + + +def openai_chat_message_template(model: str): + return { + "id": f"{model}-{str(uuid.uuid4())}", + "created": int(time.time()), + "model": model, + "choices": [{"index": 0, "logprobs": None, "finish_reason": None}], + } + + +def openai_chat_chunk_message_template( + model: str, + content: Optional[str] = None, + tool_calls: Optional[list[dict]] = None, + usage: Optional[dict] = None, +) -> dict: + template = openai_chat_message_template(model) + template["object"] = "chat.completion.chunk" + + template["choices"][0]["index"] = 0 + template["choices"][0]["delta"] = {} + + if content: + template["choices"][0]["delta"]["content"] = content + + if tool_calls: + template["choices"][0]["delta"]["tool_calls"] = tool_calls + + if not content and not tool_calls: + template["choices"][0]["finish_reason"] = "stop" + + if usage: + template["usage"] = usage + return template + + +def openai_chat_completion_message_template( + model: str, + message: Optional[str] = None, + tool_calls: Optional[list[dict]] = None, + usage: Optional[dict] = None, +) -> dict: + template = openai_chat_message_template(model) + template["object"] = "chat.completion" + if message is not None: + template["choices"][0]["message"] = { + "content": message, + "role": "assistant", + **({"tool_calls": tool_calls} if tool_calls else {}), + } + + template["choices"][0]["finish_reason"] = "stop" + + if usage: + template["usage"] = usage + return template + + +def get_gravatar_url(email): + # Trim leading and trailing whitespace from + # an email address and force all characters + # to lower case + address = str(email).strip().lower() + + # Create a SHA256 hash of the final string + hash_object = hashlib.sha256(address.encode()) + hash_hex = hash_object.hexdigest() + + # Grab the actual image URL + return f"https://www.gravatar.com/avatar/{hash_hex}?d=mp" + + +def calculate_sha256(file_path, chunk_size): + # Compute SHA-256 hash of a file efficiently in chunks + sha256 = hashlib.sha256() + with open(file_path, "rb") as f: + while chunk := f.read(chunk_size): + sha256.update(chunk) + return sha256.hexdigest() + + +def calculate_sha256_string(string): + # Create a new SHA-256 hash object + sha256_hash = hashlib.sha256() + # Update the hash object with the bytes of the input string + sha256_hash.update(string.encode("utf-8")) + # Get the hexadecimal representation of the hash + hashed_string = sha256_hash.hexdigest() + return hashed_string + + +def validate_email_format(email: str) -> bool: + if email.endswith("@localhost"): + return True + + return bool(re.match(r"[^@]+@[^@]+\.[^@]+", email)) + + +def sanitize_filename(file_name): + # Convert to lowercase + lower_case_file_name = file_name.lower() + + # Remove special characters using regular expression + sanitized_file_name = re.sub(r"[^\w\s]", "", lower_case_file_name) + + # Replace spaces with dashes + final_file_name = re.sub(r"\s+", "-", sanitized_file_name) + + return final_file_name + + +def extract_folders_after_data_docs(path): + # Convert the path to a Path object if it's not already + path = Path(path) + + # Extract parts of the path + parts = path.parts + + # Find the index of '/data/docs' in the path + try: + index_data_docs = parts.index("data") + 1 + index_docs = parts.index("docs", index_data_docs) + 1 + except ValueError: + return [] + + # Exclude the filename and accumulate folder names + tags = [] + + folders = parts[index_docs:-1] + for idx, _ in enumerate(folders): + tags.append("/".join(folders[: idx + 1])) + + return tags + + +def parse_duration(duration: str) -> Optional[timedelta]: + if duration == "-1" or duration == "0": + return None + + # Regular expression to find number and unit pairs + pattern = r"(-?\d+(\.\d+)?)(ms|s|m|h|d|w)" + matches = re.findall(pattern, duration) + + if not matches: + raise ValueError("Invalid duration string") + + total_duration = timedelta() + + for number, _, unit in matches: + number = float(number) + if unit == "ms": + total_duration += timedelta(milliseconds=number) + elif unit == "s": + total_duration += timedelta(seconds=number) + elif unit == "m": + total_duration += timedelta(minutes=number) + elif unit == "h": + total_duration += timedelta(hours=number) + elif unit == "d": + total_duration += timedelta(days=number) + elif unit == "w": + total_duration += timedelta(weeks=number) + + return total_duration + + +def parse_ollama_modelfile(model_text): + parameters_meta = { + "mirostat": int, + "mirostat_eta": float, + "mirostat_tau": float, + "num_ctx": int, + "repeat_last_n": int, + "repeat_penalty": float, + "temperature": float, + "seed": int, + "tfs_z": float, + "num_predict": int, + "top_k": int, + "top_p": float, + "num_keep": int, + "typical_p": float, + "presence_penalty": float, + "frequency_penalty": float, + "penalize_newline": bool, + "numa": bool, + "num_batch": int, + "num_gpu": int, + "main_gpu": int, + "low_vram": bool, + "f16_kv": bool, + "vocab_only": bool, + "use_mmap": bool, + "use_mlock": bool, + "num_thread": int, + } + + data = {"base_model_id": None, "params": {}} + + # Parse base model + base_model_match = re.search( + r"^FROM\s+(\w+)", model_text, re.MULTILINE | re.IGNORECASE + ) + if base_model_match: + data["base_model_id"] = base_model_match.group(1) + + # Parse template + template_match = re.search( + r'TEMPLATE\s+"""(.+?)"""', model_text, re.DOTALL | re.IGNORECASE + ) + if template_match: + data["params"] = {"template": template_match.group(1).strip()} + + # Parse stops + stops = re.findall(r'PARAMETER stop "(.*?)"', model_text, re.IGNORECASE) + if stops: + data["params"]["stop"] = stops + + # Parse other parameters from the provided list + for param, param_type in parameters_meta.items(): + param_match = re.search(rf"PARAMETER {param} (.+)", model_text, re.IGNORECASE) + if param_match: + value = param_match.group(1) + + try: + if param_type is int: + value = int(value) + elif param_type is float: + value = float(value) + elif param_type is bool: + value = value.lower() == "true" + except Exception as e: + log.exception(f"Failed to parse parameter {param}: {e}") + continue + + data["params"][param] = value + + # Parse adapter + adapter_match = re.search(r"ADAPTER (.+)", model_text, re.IGNORECASE) + if adapter_match: + data["params"]["adapter"] = adapter_match.group(1) + + # Parse system description + system_desc_match = re.search( + r'SYSTEM\s+"""(.+?)"""', model_text, re.DOTALL | re.IGNORECASE + ) + system_desc_match_single = re.search( + r"SYSTEM\s+([^\n]+)", model_text, re.IGNORECASE + ) + + if system_desc_match: + data["params"]["system"] = system_desc_match.group(1).strip() + elif system_desc_match_single: + data["params"]["system"] = system_desc_match_single.group(1).strip() + + # Parse messages + messages = [] + message_matches = re.findall(r"MESSAGE (\w+) (.+)", model_text, re.IGNORECASE) + for role, content in message_matches: + messages.append({"role": role, "content": content}) + + if messages: + data["params"]["messages"] = messages + + return data diff --git a/backend/open_webui/utils/models.py b/backend/open_webui/utils/models.py new file mode 100644 index 0000000..149e41a --- /dev/null +++ b/backend/open_webui/utils/models.py @@ -0,0 +1,246 @@ +import time +import logging +import sys + +from aiocache import cached +from fastapi import Request + +from open_webui.routers import openai, ollama +from open_webui.functions import get_function_models + + +from open_webui.models.functions import Functions +from open_webui.models.models import Models + + +from open_webui.utils.plugin import load_function_module_by_id +from open_webui.utils.access_control import has_access + + +from open_webui.config import ( + DEFAULT_ARENA_MODEL, +) + +from open_webui.env import SRC_LOG_LEVELS, GLOBAL_LOG_LEVEL +from open_webui.models.users import UserModel + + +logging.basicConfig(stream=sys.stdout, level=GLOBAL_LOG_LEVEL) +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MAIN"]) + + +async def get_all_base_models(request: Request, user: UserModel = None): + function_models = [] + openai_models = [] + ollama_models = [] + + if request.app.state.config.ENABLE_OPENAI_API: + openai_models = await openai.get_all_models(request, user=user) + openai_models = openai_models["data"] + + if request.app.state.config.ENABLE_OLLAMA_API: + ollama_models = await ollama.get_all_models(request, user=user) + ollama_models = [ + { + "id": model["model"], + "name": model["name"], + "object": "model", + "created": int(time.time()), + "owned_by": "ollama", + "ollama": model, + } + for model in ollama_models["models"] + ] + + function_models = await get_function_models(request) + models = function_models + openai_models + ollama_models + + return models + + +async def get_all_models(request, user: UserModel = None): + models = await get_all_base_models(request, user=user) + + # If there are no models, return an empty list + if len(models) == 0: + return [] + + # Add arena models + if request.app.state.config.ENABLE_EVALUATION_ARENA_MODELS: + arena_models = [] + if len(request.app.state.config.EVALUATION_ARENA_MODELS) > 0: + arena_models = [ + { + "id": model["id"], + "name": model["name"], + "info": { + "meta": model["meta"], + }, + "object": "model", + "created": int(time.time()), + "owned_by": "arena", + "arena": True, + } + for model in request.app.state.config.EVALUATION_ARENA_MODELS + ] + else: + # Add default arena model + arena_models = [ + { + "id": DEFAULT_ARENA_MODEL["id"], + "name": DEFAULT_ARENA_MODEL["name"], + "info": { + "meta": DEFAULT_ARENA_MODEL["meta"], + }, + "object": "model", + "created": int(time.time()), + "owned_by": "arena", + "arena": True, + } + ] + models = models + arena_models + + global_action_ids = [ + function.id for function in Functions.get_global_action_functions() + ] + enabled_action_ids = [ + function.id + for function in Functions.get_functions_by_type("action", active_only=True) + ] + + custom_models = Models.get_all_models() + for custom_model in custom_models: + if custom_model.base_model_id is None: + for model in models: + if ( + custom_model.id == model["id"] + or custom_model.id == model["id"].split(":")[0] + ): + if custom_model.is_active: + model["name"] = custom_model.name + model["info"] = custom_model.model_dump() + + action_ids = [] + if "info" in model and "meta" in model["info"]: + action_ids.extend( + model["info"]["meta"].get("actionIds", []) + ) + + model["action_ids"] = action_ids + else: + models.remove(model) + + elif custom_model.is_active and ( + custom_model.id not in [model["id"] for model in models] + ): + owned_by = "openai" + pipe = None + action_ids = [] + + for model in models: + if ( + custom_model.base_model_id == model["id"] + or custom_model.base_model_id == model["id"].split(":")[0] + ): + owned_by = model.get("owned_by", "unknown owner") + if "pipe" in model: + pipe = model["pipe"] + break + + if custom_model.meta: + meta = custom_model.meta.model_dump() + if "actionIds" in meta: + action_ids.extend(meta["actionIds"]) + + models.append( + { + "id": f"{custom_model.id}", + "name": custom_model.name, + "object": "model", + "created": custom_model.created_at, + "owned_by": owned_by, + "info": custom_model.model_dump(), + "preset": True, + **({"pipe": pipe} if pipe is not None else {}), + "action_ids": action_ids, + } + ) + + # Process action_ids to get the actions + def get_action_items_from_module(function, module): + actions = [] + if hasattr(module, "actions"): + actions = module.actions + return [ + { + "id": f"{function.id}.{action['id']}", + "name": action.get("name", f"{function.name} ({action['id']})"), + "description": function.meta.description, + "icon_url": action.get( + "icon_url", function.meta.manifest.get("icon_url", None) + ), + } + for action in actions + ] + else: + return [ + { + "id": function.id, + "name": function.name, + "description": function.meta.description, + "icon_url": function.meta.manifest.get("icon_url", None), + } + ] + + def get_function_module_by_id(function_id): + if function_id in request.app.state.FUNCTIONS: + function_module = request.app.state.FUNCTIONS[function_id] + else: + function_module, _, _ = load_function_module_by_id(function_id) + request.app.state.FUNCTIONS[function_id] = function_module + + for model in models: + action_ids = [ + action_id + for action_id in list(set(model.pop("action_ids", []) + global_action_ids)) + if action_id in enabled_action_ids + ] + + model["actions"] = [] + for action_id in action_ids: + action_function = Functions.get_function_by_id(action_id) + if action_function is None: + raise Exception(f"Action not found: {action_id}") + + function_module = get_function_module_by_id(action_id) + model["actions"].extend( + get_action_items_from_module(action_function, function_module) + ) + log.debug(f"get_all_models() returned {len(models)} models") + + request.app.state.MODELS = {model["id"]: model for model in models} + return models + + +def check_model_access(user, model): + if model.get("arena"): + if not has_access( + user.id, + type="read", + access_control=model.get("info", {}) + .get("meta", {}) + .get("access_control", {}), + ): + raise Exception("Model not found") + else: + model_info = Models.get_model_by_id(model.get("id")) + if not model_info: + raise Exception("Model not found") + elif not ( + user.id == model_info.user_id + or has_access( + user.id, type="read", access_control=model_info.access_control + ) + ): + raise Exception("Model not found") diff --git a/backend/open_webui/utils/oauth.py b/backend/open_webui/utils/oauth.py new file mode 100644 index 0000000..2af54c1 --- /dev/null +++ b/backend/open_webui/utils/oauth.py @@ -0,0 +1,430 @@ +import base64 +import logging +import mimetypes +import sys +import uuid + +import aiohttp +from authlib.integrations.starlette_client import OAuth +from authlib.oidc.core import UserInfo +from fastapi import ( + HTTPException, + status, +) +from starlette.responses import RedirectResponse + +from open_webui.models.auths import Auths +from open_webui.models.users import Users +from open_webui.models.groups import Groups, GroupModel, GroupUpdateForm +from open_webui.config import ( + DEFAULT_USER_ROLE, + ENABLE_OAUTH_SIGNUP, + OAUTH_MERGE_ACCOUNTS_BY_EMAIL, + OAUTH_PROVIDERS, + ENABLE_OAUTH_ROLE_MANAGEMENT, + ENABLE_OAUTH_GROUP_MANAGEMENT, + OAUTH_ROLES_CLAIM, + OAUTH_GROUPS_CLAIM, + OAUTH_EMAIL_CLAIM, + OAUTH_PICTURE_CLAIM, + OAUTH_USERNAME_CLAIM, + OAUTH_ALLOWED_ROLES, + OAUTH_ADMIN_ROLES, + OAUTH_ALLOWED_DOMAINS, + WEBHOOK_URL, + JWT_EXPIRES_IN, + AppConfig, +) +from open_webui.constants import ERROR_MESSAGES, WEBHOOK_MESSAGES +from open_webui.env import ( + WEBUI_NAME, + WEBUI_AUTH_COOKIE_SAME_SITE, + WEBUI_AUTH_COOKIE_SECURE, +) +from open_webui.utils.misc import parse_duration +from open_webui.utils.auth import get_password_hash, create_token +from open_webui.utils.webhook import post_webhook + +from open_webui.env import SRC_LOG_LEVELS, GLOBAL_LOG_LEVEL + +logging.basicConfig(stream=sys.stdout, level=GLOBAL_LOG_LEVEL) +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["OAUTH"]) + +auth_manager_config = AppConfig() +auth_manager_config.DEFAULT_USER_ROLE = DEFAULT_USER_ROLE +auth_manager_config.ENABLE_OAUTH_SIGNUP = ENABLE_OAUTH_SIGNUP +auth_manager_config.OAUTH_MERGE_ACCOUNTS_BY_EMAIL = OAUTH_MERGE_ACCOUNTS_BY_EMAIL +auth_manager_config.ENABLE_OAUTH_ROLE_MANAGEMENT = ENABLE_OAUTH_ROLE_MANAGEMENT +auth_manager_config.ENABLE_OAUTH_GROUP_MANAGEMENT = ENABLE_OAUTH_GROUP_MANAGEMENT +auth_manager_config.OAUTH_ROLES_CLAIM = OAUTH_ROLES_CLAIM +auth_manager_config.OAUTH_GROUPS_CLAIM = OAUTH_GROUPS_CLAIM +auth_manager_config.OAUTH_EMAIL_CLAIM = OAUTH_EMAIL_CLAIM +auth_manager_config.OAUTH_PICTURE_CLAIM = OAUTH_PICTURE_CLAIM +auth_manager_config.OAUTH_USERNAME_CLAIM = OAUTH_USERNAME_CLAIM +auth_manager_config.OAUTH_ALLOWED_ROLES = OAUTH_ALLOWED_ROLES +auth_manager_config.OAUTH_ADMIN_ROLES = OAUTH_ADMIN_ROLES +auth_manager_config.OAUTH_ALLOWED_DOMAINS = OAUTH_ALLOWED_DOMAINS +auth_manager_config.WEBHOOK_URL = WEBHOOK_URL +auth_manager_config.JWT_EXPIRES_IN = JWT_EXPIRES_IN + + +class OAuthManager: + def __init__(self, app): + self.oauth = OAuth() + self.app = app + for _, provider_config in OAUTH_PROVIDERS.items(): + provider_config["register"](self.oauth) + + def get_client(self, provider_name): + return self.oauth.create_client(provider_name) + + def get_user_role(self, user, user_data): + if user and Users.get_num_users() == 1: + # If the user is the only user, assign the role "admin" - actually repairs role for single user on login + log.debug("Assigning the only user the admin role") + return "admin" + if not user and Users.get_num_users() == 0: + # If there are no users, assign the role "admin", as the first user will be an admin + log.debug("Assigning the first user the admin role") + return "admin" + + if auth_manager_config.ENABLE_OAUTH_ROLE_MANAGEMENT: + log.debug("Running OAUTH Role management") + oauth_claim = auth_manager_config.OAUTH_ROLES_CLAIM + oauth_allowed_roles = auth_manager_config.OAUTH_ALLOWED_ROLES + oauth_admin_roles = auth_manager_config.OAUTH_ADMIN_ROLES + oauth_roles = None + # Default/fallback role if no matching roles are found + role = auth_manager_config.DEFAULT_USER_ROLE + + # Next block extracts the roles from the user data, accepting nested claims of any depth + if oauth_claim and oauth_allowed_roles and oauth_admin_roles: + claim_data = user_data + nested_claims = oauth_claim.split(".") + for nested_claim in nested_claims: + claim_data = claim_data.get(nested_claim, {}) + oauth_roles = claim_data if isinstance(claim_data, list) else None + + log.debug(f"Oauth Roles claim: {oauth_claim}") + log.debug(f"User roles from oauth: {oauth_roles}") + log.debug(f"Accepted user roles: {oauth_allowed_roles}") + log.debug(f"Accepted admin roles: {oauth_admin_roles}") + + # If any roles are found, check if they match the allowed or admin roles + if oauth_roles: + # If role management is enabled, and matching roles are provided, use the roles + for allowed_role in oauth_allowed_roles: + # If the user has any of the allowed roles, assign the role "user" + if allowed_role in oauth_roles: + log.debug("Assigned user the user role") + role = "user" + break + for admin_role in oauth_admin_roles: + # If the user has any of the admin roles, assign the role "admin" + if admin_role in oauth_roles: + log.debug("Assigned user the admin role") + role = "admin" + break + else: + if not user: + # If role management is disabled, use the default role for new users + role = auth_manager_config.DEFAULT_USER_ROLE + else: + # If role management is disabled, use the existing role for existing users + role = user.role + + return role + + def update_user_groups(self, user, user_data, default_permissions): + log.debug("Running OAUTH Group management") + oauth_claim = auth_manager_config.OAUTH_GROUPS_CLAIM + + # Nested claim search for groups claim + if oauth_claim: + claim_data = user_data + nested_claims = oauth_claim.split(".") + for nested_claim in nested_claims: + claim_data = claim_data.get(nested_claim, {}) + user_oauth_groups = claim_data if isinstance(claim_data, list) else [] + + user_current_groups: list[GroupModel] = Groups.get_groups_by_member_id(user.id) + all_available_groups: list[GroupModel] = Groups.get_groups() + + log.debug(f"Oauth Groups claim: {oauth_claim}") + log.debug(f"User oauth groups: {user_oauth_groups}") + log.debug(f"User's current groups: {[g.name for g in user_current_groups]}") + log.debug( + f"All groups available in OpenWebUI: {[g.name for g in all_available_groups]}" + ) + + # Remove groups that user is no longer a part of + for group_model in user_current_groups: + if group_model.name not in user_oauth_groups: + # Remove group from user + log.debug( + f"Removing user from group {group_model.name} as it is no longer in their oauth groups" + ) + + user_ids = group_model.user_ids + user_ids = [i for i in user_ids if i != user.id] + + # In case a group is created, but perms are never assigned to the group by hitting "save" + group_permissions = group_model.permissions + if not group_permissions: + group_permissions = default_permissions + + update_form = GroupUpdateForm( + name=group_model.name, + description=group_model.description, + permissions=group_permissions, + user_ids=user_ids, + ) + Groups.update_group_by_id( + id=group_model.id, form_data=update_form, overwrite=False + ) + + # Add user to new groups + for group_model in all_available_groups: + if group_model.name in user_oauth_groups and not any( + gm.name == group_model.name for gm in user_current_groups + ): + # Add user to group + log.debug( + f"Adding user to group {group_model.name} as it was found in their oauth groups" + ) + + user_ids = group_model.user_ids + user_ids.append(user.id) + + # In case a group is created, but perms are never assigned to the group by hitting "save" + group_permissions = group_model.permissions + if not group_permissions: + group_permissions = default_permissions + + update_form = GroupUpdateForm( + name=group_model.name, + description=group_model.description, + permissions=group_permissions, + user_ids=user_ids, + ) + Groups.update_group_by_id( + id=group_model.id, form_data=update_form, overwrite=False + ) + + async def handle_login(self, request, provider): + if provider not in OAUTH_PROVIDERS: + raise HTTPException(404) + # If the provider has a custom redirect URL, use that, otherwise automatically generate one + redirect_uri = OAUTH_PROVIDERS[provider].get("redirect_uri") or request.url_for( + "oauth_callback", provider=provider + ) + client = self.get_client(provider) + if client is None: + raise HTTPException(404) + return await client.authorize_redirect(request, redirect_uri) + + async def handle_callback(self, request, provider, response): + if provider not in OAUTH_PROVIDERS: + raise HTTPException(404) + client = self.get_client(provider) + try: + token = await client.authorize_access_token(request) + except Exception as e: + log.warning(f"OAuth callback error: {e}") + raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED) + user_data: UserInfo = token.get("userinfo") + if not user_data or "email" not in user_data: + user_data: UserInfo = await client.userinfo(token=token) + if not user_data: + log.warning(f"OAuth callback failed, user data is missing: {token}") + raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED) + + sub = user_data.get(OAUTH_PROVIDERS[provider].get("sub_claim", "sub")) + if not sub: + log.warning(f"OAuth callback failed, sub is missing: {user_data}") + raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED) + provider_sub = f"{provider}@{sub}" + email_claim = auth_manager_config.OAUTH_EMAIL_CLAIM + email = user_data.get(email_claim, "") + # We currently mandate that email addresses are provided + if not email: + # If the provider is GitHub,and public email is not provided, we can use the access token to fetch the user's email + if provider == "github": + try: + access_token = token.get("access_token") + headers = {"Authorization": f"Bearer {access_token}"} + async with aiohttp.ClientSession() as session: + async with session.get( + "https://api.github.com/user/emails", headers=headers + ) as resp: + if resp.ok: + emails = await resp.json() + # use the primary email as the user's email + primary_email = next( + (e["email"] for e in emails if e.get("primary")), + None, + ) + if primary_email: + email = primary_email + else: + log.warning( + "No primary email found in GitHub response" + ) + raise HTTPException( + 400, detail=ERROR_MESSAGES.INVALID_CRED + ) + else: + log.warning("Failed to fetch GitHub email") + raise HTTPException( + 400, detail=ERROR_MESSAGES.INVALID_CRED + ) + except Exception as e: + log.warning(f"Error fetching GitHub email: {e}") + raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED) + else: + log.warning(f"OAuth callback failed, email is missing: {user_data}") + raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED) + email = email.lower() + if ( + "*" not in auth_manager_config.OAUTH_ALLOWED_DOMAINS + and email.split("@")[-1] not in auth_manager_config.OAUTH_ALLOWED_DOMAINS + ): + log.warning( + f"OAuth callback failed, e-mail domain is not in the list of allowed domains: {user_data}" + ) + raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED) + + # Check if the user exists + user = Users.get_user_by_oauth_sub(provider_sub) + + if not user: + # If the user does not exist, check if merging is enabled + if auth_manager_config.OAUTH_MERGE_ACCOUNTS_BY_EMAIL: + # Check if the user exists by email + user = Users.get_user_by_email(email) + if user: + # Update the user with the new oauth sub + Users.update_user_oauth_sub_by_id(user.id, provider_sub) + + if user: + determined_role = self.get_user_role(user, user_data) + if user.role != determined_role: + Users.update_user_role_by_id(user.id, determined_role) + + if not user: + user_count = Users.get_num_users() + + # If the user does not exist, check if signups are enabled + if auth_manager_config.ENABLE_OAUTH_SIGNUP: + # Check if an existing user with the same email already exists + existing_user = Users.get_user_by_email(email) + if existing_user: + raise HTTPException(400, detail=ERROR_MESSAGES.EMAIL_TAKEN) + + picture_claim = auth_manager_config.OAUTH_PICTURE_CLAIM + picture_url = user_data.get( + picture_claim, OAUTH_PROVIDERS[provider].get("picture_url", "") + ) + if picture_url: + # Download the profile image into a base64 string + try: + access_token = token.get("access_token") + get_kwargs = {} + if access_token: + get_kwargs["headers"] = { + "Authorization": f"Bearer {access_token}", + } + async with aiohttp.ClientSession() as session: + async with session.get(picture_url, **get_kwargs) as resp: + if resp.ok: + picture = await resp.read() + base64_encoded_picture = base64.b64encode( + picture + ).decode("utf-8") + guessed_mime_type = mimetypes.guess_type( + picture_url + )[0] + if guessed_mime_type is None: + # assume JPG, browsers are tolerant enough of image formats + guessed_mime_type = "image/jpeg" + picture_url = f"data:{guessed_mime_type};base64,{base64_encoded_picture}" + else: + picture_url = "/user.png" + except Exception as e: + log.error( + f"Error downloading profile image '{picture_url}': {e}" + ) + picture_url = "/user.png" + if not picture_url: + picture_url = "/user.png" + + username_claim = auth_manager_config.OAUTH_USERNAME_CLAIM + + name = user_data.get(username_claim) + if not name: + log.warning("Username claim is missing, using email as name") + name = email + + role = self.get_user_role(None, user_data) + + user = Auths.insert_new_auth( + email=email, + password=get_password_hash( + str(uuid.uuid4()) + ), # Random password, not used + name=name, + profile_image_url=picture_url, + role=role, + oauth_sub=provider_sub, + ) + + if auth_manager_config.WEBHOOK_URL: + post_webhook( + WEBUI_NAME, + auth_manager_config.WEBHOOK_URL, + WEBHOOK_MESSAGES.USER_SIGNUP(user.name), + { + "action": "signup", + "message": WEBHOOK_MESSAGES.USER_SIGNUP(user.name), + "user": user.model_dump_json(exclude_none=True), + }, + ) + else: + raise HTTPException( + status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.ACCESS_PROHIBITED + ) + + jwt_token = create_token( + data={"id": user.id}, + expires_delta=parse_duration(auth_manager_config.JWT_EXPIRES_IN), + ) + + if auth_manager_config.ENABLE_OAUTH_GROUP_MANAGEMENT and user.role != "admin": + self.update_user_groups( + user=user, + user_data=user_data, + default_permissions=request.app.state.config.USER_PERMISSIONS, + ) + + # Set the cookie token + response.set_cookie( + key="token", + value=jwt_token, + httponly=True, # Ensures the cookie is not accessible via JavaScript + samesite=WEBUI_AUTH_COOKIE_SAME_SITE, + secure=WEBUI_AUTH_COOKIE_SECURE, + ) + + if ENABLE_OAUTH_SIGNUP.value: + oauth_id_token = token.get("id_token") + response.set_cookie( + key="oauth_id_token", + value=oauth_id_token, + httponly=True, + samesite=WEBUI_AUTH_COOKIE_SAME_SITE, + secure=WEBUI_AUTH_COOKIE_SECURE, + ) + # Redirect back to the frontend with the JWT token + redirect_url = f"{request.base_url}auth#token={jwt_token}" + return RedirectResponse(url=redirect_url, headers=response.headers) diff --git a/backend/open_webui/utils/payload.py b/backend/open_webui/utils/payload.py new file mode 100644 index 0000000..869e708 --- /dev/null +++ b/backend/open_webui/utils/payload.py @@ -0,0 +1,242 @@ +from open_webui.utils.task import prompt_template, prompt_variables_template +from open_webui.utils.misc import ( + add_or_update_system_message, +) + +from typing import Callable, Optional +import json + + +# inplace function: form_data is modified +def apply_model_system_prompt_to_body( + params: dict, form_data: dict, metadata: Optional[dict] = None, user=None +) -> dict: + system = params.get("system", None) + if not system: + return form_data + + # Metadata (WebUI Usage) + if metadata: + variables = metadata.get("variables", {}) + if variables: + system = prompt_variables_template(system, variables) + + # Legacy (API Usage) + if user: + template_params = { + "user_name": user.name, + "user_location": user.info.get("location") if user.info else None, + } + else: + template_params = {} + + system = prompt_template(system, **template_params) + + form_data["messages"] = add_or_update_system_message( + system, form_data.get("messages", []) + ) + return form_data + + +# inplace function: form_data is modified +def apply_model_params_to_body( + params: dict, form_data: dict, mappings: dict[str, Callable] +) -> dict: + if not params: + return form_data + + for key, cast_func in mappings.items(): + if (value := params.get(key)) is not None: + form_data[key] = cast_func(value) + + return form_data + + +# inplace function: form_data is modified +def apply_model_params_to_body_openai(params: dict, form_data: dict) -> dict: + mappings = { + "temperature": float, + "top_p": float, + "max_tokens": int, + "frequency_penalty": float, + "reasoning_effort": str, + "seed": lambda x: x, + "stop": lambda x: [bytes(s, "utf-8").decode("unicode_escape") for s in x], + } + return apply_model_params_to_body(params, form_data, mappings) + + +def apply_model_params_to_body_ollama(params: dict, form_data: dict) -> dict: + # Convert OpenAI parameter names to Ollama parameter names if needed. + name_differences = { + "max_tokens": "num_predict", + } + + for key, value in name_differences.items(): + if (param := params.get(key, None)) is not None: + # Copy the parameter to new name then delete it, to prevent Ollama warning of invalid option provided + params[value] = params[key] + del params[key] + + # See https://github.com/ollama/ollama/blob/main/docs/api.md#request-8 + mappings = { + "temperature": float, + "top_p": float, + "seed": lambda x: x, + "mirostat": int, + "mirostat_eta": float, + "mirostat_tau": float, + "num_ctx": int, + "num_batch": int, + "num_keep": int, + "num_predict": int, + "repeat_last_n": int, + "top_k": int, + "min_p": float, + "typical_p": float, + "repeat_penalty": float, + "presence_penalty": float, + "frequency_penalty": float, + "penalize_newline": bool, + "stop": lambda x: [bytes(s, "utf-8").decode("unicode_escape") for s in x], + "numa": bool, + "num_gpu": int, + "main_gpu": int, + "low_vram": bool, + "vocab_only": bool, + "use_mmap": bool, + "use_mlock": bool, + "num_thread": int, + } + + return apply_model_params_to_body(params, form_data, mappings) + + +def convert_messages_openai_to_ollama(messages: list[dict]) -> list[dict]: + ollama_messages = [] + + for message in messages: + # Initialize the new message structure with the role + new_message = {"role": message["role"]} + + content = message.get("content", []) + tool_calls = message.get("tool_calls", None) + tool_call_id = message.get("tool_call_id", None) + + # Check if the content is a string (just a simple message) + if isinstance(content, str) and not tool_calls: + # If the content is a string, it's pure text + new_message["content"] = content + + # If message is a tool call, add the tool call id to the message + if tool_call_id: + new_message["tool_call_id"] = tool_call_id + + elif tool_calls: + # If tool calls are present, add them to the message + ollama_tool_calls = [] + for tool_call in tool_calls: + ollama_tool_call = { + "index": tool_call.get("index", 0), + "id": tool_call.get("id", None), + "function": { + "name": tool_call.get("function", {}).get("name", ""), + "arguments": json.loads( + tool_call.get("function", {}).get("arguments", {}) + ), + }, + } + ollama_tool_calls.append(ollama_tool_call) + new_message["tool_calls"] = ollama_tool_calls + + # Put the content to empty string (Ollama requires an empty string for tool calls) + new_message["content"] = "" + + else: + # Otherwise, assume the content is a list of dicts, e.g., text followed by an image URL + content_text = "" + images = [] + + # Iterate through the list of content items + for item in content: + # Check if it's a text type + if item.get("type") == "text": + content_text += item.get("text", "") + + # Check if it's an image URL type + elif item.get("type") == "image_url": + img_url = item.get("image_url", {}).get("url", "") + if img_url: + # If the image url starts with data:, it's a base64 image and should be trimmed + if img_url.startswith("data:"): + img_url = img_url.split(",")[-1] + images.append(img_url) + + # Add content text (if any) + if content_text: + new_message["content"] = content_text.strip() + + # Add images (if any) + if images: + new_message["images"] = images + + # Append the new formatted message to the result + ollama_messages.append(new_message) + + return ollama_messages + + +def convert_payload_openai_to_ollama(openai_payload: dict) -> dict: + """ + Converts a payload formatted for OpenAI's API to be compatible with Ollama's API endpoint for chat completions. + + Args: + openai_payload (dict): The payload originally designed for OpenAI API usage. + + Returns: + dict: A modified payload compatible with the Ollama API. + """ + ollama_payload = {} + + # Mapping basic model and message details + ollama_payload["model"] = openai_payload.get("model") + ollama_payload["messages"] = convert_messages_openai_to_ollama( + openai_payload.get("messages") + ) + ollama_payload["stream"] = openai_payload.get("stream", False) + + if "tools" in openai_payload: + ollama_payload["tools"] = openai_payload["tools"] + + if "format" in openai_payload: + ollama_payload["format"] = openai_payload["format"] + + # If there are advanced parameters in the payload, format them in Ollama's options field + if openai_payload.get("options"): + ollama_payload["options"] = openai_payload["options"] + ollama_options = openai_payload["options"] + + # Re-Mapping OpenAI's `max_tokens` -> Ollama's `num_predict` + if "max_tokens" in ollama_options: + ollama_options["num_predict"] = ollama_options["max_tokens"] + del ollama_options[ + "max_tokens" + ] # To prevent Ollama warning of invalid option provided + + # Ollama lacks a "system" prompt option. It has to be provided as a direct parameter, so we copy it down. + if "system" in ollama_options: + ollama_payload["system"] = ollama_options["system"] + del ollama_options[ + "system" + ] # To prevent Ollama warning of invalid option provided + + # If there is the "stop" parameter in the openai_payload, remap it to the ollama_payload.options + if "stop" in openai_payload: + ollama_options = ollama_payload.get("options", {}) + ollama_options["stop"] = openai_payload.get("stop") + ollama_payload["options"] = ollama_options + + if "metadata" in openai_payload: + ollama_payload["metadata"] = openai_payload["metadata"] + + return ollama_payload diff --git a/backend/open_webui/utils/pdf_generator.py b/backend/open_webui/utils/pdf_generator.py new file mode 100644 index 0000000..8b04dd8 --- /dev/null +++ b/backend/open_webui/utils/pdf_generator.py @@ -0,0 +1,146 @@ +from datetime import datetime +from io import BytesIO +from pathlib import Path +from typing import Dict, Any, List +from html import escape + +from markdown import markdown + +import site +from fpdf import FPDF + +from open_webui.env import STATIC_DIR, FONTS_DIR +from open_webui.models.chats import ChatTitleMessagesForm + + +class PDFGenerator: + """ + Description: + The `PDFGenerator` class is designed to create PDF documents from chat messages. + The process involves transforming markdown content into HTML and then into a PDF format + + Attributes: + - `form_data`: An instance of `ChatTitleMessagesForm` containing title and messages. + + """ + + def __init__(self, form_data: ChatTitleMessagesForm): + self.html_body = None + self.messages_html = None + self.form_data = form_data + + self.css = Path(STATIC_DIR / "assets" / "pdf-style.css").read_text() + + def format_timestamp(self, timestamp: float) -> str: + """Convert a UNIX timestamp to a formatted date string.""" + try: + date_time = datetime.fromtimestamp(timestamp) + return date_time.strftime("%Y-%m-%d, %H:%M:%S") + except (ValueError, TypeError) as e: + # Log the error if necessary + return "" + + def _build_html_message(self, message: Dict[str, Any]) -> str: + """Build HTML for a single message.""" + role = escape(message.get("role", "user")) + content = escape(message.get("content", "")) + timestamp = message.get("timestamp") + + model = escape(message.get("model") if role == "assistant" else "") + + date_str = escape(self.format_timestamp(timestamp) if timestamp else "") + + # extends pymdownx extension to convert markdown to html. + # - https://facelessuser.github.io/pymdown-extensions/usage_notes/ + # html_content = markdown(content, extensions=["pymdownx.extra"]) + + content = content.replace("\n", "
        ") + html_message = f""" +
        +
        +

        + {role.title()} + {model} +

        +
        {date_str}
        +
        +
        +
        + +
        + {content} +
        +
        +
        + """ + return html_message + + def _generate_html_body(self) -> str: + """Generate the full HTML body for the PDF.""" + escaped_title = escape(self.form_data.title) + return f""" + + + + + +
        +
        +

        {escaped_title}

        + {self.messages_html} +
        +
        + + + """ + + def generate_chat_pdf(self) -> bytes: + """ + Generate a PDF from chat messages. + """ + try: + global FONTS_DIR + + pdf = FPDF() + pdf.add_page() + + # When running using `pip install` the static directory is in the site packages. + if not FONTS_DIR.exists(): + FONTS_DIR = Path(site.getsitepackages()[0]) / "static/fonts" + # When running using `pip install -e .` the static directory is in the site packages. + # This path only works if `open-webui serve` is run from the root of this project. + if not FONTS_DIR.exists(): + FONTS_DIR = Path("./backend/static/fonts") + + pdf.add_font("NotoSans", "", f"{FONTS_DIR}/NotoSans-Regular.ttf") + pdf.add_font("NotoSans", "b", f"{FONTS_DIR}/NotoSans-Bold.ttf") + pdf.add_font("NotoSans", "i", f"{FONTS_DIR}/NotoSans-Italic.ttf") + pdf.add_font("NotoSansKR", "", f"{FONTS_DIR}/NotoSansKR-Regular.ttf") + pdf.add_font("NotoSansJP", "", f"{FONTS_DIR}/NotoSansJP-Regular.ttf") + pdf.add_font("NotoSansSC", "", f"{FONTS_DIR}/NotoSansSC-Regular.ttf") + pdf.add_font("Twemoji", "", f"{FONTS_DIR}/Twemoji.ttf") + + pdf.set_font("NotoSans", size=12) + pdf.set_fallback_fonts( + ["NotoSansKR", "NotoSansJP", "NotoSansSC", "Twemoji"] + ) + + pdf.set_auto_page_break(auto=True, margin=15) + + # Build HTML messages + messages_html_list: List[str] = [ + self._build_html_message(msg) for msg in self.form_data.messages + ] + self.messages_html = "
        " + "".join(messages_html_list) + "
        " + + # Generate full HTML body + self.html_body = self._generate_html_body() + + pdf.write_html(self.html_body) + + # Save the pdf with name .pdf + pdf_bytes = pdf.output() + + return bytes(pdf_bytes) + except Exception as e: + raise e diff --git a/backend/open_webui/utils/plugin.py b/backend/open_webui/utils/plugin.py new file mode 100644 index 0000000..e3fe923 --- /dev/null +++ b/backend/open_webui/utils/plugin.py @@ -0,0 +1,180 @@ +import os +import re +import subprocess +import sys +from importlib import util +import types +import tempfile +import logging + +from open_webui.env import SRC_LOG_LEVELS +from open_webui.models.functions import Functions +from open_webui.models.tools import Tools + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["MAIN"]) + + +def extract_frontmatter(content): + """ + Extract frontmatter as a dictionary from the provided content string. + """ + frontmatter = {} + frontmatter_started = False + frontmatter_ended = False + frontmatter_pattern = re.compile(r"^\s*([a-z_]+):\s*(.*)\s*$", re.IGNORECASE) + + try: + lines = content.splitlines() + if len(lines) < 1 or lines[0].strip() != '"""': + # The content doesn't start with triple quotes + return {} + + frontmatter_started = True + + for line in lines[1:]: + if '"""' in line: + if frontmatter_started: + frontmatter_ended = True + break + + if frontmatter_started and not frontmatter_ended: + match = frontmatter_pattern.match(line) + if match: + key, value = match.groups() + frontmatter[key.strip()] = value.strip() + + except Exception as e: + log.exception(f"Failed to extract frontmatter: {e}") + return {} + + return frontmatter + + +def replace_imports(content): + """ + Replace the import paths in the content. + """ + replacements = { + "from utils": "from open_webui.utils", + "from apps": "from open_webui.apps", + "from main": "from open_webui.main", + "from config": "from open_webui.config", + } + + for old, new in replacements.items(): + content = content.replace(old, new) + + return content + + +def load_tools_module_by_id(toolkit_id, content=None): + + if content is None: + tool = Tools.get_tool_by_id(toolkit_id) + if not tool: + raise Exception(f"Toolkit not found: {toolkit_id}") + + content = tool.content + + content = replace_imports(content) + Tools.update_tool_by_id(toolkit_id, {"content": content}) + else: + frontmatter = extract_frontmatter(content) + # Install required packages found within the frontmatter + install_frontmatter_requirements(frontmatter.get("requirements", "")) + + module_name = f"tool_{toolkit_id}" + module = types.ModuleType(module_name) + sys.modules[module_name] = module + + # Create a temporary file and use it to define `__file__` so + # that it works as expected from the module's perspective. + temp_file = tempfile.NamedTemporaryFile(delete=False) + temp_file.close() + try: + with open(temp_file.name, "w", encoding="utf-8") as f: + f.write(content) + module.__dict__["__file__"] = temp_file.name + + # Executing the modified content in the created module's namespace + exec(content, module.__dict__) + frontmatter = extract_frontmatter(content) + log.info(f"Loaded module: {module.__name__}") + + # Create and return the object if the class 'Tools' is found in the module + if hasattr(module, "Tools"): + return module.Tools(), frontmatter + else: + raise Exception("No Tools class found in the module") + except Exception as e: + log.error(f"Error loading module: {toolkit_id}: {e}") + del sys.modules[module_name] # Clean up + raise e + finally: + os.unlink(temp_file.name) + + +def load_function_module_by_id(function_id, content=None): + if content is None: + function = Functions.get_function_by_id(function_id) + if not function: + raise Exception(f"Function not found: {function_id}") + content = function.content + + content = replace_imports(content) + Functions.update_function_by_id(function_id, {"content": content}) + else: + frontmatter = extract_frontmatter(content) + install_frontmatter_requirements(frontmatter.get("requirements", "")) + + module_name = f"function_{function_id}" + module = types.ModuleType(module_name) + sys.modules[module_name] = module + + # Create a temporary file and use it to define `__file__` so + # that it works as expected from the module's perspective. + temp_file = tempfile.NamedTemporaryFile(delete=False) + temp_file.close() + try: + with open(temp_file.name, "w", encoding="utf-8") as f: + f.write(content) + module.__dict__["__file__"] = temp_file.name + + # Execute the modified content in the created module's namespace + exec(content, module.__dict__) + frontmatter = extract_frontmatter(content) + log.info(f"Loaded module: {module.__name__}") + + # Create appropriate object based on available class type in the module + if hasattr(module, "Pipe"): + return module.Pipe(), "pipe", frontmatter + elif hasattr(module, "Filter"): + return module.Filter(), "filter", frontmatter + elif hasattr(module, "Action"): + return module.Action(), "action", frontmatter + else: + raise Exception("No Function class found in the module") + except Exception as e: + log.error(f"Error loading module: {function_id}: {e}") + del sys.modules[module_name] # Cleanup by removing the module in case of error + + Functions.update_function_by_id(function_id, {"is_active": False}) + raise e + finally: + os.unlink(temp_file.name) + + +def install_frontmatter_requirements(requirements): + if requirements: + try: + req_list = [req.strip() for req in requirements.split(",")] + for req in req_list: + log.info(f"Installing requirement: {req}") + subprocess.check_call([sys.executable, "-m", "pip", "install", req]) + except Exception as e: + log.error(f"Error installing package: {req}") + raise e + + else: + log.info("No requirements found in frontmatter.") diff --git a/backend/open_webui/utils/response.py b/backend/open_webui/utils/response.py new file mode 100644 index 0000000..8c3f1a5 --- /dev/null +++ b/backend/open_webui/utils/response.py @@ -0,0 +1,127 @@ +import json +from uuid import uuid4 +from open_webui.utils.misc import ( + openai_chat_chunk_message_template, + openai_chat_completion_message_template, +) + + +def convert_ollama_tool_call_to_openai(tool_calls: dict) -> dict: + openai_tool_calls = [] + for tool_call in tool_calls: + openai_tool_call = { + "index": tool_call.get("index", 0), + "id": tool_call.get("id", f"call_{str(uuid4())}"), + "type": "function", + "function": { + "name": tool_call.get("function", {}).get("name", ""), + "arguments": json.dumps( + tool_call.get("function", {}).get("arguments", {}) + ), + }, + } + openai_tool_calls.append(openai_tool_call) + return openai_tool_calls + + +def convert_ollama_usage_to_openai(data: dict) -> dict: + return { + "response_token/s": ( + round( + ( + ( + data.get("eval_count", 0) + / ((data.get("eval_duration", 0) / 10_000_000)) + ) + * 100 + ), + 2, + ) + if data.get("eval_duration", 0) > 0 + else "N/A" + ), + "prompt_token/s": ( + round( + ( + ( + data.get("prompt_eval_count", 0) + / ((data.get("prompt_eval_duration", 0) / 10_000_000)) + ) + * 100 + ), + 2, + ) + if data.get("prompt_eval_duration", 0) > 0 + else "N/A" + ), + "total_duration": data.get("total_duration", 0), + "load_duration": data.get("load_duration", 0), + "prompt_eval_count": data.get("prompt_eval_count", 0), + "prompt_tokens": int( + data.get("prompt_eval_count", 0) + ), # This is the OpenAI compatible key + "prompt_eval_duration": data.get("prompt_eval_duration", 0), + "eval_count": data.get("eval_count", 0), + "completion_tokens": int( + data.get("eval_count", 0) + ), # This is the OpenAI compatible key + "eval_duration": data.get("eval_duration", 0), + "approximate_total": (lambda s: f"{s // 3600}h{(s % 3600) // 60}m{s % 60}s")( + (data.get("total_duration", 0) or 0) // 1_000_000_000 + ), + "total_tokens": int( # This is the OpenAI compatible key + data.get("prompt_eval_count", 0) + data.get("eval_count", 0) + ), + "completion_tokens_details": { # This is the OpenAI compatible key + "reasoning_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0, + }, + } + + +def convert_response_ollama_to_openai(ollama_response: dict) -> dict: + model = ollama_response.get("model", "ollama") + message_content = ollama_response.get("message", {}).get("content", "") + tool_calls = ollama_response.get("message", {}).get("tool_calls", None) + openai_tool_calls = None + + if tool_calls: + openai_tool_calls = convert_ollama_tool_call_to_openai(tool_calls) + + data = ollama_response + + usage = convert_ollama_usage_to_openai(data) + + response = openai_chat_completion_message_template( + model, message_content, openai_tool_calls, usage + ) + return response + + +async def convert_streaming_response_ollama_to_openai(ollama_streaming_response): + async for data in ollama_streaming_response.body_iterator: + data = json.loads(data) + + model = data.get("model", "ollama") + message_content = data.get("message", {}).get("content", None) + tool_calls = data.get("message", {}).get("tool_calls", None) + openai_tool_calls = None + + if tool_calls: + openai_tool_calls = convert_ollama_tool_call_to_openai(tool_calls) + + done = data.get("done", False) + + usage = None + if done: + usage = convert_ollama_usage_to_openai(data) + + data = openai_chat_chunk_message_template( + model, message_content, openai_tool_calls, usage + ) + + line = f"data: {json.dumps(data)}\n\n" + yield line + + yield "data: [DONE]\n\n" diff --git a/backend/open_webui/utils/security_headers.py b/backend/open_webui/utils/security_headers.py new file mode 100644 index 0000000..fbcf7d6 --- /dev/null +++ b/backend/open_webui/utils/security_headers.py @@ -0,0 +1,133 @@ +import re +import os + +from fastapi import Request +from starlette.middleware.base import BaseHTTPMiddleware +from typing import Dict + + +class SecurityHeadersMiddleware(BaseHTTPMiddleware): + async def dispatch(self, request: Request, call_next): + response = await call_next(request) + response.headers.update(set_security_headers()) + return response + + +def set_security_headers() -> Dict[str, str]: + """ + Sets security headers based on environment variables. + + This function reads specific environment variables and uses their values + to set corresponding security headers. The headers that can be set are: + - cache-control + - permissions-policy + - strict-transport-security + - referrer-policy + - x-content-type-options + - x-download-options + - x-frame-options + - x-permitted-cross-domain-policies + - content-security-policy + + Each environment variable is associated with a specific setter function + that constructs the header. If the environment variable is set, the + corresponding header is added to the options dictionary. + + Returns: + dict: A dictionary containing the security headers and their values. + """ + options = {} + header_setters = { + "CACHE_CONTROL": set_cache_control, + "HSTS": set_hsts, + "PERMISSIONS_POLICY": set_permissions_policy, + "REFERRER_POLICY": set_referrer, + "XCONTENT_TYPE": set_xcontent_type, + "XDOWNLOAD_OPTIONS": set_xdownload_options, + "XFRAME_OPTIONS": set_xframe, + "XPERMITTED_CROSS_DOMAIN_POLICIES": set_xpermitted_cross_domain_policies, + "CONTENT_SECURITY_POLICY": set_content_security_policy, + } + + for env_var, setter in header_setters.items(): + value = os.environ.get(env_var, None) + if value: + header = setter(value) + if header: + options.update(header) + + return options + + +# Set HTTP Strict Transport Security(HSTS) response header +def set_hsts(value: str): + pattern = r"^max-age=(\d+)(;includeSubDomains)?(;preload)?$" + match = re.match(pattern, value, re.IGNORECASE) + if not match: + value = "max-age=31536000;includeSubDomains" + return {"Strict-Transport-Security": value} + + +# Set X-Frame-Options response header +def set_xframe(value: str): + pattern = r"^(DENY|SAMEORIGIN)$" + match = re.match(pattern, value, re.IGNORECASE) + if not match: + value = "DENY" + return {"X-Frame-Options": value} + + +# Set Permissions-Policy response header +def set_permissions_policy(value: str): + pattern = r"^(?:(accelerometer|autoplay|camera|clipboard-read|clipboard-write|fullscreen|geolocation|gyroscope|magnetometer|microphone|midi|payment|picture-in-picture|sync-xhr|usb|xr-spatial-tracking)=\((self)?\),?)*$" + match = re.match(pattern, value, re.IGNORECASE) + if not match: + value = "none" + return {"Permissions-Policy": value} + + +# Set Referrer-Policy response header +def set_referrer(value: str): + pattern = r"^(no-referrer|no-referrer-when-downgrade|origin|origin-when-cross-origin|same-origin|strict-origin|strict-origin-when-cross-origin|unsafe-url)$" + match = re.match(pattern, value, re.IGNORECASE) + if not match: + value = "no-referrer" + return {"Referrer-Policy": value} + + +# Set Cache-Control response header +def set_cache_control(value: str): + pattern = r"^(public|private|no-cache|no-store|must-revalidate|proxy-revalidate|max-age=\d+|s-maxage=\d+|no-transform|immutable)(,\s*(public|private|no-cache|no-store|must-revalidate|proxy-revalidate|max-age=\d+|s-maxage=\d+|no-transform|immutable))*$" + match = re.match(pattern, value, re.IGNORECASE) + if not match: + value = "no-store, max-age=0" + + return {"Cache-Control": value} + + +# Set X-Download-Options response header +def set_xdownload_options(value: str): + if value != "noopen": + value = "noopen" + return {"X-Download-Options": value} + + +# Set X-Content-Type-Options response header +def set_xcontent_type(value: str): + if value != "nosniff": + value = "nosniff" + return {"X-Content-Type-Options": value} + + +# Set X-Permitted-Cross-Domain-Policies response header +def set_xpermitted_cross_domain_policies(value: str): + pattern = r"^(none|master-only|by-content-type|by-ftp-filename)$" + match = re.match(pattern, value, re.IGNORECASE) + if not match: + value = "none" + return {"X-Permitted-Cross-Domain-Policies": value} + + +# Set Content-Security-Policy response header +def set_content_security_policy(value: str): + return {"Content-Security-Policy": value} diff --git a/backend/open_webui/utils/task.py b/backend/open_webui/utils/task.py new file mode 100644 index 0000000..5663ce2 --- /dev/null +++ b/backend/open_webui/utils/task.py @@ -0,0 +1,339 @@ +import logging +import math +import re +from datetime import datetime +from typing import Optional +import uuid + + +from open_webui.utils.misc import get_last_user_message, get_messages_content + +from open_webui.env import SRC_LOG_LEVELS +from open_webui.config import DEFAULT_RAG_TEMPLATE + + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["RAG"]) + + +def get_task_model_id( + default_model_id: str, task_model: str, task_model_external: str, models +) -> str: + # Set the task model + task_model_id = default_model_id + # Check if the user has a custom task model and use that model + if models[task_model_id].get("owned_by") == "ollama": + if task_model and task_model in models: + task_model_id = task_model + else: + if task_model_external and task_model_external in models: + task_model_id = task_model_external + + return task_model_id + + +def prompt_variables_template(template: str, variables: dict[str, str]) -> str: + for variable, value in variables.items(): + template = template.replace(variable, value) + return template + + +def prompt_template( + template: str, user_name: Optional[str] = None, user_location: Optional[str] = None +) -> str: + # Get the current date + current_date = datetime.now() + + # Format the date to YYYY-MM-DD + formatted_date = current_date.strftime("%Y-%m-%d") + formatted_time = current_date.strftime("%I:%M:%S %p") + formatted_weekday = current_date.strftime("%A") + + template = template.replace("{{CURRENT_DATE}}", formatted_date) + template = template.replace("{{CURRENT_TIME}}", formatted_time) + template = template.replace( + "{{CURRENT_DATETIME}}", f"{formatted_date} {formatted_time}" + ) + template = template.replace("{{CURRENT_WEEKDAY}}", formatted_weekday) + + if user_name: + # Replace {{USER_NAME}} in the template with the user's name + template = template.replace("{{USER_NAME}}", user_name) + else: + # Replace {{USER_NAME}} in the template with "Unknown" + template = template.replace("{{USER_NAME}}", "Unknown") + + if user_location: + # Replace {{USER_LOCATION}} in the template with the current location + template = template.replace("{{USER_LOCATION}}", user_location) + else: + # Replace {{USER_LOCATION}} in the template with "Unknown" + template = template.replace("{{USER_LOCATION}}", "Unknown") + + return template + + +def replace_prompt_variable(template: str, prompt: str) -> str: + def replacement_function(match): + full_match = match.group( + 0 + ).lower() # Normalize to lowercase for consistent handling + start_length = match.group(1) + end_length = match.group(2) + middle_length = match.group(3) + + if full_match == "{{prompt}}": + return prompt + elif start_length is not None: + return prompt[: int(start_length)] + elif end_length is not None: + return prompt[-int(end_length) :] + elif middle_length is not None: + middle_length = int(middle_length) + if len(prompt) <= middle_length: + return prompt + start = prompt[: math.ceil(middle_length / 2)] + end = prompt[-math.floor(middle_length / 2) :] + return f"{start}...{end}" + return "" + + # Updated regex pattern to make it case-insensitive with the `(?i)` flag + pattern = r"(?i){{prompt}}|{{prompt:start:(\d+)}}|{{prompt:end:(\d+)}}|{{prompt:middletruncate:(\d+)}}" + template = re.sub(pattern, replacement_function, template) + return template + + +def replace_messages_variable( + template: str, messages: Optional[list[str]] = None +) -> str: + def replacement_function(match): + full_match = match.group(0) + start_length = match.group(1) + end_length = match.group(2) + middle_length = match.group(3) + # If messages is None, handle it as an empty list + if messages is None: + return "" + + # Process messages based on the number of messages required + if full_match == "{{MESSAGES}}": + return get_messages_content(messages) + elif start_length is not None: + return get_messages_content(messages[: int(start_length)]) + elif end_length is not None: + return get_messages_content(messages[-int(end_length) :]) + elif middle_length is not None: + mid = int(middle_length) + + if len(messages) <= mid: + return get_messages_content(messages) + # Handle middle truncation: split to get start and end portions of the messages list + half = mid // 2 + start_msgs = messages[:half] + end_msgs = messages[-half:] if mid % 2 == 0 else messages[-(half + 1) :] + formatted_start = get_messages_content(start_msgs) + formatted_end = get_messages_content(end_msgs) + return f"{formatted_start}\n{formatted_end}" + return "" + + template = re.sub( + r"{{MESSAGES}}|{{MESSAGES:START:(\d+)}}|{{MESSAGES:END:(\d+)}}|{{MESSAGES:MIDDLETRUNCATE:(\d+)}}", + replacement_function, + template, + ) + + return template + + +# {{prompt:middletruncate:8000}} + + +def rag_template(template: str, context: str, query: str): + if template.strip() == "": + template = DEFAULT_RAG_TEMPLATE + + if "[context]" not in template and "{{CONTEXT}}" not in template: + log.debug( + "WARNING: The RAG template does not contain the '[context]' or '{{CONTEXT}}' placeholder." + ) + + if "" in context and "" in context: + log.debug( + "WARNING: Potential prompt injection attack: the RAG " + "context contains '' and ''. This might be " + "nothing, or the user might be trying to hack something." + ) + + query_placeholders = [] + if "[query]" in context: + query_placeholder = "{{QUERY" + str(uuid.uuid4()) + "}}" + template = template.replace("[query]", query_placeholder) + query_placeholders.append(query_placeholder) + + if "{{QUERY}}" in context: + query_placeholder = "{{QUERY" + str(uuid.uuid4()) + "}}" + template = template.replace("{{QUERY}}", query_placeholder) + query_placeholders.append(query_placeholder) + + template = template.replace("[context]", context) + template = template.replace("{{CONTEXT}}", context) + template = template.replace("[query]", query) + template = template.replace("{{QUERY}}", query) + + for query_placeholder in query_placeholders: + template = template.replace(query_placeholder, query) + + return template + + +def title_generation_template( + template: str, messages: list[dict], user: Optional[dict] = None +) -> str: + prompt = get_last_user_message(messages) + template = replace_prompt_variable(template, prompt) + template = replace_messages_variable(template, messages) + + template = prompt_template( + template, + **( + {"user_name": user.get("name"), "user_location": user.get("location")} + if user + else {} + ), + ) + + return template + + +def tags_generation_template( + template: str, messages: list[dict], user: Optional[dict] = None +) -> str: + prompt = get_last_user_message(messages) + template = replace_prompt_variable(template, prompt) + template = replace_messages_variable(template, messages) + + template = prompt_template( + template, + **( + {"user_name": user.get("name"), "user_location": user.get("location")} + if user + else {} + ), + ) + return template + + +def image_prompt_generation_template( + template: str, messages: list[dict], user: Optional[dict] = None +) -> str: + prompt = get_last_user_message(messages) + template = replace_prompt_variable(template, prompt) + template = replace_messages_variable(template, messages) + + template = prompt_template( + template, + **( + {"user_name": user.get("name"), "user_location": user.get("location")} + if user + else {} + ), + ) + return template + + +def emoji_generation_template( + template: str, prompt: str, user: Optional[dict] = None +) -> str: + template = replace_prompt_variable(template, prompt) + template = prompt_template( + template, + **( + {"user_name": user.get("name"), "user_location": user.get("location")} + if user + else {} + ), + ) + + return template + + +def autocomplete_generation_template( + template: str, + prompt: str, + messages: Optional[list[dict]] = None, + type: Optional[str] = None, + user: Optional[dict] = None, +) -> str: + template = template.replace("{{TYPE}}", type if type else "") + template = replace_prompt_variable(template, prompt) + template = replace_messages_variable(template, messages) + + template = prompt_template( + template, + **( + {"user_name": user.get("name"), "user_location": user.get("location")} + if user + else {} + ), + ) + return template + + +def query_generation_template( + template: str, messages: list[dict], user: Optional[dict] = None +) -> str: + prompt = get_last_user_message(messages) + template = replace_prompt_variable(template, prompt) + template = replace_messages_variable(template, messages) + + template = prompt_template( + template, + **( + {"user_name": user.get("name"), "user_location": user.get("location")} + if user + else {} + ), + ) + return template + + +def moa_response_generation_template( + template: str, prompt: str, responses: list[str] +) -> str: + def replacement_function(match): + full_match = match.group(0) + start_length = match.group(1) + end_length = match.group(2) + middle_length = match.group(3) + + if full_match == "{{prompt}}": + return prompt + elif start_length is not None: + return prompt[: int(start_length)] + elif end_length is not None: + return prompt[-int(end_length) :] + elif middle_length is not None: + middle_length = int(middle_length) + if len(prompt) <= middle_length: + return prompt + start = prompt[: math.ceil(middle_length / 2)] + end = prompt[-math.floor(middle_length / 2) :] + return f"{start}...{end}" + return "" + + template = re.sub( + r"{{prompt}}|{{prompt:start:(\d+)}}|{{prompt:end:(\d+)}}|{{prompt:middletruncate:(\d+)}}", + replacement_function, + template, + ) + + responses = [f'"""{response}"""' for response in responses] + responses = "\n\n".join(responses) + + template = template.replace("{{responses}}", responses) + return template + + +def tools_function_calling_generation_template(template: str, tools_specs: str) -> str: + template = template.replace("{{TOOLS}}", tools_specs) + return template diff --git a/backend/open_webui/utils/tools.py b/backend/open_webui/utils/tools.py new file mode 100644 index 0000000..c44c304 --- /dev/null +++ b/backend/open_webui/utils/tools.py @@ -0,0 +1,215 @@ +import inspect +import logging +import re +from typing import Any, Awaitable, Callable, get_type_hints +from functools import update_wrapper, partial + + +from fastapi import Request +from pydantic import BaseModel, Field, create_model +from langchain_core.utils.function_calling import convert_to_openai_function + + +from open_webui.models.tools import Tools +from open_webui.models.users import UserModel +from open_webui.utils.plugin import load_tools_module_by_id + +log = logging.getLogger(__name__) + + +def apply_extra_params_to_tool_function( + function: Callable, extra_params: dict +) -> Callable[..., Awaitable]: + sig = inspect.signature(function) + extra_params = {k: v for k, v in extra_params.items() if k in sig.parameters} + partial_func = partial(function, **extra_params) + if inspect.iscoroutinefunction(function): + update_wrapper(partial_func, function) + return partial_func + + async def new_function(*args, **kwargs): + return partial_func(*args, **kwargs) + + update_wrapper(new_function, function) + return new_function + + +# Mutation on extra_params +def get_tools( + request: Request, tool_ids: list[str], user: UserModel, extra_params: dict +) -> dict[str, dict]: + tools_dict = {} + + for tool_id in tool_ids: + tools = Tools.get_tool_by_id(tool_id) + if tools is None: + continue + + module = request.app.state.TOOLS.get(tool_id, None) + if module is None: + module, _ = load_tools_module_by_id(tool_id) + request.app.state.TOOLS[tool_id] = module + + extra_params["__id__"] = tool_id + if hasattr(module, "valves") and hasattr(module, "Valves"): + valves = Tools.get_tool_valves_by_id(tool_id) or {} + module.valves = module.Valves(**valves) + + if hasattr(module, "UserValves"): + extra_params["__user__"]["valves"] = module.UserValves( # type: ignore + **Tools.get_user_valves_by_id_and_user_id(tool_id, user.id) + ) + + for spec in tools.specs: + # TODO: Fix hack for OpenAI API + # Some times breaks OpenAI but others don't. Leaving the comment + for val in spec.get("parameters", {}).get("properties", {}).values(): + if val["type"] == "str": + val["type"] = "string" + + # Remove internal parameters + spec["parameters"]["properties"] = { + key: val + for key, val in spec["parameters"]["properties"].items() + if not key.startswith("__") + } + + function_name = spec["name"] + + # convert to function that takes only model params and inserts custom params + original_func = getattr(module, function_name) + callable = apply_extra_params_to_tool_function(original_func, extra_params) + + if callable.__doc__ and callable.__doc__.strip() != "": + s = re.split(":(param|return)", callable.__doc__, 1) + spec["description"] = s[0] + else: + spec["description"] = function_name + + # TODO: This needs to be a pydantic model + tool_dict = { + "toolkit_id": tool_id, + "callable": callable, + "spec": spec, + "pydantic_model": function_to_pydantic_model(callable), + "file_handler": hasattr(module, "file_handler") and module.file_handler, + "citation": hasattr(module, "citation") and module.citation, + } + + # TODO: if collision, prepend toolkit name + if function_name in tools_dict: + log.warning(f"Tool {function_name} already exists in another tools!") + log.warning(f"Collision between {tools} and {tool_id}.") + log.warning(f"Discarding {tools}.{function_name}") + else: + tools_dict[function_name] = tool_dict + + return tools_dict + + +def parse_description(docstring: str | None) -> str: + """ + Parse a function's docstring to extract the description. + + Args: + docstring (str): The docstring to parse. + + Returns: + str: The description. + """ + + if not docstring: + return "" + + lines = [line.strip() for line in docstring.strip().split("\n")] + description_lines: list[str] = [] + + for line in lines: + if re.match(r":param", line) or re.match(r":return", line): + break + + description_lines.append(line) + + return "\n".join(description_lines) + + +def parse_docstring(docstring): + """ + Parse a function's docstring to extract parameter descriptions in reST format. + + Args: + docstring (str): The docstring to parse. + + Returns: + dict: A dictionary where keys are parameter names and values are descriptions. + """ + if not docstring: + return {} + + # Regex to match `:param name: description` format + param_pattern = re.compile(r":param (\w+):\s*(.+)") + param_descriptions = {} + + for line in docstring.splitlines(): + match = param_pattern.match(line.strip()) + if not match: + continue + param_name, param_description = match.groups() + if param_name.startswith("__"): + continue + param_descriptions[param_name] = param_description + + return param_descriptions + + +def function_to_pydantic_model(func: Callable) -> type[BaseModel]: + """ + Converts a Python function's type hints and docstring to a Pydantic model, + including support for nested types, default values, and descriptions. + + Args: + func: The function whose type hints and docstring should be converted. + model_name: The name of the generated Pydantic model. + + Returns: + A Pydantic model class. + """ + type_hints = get_type_hints(func) + signature = inspect.signature(func) + parameters = signature.parameters + + docstring = func.__doc__ + descriptions = parse_docstring(docstring) + + tool_description = parse_description(docstring) + + field_defs = {} + for name, param in parameters.items(): + type_hint = type_hints.get(name, Any) + default_value = param.default if param.default is not param.empty else ... + description = descriptions.get(name, None) + if not description: + field_defs[name] = type_hint, default_value + continue + field_defs[name] = type_hint, Field(default_value, description=description) + + model = create_model(func.__name__, **field_defs) + model.__doc__ = tool_description + + return model + + +def get_callable_attributes(tool: object) -> list[Callable]: + return [ + getattr(tool, func) + for func in dir(tool) + if callable(getattr(tool, func)) + and not func.startswith("__") + and not inspect.isclass(getattr(tool, func)) + ] + + +def get_tools_specs(tool_class: object) -> list[dict]: + function_list = get_callable_attributes(tool_class) + models = map(function_to_pydantic_model, function_list) + return [convert_to_openai_function(tool) for tool in models] diff --git a/backend/open_webui/utils/webhook.py b/backend/open_webui/utils/webhook.py new file mode 100644 index 0000000..bf0b334 --- /dev/null +++ b/backend/open_webui/utils/webhook.py @@ -0,0 +1,60 @@ +import json +import logging + +import requests +from open_webui.config import WEBUI_FAVICON_URL +from open_webui.env import SRC_LOG_LEVELS, VERSION + +log = logging.getLogger(__name__) +log.setLevel(SRC_LOG_LEVELS["WEBHOOK"]) + + +def post_webhook(name: str, url: str, message: str, event_data: dict) -> bool: + try: + log.debug(f"post_webhook: {url}, {message}, {event_data}") + payload = {} + + # Slack and Google Chat Webhooks + if "https://hooks.slack.com" in url or "https://chat.googleapis.com" in url: + payload["text"] = message + # Discord Webhooks + elif "https://discord.com/api/webhooks" in url: + payload["content"] = ( + message + if len(message) < 2000 + else f"{message[: 2000 - 20]}... (truncated)" + ) + # Microsoft Teams Webhooks + elif "webhook.office.com" in url: + action = event_data.get("action", "undefined") + facts = [ + {"name": name, "value": value} + for name, value in json.loads(event_data.get("user", {})).items() + ] + payload = { + "@type": "MessageCard", + "@context": "http://schema.org/extensions", + "themeColor": "0076D7", + "summary": message, + "sections": [ + { + "activityTitle": message, + "activitySubtitle": f"{name} ({VERSION}) - {action}", + "activityImage": WEBUI_FAVICON_URL, + "facts": facts, + "markdown": True, + } + ], + } + # Default Payload + else: + payload = {**event_data} + + log.debug(f"payload: {payload}") + r = requests.post(url, json=payload) + r.raise_for_status() + log.debug(f"r.text: {r.text}") + return True + except Exception as e: + log.exception(e) + return False diff --git a/backend/requirements.txt b/backend/requirements.txt new file mode 100644 index 0000000..6168271 --- /dev/null +++ b/backend/requirements.txt @@ -0,0 +1,118 @@ +fastapi==0.115.7 +uvicorn[standard]==0.30.6 +pydantic==2.10.6 +python-multipart==0.0.18 + +python-socketio==5.11.3 +python-jose==3.4.0 +passlib[bcrypt]==1.7.4 + +requests==2.32.3 +aiohttp==3.11.11 +async-timeout +aiocache +aiofiles + +sqlalchemy==2.0.32 +alembic==1.14.0 +peewee==3.17.8 +peewee-migrate==1.12.2 +psycopg2-binary==2.9.9 +pgvector==0.3.5 +PyMySQL==1.1.1 +bcrypt==4.2.0 + +pymongo +redis +boto3==1.35.53 + +argon2-cffi==23.1.0 +APScheduler==3.10.4 + +RestrictedPython==8.0 + +loguru==0.7.2 +asgiref==3.8.1 + +# AI libraries +openai +anthropic +google-generativeai==0.7.2 +tiktoken + +langchain==0.3.7 +langchain-community==0.3.7 + +fake-useragent==1.5.1 +chromadb==0.6.2 +pymilvus==2.5.0 +qdrant-client~=1.12.0 +opensearch-py==2.8.0 +playwright==1.49.1 # Caution: version must match docker-compose.playwright.yaml + +transformers +sentence-transformers==3.3.1 +colbert-ai==0.2.21 +einops==0.8.0 + + +ftfy==6.2.3 +pypdf==4.3.1 +fpdf2==2.8.2 +pymdown-extensions==10.14.2 +docx2txt==0.8 +python-pptx==1.0.0 +unstructured==0.16.17 +nltk==3.9.1 +Markdown==3.7 +pypandoc==1.13 +pandas==2.2.3 +openpyxl==3.1.5 +pyxlsb==1.0.10 +xlrd==2.0.1 +validators==0.34.0 +psutil +sentencepiece +soundfile==0.13.1 +azure-ai-documentintelligence==1.0.0 + +opencv-python-headless==4.11.0.86 +rapidocr-onnxruntime==1.3.24 +rank-bm25==0.2.2 + +faster-whisper==1.1.1 + +PyJWT[crypto]==2.10.1 +authlib==1.4.1 + +black==24.8.0 +langfuse==2.44.0 +youtube-transcript-api==0.6.3 +pytube==15.0.0 + +extract_msg +pydub +duckduckgo-search~=7.3.2 + +## Google Drive +google-api-python-client +google-auth-httplib2 +google-auth-oauthlib + +## Tests +docker~=7.1.0 +pytest~=8.3.2 +pytest-docker~=3.1.1 + +googleapis-common-protos==1.63.2 +google-cloud-storage==2.19.0 + +azure-identity==1.20.0 +azure-storage-blob==12.24.1 + + +## LDAP +ldap3==2.9.1 + +## Firecrawl +firecrawl-py==1.12.0 diff --git a/backend/start.sh b/backend/start.sh new file mode 100755 index 0000000..671c22f --- /dev/null +++ b/backend/start.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +cd "$SCRIPT_DIR" || exit + +# Add conditional Playwright browser installation +if [[ "${RAG_WEB_LOADER_ENGINE,,}" == "playwright" ]]; then + if [[ -z "${PLAYWRIGHT_WS_URI}" ]]; then + echo "Installing Playwright browsers..." + playwright install chromium + playwright install-deps chromium + fi + + python -c "import nltk; nltk.download('punkt_tab')" +fi + +KEY_FILE=.webui_secret_key + +PORT="${PORT:-8080}" +HOST="${HOST:-0.0.0.0}" +if test "$WEBUI_SECRET_KEY $WEBUI_JWT_SECRET_KEY" = " "; then + echo "Loading WEBUI_SECRET_KEY from file, not provided as an environment variable." + + if ! [ -e "$KEY_FILE" ]; then + echo "Generating WEBUI_SECRET_KEY" + # Generate a random value to use as a WEBUI_SECRET_KEY in case the user didn't provide one. + echo $(head -c 12 /dev/random | base64) > "$KEY_FILE" + fi + + echo "Loading WEBUI_SECRET_KEY from $KEY_FILE" + WEBUI_SECRET_KEY=$(cat "$KEY_FILE") +fi + +if [[ "${USE_OLLAMA_DOCKER,,}" == "true" ]]; then + echo "USE_OLLAMA is set to true, starting ollama serve." + ollama serve & +fi + +if [[ "${USE_CUDA_DOCKER,,}" == "true" ]]; then + echo "CUDA is enabled, appending LD_LIBRARY_PATH to include torch/cudnn & cublas libraries." + export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/lib/python3.11/site-packages/torch/lib:/usr/local/lib/python3.11/site-packages/nvidia/cudnn/lib" +fi + +# Check if SPACE_ID is set, if so, configure for space +if [ -n "$SPACE_ID" ]; then + echo "Configuring for HuggingFace Space deployment" + if [ -n "$ADMIN_USER_EMAIL" ] && [ -n "$ADMIN_USER_PASSWORD" ]; then + echo "Admin user configured, creating" + WEBUI_SECRET_KEY="$WEBUI_SECRET_KEY" uvicorn open_webui.main:app --host "$HOST" --port "$PORT" --forwarded-allow-ips '*' & + webui_pid=$! + echo "Waiting for webui to start..." + while ! curl -s http://localhost:8080/health > /dev/null; do + sleep 1 + done + echo "Creating admin user..." + curl \ + -X POST "http://localhost:8080/api/v1/auths/signup" \ + -H "accept: application/json" \ + -H "Content-Type: application/json" \ + -d "{ \"email\": \"${ADMIN_USER_EMAIL}\", \"password\": \"${ADMIN_USER_PASSWORD}\", \"name\": \"Admin\" }" + echo "Shutting down webui..." + kill $webui_pid + fi + + export WEBUI_URL=${SPACE_HOST} +fi + +WEBUI_SECRET_KEY="$WEBUI_SECRET_KEY" exec uvicorn open_webui.main:app --host "$HOST" --port "$PORT" --forwarded-allow-ips '*' diff --git a/backend/start_windows.bat b/backend/start_windows.bat new file mode 100644 index 0000000..7049cd1 --- /dev/null +++ b/backend/start_windows.bat @@ -0,0 +1,44 @@ +:: This method is not recommended, and we recommend you use the `start.sh` file with WSL instead. +@echo off +SETLOCAL ENABLEDELAYEDEXPANSION + +:: Get the directory of the current script +SET "SCRIPT_DIR=%~dp0" +cd /d "%SCRIPT_DIR%" || exit /b + +:: Add conditional Playwright browser installation +IF /I "%RAG_WEB_LOADER_ENGINE%" == "playwright" ( + IF "%PLAYWRIGHT_WS_URI%" == "" ( + echo Installing Playwright browsers... + playwright install chromium + playwright install-deps chromium + ) + + python -c "import nltk; nltk.download('punkt_tab')" +) + +SET "KEY_FILE=.webui_secret_key" +IF "%PORT%"=="" SET PORT=8080 +IF "%HOST%"=="" SET HOST=0.0.0.0 +SET "WEBUI_SECRET_KEY=%WEBUI_SECRET_KEY%" +SET "WEBUI_JWT_SECRET_KEY=%WEBUI_JWT_SECRET_KEY%" + +:: Check if WEBUI_SECRET_KEY and WEBUI_JWT_SECRET_KEY are not set +IF "%WEBUI_SECRET_KEY%%WEBUI_JWT_SECRET_KEY%" == " " ( + echo Loading WEBUI_SECRET_KEY from file, not provided as an environment variable. + + IF NOT EXIST "%KEY_FILE%" ( + echo Generating WEBUI_SECRET_KEY + :: Generate a random value to use as a WEBUI_SECRET_KEY in case the user didn't provide one + SET /p WEBUI_SECRET_KEY=>%KEY_FILE% + echo WEBUI_SECRET_KEY generated + ) + + echo Loading WEBUI_SECRET_KEY from %KEY_FILE% + SET /p WEBUI_SECRET_KEY=<%KEY_FILE% +) + +:: Execute uvicorn +SET "WEBUI_SECRET_KEY=%WEBUI_SECRET_KEY%" +uvicorn open_webui.main:app --host "%HOST%" --port "%PORT%" --forwarded-allow-ips '*' diff --git a/catalog.json b/catalog.json deleted file mode 100644 index 128779e..0000000 --- a/catalog.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "kodekspracy": "Kodeks Pracy", - "urlopproporcjonalny": "Rozporządzenie BHP", - "ustawaopanstwowejinspekcjipracy": "Ustawa o Państwowej inspekcji pracy" -} \ No newline at end of file diff --git a/confirm_remove.sh b/confirm_remove.sh new file mode 100755 index 0000000..051908e --- /dev/null +++ b/confirm_remove.sh @@ -0,0 +1,13 @@ +#!/bin/bash +echo "Warning: This will remove all containers and volumes, including persistent data. Do you want to continue? [Y/N]" +read ans +if [ "$ans" == "Y" ] || [ "$ans" == "y" ]; then + command docker-compose 2>/dev/null + if [ "$?" == "0" ]; then + docker-compose down -v + else + docker compose down -v + fi +else + echo "Operation cancelled." +fi diff --git a/cypress.config.ts b/cypress.config.ts new file mode 100644 index 0000000..dbb5382 --- /dev/null +++ b/cypress.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from 'cypress'; + +export default defineConfig({ + e2e: { + baseUrl: 'http://localhost:8080' + }, + video: true +}); diff --git a/cypress/data/example-doc.txt b/cypress/data/example-doc.txt new file mode 100644 index 0000000..d4f6f45 --- /dev/null +++ b/cypress/data/example-doc.txt @@ -0,0 +1,9 @@ +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Pellentesque elit eget gravida cum sociis natoque. Morbi tristique senectus et netus et malesuada. Sapien nec sagittis aliquam malesuada bibendum. Amet consectetur adipiscing elit duis tristique sollicitudin. Non pulvinar neque laoreet suspendisse interdum consectetur libero. Arcu cursus vitae congue mauris rhoncus aenean vel elit scelerisque. Nec feugiat nisl pretium fusce id velit. Imperdiet proin fermentum leo vel. Arcu dui vivamus arcu felis bibendum ut tristique et egestas. Pellentesque sit amet porttitor eget dolor morbi non arcu risus. Egestas tellus rutrum tellus pellentesque eu tincidunt tortor aliquam. Et ultrices neque ornare aenean euismod. + +Enim nulla aliquet porttitor lacus luctus accumsan tortor posuere ac. Viverra nibh cras pulvinar mattis nunc. Lacinia at quis risus sed vulputate. Ac tortor vitae purus faucibus ornare suspendisse sed nisi lacus. Bibendum arcu vitae elementum curabitur vitae nunc. Consectetur adipiscing elit duis tristique sollicitudin nibh sit amet commodo. Velit egestas dui id ornare arcu odio ut. Et malesuada fames ac turpis egestas integer eget aliquet. Lacus suspendisse faucibus interdum posuere lorem ipsum dolor sit. Morbi tristique senectus et netus. Pretium viverra suspendisse potenti nullam ac tortor vitae. Parturient montes nascetur ridiculus mus mauris vitae. Quis viverra nibh cras pulvinar mattis nunc sed blandit libero. Euismod nisi porta lorem mollis aliquam ut porttitor leo. Mauris in aliquam sem fringilla ut morbi. Faucibus pulvinar elementum integer enim neque. Neque sodales ut etiam sit. Consectetur a erat nam at. + +Sed nisi lacus sed viverra tellus in hac habitasse. Proin sagittis nisl rhoncus mattis rhoncus. Risus commodo viverra maecenas accumsan lacus. Morbi quis commodo odio aenean sed adipiscing. Mollis nunc sed id semper risus in. Ultricies mi eget mauris pharetra et ultrices neque. Amet luctus venenatis lectus magna fringilla urna porttitor rhoncus. Eget magna fermentum iaculis eu non diam phasellus. Id diam maecenas ultricies mi eget mauris pharetra et ultrices. Id donec ultrices tincidunt arcu non sodales. Sed cras ornare arcu dui vivamus arcu felis bibendum ut. Urna duis convallis convallis tellus id interdum velit. Rhoncus mattis rhoncus urna neque viverra justo nec. Purus semper eget duis at tellus at urna condimentum. Et odio pellentesque diam volutpat commodo sed egestas. Blandit volutpat maecenas volutpat blandit. In egestas erat imperdiet sed euismod nisi porta lorem mollis. Est ullamcorper eget nulla facilisi etiam dignissim. + +Justo nec ultrices dui sapien eget mi proin sed. Purus gravida quis blandit turpis cursus in hac. Placerat orci nulla pellentesque dignissim enim sit. Morbi tristique senectus et netus et malesuada fames ac. Consequat mauris nunc congue nisi. Eu lobortis elementum nibh tellus molestie nunc non blandit. Viverra justo nec ultrices dui. Morbi non arcu risus quis. Elementum sagittis vitae et leo duis. Lectus mauris ultrices eros in cursus. Neque laoreet suspendisse interdum consectetur. + +Facilisis gravida neque convallis a cras. Nisl rhoncus mattis rhoncus urna neque viverra justo. Faucibus purus in massa tempor. Lacus laoreet non curabitur gravida arcu ac tortor. Tincidunt eget nullam non nisi est sit amet. Ornare lectus sit amet est placerat in egestas. Sollicitudin tempor id eu nisl nunc mi. Scelerisque viverra mauris in aliquam sem fringilla ut. Ullamcorper sit amet risus nullam. Mauris rhoncus aenean vel elit scelerisque mauris pellentesque pulvinar. Velit euismod in pellentesque massa placerat duis ultricies lacus. Pharetra magna ac placerat vestibulum lectus mauris ultrices eros in. Lorem ipsum dolor sit amet. Sit amet mauris commodo quis imperdiet. Quam pellentesque nec nam aliquam sem et tortor. Amet nisl purus in mollis nunc. Sed risus pretium quam vulputate dignissim suspendisse in est. Nisl condimentum id venenatis a condimentum. Velit euismod in pellentesque massa. Quam id leo in vitae turpis massa sed. diff --git a/cypress/e2e/chat.cy.ts b/cypress/e2e/chat.cy.ts new file mode 100644 index 0000000..17c4d8e --- /dev/null +++ b/cypress/e2e/chat.cy.ts @@ -0,0 +1,106 @@ +// eslint-disable-next-line @typescript-eslint/triple-slash-reference +/// + +// These tests run through the chat flow. +describe('Settings', () => { + // Wait for 2 seconds after all tests to fix an issue with Cypress's video recording missing the last few frames + after(() => { + // eslint-disable-next-line cypress/no-unnecessary-waiting + cy.wait(2000); + }); + + beforeEach(() => { + // Login as the admin user + cy.loginAdmin(); + // Visit the home page + cy.visit('/'); + }); + + context('Ollama', () => { + it('user can select a model', () => { + // Click on the model selector + cy.get('button[aria-label="Select a model"]').click(); + // Select the first model + cy.get('button[aria-label="model-item"]').first().click(); + }); + + it('user can perform text chat', () => { + // Click on the model selector + cy.get('button[aria-label="Select a model"]').click(); + // Select the first model + cy.get('button[aria-label="model-item"]').first().click(); + // Type a message + cy.get('#chat-input').type('Hi, what can you do? A single sentence only please.', { + force: true + }); + // Send the message + cy.get('button[type="submit"]').click(); + // User's message should be visible + cy.get('.chat-user').should('exist'); + // Wait for the response + // .chat-assistant is created after the first token is received + cy.get('.chat-assistant', { timeout: 10_000 }).should('exist'); + // Generation Info is created after the stop token is received + cy.get('div[aria-label="Generation Info"]', { timeout: 120_000 }).should('exist'); + }); + + it('user can share chat', () => { + // Click on the model selector + cy.get('button[aria-label="Select a model"]').click(); + // Select the first model + cy.get('button[aria-label="model-item"]').first().click(); + // Type a message + cy.get('#chat-input').type('Hi, what can you do? A single sentence only please.', { + force: true + }); + // Send the message + cy.get('button[type="submit"]').click(); + // User's message should be visible + cy.get('.chat-user').should('exist'); + // Wait for the response + // .chat-assistant is created after the first token is received + cy.get('.chat-assistant', { timeout: 10_000 }).should('exist'); + // Generation Info is created after the stop token is received + cy.get('div[aria-label="Generation Info"]', { timeout: 120_000 }).should('exist'); + // spy on requests + const spy = cy.spy(); + cy.intercept('POST', '/api/v1/chats/**/share', spy); + // Open context menu + cy.get('#chat-context-menu-button').click(); + // Click share button + cy.get('#chat-share-button').click(); + // Check if the share dialog is visible + cy.get('#copy-and-share-chat-button').should('exist'); + // Click the copy button + cy.get('#copy-and-share-chat-button').click(); + cy.wrap({}, { timeout: 5_000 }).should(() => { + // Check if the share request was made + expect(spy).to.be.callCount(1); + }); + }); + + it('user can generate image', () => { + // Click on the model selector + cy.get('button[aria-label="Select a model"]').click(); + // Select the first model + cy.get('button[aria-label="model-item"]').first().click(); + // Type a message + cy.get('#chat-input').type('Hi, what can you do? A single sentence only please.', { + force: true + }); + // Send the message + cy.get('button[type="submit"]').click(); + // User's message should be visible + cy.get('.chat-user').should('exist'); + // Wait for the response + // .chat-assistant is created after the first token is received + cy.get('.chat-assistant', { timeout: 10_000 }).should('exist'); + // Generation Info is created after the stop token is received + cy.get('div[aria-label="Generation Info"]', { timeout: 120_000 }).should('exist'); + // Click on the generate image button + cy.get('[aria-label="Generate Image"]').click(); + // Wait for image to be visible + cy.get('img[data-cy="image"]', { timeout: 60_000 }).should('be.visible'); + }); + }); +}); diff --git a/cypress/e2e/documents.cy.ts b/cypress/e2e/documents.cy.ts new file mode 100644 index 0000000..b14b1de --- /dev/null +++ b/cypress/e2e/documents.cy.ts @@ -0,0 +1,2 @@ +// eslint-disable-next-line @typescript-eslint/triple-slash-reference +/// diff --git a/cypress/e2e/registration.cy.ts b/cypress/e2e/registration.cy.ts new file mode 100644 index 0000000..232d75e --- /dev/null +++ b/cypress/e2e/registration.cy.ts @@ -0,0 +1,52 @@ +// eslint-disable-next-line @typescript-eslint/triple-slash-reference +/// +import { adminUser } from '../support/e2e'; + +// These tests assume the following defaults: +// 1. No users exist in the database or that the test admin user is an admin +// 2. Language is set to English +// 3. The default role for new users is 'pending' +describe('Registration and Login', () => { + // Wait for 2 seconds after all tests to fix an issue with Cypress's video recording missing the last few frames + after(() => { + // eslint-disable-next-line cypress/no-unnecessary-waiting + cy.wait(2000); + }); + + beforeEach(() => { + cy.visit('/'); + }); + + it('should register a new user as pending', () => { + const userName = `Test User - ${Date.now()}`; + const userEmail = `cypress-${Date.now()}@example.com`; + // Toggle from sign in to sign up + cy.contains('Sign up').click(); + // Fill out the form + cy.get('input[autocomplete="name"]').type(userName); + cy.get('input[autocomplete="email"]').type(userEmail); + cy.get('input[type="password"]').type('password'); + // Submit the form + cy.get('button[type="submit"]').click(); + // Wait until the user is redirected to the home page + cy.contains(userName); + // Expect the user to be pending + cy.contains('Check Again'); + }); + + it('can login with the admin user', () => { + // Fill out the form + cy.get('input[autocomplete="email"]').type(adminUser.email); + cy.get('input[type="password"]').type(adminUser.password); + // Submit the form + cy.get('button[type="submit"]').click(); + // Wait until the user is redirected to the home page + cy.contains(adminUser.name); + // Dismiss the changelog dialog if it is visible + cy.getAllLocalStorage().then((ls) => { + if (!ls['version']) { + cy.get('button').contains("Okay, Let's Go!").click(); + } + }); + }); +}); diff --git a/cypress/e2e/settings.cy.ts b/cypress/e2e/settings.cy.ts new file mode 100644 index 0000000..4ea9169 --- /dev/null +++ b/cypress/e2e/settings.cy.ts @@ -0,0 +1,63 @@ +// eslint-disable-next-line @typescript-eslint/triple-slash-reference +/// +import { adminUser } from '../support/e2e'; + +// These tests run through the various settings pages, ensuring that the user can interact with them as expected +describe('Settings', () => { + // Wait for 2 seconds after all tests to fix an issue with Cypress's video recording missing the last few frames + after(() => { + // eslint-disable-next-line cypress/no-unnecessary-waiting + cy.wait(2000); + }); + + beforeEach(() => { + // Login as the admin user + cy.loginAdmin(); + // Visit the home page + cy.visit('/'); + // Click on the user menu + cy.get('button[aria-label="User Menu"]').click(); + // Click on the settings link + cy.get('button').contains('Settings').click(); + }); + + context('General', () => { + it('user can open the General modal and hit save', () => { + cy.get('button').contains('General').click(); + cy.get('button').contains('Save').click(); + }); + }); + + context('Interface', () => { + it('user can open the Interface modal and hit save', () => { + cy.get('button').contains('Interface').click(); + cy.get('button').contains('Save').click(); + }); + }); + + context('Audio', () => { + it('user can open the Audio modal and hit save', () => { + cy.get('button').contains('Audio').click(); + cy.get('button').contains('Save').click(); + }); + }); + + context('Chats', () => { + it('user can open the Chats modal', () => { + cy.get('button').contains('Chats').click(); + }); + }); + + context('Account', () => { + it('user can open the Account modal and hit save', () => { + cy.get('button').contains('Account').click(); + cy.get('button').contains('Save').click(); + }); + }); + + context('About', () => { + it('user can open the About modal', () => { + cy.get('button').contains('About').click(); + }); + }); +}); diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.ts new file mode 100644 index 0000000..0b94c47 --- /dev/null +++ b/cypress/support/e2e.ts @@ -0,0 +1,78 @@ +/// +// eslint-disable-next-line @typescript-eslint/triple-slash-reference +/// + +export const adminUser = { + name: 'Admin User', + email: 'admin@example.com', + password: 'password' +}; + +const login = (email: string, password: string) => { + return cy.session( + email, + () => { + // Make sure to test against us english to have stable tests, + // regardless on local language preferences + localStorage.setItem('locale', 'en-US'); + // Visit auth page + cy.visit('/auth'); + // Fill out the form + cy.get('input[autocomplete="email"]').type(email); + cy.get('input[type="password"]').type(password); + // Submit the form + cy.get('button[type="submit"]').click(); + // Wait until the user is redirected to the home page + cy.get('#chat-search').should('exist'); + // Get the current version to skip the changelog dialog + if (localStorage.getItem('version') === null) { + cy.get('button').contains("Okay, Let's Go!").click(); + } + }, + { + validate: () => { + cy.request({ + method: 'GET', + url: '/api/v1/auths/', + headers: { + Authorization: 'Bearer ' + localStorage.getItem('token') + } + }); + } + } + ); +}; + +const register = (name: string, email: string, password: string) => { + return cy + .request({ + method: 'POST', + url: '/api/v1/auths/signup', + body: { + name: name, + email: email, + password: password + }, + failOnStatusCode: false + }) + .then((response) => { + expect(response.status).to.be.oneOf([200, 400]); + }); +}; + +const registerAdmin = () => { + return register(adminUser.name, adminUser.email, adminUser.password); +}; + +const loginAdmin = () => { + return login(adminUser.email, adminUser.password); +}; + +Cypress.Commands.add('login', (email, password) => login(email, password)); +Cypress.Commands.add('register', (name, email, password) => register(name, email, password)); +Cypress.Commands.add('registerAdmin', () => registerAdmin()); +Cypress.Commands.add('loginAdmin', () => loginAdmin()); + +before(() => { + cy.registerAdmin(); +}); diff --git a/cypress/support/index.d.ts b/cypress/support/index.d.ts new file mode 100644 index 0000000..647db92 --- /dev/null +++ b/cypress/support/index.d.ts @@ -0,0 +1,13 @@ +// load the global Cypress types +/// + +declare namespace Cypress { + interface Chainable { + login(email: string, password: string): Chainable; + register(name: string, email: string, password: string): Chainable; + registerAdmin(): Chainable; + loginAdmin(): Chainable; + uploadTestDocument(suffix: any): Chainable; + deleteTestDocument(suffix: any): Chainable; + } +} diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json new file mode 100644 index 0000000..ff28d94 --- /dev/null +++ b/cypress/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "inlineSourceMap": true, + "sourceMap": false + } +} diff --git a/demo.gif b/demo.gif new file mode 100644 index 0000000..6e56b74 Binary files /dev/null and b/demo.gif differ diff --git a/docker-compose.a1111-test.yaml b/docker-compose.a1111-test.yaml new file mode 100644 index 0000000..e6ab12c --- /dev/null +++ b/docker-compose.a1111-test.yaml @@ -0,0 +1,31 @@ +# This is an overlay that spins up stable-diffusion-webui for integration testing +# This is not designed to be used in production +services: + stable-diffusion-webui: + # Not built for ARM64 + platform: linux/amd64 + image: ghcr.io/neggles/sd-webui-docker:latest + restart: unless-stopped + environment: + CLI_ARGS: "--api --use-cpu all --precision full --no-half --skip-torch-cuda-test --ckpt /empty.pt --do-not-download-clip --disable-nan-check --disable-opt-split-attention" + PYTHONUNBUFFERED: "1" + TERM: "vt100" + SD_WEBUI_VARIANT: "default" + # Hack to get container working on Apple Silicon + # Rosetta creates a conflict ${HOME}/.cache folder + entrypoint: /bin/bash + command: + - -c + - | + export HOME=/root-home + rm -rf $${HOME}/.cache + /docker/entrypoint.sh python -u webui.py --listen --port $${WEBUI_PORT} --skip-version-check $${CLI_ARGS} + volumes: + - ./test/test_files/image_gen/sd-empty.pt:/empty.pt + + open-webui: + environment: + ENABLE_IMAGE_GENERATION: "true" + AUTOMATIC1111_BASE_URL: http://stable-diffusion-webui:7860 + IMAGE_SIZE: "64x64" + IMAGE_STEPS: "3" diff --git a/docker-compose.amdgpu.yaml b/docker-compose.amdgpu.yaml new file mode 100644 index 0000000..7a1295d --- /dev/null +++ b/docker-compose.amdgpu.yaml @@ -0,0 +1,8 @@ +services: + ollama: + devices: + - /dev/kfd:/dev/kfd + - /dev/dri:/dev/dri + image: ollama/ollama:${OLLAMA_DOCKER_TAG-rocm} + environment: + - 'HSA_OVERRIDE_GFX_VERSION=${HSA_OVERRIDE_GFX_VERSION-11.0.0}' \ No newline at end of file diff --git a/docker-compose.api.yaml b/docker-compose.api.yaml new file mode 100644 index 0000000..8f8fbe5 --- /dev/null +++ b/docker-compose.api.yaml @@ -0,0 +1,5 @@ +services: + ollama: + # Expose Ollama API outside the container stack + ports: + - ${OLLAMA_WEBAPI_PORT-11434}:11434 diff --git a/docker-compose.data.yaml b/docker-compose.data.yaml new file mode 100644 index 0000000..4b70601 --- /dev/null +++ b/docker-compose.data.yaml @@ -0,0 +1,4 @@ +services: + ollama: + volumes: + - ${OLLAMA_DATA_DIR-./ollama-data}:/root/.ollama diff --git a/docker-compose.gpu.yaml b/docker-compose.gpu.yaml new file mode 100644 index 0000000..de82123 --- /dev/null +++ b/docker-compose.gpu.yaml @@ -0,0 +1,11 @@ +services: + ollama: + # GPU support + deploy: + resources: + reservations: + devices: + - driver: ${OLLAMA_GPU_DRIVER-nvidia} + count: ${OLLAMA_GPU_COUNT-1} + capabilities: + - gpu diff --git a/docker-compose.playwright.yaml b/docker-compose.playwright.yaml new file mode 100644 index 0000000..fe570be --- /dev/null +++ b/docker-compose.playwright.yaml @@ -0,0 +1,10 @@ +services: + playwright: + image: mcr.microsoft.com/playwright:v1.49.1-noble # Version must match requirements.txt + container_name: playwright + command: npx -y playwright@1.49.1 run-server --port 3000 --host 0.0.0.0 + + open-webui: + environment: + - 'RAG_WEB_LOADER_ENGINE=playwright' + - 'PLAYWRIGHT_WS_URI=ws://playwright:3000' \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..74249fe --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,34 @@ +services: + ollama: + volumes: + - ollama:/root/.ollama + container_name: ollama + pull_policy: always + tty: true + restart: unless-stopped + image: ollama/ollama:${OLLAMA_DOCKER_TAG-latest} + + open-webui: + build: + context: . + args: + OLLAMA_BASE_URL: '/ollama' + dockerfile: Dockerfile + image: ghcr.io/open-webui/open-webui:${WEBUI_DOCKER_TAG-main} + container_name: open-webui + volumes: + - open-webui:/app/backend/data + depends_on: + - ollama + ports: + - ${OPEN_WEBUI_PORT-3000}:8080 + environment: + - 'OLLAMA_BASE_URL=http://ollama:11434' + - 'WEBUI_SECRET_KEY=' + extra_hosts: + - host.docker.internal:host-gateway + restart: unless-stopped + +volumes: + ollama: {} + open-webui: {} diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md new file mode 100644 index 0000000..ec8a79b --- /dev/null +++ b/docs/CONTRIBUTING.md @@ -0,0 +1,73 @@ +# Contributing to Open WebUI + +🚀 **Welcome, Contributors!** 🚀 + +Your interest in contributing to Open WebUI is greatly appreciated. This document is here to guide you through the process, ensuring your contributions enhance the project effectively. Let's make Open WebUI even better, together! + +## 📌 Key Points + +### 🦙 Ollama vs. Open WebUI + +It's crucial to distinguish between Ollama and Open WebUI: + +- **Open WebUI** focuses on providing an intuitive and responsive web interface for chat interactions. +- **Ollama** is the underlying technology that powers these interactions. + +If your issue or contribution pertains directly to the core Ollama technology, please direct it to the appropriate [Ollama project repository](https://ollama.com/). Open WebUI's repository is dedicated to the web interface aspect only. + +### 🚨 Reporting Issues + +Noticed something off? Have an idea? Check our [Issues tab](https://github.com/open-webui/open-webui/issues) to see if it's already been reported or suggested. If not, feel free to open a new issue. When reporting an issue, please follow our issue templates. These templates are designed to ensure that all necessary details are provided from the start, enabling us to address your concerns more efficiently. + +> [!IMPORTANT] +> +> - **Template Compliance:** Please be aware that failure to follow the provided issue template, or not providing the requested information at all, will likely result in your issue being closed without further consideration. This approach is critical for maintaining the manageability and integrity of issue tracking. +> - **Detail is Key:** To ensure your issue is understood and can be effectively addressed, it's imperative to include comprehensive details. Descriptions should be clear, including steps to reproduce, expected outcomes, and actual results. Lack of sufficient detail may hinder our ability to resolve your issue. + +### 🧭 Scope of Support + +We've noticed an uptick in issues not directly related to Open WebUI but rather to the environment it's run in, especially Docker setups. While we strive to support Docker deployment, understanding Docker fundamentals is crucial for a smooth experience. + +- **Docker Deployment Support**: Open WebUI supports Docker deployment. Familiarity with Docker is assumed. For Docker basics, please refer to the [official Docker documentation](https://docs.docker.com/get-started/overview/). + +- **Advanced Configurations**: Setting up reverse proxies for HTTPS and managing Docker deployments requires foundational knowledge. There are numerous online resources available to learn these skills. Ensuring you have this knowledge will greatly enhance your experience with Open WebUI and similar projects. + +## 💡 Contributing + +Looking to contribute? Great! Here's how you can help: + +### 🛠 Pull Requests + +We welcome pull requests. Before submitting one, please: + +1. Open a discussion regarding your ideas [here](https://github.com/open-webui/open-webui/discussions/new/choose). +2. Follow the project's coding standards and include tests for new features. +3. Update documentation as necessary. +4. Write clear, descriptive commit messages. +5. It's essential to complete your pull request in a timely manner. We move fast, and having PRs hang around too long is not feasible. If you can't get it done within a reasonable time frame, we may have to close it to keep the project moving forward. + +### 📚 Documentation & Tutorials + +Help us make Open WebUI more accessible by improving documentation, writing tutorials, or creating guides on setting up and optimizing the web UI. + +### 🌐 Translations and Internationalization + +Help us make Open WebUI available to a wider audience. In this section, we'll guide you through the process of adding new translations to the project. + +We use JSON files to store translations. You can find the existing translation files in the `src/lib/i18n/locales` directory. Each directory corresponds to a specific language, for example, `en-US` for English (US), `fr-FR` for French (France) and so on. You can refer to [ISO 639 Language Codes](http://www.lingoes.net/en/translator/langcode.htm) to find the appropriate code for a specific language. + +To add a new language: + +- Create a new directory in the `src/lib/i18n/locales` path with the appropriate language code as its name. For instance, if you're adding translations for Spanish (Spain), create a new directory named `es-ES`. +- Copy the American English translation file(s) (from `en-US` directory in `src/lib/i18n/locale`) to this new directory and update the string values in JSON format according to your language. Make sure to preserve the structure of the JSON object. +- Add the language code and its respective title to languages file at `src/lib/i18n/locales/languages.json`. + +### 🤔 Questions & Feedback + +Got questions or feedback? Join our [Discord community](https://discord.gg/5rJgQTnV4s) or open an issue. We're here to help! + +## 🙏 Thank You! + +Your contributions, big or small, make a significant impact on Open WebUI. We're excited to see what you bring to the project! + +Together, let's create an even more powerful tool for the community. 🌟 diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..4113c35 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,3 @@ +# Project workflow + +[![](https://mermaid.ink/img/pako:eNq1k01rAjEQhv_KkFNLFe1N9iAUevFSRVl6Cci4Gd1ANtlmsmtF_O_N7iqtHxR76ClhMu87zwyZvcicIpEIpo-KbEavGjceC2lL9EFnukQbIGXygNye5y9TY7DAZTpZLsjXXVYXg3dapRM4hh9mu5A7-3hTfSXtAtJK21Tsj8dPl3USmJZkGVbebWNKD2rNOjAYl6HJHYdkNBwNpb3U9aNZvzFNYE6h8tFiSyZzBUGJG4K1dwVwTSYQrCptlLRvLt5dA5i2la5Ruk51Ux0VKQjuxPVbAwuyiuFlNgHfzJ5DoxtgqQf1813gnZRLZ5lAYcD7WT1lpGtiQKug9C4jZrrp-Fd-1-Y1bdzo4dvnZDLz7lPHyj8sOgfg4x84E7RTuEaZt8yRZqtDfgT_rwG2u3Dv_ERPFOQL1Cqu2F5aAClCTgVJkcSrojVWJkgh7SGmYhXcYmczkQRfUU9UZfQ4baRI1miYDl_QqlPg?type=png)](https://mermaid.live/edit#pako:eNq1k01rAjEQhv_KkFNLFe1N9iAUevFSRVl6Cci4Gd1ANtlmsmtF_O_N7iqtHxR76ClhMu87zwyZvcicIpEIpo-KbEavGjceC2lL9EFnukQbIGXygNye5y9TY7DAZTpZLsjXXVYXg3dapRM4hh9mu5A7-3hTfSXtAtJK21Tsj8dPl3USmJZkGVbebWNKD2rNOjAYl6HJHYdkNBwNpb3U9aNZvzFNYE6h8tFiSyZzBUGJG4K1dwVwTSYQrCptlLRvLt5dA5i2la5Ruk51Ux0VKQjuxPVbAwuyiuFlNgHfzJ5DoxtgqQf1813gnZRLZ5lAYcD7WT1lpGtiQKug9C4jZrrp-Fd-1-Y1bdzo4dvnZDLz7lPHyj8sOgfg4x84E7RTuEaZt8yRZqtDfgT_rwG2u3Dv_ERPFOQL1Cqu2F5aAClCTgVJkcSrojVWJkgh7SGmYhXcYmczkQRfUU9UZfQ4baRI1miYDl_QqlPg) diff --git a/docs/SECURITY.md b/docs/SECURITY.md new file mode 100644 index 0000000..507e3c6 --- /dev/null +++ b/docs/SECURITY.md @@ -0,0 +1,44 @@ +# Security Policy + +Our primary goal is to ensure the protection and confidentiality of sensitive data stored by users on open-webui. + +## Supported Versions + +| Version | Supported | +| ------- | ------------------ | +| main | :white_check_mark: | +| others | :x: | + +## Zero Tolerance for External Platforms + +Based on a precedent of an unacceptable degree of spamming and unsolicited communications from third-party platforms, we forcefully reaffirm our stance. **We refuse to engage with, join, or monitor any platforms outside of GitHub for vulnerability reporting.** Our reasons are not just procedural but are deep-seated in the ethos of our project, which champions transparency and direct community interaction inherent in the open-source culture. Any attempts to divert our processes to external platforms will be met with outright rejection. This policy is non-negotiable and understands no exceptions. + +Any reports or solicitations arriving from sources other than our designated GitHub repository will be dismissed without consideration. We’ve seen how external engagements can dilute and compromise the integrity of community-driven projects, and we’re not here to gamble with the security and privacy of our user community. + +## Reporting a Vulnerability + +We appreciate the community's interest in identifying potential vulnerabilities. However, effective immediately, we will **not** accept low-effort vulnerability reports. To ensure that submissions are constructive and actionable, please adhere to the following guidelines: + +Reports not submitted through our designated GitHub repository will be disregarded, and we will categorically reject invitations to collaborate on external platforms. Our aggressive stance on this matter underscores our commitment to a secure, transparent, and open community where all operations are visible and contributors are accountable. + +1. **No Vague Reports**: Submissions such as "I found a vulnerability" without any details will be treated as spam and will not be accepted. + +2. **In-Depth Understanding Required**: Reports must reflect a clear understanding of the codebase and provide specific details about the vulnerability, including the affected components and potential impacts. + +3. **Proof of Concept (PoC) is Mandatory**: Each submission must include a well-documented proof of concept (PoC) that demonstrates the vulnerability. If confidentiality is a concern, reporters are encouraged to create a private fork of the repository and share access with the maintainers. Reports lacking valid evidence will be disregarded. + +4. **Required Patch Submission**: Along with the PoC, reporters must provide a patch or actionable steps to remediate the identified vulnerability. This helps us evaluate and implement fixes rapidly. + +5. **Streamlined Merging Process**: When vulnerability reports meet the above criteria, we can consider them for immediate merging, similar to regular pull requests. Well-structured and thorough submissions will expedite the process of enhancing our security. + +**Non-compliant submissions will be closed, and repeat violators may be banned.** Our goal is to foster a constructive reporting environment where quality submissions promote better security for all users. + +## Product Security + +We regularly audit our internal processes and system architecture for vulnerabilities using a combination of automated and manual testing techniques. We are also planning to implement SAST and SCA scans in our project soon. + +For immediate concerns or detailed reports that meet our guidelines, please create an issue in our [issue tracker](/open-webui/open-webui/issues) or contact us on [Discord](https://discord.gg/5rJgQTnV4s). + +--- + +_Last updated on **2024-08-19**._ diff --git a/docs/apache.md b/docs/apache.md new file mode 100644 index 0000000..1bd9205 --- /dev/null +++ b/docs/apache.md @@ -0,0 +1,205 @@ +# Hosting UI and Models separately + +Sometimes, its beneficial to host Ollama, separate from the UI, but retain the RAG and RBAC support features shared across users: + +# Open WebUI Configuration + +## UI Configuration + +For the UI configuration, you can set up the Apache VirtualHost as follows: + +``` +# Assuming you have a website hosting this UI at "server.com" + + ServerName server.com + DocumentRoot /home/server/public_html + + ProxyPass / http://server.com:3000/ nocanon + ProxyPassReverse / http://server.com:3000/ + # Needed after 0.5 + ProxyPass / ws://server.com:3000/ nocanon + ProxyPassReverse / ws://server.com:3000/ + + +``` + +Enable the site first before you can request SSL: + +`a2ensite server.com.conf` # this will enable the site. a2ensite is short for "Apache 2 Enable Site" + +``` +# For SSL + + ServerName server.com + DocumentRoot /home/server/public_html + + ProxyPass / http://server.com:3000/ nocanon + ProxyPassReverse / http://server.com:3000/ + # Needed after 0.5 + ProxyPass / ws://server.com:3000/ nocanon + ProxyPassReverse / ws://server.com:3000/ + + SSLEngine on + SSLCertificateFile /etc/ssl/virtualmin/170514456861234/ssl.cert + SSLCertificateKeyFile /etc/ssl/virtualmin/170514456861234/ssl.key + SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 + + SSLProxyEngine on + SSLCACertificateFile /etc/ssl/virtualmin/170514456865864/ssl.ca + + +``` + +I'm using virtualmin here for my SSL clusters, but you can also use certbot directly or your preferred SSL method. To use SSL: + +### Prerequisites. + +Run the following commands: + +`snap install certbot --classic` +`snap apt install python3-certbot-apache` (this will install the apache plugin). + +Navigate to the apache sites-available directory: + +`cd /etc/apache2/sites-available/` + +Create server.com.conf if it is not yet already created, containing the above `` configuration (it should match your case. Modify as necessary). Use the one without the SSL: + +Once it's created, run `certbot --apache -d server.com`, this will request and add/create an SSL keys for you as well as create the server.com.le-ssl.conf + +# Configuring Ollama Server + +On your latest installation of Ollama, make sure that you have setup your api server from the official Ollama reference: + +[Ollama FAQ](https://github.com/jmorganca/ollama/blob/main/docs/faq.md) + +### TL;DR + +The guide doesn't seem to match the current updated service file on linux. So, we will address it here: + +Unless when you're compiling Ollama from source, installing with the standard install `curl https://ollama.com/install.sh | sh` creates a file called `ollama.service` in /etc/systemd/system. You can use nano to edit the file: + +``` +sudo nano /etc/systemd/system/ollama.service +``` + +Add the following lines: + +``` +Environment="OLLAMA_HOST=0.0.0.0:11434" # this line is mandatory. You can also specify +``` + +For instance: + +``` +[Unit] +Description=Ollama Service +After=network-online.target + +[Service] +ExecStart=/usr/local/bin/ollama serve +Environment="OLLAMA_HOST=0.0.0.0:11434" # this line is mandatory. You can also specify 192.168.254.109:DIFFERENT_PORT, format +Environment="OLLAMA_ORIGINS=http://192.168.254.106:11434,https://models.server.city" # this line is optional +User=ollama +Group=ollama +Restart=always +RestartSec=3 +Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/s> + +[Install] +WantedBy=default.target +``` + +Save the file by pressing CTRL+S, then press CTRL+X + +When your computer restarts, the Ollama server will now be listening on the IP:PORT you specified, in this case 0.0.0.0:11434, or 192.168.254.106:11434 (whatever your local IP address is). Make sure that your router is correctly configured to serve pages from that local IP by forwarding 11434 to your local IP server. + +# Ollama Model Configuration + +## For the Ollama model configuration, use the following Apache VirtualHost setup: + +Navigate to the apache sites-available directory: + +`cd /etc/apache2/sites-available/` + +`nano models.server.city.conf` # match this with your ollama server domain + +Add the following virtualhost containing this example (modify as needed): + +``` + +# Assuming you have a website hosting this UI at "models.server.city" + + + DocumentRoot "/var/www/html/" + ServerName models.server.city + + Options None + Require all granted + + + ProxyRequests Off + ProxyPreserveHost On + ProxyAddHeaders On + SSLProxyEngine on + + ProxyPass / http://server.city:1000/ nocanon # or port 11434 + ProxyPassReverse / http://server.city:1000/ # or port 11434 + + SSLCertificateFile /etc/letsencrypt/live/models.server.city/fullchain.pem + SSLCertificateKeyFile /etc/letsencrypt/live/models.server.city/privkey.pem + Include /etc/letsencrypt/options-ssl-apache.conf + + +``` + +You may need to enable the site first (if you haven't done so yet) before you can request SSL: + +`a2ensite models.server.city.conf` + +#### For the SSL part of Ollama server + +Run the following commands: + +Navigate to the apache sites-available directory: + +`cd /etc/apache2/sites-available/` +`certbot --apache -d server.com` + +``` + + DocumentRoot "/var/www/html/" + ServerName models.server.city + + Options None + Require all granted + + + ProxyRequests Off + ProxyPreserveHost On + ProxyAddHeaders On + SSLProxyEngine on + + ProxyPass / http://server.city:1000/ nocanon # or port 11434 + ProxyPassReverse / http://server.city:1000/ # or port 11434 + + RewriteEngine on + RewriteCond %{SERVER_NAME} =models.server.city + RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent] + + +``` + +Don't forget to restart/reload Apache with `systemctl reload apache2` + +Open your site at https://server.com! + +**Congratulations**, your _**Open-AI-like Chat-GPT style UI**_ is now serving AI with RAG, RBAC and multimodal features! Download Ollama models if you haven't yet done so! + +If you encounter any misconfiguration or errors, please file an issue or engage with our discussion. There are a lot of friendly developers here to assist you. + +Let's make this UI much more user friendly for everyone! + +Thanks for making open-webui your UI Choice for AI! + +This doc is made by **Bob Reyes**, your **Open-WebUI** fan from the Philippines. diff --git a/docs/kodekspracy.txt b/docs/kodekspracy.txt deleted file mode 100644 index 8b1e293..0000000 --- a/docs/kodekspracy.txt +++ /dev/null @@ -1,3859 +0,0 @@ -USTAWA - -z dnia 26 czerwca 1974 r. - -Kodeks pracy - -(Dz. U. z 2023 r. poz. 1465 oraz z 2024 r. poz. 878, 1222, 1871 i 1965) - -ogłoszono dnia 31 lipca 2023 r. -obowiązuje od dnia 1 stycznia 1975 r. - -historia od dnia 16 lutego 1998 r. - -DZIAŁ PIERWSZY -Przepisy ogólne - -Rozdział I -Przepisy wstępne - -Art. 1. Kodeks pracy określa prawa i obowiązki pracowników i pracodawców. - -Art. 2. Pracownikiem jest osoba zatrudniona na podstawie umowy o pracę, powołania, wyboru, mianowania lub spółdzielczej umowy o pracę. - -Art. 3. Pracodawcą jest jednostka organizacyjna, choćby nie posiadała osobowości prawnej, a także osoba fizyczna, jeżeli zatrudniają one pracowników. - -Art. 31. § 1. Za pracodawcę będącego jednostką organizacyjną czynności w sprawach z zakresu prawa pracy dokonuje osoba lub organ zarządzający tą jednostką albo inna wyznaczona do tego osoba. - -§ 2. Przepis § 1 stosuje się odpowiednio do pracodawcy będącego osobą fizyczną, jeżeli nie dokonuje on osobiście czynności, o których mowa w tym przepisie. - -Art. 4. (uchylony) - -Art. 5. Jeżeli stosunek pracy określonej kategorii pracowników regulują przepisy szczególne, przepisy kodeksu stosuje się w zakresie nie uregulowanym tymi przepisami. - -Art. 6. (uchylony). - -Art. 7. (skreślony). - -Art. 8. Nie można czynić ze swego prawa użytku, który byłby sprzeczny ze społeczno-gospodarczym przeznaczeniem tego prawa lub zasadami współżycia społecznego. Takie działanie lub zaniechanie uprawnionego nie jest uważane za wykonywanie prawa i nie korzysta z ochrony. - -Art. 9. § 1. Ilekroć w Kodeksie pracy jest mowa o prawie pracy, rozumie się przez to przepisy Kodeksu pracy oraz przepisy innych ustaw i aktów wykonawczych, określające prawa i obowiązki pracowników i pracodawców, a także postanowienia układów zbiorowych pracy i innych opartych na ustawie porozumień zbiorowych, regulaminów i statutów określających prawa i obowiązki stron stosunku pracy. - -§ 2. Postanowienia układów zbiorowych pracy i porozumień zbiorowych oraz regulaminów i statutów nie mogą być mniej korzystne dla pracowników niż przepisy Kodeksu pracy oraz innych ustaw i aktów wykonawczych. - -§ 3. Postanowienia regulaminów i statutów nie mogą być mniej korzystne dla pracowników niż postanowienia układów zbiorowych pracy i porozumień zbiorowych. - -§ 4. Postanowienia układów zbiorowych pracy i innych opartych na ustawie porozumień zbiorowych, regulaminów oraz statutów określających prawa i obowiązki stron stosunku pracy, naruszające zasadę równego traktowania w zatrudnieniu, nie obowiązują. - - -Art. 91. § 1. Jeżeli jest to uzasadnione sytuacją finansową pracodawcy, może być zawarte porozumienie o zawieszeniu stosowania w całości lub w części przepisów prawa pracy, określających prawa i obowiązki stron stosunku pracy; nie dotyczy to przepisów Kodeksu pracy oraz przepisów innych ustaw i aktów wykonawczych. - -§ 2. Porozumienie, o którym mowa w § 1, zawiera pracodawca i reprezentująca pracowników organizacja związkowa, a jeżeli pracodawca nie jest objęty działaniem takiej organizacji, porozumienie zawiera pracodawca i przedstawicielstwo pracowników wyłonione w trybie przyjętym u tego pracodawcy. - -§ 3. Zawieszenie stosowania przepisów prawa pracy nie może trwać dłużej niż przez okres 3 lat. Przepis art. 24127 § 3 stosuje się odpowiednio. - -§ 4. Pracodawca przekazuje porozumienie właściwemu okręgowemu inspektorowi pracy. - -§ 5. Przepisy § 1-4 nie naruszają przepisów art. 24127. - -Rozdział II -Podstawowe zasady prawa pracy - -Art. 10. § 1. Każdy ma prawo do swobodnie wybranej pracy. Nikomu, z wyjątkiem przypadków określonych w ustawie, nie można zabronić wykonywania zawodu. - -§ 2. Państwo określa minimalną wysokość wynagrodzenia za pracę. - -§ 3. Państwo prowadzi politykę zmierzającą do pełnego produktywnego zatrudnienia. - -Art. 11. Nawiązanie stosunku pracy oraz ustalenie warunków pracy i płacy, bez względu na podstawę prawną tego stosunku, wymaga zgodnego oświadczenia woli pracodawcy i pracownika. - -Art. 111. Pracodawca jest obowiązany szanować godność i inne dobra osobiste pracownika. - -Art. 112. Pracownicy mają równe prawa z tytułu jednakowego wypełniania takich samych obowiązków; dotyczy to w szczególności równego traktowania mężczyzn i kobiet w zatrudnieniu. - -Art. 113. Jakakolwiek dyskryminacja w zatrudnieniu, bezpośrednia lub pośrednia, w szczególności ze względu na płeć, wiek, niepełnosprawność, rasę, religię, narodowość, przekonania polityczne, przynależność związkową, pochodzenie etniczne, wyznanie, orientację seksualną, zatrudnienie na czas określony lub nieokreślony, zatrudnienie w pełnym lub w niepełnym wymiarze czasu pracy - jest niedopuszczalna. - -Art. 12. (skreślony). - -Art. 13. Pracownik ma prawo do godziwego wynagrodzenia za pracę. Warunki realizacji tego prawa określają przepisy prawa pracy oraz polityka państwa w dziedzinie płac, w szczególności poprzez ustalanie minimalnego wynagrodzenia za pracę. - -Art. 14. Pracownik ma prawo do wypoczynku, który zapewniają przepisy o czasie pracy, dniach wolnych od pracy oraz o urlopach wypoczynkowych. - -Art. 15. Pracodawca jest obowiązany zapewnić pracownikom bezpieczne i higieniczne warunki pracy. - -Art. 16. Pracodawca, stosownie do możliwości i warunków, zaspokaja bytowe, socjalne i kulturalne potrzeby pracowników. - -Art. 17. Pracodawca jest obowiązany ułatwiać pracownikom podnoszenie kwalifikacji zawodowych. - -Art. 18. § 1. Postanowienia umów o pracę oraz innych aktów, na których podstawie powstaje stosunek pracy, nie mogą być mniej korzystne dla pracownika niż przepisy prawa pracy. - -§ 2. Postanowienia umów i aktów, o których mowa w § 1, mniej korzystne dla pracownika niż przepisy prawa pracy są nieważne; zamiast nich stosuje się odpowiednie przepisy prawa pracy. - -§ 3. Postanowienia umów o pracę i innych aktów, na podstawie których powstaje stosunek pracy, naruszające zasadę równego traktowania w zatrudnieniu są nieważne. Zamiast takich postanowień stosuje się odpowiednie przepisy prawa pracy, a w razie braku takich przepisów - postanowienia te należy zastąpić odpowiednimi postanowieniami niemającymi charakteru dyskryminacyjnego. - -Art. 181. § 1. Pracownicy i pracodawcy, w celu reprezentacji i obrony swoich praw i interesów, mają prawo tworzyć organizacje i przystępować do tych organizacji. - -§ 2. Zasady tworzenia i działania organizacji, o których mowa w § 1, określa ustawa o związkach zawodowych, ustawa o organizacjach pracodawców oraz inne przepisy prawa. - -Art. 182. Pracownicy uczestniczą w zarządzaniu zakładem pracy w zakresie i na zasadach określonych w odrębnych przepisach. - -Art. 183. Pracodawcy oraz organy administracji są obowiązani tworzyć warunki umożliwiające korzystanie z uprawnień określonych w przepisach, o których mowa w art. 181 i 182. - - -Rozdział IIa -Równe traktowanie w zatrudnieniu - - -Art. 183a. - -§ 1. Pracownicy powinni być równo traktowani w zakresie nawiązania i rozwiązania stosunku pracy, warunków zatrudnienia, awansowania oraz dostępu do szkolenia w celu podnoszenia kwalifikacji zawodowych, w szczególności bez względu na płeć, wiek, niepełnosprawność, rasę, religię, narodowość, przekonania polityczne, przynależność związkową, pochodzenie etniczne, wyznanie, orientację seksualną, zatrudnienie na czas określony lub nieokreślony, zatrudnienie w pełnym lub w niepełnym wymiarze czasu pracy. - -§ 2. Równe traktowanie w zatrudnieniu oznacza niedyskryminowanie w jakikolwiek sposób, bezpośrednio lub pośrednio, z przyczyn określonych w § 1. - -§ 3. Dyskryminowanie bezpośrednie istnieje wtedy, gdy pracownik z jednej lub z kilku przyczyn określonych w § 1 był, jest lub mógłby być traktowany w porównywalnej sytuacji mniej korzystnie niż inni pracownicy. - -§ 4. Dyskryminowanie pośrednie istnieje wtedy, gdy na skutek pozornie neutralnego postanowienia, zastosowanego kryterium lub podjętego działania występują lub mogłyby wystąpić niekorzystne dysproporcje albo szczególnie niekorzystna sytuacja w zakresie nawiązania i rozwiązania stosunku pracy, warunków zatrudnienia, awansowania oraz dostępu do szkolenia w celu podnoszenia kwalifikacji zawodowych wobec wszystkich lub znacznej liczby pracowników należących do grupy wyróżnionej ze względu na jedną lub kilka przyczyn określonych w § 1, chyba że postanowienie, kryterium lub działanie jest obiektywnie uzasadnione ze względu na zgodny z prawem cel, który ma być osiągnięty, a środki służące osiągnięciu tego celu są właściwe i konieczne. - -§ 5. Przejawem dyskryminowania w rozumieniu § 2 jest także: - -1) działanie polegające na zachęcaniu innej osoby do naruszenia zasady równego traktowania w zatrudnieniu lub nakazaniu jej naruszenia tej zasady. -2) niepożądane zachowanie, którego celem lub skutkiem jest naruszenie godności pracownika i stworzenie wobec niego zastraszającej, wrogiej, poniżającej, upokarzającej lub uwłaczającej atmosfery (molestowanie). -§ 6. Dyskryminowaniem ze względu na płeć jest także każde niepożądane zachowanie o charakterze seksualnym lub odnoszące się do płci pracownika, którego celem lub skutkiem jest naruszenie godności pracownika, w szczególności stworzenie wobec niego zastraszającej, wrogiej, poniżającej, upokarzającej lub uwłaczającej atmosfery; na zachowanie to mogą się składać fizyczne, werbalne lub pozawerbalne elementy (molestowanie seksualne). - -§ 7. Podporządkowanie się przez pracownika molestowaniu lub molestowaniu seksualnemu, a także podjęcie przez niego działań przeciwstawiających się molestowaniu lub molestowaniu seksualnemu nie może powodować jakichkolwiek negatywnych konsekwencji wobec pracownika. - - -Art. 183b. - -§ 1. Za naruszenie zasady równego traktowania w zatrudnieniu, z zastrzeżeniem § 2-4, uważa się różnicowanie przez pracodawcę sytuacji pracownika z jednej lub kilku przyczyn określonych w art. 183a § 1, którego skutkiem jest w szczególności: - -1) odmowa nawiązania lub rozwiązanie stosunku pracy, -2) niekorzystne ukształtowanie wynagrodzenia za pracę lub innych warunków zatrudnienia albo pominięcie przy awansowaniu lub przyznawaniu innych świadczeń związanych z pracą, -3) pominięcie przy typowaniu do udziału w szkoleniach podnoszących kwalifikacje zawodowe -- chyba że pracodawca udowodni, że kierował się obiektywnymi powodami. -§ 2. Zasady równego traktowania w zatrudnieniu nie naruszają działania, proporcjonalne do osiągnięcia zgodnego z prawem celu różnicowania sytuacji pracownika, polegające na: - -1) niezatrudnianiu pracownika z jednej lub kilku przyczyn określonych w art. 183a § 1, jeżeli rodzaj pracy lub warunki jej wykonywania powodują, że przyczyna lub przyczyny wymienione w tym przepisie są rzeczywistym i decydującym wymaganiem zawodowym stawianym pracownikowi, -2) wypowiedzeniu pracownikowi warunków zatrudnienia w zakresie wymiaru czasu pracy, jeżeli jest to uzasadnione przyczynami niedotyczącymi pracowników bez powoływania się na inną przyczynę lub inne przyczyny wymienione w art. 183a § 1, -3) stosowaniu środków, które różnicują sytuację prawną pracownika, ze względu na ochronę rodzicielstwa lub niepełnosprawność, -4) stosowaniu kryterium stażu pracy przy ustalaniu warunków zatrudniania i zwalniania pracowników, zasad wynagradzania i awansowania oraz dostępu do szkolenia w celu podnoszenia kwalifikacji zawodowych, co uzasadnia odmienne traktowanie pracowników ze względu na wiek. -§ 3. Nie stanowią naruszenia zasady równego traktowania w zatrudnieniu działania podejmowane przez określony czas, zmierzające do wyrównywania szans wszystkich lub znacznej liczby pracowników wyróżnionych z jednej lub kilku przyczyn określonych w art. 183a § 1, przez zmniejszenie na korzyść takich pracowników faktycznych nierówności, w zakresie określonym w tym przepisie. - -§ 4. Nie stanowi naruszenia zasady równego traktowania ograniczanie przez kościoły i inne związki wyznaniowe, a także organizacje, których etyka opiera się na religii, wyznaniu lub światopoglądzie, dostępu do zatrudnienia, ze względu na religię, wyznanie lub światopogląd jeżeli rodzaj lub charakter wykonywania działalności przez kościoły i inne związki wyznaniowe, a także organizacje powoduje, że religia, wyznanie lub światopogląd są rzeczywistym i decydującym wymaganiem zawodowym stawianym pracownikowi, proporcjonalnym do osiągnięcia zgodnego z prawem celu zróżnicowania sytuacji tej osoby; dotyczy to również wymagania od zatrudnionych działania w dobrej wierze i lojalności wobec etyki kościoła, innego związku wyznaniowego oraz organizacji, których etyka opiera się na religii, wyznaniu lub światopoglądzie. - - -Art. 183c. - -§ 1. Pracownicy mają prawo do jednakowego wynagrodzenia za jednakową pracę lub za pracę o jednakowej wartości. - -§ 2. Wynagrodzenie, o którym mowa w § 1, obejmuje wszystkie składniki wynagrodzenia, bez względu na ich nazwę i charakter, a także inne świadczenia związane z pracą, przyznawane pracownikom w formie pieniężnej lub w innej formie niż pieniężna. - -§ 3. Pracami o jednakowej wartości są prace, których wykonywanie wymaga od pracowników porównywalnych kwalifikacji zawodowych, potwierdzonych dokumentami przewidzianymi w odrębnych przepisach lub praktyką i doświadczeniem zawodowym, a także porównywalnej odpowiedzialności i wysiłku. - - -Art. 183d. Osoba, wobec której pracodawca naruszył zasadę równego traktowania w zatrudnieniu, ma prawo do odszkodowania w wysokości nie niższej niż minimalne wynagrodzenie za pracę, ustalane na podstawie odrębnych przepisów. - - -Art. 183e. - -§ 1. Skorzystanie przez pracownika z uprawnień przysługujących z tytułu naruszenia przepisów prawa pracy, w tym zasady równego traktowania w zatrudnieniu, nie może być podstawą jakiegokolwiek niekorzystnego traktowania pracownika, a także nie może powodować jakichkolwiek negatywnych konsekwencji dla pracownika, zwłaszcza nie może stanowić przyczyny uzasadniającej wypowiedzenie stosunku pracy lub jego rozwiązanie bez wypowiedzenia przez pracodawcę. - -§ 2. Przepis § 1 stosuje się odpowiednio do pracownika, który udzielił w jakiejkolwiek formie wsparcia pracownikowi korzystającemu z uprawnień przysługujących z tytułu naruszenia przepisów prawa pracy, w tym zasady równego traktowania w zatrudnieniu. - -§ 3. Pracownik, o którym mowa w § 1 i 2, którego prawa zostały naruszone przez pracodawcę, ma prawo do odszkodowania w wysokości nie niższej niż minimalne wynagrodzenie za pracę, ustalane na podstawie odrębnych przepisów. - -Rozdział IIb -Nadzór i kontrola przestrzegania prawa pracy - -Art. 184. § 1. Nadzór i kontrolę przestrzegania prawa pracy, w tym przepisów i zasad bezpieczeństwa i higieny pracy, sprawuje Państwowa Inspekcja Pracy. - -§ 2. Nadzór i kontrolę przestrzegania zasad, przepisów higieny pracy i warunków środowiska pracy sprawuje Państwowa Inspekcja Sanitarna. - -§ 3. Organizację i zakres działania inspekcji, o których mowa w § 1 i 2, określają odrębne przepisy. - -Art. 185. § 1. Społeczną kontrolę przestrzegania prawa pracy, w tym przepisów i zasad bezpieczeństwa i higieny pracy, sprawuje społeczna inspekcja pracy. - -§ 2. Organizację, zadania i uprawnienia społecznej inspekcji pracy oraz zasady jej współdziałania z Państwową Inspekcją Pracy i innymi państwowymi organami nadzoru i kontroli określają odrębne przepisy. - -Rozdział III -(skreślony) - -Art. 19. (skreślony). - -Art. 20. (skreślony). - -Art. 21. (skreślony). - -DZIAŁ DRUGI -Stosunek pracy - -Rozdział I -Przepisy ogólne - -Art. 22. § 1. Przez nawiązanie stosunku pracy pracownik zobowiązuje się do wykonywania pracy określonego rodzaju na rzecz pracodawcy i pod jego kierownictwem oraz w miejscu i czasie wyznaczonym przez pracodawcę, a pracodawca - do zatrudniania pracownika za wynagrodzeniem. - -§ 11. Zatrudnienie w warunkach określonych w § 1 jest zatrudnieniem na podstawie stosunku pracy, bez względu na nazwę zawartej przez strony umowy. - -§ 12. Nie jest dopuszczalne zastąpienie umowy o pracę umową cywilnoprawną przy zachowaniu warunków wykonywania pracy, określonych w § 1. - -§ 2. Pracownikiem może być osoba, która ukończyła 18 lat. Na warunkach określonych w dziale dziewiątym pracownikiem może być również osoba, która nie ukończyła 18 lat. - -§ 3. Osoba ograniczona w zdolności do czynności prawnych może bez zgody przedstawiciela ustawowego nawiązać stosunek pracy oraz dokonywać czynności prawnych, które dotyczą tego stosunku. Jednakże gdy stosunek pracy sprzeciwia się dobru tej osoby, przedstawiciel ustawowy za zezwoleniem sądu opiekuńczego może stosunek pracy rozwiązać. - - -Art. 221. - -§ 1. Pracodawca żąda od osoby ubiegającej się o zatrudnienie podania danych osobowych obejmujących: - -1) imię (imiona) i nazwisko; -2) datę urodzenia; -3) dane kontaktowe wskazane przez taką osobę; -4) wykształcenie; -5) kwalifikacje zawodowe; -6) przebieg dotychczasowego zatrudnienia. -§ 2. Pracodawca żąda podania danych osobowych, o których mowa w § 1 pkt 4-6, gdy jest to niezbędne do wykonywania pracy określonego rodzaju lub na określonym stanowisku. - -§ 3. Pracodawca żąda od pracownika podania dodatkowo danych osobowych obejmujących: - -1) adres zamieszkania; -2) numer PESEL, a w przypadku jego braku - rodzaj i numer dokumentu potwierdzającego tożsamość; -3) inne dane osobowe pracownika, a także dane osobowe dzieci pracownika i innych członków jego najbliższej rodziny, jeżeli podanie takich danych jest konieczne ze względu na korzystanie przez pracownika ze szczególnych uprawnień przewidzianych w prawie pracy; -4) wykształcenie i przebieg dotychczasowego zatrudnienia, jeżeli nie istniała podstawa do ich żądania od osoby ubiegającej się o zatrudnienie; -5) numer rachunku płatniczego, jeżeli pracownik nie złożył wniosku o wypłatę wynagrodzenia do rąk własnych. -§ 4. Pracodawca żąda podania innych danych osobowych niż określone w § 1 i 3, gdy jest to niezbędne do zrealizowania uprawnienia lub spełnienia obowiązku wynikającego z przepisu prawa. - -§ 5. Udostępnienie pracodawcy danych osobowych następuje w formie oświadczenia osoby, której dane dotyczą. Pracodawca może żądać udokumentowania danych osobowych osób, o których mowa w § 1 i 3, w zakresie niezbędnym do ich potwierdzenia. - - -Art. 221a. § 1. Zgoda osoby ubiegającej się o zatrudnienie lub pracownika może stanowić podstawę przetwarzania przez pracodawcę innych danych osobowych niż wymienione w art. 221 § 1 i 3, z wyjątkiem danych osobowych, o których mowa w art. 10 rozporządzenia Parlamentu Europejskiego i Rady (UE) 2016/679 z dnia 27 kwietnia 2016 r. w sprawie ochrony osób fizycznych w związku z przetwarzaniem danych osobowych i w sprawie swobodnego przepływu takich danych oraz uchylenia dyrektywy 95/46/WE (ogólne rozporządzenie o ochronie danych) (Dz. Urz. UE L 119 z 04.05.2016, str. 1, z późn. zm.), zwanego dalej „rozporządzeniem 2016/679”. - -§ 2. Brak zgody, o której mowa w § 1, lub jej wycofanie, nie może być podstawą niekorzystnego traktowania osoby ubiegającej się o zatrudnienie lub pracownika, a także nie może powodować wobec nich jakichkolwiek negatywnych konsekwencji, zwłaszcza nie może stanowić przyczyny uzasadniającej odmowę zatrudnienia, wypowiedzenie umowy o pracę lub jej rozwiązanie bez wypowiedzenia przez pracodawcę. - -§ 3. Przetwarzanie, o którym mowa w § 1, dotyczy danych osobowych udostępnianych przez osobę ubiegającą się o zatrudnienie lub pracownika na wniosek pracodawcy lub danych osobowych przekazanych pracodawcy z inicjatywy osoby ubiegającej się o zatrudnienie lub pracownika. - - -Art. 221b. § 1. Zgoda osoby ubiegającej się o zatrudnienie lub pracownika może stanowić podstawę przetwarzania przez pracodawcę danych osobowych, o których mowa w art. 9 ust. 1 rozporządzenia 2016/679, wyłącznie w przypadku, gdy przekazanie tych danych osobowych następuje z inicjatywy osoby ubiegającej się o zatrudnienie lub pracownika. Przepis art. 221a § 2 stosuje się odpowiednio. - -§ 2. Przetwarzanie danych biometrycznych pracownika jest dopuszczalne także wtedy, gdy podanie takich danych jest niezbędne ze względu na kontrolę dostępu do szczególnie ważnych informacji, których ujawnienie może narazić pracodawcę na szkodę, lub dostępu do pomieszczeń wymagających szczególnej ochrony. - -§ 3. Do przetwarzania danych osobowych, o których mowa w § 1, mogą być dopuszczone wyłącznie osoby posiadające pisemne upoważnienie do przetwarzania takich danych wydane przez pracodawcę. Osoby dopuszczone do przetwarzania takich danych są obowiązane do zachowania ich w tajemnicy. - - -Art. 221c. § 1. Jeżeli jest to niezbędne do zapewnienia ochrony życia i zdrowia pracowników lub innych osób lub ochrony mienia, pracodawca może wprowadzić kontrolę trzeźwości pracowników. - -§ 2. Kontrola trzeźwości nie może naruszać godności oraz innych dóbr osobistych pracownika. - -§ 3. Kontrola trzeźwości jest przeprowadzana przez pracodawcę w sposób ustalony zgodnie z § 10, uwzględniający wymagania wynikające z przepisów wydanych na podstawie art. 221g. - -§ 4. Kontrola trzeźwości obejmuje badanie przy użyciu metod niewymagających badania laboratoryjnego za pomocą urządzenia posiadającego ważny dokument potwierdzający jego kalibrację lub wzorcowanie. - -§ 5. Badanie, o którym mowa w § 4, polega na stwierdzeniu braku obecności alkoholu w organizmie pracownika albo obecności alkoholu wskazującej na stan po użyciu alkoholu albo stan nietrzeźwości w rozumieniu art. 46 ust. 2 albo 3 ustawy z dnia 26 października 1982 r. o wychowaniu w trzeźwości i przeciwdziałaniu alkoholizmowi. Za równoznaczne ze stwierdzeniem braku obecności alkoholu w organizmie pracownika uznaje się przypadki, w których zawartość alkoholu nie osiąga lub nie prowadzi do osiągnięcia wartości właściwych dla stanu po użyciu alkoholu. - -§ 6. Pracodawca przetwarza informacje o dacie, godzinie i minucie badania, o którym mowa w § 4, oraz jego wyniku wskazującym na stan po użyciu alkoholu albo stan nietrzeźwości wyłącznie w przypadku, gdy jest to niezbędne do zapewnienia ochrony dóbr, o których mowa w § 1, i przechowuje te informacje w aktach osobowych pracownika przez okres nieprzekraczający roku od dnia ich zebrania. - -§ 7. W przypadku zastosowania kary upomnienia, kary nagany lub kary pieniężnej pracodawca przechowuje informacje, o których mowa w § 6, w aktach osobowych pracownika do czasu uznania kary za niebyłą zgodnie z art. 113. - -§ 8. W przypadku, w którym informacje, o których mowa w § 6, mogą stanowić lub stanowią dowód w postępowaniu prowadzonym na podstawie prawa, a pracodawca jest stroną tego postępowania lub powziął wiadomość o wytoczeniu powództwa lub wszczęciu postępowania, okres, o którym mowa w § 6, ulega przedłużeniu do czasu prawomocnego zakończenia postępowania. - -§ 9. Po upływie okresów, o których mowa w § 6, 7 lub 8, informacje, o których mowa w § 6, podlegają usunięciu. - -§ 10. Wprowadzenie kontroli trzeźwości, grupę lub grupy pracowników objętych kontrolą trzeźwości i sposób przeprowadzania kontroli trzeźwości, w tym rodzaj urządzenia wykorzystywanego do kontroli, czas i częstotliwość jej przeprowadzania, ustala się w układzie zbiorowym pracy lub w regulaminie pracy albo w obwieszczeniu, jeżeli pracodawca nie jest objęty układem zbiorowym pracy lub nie jest obowiązany do ustalenia regulaminu pracy. - -§ 11. O wprowadzeniu kontroli trzeźwości, o którym mowa w § 10, pracodawca informuje pracowników w sposób przyjęty u danego pracodawcy nie później niż 2 tygodnie przed rozpoczęciem jej przeprowadzania. - -§ 12. W związku z zatrudnieniem pracownika objętego kontrolą trzeźwości pracodawca przekazuje temu pracownikowi przed dopuszczeniem go do pracy informacje, o których mowa w § 10, w postaci papierowej lub elektronicznej. - - -Art. 221d. § 1. Pracodawca nie dopuszcza pracownika do pracy, jeżeli kontrola trzeźwości wykaże obecność alkoholu w organizmie pracownika wskazującą na stan po użyciu alkoholu albo stan nietrzeźwości w rozumieniu art. 46 ust. 2 albo 3 ustawy z dnia 26 października 1982 r. o wychowaniu w trzeźwości i przeciwdziałaniu alkoholizmowi albo zachodzi uzasadnione podejrzenie, że pracownik stawił się do pracy w stanie po użyciu alkoholu albo w stanie nietrzeźwości lub spożywał alkohol w czasie pracy. - -§ 2. Informację dotyczącą podstawy niedopuszczenia pracownika do pracy przekazuje się pracownikowi do wiadomości. - -§ 3. Na żądanie pracodawcy lub pracownika niedopuszczonego do pracy badanie stanu trzeźwości pracownika przeprowadza uprawniony organ powołany do ochrony porządku publicznego. - -§ 4. Organ, o którym mowa w § 3, przeprowadza badanie stanu trzeźwości pracownika przy użyciu metod niewymagających badania laboratoryjnego. - -§ 5. Organ, o którym mowa w § 3, zleca przeprowadzenie badania krwi, jeżeli: - -1) nie ma możliwości przeprowadzenia badania metodą, o której mowa w § 4; -2) pracownik niedopuszczony do pracy odmawia poddania się badaniu metodą, o której mowa w § 4; -3) pracownik niedopuszczony do pracy żąda przeprowadzenia badania krwi pomimo przeprowadzenia badania metodą, o której mowa w § 4; -4) stan pracownika niedopuszczonego do pracy uniemożliwia przeprowadzenie badania metodą, o której mowa w § 4; -5) nie ma możliwości wskazania stężenia alkoholu z powodu przekroczenia zakresu pomiarowego urządzenia wykorzystywanego do pomiaru. -§ 6. Badania, o których mowa w § 4 i 5, przeprowadza się z poszanowaniem godności i intymności pracownika. - -§ 7. Zabiegu pobrania krwi dokonuje osoba posiadająca odpowiednie kwalifikacje zawodowe. - -§ 8. W przypadku gdy wynik badania nie wskazuje na stan po użyciu alkoholu albo stan nietrzeźwości pracownika, okres niedopuszczenia pracownika do pracy jest okresem usprawiedliwionej nieobecności w pracy, za który pracownik zachowuje prawo do wynagrodzenia. - -§ 9. Przebieg badań, o których mowa w § 4 i 5, dokumentuje się z uwzględnieniem: - -1) daty, godziny i minuty oraz miejsca przeprowadzenia badania; -2) wyniku badania; -3) danych osobowych pracownika: -a) imienia i nazwiska, -b) numeru PESEL, a jeżeli nie posiada - serii i numeru dokumentu potwierdzającego tożsamość pracownika, -c) daty urodzenia, płci, wzrostu, masy ciała, informacji o chorobach, na jakie pracownik choruje, oraz podpisu pracownika - jeżeli dane te pozyskano w związku z przeprowadzanym badaniem; -4) imienia i nazwiska oraz podpisu osoby przeprowadzającej badanie; -5) imienia, nazwiska, stanowiska i podpisu osoby przeprowadzającej pobranie próbek materiału biologicznego do badań; -6) imienia i nazwiska oraz podpisu osoby, w obecności której przeprowadzono badanie; -7) informacji o objawach lub okolicznościach uzasadniających przeprowadzenie badania oraz dacie i godzinie ich stwierdzenia; -8) innych informacji niezbędnych do oceny wiarygodności i poprawności badania; -9) w przypadku odstąpienia od pobrania próbek krwi - informacji o przyczynie odstąpienia. -§ 10. Organ przeprowadzający badanie, o którym mowa w § 3, przekazuje pracodawcy i pracownikowi niedopuszczonemu do pracy informację w formie pisemnej, obejmującą imię i nazwisko osoby badanej oraz jej numer PESEL, a w przypadku jego braku - serię i numer dokumentu potwierdzającego tożsamość, datę, godzinę oraz minutę przeprowadzonego badania, a także jego wynik. W przypadku przeprowadzenia kilku pomiarów organ przeprowadzający badanie przekazuje informację o czasie przeprowadzenia pomiarów i wyniku każdego z nich. - -§ 11. Do przetwarzania informacji, o której mowa w § 10, stosuje się odpowiednio art. 221c § 6-9. - - -Art. 221e. § 1. Jeżeli jest to niezbędne do zapewnienia ochrony życia i zdrowia pracowników lub innych osób lub ochrony mienia, pracodawca może wprowadzić kontrolę pracowników na obecność w ich organizmach środków działających podobnie do alkoholu. - -§ 2. Przepisy art. 221c § 2-12 stosuje się odpowiednio. - - -Art. 221f. § 1. Pracodawca nie dopuszcza pracownika do pracy, jeżeli kontrola, o której mowa w art. 221e § 1, wykaże obecność w organizmie pracownika środka działającego podobnie do alkoholu albo zachodzi uzasadnione podejrzenie, że pracownik stawił się do pracy w stanie po użyciu takiego środka lub zażywał taki środek w czasie pracy. - -§ 2. Przepisy art. 221d § 2-4, 7, 8, 10 i 11 stosuje się odpowiednio. - -§ 3. Uprawniony organ powołany do ochrony porządku publicznego zleca przeprowadzenie badania krwi lub moczu, jeżeli: - -1) nie ma możliwości przeprowadzenia badania metodą niewymagającą badania laboratoryjnego; -2) pracownik niedopuszczony do pracy odmawia poddania się badaniu metodą niewymagającą badania laboratoryjnego; -3) pracownik niedopuszczony do pracy żąda przeprowadzenia badania krwi lub moczu pomimo przeprowadzenia badania metodą niewymagającą badania laboratoryjnego; -4) stan pracownika niedopuszczonego do pracy uniemożliwia przeprowadzenie badania metodą niewymagającą badania laboratoryjnego. -§ 4. Badanie przy użyciu metod niewymagających badania laboratoryjnego oraz badanie, o którym mowa w § 3, przeprowadza się z poszanowaniem godności i intymności pracownika. - -§ 5. Czynności związane z pobraniem moczu do badania, o którym mowa w § 3, odbywają się w obecności osoby posiadającej odpowiednie kwalifikacje zawodowe do przeprowadzania badania moczu, tej samej płci co pracownik, od którego pobiera się mocz. - -§ 6. Przebieg badania przeprowadzonego przez uprawniony organ powołany do ochrony porządku publicznego przy użyciu metod niewymagających badania laboratoryjnego oraz badania, o którym mowa w § 3, dokumentuje się z uwzględnieniem: - -1) daty, godziny i minuty oraz miejsca przeprowadzenia badania; -2) wyniku badania; -3) danych osobowych pracownika: -a) imienia i nazwiska, -b) numeru PESEL, a jeżeli nie posiada - serii i numeru dokumentu potwierdzającego tożsamość pracownika, -c) daty urodzenia, informacji o chorobach, na jakie pracownik choruje, oraz podpisu pracownika - jeżeli dane te pozyskano w związku z przeprowadzanym badaniem; -4) imienia i nazwiska oraz podpisu osoby przeprowadzającej badanie; -5) imienia, nazwiska, stanowiska i podpisu osoby przeprowadzającej pobranie próbek materiału biologicznego do badań; -6) imienia i nazwiska oraz podpisu osoby, w obecności której przeprowadzono badanie; -7) informacji o objawach lub okolicznościach uzasadniających przeprowadzenie badania oraz dacie i godzinie ich stwierdzenia; -8) innych informacji niezbędnych do oceny wiarygodności i poprawności badania; -9) w przypadku odstąpienia od pobrania próbek krwi lub moczu - informacji o przyczynie odstąpienia. - -Art. 221g. Minister właściwy do spraw zdrowia w porozumieniu z ministrem właściwym do spraw wewnętrznych oraz ministrem właściwym do spraw pracy określi, w drodze rozporządzenia: - -1) warunki i metody przeprowadzania badań na obecność alkoholu w organizmie pracownika oraz badań na obecność w organizmie pracownika środków działających podobnie do alkoholu przez pracodawcę oraz przez uprawniony organ powołany do ochrony porządku publicznego lub zlecanych przez ten organ, -2) sposób dokumentowania badań przeprowadzanych lub zlecanych przez uprawniony organ powołany do ochrony porządku publicznego, -3) wykaz środków działających podobnie do alkoholu -- mając na uwadze metodykę przeprowadzania takich badań, konieczność zapewnienia ochrony życia i zdrowia pracowników lub innych osób lub ochrony mienia, a także konieczność sprawnego przeprowadzania badań i zagwarantowania wiarygodności wyników badania krwi i moczu przy jednoczesnym poszanowaniu godności oraz innych dóbr osobistych pracownika i zasad ochrony danych osobowych. - -Art. 221h. Przepisy art. 221c-221f oraz przepisy wydane na podstawie art. 221g stosuje się odpowiednio do pracodawców organizujących pracę wykonywaną przez osoby fizyczne na innej podstawie niż stosunek pracy oraz osoby fizyczne prowadzące na własny rachunek działalność gospodarczą, a także do osób fizycznych wykonujących pracę na innej podstawie niż stosunek pracy oraz osób fizycznych prowadzących na własny rachunek działalność gospodarczą, których praca jest organizowana przez tych pracodawców. - - -Art. 222. § 1. Jeżeli jest to niezbędne do zapewnienia bezpieczeństwa pracowników lub ochrony mienia lub kontroli produkcji lub zachowania w tajemnicy informacji, których ujawnienie mogłoby narazić pracodawcę na szkodę, pracodawca może wprowadzić szczególny nadzór nad terenem zakładu pracy lub terenem wokół zakładu pracy w postaci środków technicznych umożliwiających rejestrację obrazu (monitoring). - -§ 11. Monitoring nie obejmuje pomieszczeń udostępnianych zakładowej organizacji związkowej. - -§ 2. Monitoring nie obejmuje pomieszczeń sanitarnych, szatni, stołówek oraz palarni, chyba że stosowanie monitoringu w tych pomieszczeniach jest niezbędne do realizacji celu określonego w § 1 i nie naruszy to godności oraz innych dóbr osobistych pracownika, w szczególności poprzez zastosowanie technik uniemożliwiających rozpoznanie przebywających w tych pomieszczeniach osób. Monitoring pomieszczeń sanitarnych wymaga uzyskania uprzedniej zgody zakładowej organizacji związkowej, a jeżeli u pracodawcy nie działa zakładowa organizacja związkowa - uprzedniej zgody przedstawicieli pracowników wybranych w trybie przyjętym u danego pracodawcy. - -§ 3. Nagrania obrazu pracodawca przetwarza wyłącznie do celów, dla których zostały zebrane, i przechowuje przez okres nieprzekraczający 3 miesięcy od dnia nagrania. - -§ 4. W przypadku, w którym nagrania obrazu stanowią dowód w postępowaniu prowadzonym na podstawie prawa lub pracodawca powziął wiadomość, iż mogą one stanowić dowód w postępowaniu, termin określony w § 3 ulega przedłużeniu do czasu prawomocnego zakończenia postępowania. - -§ 5. Po upływie okresów, o których mowa w § 3 lub 4, uzyskane w wyniku monitoringu nagrania obrazu zawierające dane osobowe podlegają zniszczeniu, o ile przepisy odrębne nie stanowią inaczej. - -§ 6. Cele, zakres oraz sposób zastosowania monitoringu ustala się w układzie zbiorowym pracy lub w regulaminie pracy albo w obwieszczeniu, jeżeli pracodawca nie jest objęty układem zbiorowym pracy lub nie jest obowiązany do ustalenia regulaminu pracy. - -§ 7. Pracodawca informuje pracowników o wprowadzeniu monitoringu, w sposób przyjęty u danego pracodawcy, nie później niż 2 tygodnie przed jego uruchomieniem. - -§ 8. Pracodawca przed dopuszczeniem pracownika do pracy przekazuje mu na piśmie informacje, o których mowa w § 6. - -§ 9. W przypadku wprowadzenia monitoringu pracodawca oznacza pomieszczenia i teren monitorowany w sposób widoczny i czytelny, za pomocą odpowiednich znaków lub ogłoszeń dźwiękowych, nie później niż jeden dzień przed jego uruchomieniem. - -§ 10. Przepis § 9 nie narusza przepisów art. 12 i art. 13 rozporządzenia 2016/679. - - -Art. 223. § 1. Jeżeli jest to niezbędne do zapewnienia organizacji pracy umożliwiającej pełne wykorzystanie czasu pracy oraz właściwego użytkowania udostępnionych pracownikowi narzędzi pracy, pracodawca może wprowadzić kontrolę służbowej poczty elektronicznej pracownika (monitoring poczty elektronicznej). - -§ 2. Monitoring poczty elektronicznej nie może naruszać tajemnicy korespondencji oraz innych dóbr osobistych pracownika. - -§ 3. Przepisy art. 222 § 6-10 stosuje się odpowiednio. - -§ 4. Przepisy § 1-3 stosuje się odpowiednio do innych form monitoringu niż określone w § 1, jeśli ich zastosowanie jest konieczne do realizacji celów określonych w § 1. - -Art. 23. (skreślony). - -Art. 231. § 1. W razie przejścia zakładu pracy lub jego części na innego pracodawcę staje się on z mocy prawa stroną w dotychczasowych stosunkach pracy, z zastrzeżeniem przepisów § 5. - -§ 2. Za zobowiązania wynikające ze stosunku pracy, powstałe przed przejściem części zakładu pracy na innego pracodawcę, dotychczasowy i nowy pracodawca odpowiadają solidarnie. - -§ 3. Jeżeli u pracodawców, o których mowa w § 1, nie działają zakładowe organizacje związkowe, dotychczasowy i nowy pracodawca informują na piśmie swoich pracowników o przewidywanym terminie przejścia zakładu pracy lub jego części na innego pracodawcę, jego przyczynach, prawnych, ekonomicznych oraz socjalnych skutkach dla pracowników, a także zamierzonych działaniach dotyczących warunków zatrudnienia pracowników, w szczególności warunków pracy, płacy i przekwalifikowania; przekazanie informacji powinno nastąpić co najmniej na 30 dni przed przewidywanym terminem przejścia zakładu pracy lub jego części na innego pracodawcę. - -§ 4. W terminie 2 miesięcy od przejścia zakładu pracy lub jego części na innego pracodawcę, pracownik może bez wypowiedzenia, za siedmiodniowym uprzedzeniem, rozwiązać stosunek pracy. Rozwiązanie stosunku pracy w tym trybie powoduje dla pracownika skutki, jakie przepisy prawa pracy wiążą z rozwiązaniem stosunku pracy przez pracodawcę za wypowiedzeniem. - -§ 5. Pracodawca, z dniem przejęcia zakładu pracy lub jego części, jest obowiązany zaproponować nowe warunki pracy i płacy pracownikom świadczącym dotychczas pracę na innej podstawie niż umowa o pracę oraz wskazać termin, nie krótszy niż 7 dni, do którego pracownicy mogą złożyć oświadczenie o przyjęciu lub odmowie przyjęcia proponowanych warunków. W razie nieuzgodnienia nowych warunków pracy i płacy dotychczasowy stosunek pracy rozwiązuje się z upływem okresu równego okresowi wypowiedzenia, liczonego od dnia, w którym pracownik złożył oświadczenie o odmowie przyjęcia proponowanych warunków, lub od dnia, do którego mógł złożyć takie oświadczenie. Przepis § 4 zdanie drugie stosuje się odpowiednio. - -§ 6. Przejście zakładu pracy lub jego części na innego pracodawcę nie może stanowić przyczyny uzasadniającej wypowiedzenie przez pracodawcę stosunku pracy. - - -Art. 231a § 1. Jeżeli jest to uzasadnione sytuacją finansową pracodawcy, nieobjętego układem zbiorowym pracy lub zatrudniającego mniej niż 20 pracowników, może być zawarte porozumienie o stosowaniu mniej korzystnych warunków zatrudnienia pracowników niż wynikające z umów o pracę zawartych z tymi pracownikami, w zakresie i przez czas ustalone w porozumieniu. - -§ 2. Przepisy art. 91 § 1-4 stosuje się odpowiednio. - -Art. 232. Jeżeli przepisy prawa pracy przewidują współdziałanie pracodawcy z zakładową organizacją związkową w indywidualnych sprawach ze stosunku pracy, pracodawca ma obowiązek współdziałać w takich sprawach z zakładową organizacją związkową reprezentującą pracownika z tytułu jego członkostwa w związku zawodowym albo wyrażenia zgody na obronę praw pracownika nie zrzeszonego w związku - zgodnie z ustawą o związkach zawodowych. - -Art. 24. (skreślony). - -Rozdział II -Umowa o pracę - -Oddział 1 -Zawarcie umowy o pracę - -Art. 25. - -§ 1. Umowę o pracę zawiera się na okres próbny, na czas określony albo na czas nieokreślony. - -§ 2. Umowę o pracę na okres próbny zawiera się na okres nieprzekraczający 3 miesięcy, z zastrzeżeniem § 21-23, w celu sprawdzenia kwalifikacji pracownika i możliwości jego zatrudnienia w celu wykonywania określonego rodzaju pracy. - -§ 21. Strony mogą uzgodnić w umowie o pracę na okres próbny, że umowę tę przedłuża się o czas urlopu, a także o czas innej usprawiedliwionej nieobecności pracownika w pracy, jeżeli wystąpią takie nieobecności. - -§ 22. Umowę o pracę na okres próbny zawiera się na okres nieprzekraczający: - -1) 1 miesiąca - w przypadku zamiaru zawarcia umowy o pracę na czas określony krótszy niż 6 miesięcy; -2) 2 miesięcy - w przypadku zamiaru zawarcia umowy o pracę na czas określony wynoszący co najmniej 6 miesięcy i krótszy niż 12 miesięcy. -§ 23. Strony mogą jednokrotnie wydłużyć w umowie o pracę na okres próbny okresy, o których mowa w § 22, nie więcej jednak niż o 1 miesiąc, jeżeli jest to uzasadnione rodzajem pracy. - -§ 3. Ponowne zawarcie umowy o pracę na okres próbny z tym samym pracownikiem jest dopuszczalne, jeżeli pracownik ma być zatrudniony w celu wykonywania innego rodzaju pracy. - -Art. 251. - -§ 1. Okres zatrudnienia na podstawie umowy o pracę na czas określony, a także łączny okres zatrudnienia na podstawie umów o pracę na czas określony zawieranych między tymi samymi stronami stosunku pracy, nie może przekraczać 33 miesięcy, a łączna liczba tych umów nie może przekraczać trzech. - -§ 2. Uzgodnienie między stronami w trakcie trwania umowy o pracę na czas określony dłuższego okresu wykonywania pracy na podstawie tej umowy uważa się za zawarcie, od dnia następującego po dniu, w którym miało nastąpić jej rozwiązanie, nowej umowy o pracę na czas określony w rozumieniu § 1. - -§ 3. Jeżeli okres zatrudnienia na podstawie umowy o pracę na czas określony jest dłuższy niż okres, o którym mowa w § 1, lub jeżeli liczba zawartych umów jest większa niż liczba umów określona w tym przepisie, uważa się, że pracownik, odpowiednio od dnia następującego po upływie okresu, o którym mowa w § 1, lub od dnia zawarcia czwartej umowy o pracę na czas określony, jest zatrudniony na podstawie umowy o pracę na czas nieokreślony. - -§ 4. Przepisu § 1 nie stosuje się do umów o pracę zawartych na czas określony: - -1) w celu zastępstwa pracownika w czasie jego usprawiedliwionej nieobecności w pracy, -2) w celu wykonywania pracy o charakterze dorywczym lub sezonowym, -3) w celu wykonywania pracy przez okres kadencji, -4) w przypadku gdy pracodawca wskaże obiektywne przyczyny leżące po jego stronie -- jeżeli ich zawarcie w danym przypadku służy zaspokojeniu rzeczywistego okresowego zapotrzebowania i jest niezbędne w tym zakresie w świetle wszystkich okoliczności zawarcia umowy. -§ 41. Przepisów § 1 i 3 nie stosuje się w przypadku przedłużenia umowy o pracę do dnia porodu zgodnie z art. 177 § 3. - -§ 5. Pracodawca zawiadamia właściwego okręgowego inspektora pracy, w formie pisemnej lub elektronicznej, o zawarciu umowy o pracę, o której mowa w § 4 pkt 4, wraz ze wskazaniem przyczyn zawarcia takiej umowy, w terminie 5 dni roboczych od dnia jej zawarcia. - -Art. 26. Stosunek pracy nawiązuje się w dniu określonym w umowie jako dzień rozpoczęcia pracy. - - -Art. 261. § 1. Pracodawca nie może zakazać pracownikowi jednoczesnego pozostawania w stosunku pracy z innym pracodawcą lub jednoczesnego pozostawania w stosunku prawnym będącym podstawą świadczenia pracy innym niż stosunek pracy. - -§ 2. Przepisu § 1 nie stosuje się: - -1) w przypadku określonym w art. 1011 § 1; -2) jeżeli odrębne przepisy stanowią inaczej. -Art. 27. (skreślony). - -Art. 28. (skreślony). - -Art. 29. - -§ 1. Umowa o pracę określa strony umowy, adres siedziby pracodawcy, a w przypadku pracodawcy będącego osobą fizyczną nieposiadającego siedziby - adres zamieszkania, a także rodzaj umowy, datę jej zawarcia oraz warunki pracy i płacy, w szczególności: - -1) rodzaj pracy; -2) miejsce lub miejsca wykonywania pracy; -3) wynagrodzenie za pracę odpowiadające rodzajowi pracy, ze wskazaniem składników wynagrodzenia; -4) wymiar czasu pracy; -5) dzień rozpoczęcia pracy; -6) w przypadku umowy o pracę na okres próbny: -a) czas jej trwania lub dzień jej zakończenia oraz, gdy strony tak uzgodnią, postanowienie o przedłużeniu umowy o czas urlopu, a także o czas innej usprawiedliwionej nieobecności pracownika w pracy, jeżeli wystąpią takie nieobecności, -b) okres, na który strony mają zamiar zawrzeć umowę o pracę na czas określony w przypadku, o którym mowa w art. 25 § 22, a także postanowienie o wydłużeniu umowy w przypadku, o którym mowa w art. 25 § 23; -7) w przypadku umowy o pracę na czas określony - czas jej trwania lub dzień jej zakończenia. -§ 11. W przypadku zawarcia umowy o pracę na czas określony w celu, o którym mowa w art. 251 § 4 pkt 1-3, lub w przypadku, o którym mowa w art. 251 § 4 pkt 4, w umowie określa się ten cel lub okoliczności tego przypadku, przez zamieszczenie informacji o obiektywnych przyczynach uzasadniających zawarcie takiej umowy. - -§ 2. Umowę o pracę zawiera się na piśmie. Jeżeli umowa o pracę nie została zawarta z zachowaniem formy pisemnej, pracodawca przed dopuszczeniem pracownika do pracy potwierdza pracownikowi na piśmie ustalenia co do stron umowy, rodzaju umowy oraz jej warunków. - -§ 3. Pracodawca informuje pracownika w postaci papierowej lub elektronicznej: - -1) nie później niż w terminie 7 dni od dnia dopuszczenia pracownika do pracy, co najmniej o: -a) obowiązującej pracownika dobowej i tygodniowej normie czasu pracy, -b) obowiązującym pracownika dobowym i tygodniowym wymiarze czasu pracy, -c) przysługujących pracownikowi przerwach w pracy, -d) przysługującym pracownikowi dobowym i tygodniowym odpoczynku, -e) zasadach dotyczących pracy w godzinach nadliczbowych i rekompensaty za nią, -f) w przypadku pracy zmianowej - zasadach dotyczących przechodzenia ze zmiany na zmianę, -g) w przypadku kilku miejsc wykonywania pracy - zasadach dotyczących przemieszczania się między miejscami wykonywania pracy, -h) innych niż uzgodnione w umowie o pracę przysługujących pracownikowi składnikach wynagrodzenia oraz świadczeniach pieniężnych lub rzeczowych, -i) wymiarze przysługującego pracownikowi płatnego urlopu, w szczególności urlopu wypoczynkowego lub, jeżeli nie jest możliwe jego określenie w dacie przekazywania pracownikowi tej informacji, o zasadach jego ustalania i przyznawania, -j) obowiązujących zasadach rozwiązania stosunku pracy, w tym o wymogach formalnych, długości okresów wypowiedzenia oraz terminie odwołania się do sądu pracy lub, jeżeli nie jest możliwe określenie długości okresów wypowiedzenia w dacie przekazywania pracownikowi tej informacji, sposobie ustalania takich okresów wypowiedzenia, -k) prawie pracownika do szkoleń, jeżeli pracodawca je zapewnia, w szczególności o ogólnych zasadach polityki szkoleniowej pracodawcy, -l) układzie zbiorowym pracy lub innym porozumieniu zbiorowym, którym pracownik jest objęty, a w przypadku zawarcia porozumienia zbiorowego poza zakładem pracy przez wspólne organy lub instytucje - nazwie takich organów lub instytucji, -m) w przypadku gdy pracodawca nie ustalił regulaminu pracy - terminie, miejscu, czasie i częstotliwości wypłacania wynagrodzenia za pracę, porze nocnej oraz przyjętym u danego pracodawcy sposobie potwierdzania przez pracowników przybycia i obecności w pracy oraz usprawiedliwiania nieobecności w pracy; -2) nie później niż w terminie 30 dni od dnia dopuszczenia pracownika do pracy, o nazwie instytucji zabezpieczenia społecznego, do których wpływają składki na ubezpieczenia społeczne związane ze stosunkiem pracy oraz informacje na temat ochrony związanej z zabezpieczeniem społecznym, zapewnianej przez pracodawcę; nie dotyczy to przypadku, w którym pracownik dokonuje wyboru instytucji zabezpieczenia społecznego. -§ 31. Poinformowanie pracownika o warunkach zatrudnienia, o których mowa w § 3 pkt 1 lit. a-f, h-k i pkt 2, może nastąpić przez wskazanie w postaci papierowej lub elektronicznej odpowiednich przepisów prawa pracy oraz prawa ubezpieczeń społecznych. - -§ 32. Pracodawca informuje pracownika w postaci papierowej lub elektronicznej o zmianie adresu swojej siedziby, a w przypadku pracodawcy będącego osobą fizyczną nieposiadającego siedziby - adresu zamieszkania, nie później niż w terminie 7 dni od dnia zmiany adresu. - -§ 33. Pracodawca informuje pracownika w postaci papierowej lub elektronicznej o zmianie warunków zatrudnienia, o których mowa w § 3, a także o objęciu pracownika układem zbiorowym pracy lub innym porozumieniem zbiorowym niezwłocznie, nie później jednak niż w dniu, w którym taka zmiana ma zastosowanie do pracownika. Nie dotyczy to przypadku, w którym zmiana warunków zatrudnienia wynika ze zmiany przepisów prawa pracy oraz prawa ubezpieczeń społecznych, jeżeli przepisy te zostały wskazane w informacji przekazanej pracownikowi. - -§ 34. Informacje, o których mowa w § 3-33, pracodawca może przekazać pracownikowi w postaci elektronicznej, jeżeli będą dostępne dla pracownika z możliwością ich wydrukowania oraz przechowywania, a pracodawca zachowa dowód ich przekazania lub otrzymania przez pracownika. - -§ 4. Zmiana warunków umowy o pracę wymaga formy pisemnej. - -§ 5. Przepisy § 1-4 stosuje się odpowiednio do stosunków pracy nawiązanych na innej podstawie niż umowa o pracę. - - -Art. 291. § 1. (uchylony) - -§ 2. Przed wyjazdem pracownika do pracy lub w celu wykonania zadania służbowego poza granicami kraju na okres przekraczający 4 kolejne tygodnie pracodawca przekazuje pracownikowi niezależnie od informacji, o których mowa w art. 29 § 3, informacje w postaci papierowej lub elektronicznej o: - -1) państwie lub państwach, w których praca lub zadanie służbowe poza granicami kraju mają być wykonywane; -2) przewidywanym czasie trwania pracy lub zadania służbowego poza granicami kraju; -3) walucie, w której będzie wypłacane pracownikowi wynagrodzenie w czasie wykonywania pracy lub zadania służbowego poza granicami kraju; -4) świadczeniach pieniężnych lub rzeczowych związanych z wykonywaniem pracy lub zadania służbowego poza granicami kraju, jeżeli takie świadczenia przewidują przepisy prawa pracy lub wynika to z umowy o pracę; -5) zapewnieniu lub braku zapewnienia powrotu pracownika do kraju; -6) warunkach powrotu pracownika do kraju - w przypadku zapewnienia takiego powrotu. -§ 3. Poinformowanie pracownika o warunku zatrudnienia, o którym mowa w § 2 pkt 3, może nastąpić przez wskazanie w postaci papierowej lub elektronicznej odpowiednich przepisów prawa pracy. - -§ 4. Pracodawca informuje pracownika w postaci papierowej lub elektronicznej o zmianie warunków zatrudnienia, o których mowa w § 2, niezwłocznie, nie później jednak niż w dniu, w którym taka zmiana ma zastosowanie do pracownika. Nie dotyczy to przypadku, w którym zmiana warunków zatrudnienia wynika ze zmiany przepisów prawa pracy, jeżeli przepisy te zostały wskazane w informacji przekazanej pracownikowi. - -§ 5. (uchylony) - -§ 51. Do informacji, o których mowa w § 2 i 3, przepis art. 29 § 34 stosuje się odpowiednio. - -§ 6. Przepisy § 2-4 i 51 stosuje się odpowiednio do stosunków pracy nawiązanych na innej podstawie niż umowa o pracę. - - -Art. 292. § 1. Zawarcie z pracownikiem umowy o pracę przewidującej zatrudnienie w niepełnym wymiarze czasu pracy nie może powodować ustalenia jego warunków pracy i płacy w sposób mniej korzystny w stosunku do pracowników wykonujących taką samą lub podobną pracę w pełnym wymiarze czasu pracy, z uwzględnieniem jednak proporcjonalności wynagrodzenia za pracę i innych świadczeń związanych z pracą, do wymiaru czasu pracy pracownika. - -§ 2. (uchylony) - - -Art. 293. § 1. Pracownik zatrudniony u danego pracodawcy co najmniej 6 miesięcy może raz w roku kalendarzowym wystąpić do pracodawcy z wnioskiem, złożonym w postaci papierowej lub elektronicznej, o zmianę rodzaju umowy o pracę na umowę o pracę na czas nieokreślony lub o bardziej przewidywalne i bezpieczne warunki pracy, w tym polegające na zmianie rodzaju pracy lub zatrudnieniu w pełnym wymiarze czasu pracy. Nie dotyczy to pracownika zatrudnionego na podstawie umowy o pracę na okres próbny. Do okresu zatrudnienia pracownika u danego pracodawcy wlicza się pracownikowi okres zatrudnienia u poprzedniego pracodawcy, jeżeli zmiana pracodawcy nastąpiła na zasadach określonych w art. 231, a także w innych przypadkach, gdy z mocy odrębnych przepisów nowy pracodawca jest następcą prawnym w stosunkach pracy nawiązanych przez pracodawcę poprzednio zatrudniającego tego pracownika. - -§ 2. Pracodawca powinien, w miarę możliwości, uwzględnić wniosek pracownika, o którym mowa w § 1. - -§ 3. Pracodawca udziela pracownikowi w postaci papierowej lub elektronicznej odpowiedzi na wniosek, o którym mowa w § 1, biorąc pod uwagę potrzeby pracodawcy i pracownika, nie później niż w terminie 1 miesiąca od dnia otrzymania wniosku; w razie nieuwzględnienia wniosku pracodawca informuje pracownika o przyczynie odmowy. - - -Art. 294. § 1. Przyczyny uzasadniającej wypowiedzenie umowy o pracę lub jej rozwiązanie bez wypowiedzenia przez pracodawcę, przyczyny uzasadniającej przygotowanie do wypowiedzenia lub rozwiązania umowy bez wypowiedzenia albo przyczyny zastosowania działania mającego skutek równoważny z rozwiązaniem umowy o pracę nie może stanowić: - -1) wystąpienie przez pracownika z wnioskiem, o którym mowa w art. 293 § 1; -2) jednoczesne pozostawanie w stosunku pracy z innym pracodawcą lub jednoczesne pozostawanie w stosunku prawnym będącym podstawą świadczenia pracy innym niż stosunek pracy, chyba że ograniczenia w tym zakresie wynikają z odrębnych przepisów albo zachodzi przypadek określony w art. 1011 § 1; -3) dochodzenie przez pracownika udzielenia informacji, o których mowa w art. 29 § 3, 32 i 33 oraz art. 291 § 2 i 4; -4) skorzystanie z praw, o których mowa w art. 9413. -§ 2. Pracodawca udowodni, że przy rozwiązywaniu umowy o pracę lub zastosowaniu działania mającego skutek równoważny z rozwiązaniem umowy o pracę kierował się powodami innymi niż wskazane w § 1. - -§ 3. Jeżeli pracownik uważa, że przyczyną rozwiązania umowy o pracę na okres próbny za wypowiedzeniem albo zastosowania działania mającego skutek równoważny z rozwiązaniem umowy o pracę było jednoczesne pozostawanie w stosunku pracy z innym pracodawcą lub jednoczesne pozostawanie w stosunku prawnym innym niż stosunek pracy, lub dochodzenie udzielenia informacji, o których mowa w art. 29 § 3, 32 i 33 oraz art. 291 § 2 i 4, lub skorzystanie z praw, o których mowa w art. 9413, może, w terminie 7 dni od dnia złożenia oświadczenia woli pracodawcy o rozwiązaniu umowy o pracę na okres próbny za wypowiedzeniem albo zastosowania działania mającego skutek równoważny z rozwiązaniem umowy o pracę, złożyć do pracodawcy wniosek w postaci papierowej lub elektronicznej o wskazanie przyczyny uzasadniającej to rozwiązanie umowy o pracę albo zastosowanie działania. - -§ 4. Pracodawca udziela pracownikowi odpowiedzi na wniosek, o którym mowa w § 3, w postaci papierowej lub elektronicznej w terminie 7 dni od dnia złożenia przez pracownika wniosku. - -Oddział 2 -Przepisy ogólne o rozwiązaniu umowy o pracę - -Art. 30. § 1. Umowa o pracę rozwiązuje się: - -1) na mocy porozumienia stron; -2) przez oświadczenie jednej ze stron z zachowaniem okresu wypowiedzenia (rozwiązanie umowy o pracę za wypowiedzeniem); -3) przez oświadczenie jednej ze stron bez zachowania okresu wypowiedzenia (rozwiązanie umowy o pracę bez wypowiedzenia); -4) z upływem czasu, na który była zawarta. -5) (uchylony) -§ 2. Umowa o pracę na okres próbny rozwiązuje się z upływem tego okresu, a przed jego upływem może być rozwiązana za wypowiedzeniem. - -§ 21. Okres wypowiedzenia umowy o pracę obejmujący tydzień lub miesiąc albo ich wielokrotność kończy się odpowiednio w sobotę lub w ostatnim dniu miesiąca. - -§ 3. Oświadczenie każdej ze stron o wypowiedzeniu lub rozwiązaniu umowy o pracę bez wypowiedzenia powinno nastąpić na piśmie. - -§ 4. W oświadczeniu pracodawcy o wypowiedzeniu umowy o pracę zawartej na czas określony lub umowy o pracę zawartej na czas nieokreślony lub o rozwiązaniu umowy o pracę bez wypowiedzenia powinna być wskazana przyczyna uzasadniająca wypowiedzenie lub rozwiązanie umowy. - -§ 5. W oświadczeniu pracodawcy o wypowiedzeniu umowy o pracę lub jej rozwiązaniu bez wypowiedzenia powinno być zawarte pouczenie o przysługującym pracownikowi prawie odwołania do sądu pracy. - -Art. 31. (skreślony). - -Oddział 3 -Rozwiązanie umowy o pracę za wypowiedzeniem - -Art. 32. § 1. Każda ze stron może rozwiązać umowę o pracę za wypowiedzeniem. - -§ 2. Rozwiązanie umowy o pracę następuje z upływem okresu wypowiedzenia. - -Art. 33. (uchylony). - - -Art. 331. (uchylony). - -Art. 34. Okres wypowiedzenia umowy o pracę zawartej na okres próbny wynosi: - -1) 3 dni robocze, jeżeli okres próbny nie przekracza 2 tygodni, -2) 1 tydzień, jeżeli okres próbny jest dłuższy niż 2 tygodnie, -3) 2 tygodnie, jeżeli okres próbny wynosi 3 miesiące. -Art. 35. (skreślony). - -Art. 36. § 1. Okres wypowiedzenia umowy o pracę zawartej na czas nieokreślony i umowy o pracę zawartej na czas określony jest uzależniony od okresu zatrudnienia u danego pracodawcy i wynosi: - -1) 2 tygodnie, jeżeli pracownik był zatrudniony krócej niż 6 miesięcy, -2) 1 miesiąc, jeżeli pracownik był zatrudniony co najmniej 6 miesięcy, -3) 3 miesiące, jeżeli pracownik był zatrudniony co najmniej 3 lata. -§ 11. Do okresu zatrudnienia, o którym mowa w § 1, wlicza się pracownikowi okres zatrudnienia u poprzedniego pracodawcy, jeżeli zmiana pracodawcy nastąpiła na zasadach określonych w art. 231, a także w innych przypadkach, gdy z mocy odrębnych przepisów nowy pracodawca jest następcą prawnym w stosunkach pracy nawiązanych przez pracodawcę poprzednio zatrudniającego tego pracownika. - -§ 2. (skreślony) - -§ 3. (skreślony) - -§ 4. (skreślony) - -§ 5. Jeżeli pracownik jest zatrudniony na stanowisku związanym z odpowiedzialnością materialną za powierzone mienie, strony mogą ustalić w umowie o pracę, że w przypadku, o którym mowa w § 1 pkt 1, okres wypowiedzenia wynosi 1 miesiąc, a w przypadku, o którym mowa w § 1 pkt 2 - 3 miesiące. - -§ 6. Strony mogą po dokonaniu wypowiedzenia umowy o pracę przez jedną z nich ustalić wcześniejszy termin rozwiązania umowy; ustalenie takie nie zmienia trybu rozwiązania umowy o pracę. - -Art. 361. § 1. Jeżeli wypowiedzenie pracownikowi umowy o pracę zawartej na czas nieokreślony lub umowy o pracę zawartej na czas określony następuje z powodu ogłoszenia upadłości lub likwidacji pracodawcy albo z innych przyczyn niedotyczących pracowników, pracodawca może, w celu wcześniejszego rozwiązania umowy o pracę, skrócić okres trzymiesięcznego wypowiedzenia, najwyżej jednak do 1 miesiąca. W takim przypadku pracownikowi przysługuje odszkodowanie w wysokości wynagrodzenia za pozostałą część okresu wypowiedzenia. - -§ 2. Okres, za który przysługuje odszkodowanie, wlicza się pracownikowi pozostającemu w tym okresie bez pracy do okresu zatrudnienia. - - -Art. 362. W związku z wypowiedzeniem umowy o pracę pracodawca może zwolnić pracownika z obowiązku świadczenia pracy do upływu okresu wypowiedzenia. W okresie tego zwolnienia pracownik zachowuje prawo do wynagrodzenia. - -Art. 37. § 1. W okresie co najmniej dwutygodniowego wypowiedzenia umowy o pracę dokonanego przez pracodawcę pracownikowi przysługuje zwolnienie na poszukiwanie pracy, z zachowaniem prawa do wynagrodzenia. - -§ 2. Wymiar zwolnienia wynosi: - -1) 2 dni robocze - w okresie dwutygodniowego i jednomiesięcznego wypowiedzenia, -2) 3 dni robocze - w okresie trzymiesięcznego wypowiedzenia, także w przypadku jego skrócenia na podstawie art. 361 § 1. -Art. 38. § 1. O zamiarze wypowiedzenia pracownikowi umowy o pracę zawartej na czas określony lub umowy o pracę zawartej na czas nieokreślony pracodawca zawiadamia na piśmie reprezentującą pracownika zakładową organizację związkową, podając przyczynę uzasadniającą rozwiązanie umowy. - -§ 2. Jeżeli zakładowa organizacja związkowa uważa, że wypowiedzenie byłoby nieuzasadnione, może w ciągu 5 dni od otrzymania zawiadomienia zgłosić na piśmie pracodawcy umotywowane zastrzeżenia. - -§ 3. (skreślony). - -§ 4. (skreślony). - -§ 5. Po rozpatrzeniu stanowiska organizacji związkowej, a także w razie niezajęcia przez nią stanowiska w ustalonym terminie, pracodawca podejmuje decyzję w sprawie wypowiedzenia. - -Art. 39. Pracodawca nie może wypowiedzieć umowy o pracę pracownikowi, któremu brakuje nie więcej niż 4 lata do osiągnięcia wieku emerytalnego, jeżeli okres zatrudnienia umożliwia mu uzyskanie prawa do emerytury z osiągnięciem tego wieku. - -Art. 40. Przepisu art. 39 nie stosuje się w razie uzyskania przez pracownika prawa do renty z tytułu całkowitej niezdolności do pracy. - -Art. 41. Pracodawca nie może wypowiedzieć umowy o pracę w czasie urlopu pracownika, a także w czasie innej usprawiedliwionej nieobecności pracownika w pracy, jeżeli nie upłynął jeszcze okres uprawniający do rozwiązania umowy o pracę bez wypowiedzenia. - -Art. 411. § 1. W razie ogłoszenia upadłości lub likwidacji pracodawcy, nie stosuje się przepisów art. 38, 39 i 41, ani przepisów szczególnych dotyczących ochrony pracowników przed wypowiedzeniem lub rozwiązaniem umowy o pracę. - -§ 2. (uchylony). - -§ 3. (skreślony). - -§ 4. (skreślony). - -Art. 42. § 1. Przepisy o wypowiedzeniu umowy o pracę stosuje się odpowiednio do wypowiedzenia wynikających z umowy warunków pracy i płacy. - -§ 2. Wypowiedzenie warunków pracy lub płacy uważa się za dokonane, jeżeli pracownikowi zaproponowano na piśmie nowe warunki. - -§ 3. W razie odmowy przyjęcia przez pracownika zaproponowanych warunków pracy lub płacy, umowa o pracę rozwiązuje się z upływem okresu dokonanego wypowiedzenia. Jeżeli pracownik przed upływem połowy okresu wypowiedzenia nie złoży oświadczenia o odmowie przyjęcia zaproponowanych warunków, uważa się, że wyraził zgodę na te warunki; pismo pracodawcy wypowiadające warunki pracy lub płacy powinno zawierać pouczenie w tej sprawie. W razie braku takiego pouczenia, pracownik może do końca okresu wypowiedzenia złożyć oświadczenie o odmowie przyjęcia zaproponowanych warunków. - -§ 4. Wypowiedzenie dotychczasowych warunków pracy lub płacy nie jest wymagane w razie powierzenia pracownikowi, w przypadkach uzasadnionych potrzebami pracodawcy, innej pracy niż określona w umowie o pracę na okres nie przekraczający 3 miesięcy w roku kalendarzowym, jeżeli nie powoduje to obniżenia wynagrodzenia i odpowiada kwalifikacjom pracownika. - -Art. 43. Pracodawca może wypowiedzieć warunki pracy lub płacy pracownikowi, o którym mowa w art. 39, jeżeli wypowiedzenie stało się konieczne ze względu na: - -1) wprowadzenie nowych zasad wynagradzania dotyczących ogółu pracowników zatrudnionych u danego pracodawcy lub tej ich grupy, do której pracownik należy, -2) stwierdzoną orzeczeniem lekarskim utratę zdolności do wykonywania dotychczasowej pracy albo niezawinioną przez pracownika utratę uprawnień koniecznych do jej wykonywania. -Oddział 4 -Uprawnienia pracownika w razie nieuzasadnionego lub niezgodnego z prawem wypowiedzenia umowy o pracę przez pracodawcę - -Art. 44. Pracownik może wnieść odwołanie od wypowiedzenia umowy o pracę do sądu pracy, o którym mowa w dziale dwunastym. - -Art. 45. § 1. W razie ustalenia, że wypowiedzenie umowy o pracę zawartej na czas określony lub umowy o pracę zawartej na czas nieokreślony jest nieuzasadnione lub narusza przepisy o wypowiadaniu umów o pracę, sąd pracy - stosownie do żądania pracownika - orzeka o bezskuteczności wypowiedzenia, a jeżeli umowa uległa już rozwiązaniu - o przywróceniu pracownika do pracy na poprzednich warunkach albo o odszkodowaniu. - -§ 2. Sąd pracy może nie uwzględnić żądania pracownika uznania wypowiedzenia za bezskuteczne lub przywrócenia do pracy, jeżeli ustali, że uwzględnienie takiego żądania jest niemożliwe lub niecelowe; w takim przypadku sąd pracy orzeka o odszkodowaniu. Jeżeli przed wydaniem orzeczenia upłynął termin, do którego umowa o pracę zawarta na czas określony miała trwać, lub jeżeli przywrócenie do pracy byłoby niewskazane ze względu na krótki okres, jaki pozostał do upływu tego terminu, pracownikowi przysługuje wyłącznie odszkodowanie. - -§ 3. Przepisu § 2 zdanie pierwsze nie stosuje się do pracowników, o których mowa w art. 39 i 177, oraz w przepisach szczególnych dotyczących ochrony pracowników przed wypowiedzeniem lub rozwiązaniem umowy o pracę, chyba że uwzględnienie żądania pracownika przywrócenia do pracy jest niemożliwe z przyczyn określonych w art. 411; w takim przypadku sąd pracy orzeka o odszkodowaniu. - -Art. 46. (skreślony). - -Art. 47. Pracownikowi, który podjął pracę w wyniku przywrócenia do pracy, przysługuje wynagrodzenie za czas pozostawania bez pracy, nie więcej jednak niż za 2 miesiące, a gdy okres wypowiedzenia wynosił 3 miesiące - nie więcej niż za 1 miesiąc. Jeżeli umowę o pracę rozwiązano z pracownikiem, o którym mowa w art. 39, albo z pracownicą w okresie ciąży oraz w okresie urlopu macierzyńskiego lub od dnia złożenia przez pracownika wniosku o udzielenie urlopu macierzyńskiego albo jego części - do dnia zakończenia tego urlopu, wynagrodzenie przysługuje za cały czas pozostawania bez pracy. Dotyczy to także przypadku, gdy rozwiązanie umowy o pracę podlega ograniczeniu z mocy przepisu szczególnego. - -Art. 471. Odszkodowanie, o którym mowa w art. 45, przysługuje w wysokości wynagrodzenia za okres od 2 tygodni do 3 miesięcy, nie niższej jednak od wynagrodzenia za okres wypowiedzenia. W przypadku wypowiedzenia umowy o pracę zawartej na czas określony, której termin, do którego umowa ta miała trwać, określony w umowie upłynął przed wydaniem orzeczenia przez sąd pracy, lub gdy przywrócenie do pracy byłoby niewskazane ze względu na krótki okres, jaki pozostał do upływu tego terminu, odszkodowanie przysługuje w wysokości wynagrodzenia za czas, do upływu którego umowa miała trwać, nie więcej jednak niż za okres 3 miesięcy. - -Art. 48. § 1. Pracodawca może odmówić ponownego zatrudnienia pracownika, jeżeli w ciągu 7 dni od przywrócenia do pracy nie zgłosił on gotowości niezwłocznego podjęcia pracy, chyba że przekroczenie terminu nastąpiło z przyczyn niezależnych od pracownika. - -§ 2. Pracownik, który przed przywróceniem do pracy podjął zatrudnienie u innego pracodawcy, może bez wypowiedzenia, za trzydniowym uprzedzeniem, rozwiązać umowę o pracę z tym pracodawcą w ciągu 7 dni od przywrócenia do pracy. Rozwiązanie umowy w tym trybie pociąga za sobą skutki, jakie przepisy prawa wiążą z rozwiązaniem umowy o pracę przez pracodawcę za wypowiedzeniem. - -Art. 49. W razie zastosowania okresu wypowiedzenia krótszego niż wymagany, umowa o pracę rozwiązuje się z upływem okresu wymaganego, a pracownikowi przysługuje wynagrodzenie do czasu rozwiązania umowy. - -Art. 50. § 1. Jeżeli wypowiedzenie umowy o pracę zawartej na okres próbny nastąpiło z naruszeniem przepisów o wypowiadaniu tych umów, pracownikowi przysługuje wyłącznie odszkodowanie. Odszkodowanie przysługuje w wysokości wynagrodzenia za czas, do upływu którego umowa miała trwać. - -§ 2. (skreślony). - -§ 3. (uchylony) - -§ 4. (uchylony) - -§ 5. (uchylony) - -Art. 51. § 1. Pracownikowi, który podjął pracę w wyniku przywrócenia do pracy, wlicza się do okresu zatrudnienia okres pozostawania bez pracy, za który przyznano wynagrodzenie. Okresu pozostawania bez pracy, za który nie przyznano wynagrodzenia, nie uważa się za przerwę w zatrudnieniu, pociągającą za sobą utratę uprawnień uzależnionych od nieprzerwanego zatrudnienia. - -§ 2. Pracownikowi, któremu przyznano odszkodowanie, wlicza się do okresu zatrudnienia okres pozostawania bez pracy, odpowiadający okresowi, za który przyznano odszkodowanie. - -Oddział 5 -Rozwiązanie umowy o pracę bez wypowiedzenia - -Art. 52. § 1. Pracodawca może rozwiązać umowę o pracę bez wypowiedzenia z winy pracownika w razie: - -1) ciężkiego naruszenia przez pracownika podstawowych obowiązków pracowniczych, -2) popełnienia przez pracownika w czasie trwania umowy o pracę przestępstwa, które uniemożliwia dalsze zatrudnianie go na zajmowanym stanowisku, jeżeli przestępstwo jest oczywiste lub zostało stwierdzone prawomocnym wyrokiem, -3) zawinionej przez pracownika utraty uprawnień koniecznych do wykonywania pracy na zajmowanym stanowisku. -§ 2. Rozwiązanie umowy o pracę bez wypowiedzenia z winy pracownika nie może nastąpić po upływie 1 miesiąca od uzyskania przez pracodawcę wiadomości o okoliczności uzasadniającej rozwiązanie umowy. - -§ 3. Pracodawca podejmuje decyzję w sprawie rozwiązania umowy po zasięgnięciu opinii reprezentującej pracownika zakładowej organizacji związkowej, którą zawiadamia o przyczynie uzasadniającej rozwiązanie umowy. W razie zastrzeżeń co do zasadności rozwiązania umowy zakładowa organizacja związkowa wyraża swoją opinię niezwłocznie, nie później jednak niż w ciągu 3 dni. - -§ 4. (skreślony). - -Art. 53. § 1. Pracodawca może rozwiązać umowę o pracę bez wypowiedzenia: - -1) jeżeli niezdolność pracownika do pracy wskutek choroby trwa: -a) dłużej niż 3 miesiące - gdy pracownik był zatrudniony u danego pracodawcy krócej niż 6 miesięcy, -b) dłużej niż łączny okres pobierania z tego tytułu wynagrodzenia i zasiłku oraz pobierania świadczenia rehabilitacyjnego przez pierwsze 3 miesiące - gdy pracownik był zatrudniony u danego pracodawcy co najmniej 6 miesięcy lub jeżeli niezdolność do pracy została spowodowana wypadkiem przy pracy albo chorobą zawodową, -2) w razie usprawiedliwionej nieobecności pracownika w pracy z innych przyczyn niż wymienione w pkt 1, trwającej dłużej niż 1 miesiąc. -§ 2. Rozwiązanie umowy o pracę bez wypowiedzenia nie może nastąpić w razie nieobecności pracownika w pracy z powodu sprawowania opieki nad dzieckiem - w okresie pobierania z tego tytułu zasiłku, a w przypadku odosobnienia pracownika ze względu na chorobę zakaźną - w okresie pobierania z tego tytułu wynagrodzenia i zasiłku. - -§ 3. Rozwiązanie umowy o pracę bez wypowiedzenia nie może nastąpić po stawieniu się pracownika do pracy w związku z ustaniem przyczyny nieobecności. - -§ 4. Przepisy art. 36 § 11 i art. 52 § 3 stosuje się odpowiednio. - -§ 5. Pracodawca powinien w miarę możliwości ponownie zatrudnić pracownika, który w okresie 6 miesięcy od rozwiązania umowy o pracę bez wypowiedzenia, z przyczyn wymienionych w § 1 i 2, zgłosi swój powrót do pracy niezwłocznie po ustaniu tych przyczyn. - -Art. 54. (skreślony). - -Art. 55. § 1. Pracownik może rozwiązać umowę o pracę bez wypowiedzenia, jeżeli zostanie wydane orzeczenie lekarskie stwierdzające szkodliwy wpływ wykonywanej pracy na zdrowie pracownika, a pracodawca nie przeniesie go w terminie wskazanym w orzeczeniu lekarskim do innej pracy, odpowiedniej ze względu na stan jego zdrowia i kwalifikacje zawodowe. - -§ 11. Pracownik może rozwiązać umowę o pracę w trybie określonym w § 1 także wtedy, gdy pracodawca dopuścił się ciężkiego naruszenia podstawowych obowiązków wobec pracownika; w takim przypadku pracownikowi przysługuje odszkodowanie w wysokości wynagrodzenia za okres wypowiedzenia. W przypadku rozwiązania umowy o pracę zawartej na czas określony odszkodowanie przysługuje w wysokości wynagrodzenia za czas, do którego umowa miała trwać, nie więcej jednak niż za okres wypowiedzenia. - -§ 2. Oświadczenie pracownika o rozwiązaniu umowy o pracę bez wypowiedzenia powinno nastąpić na piśmie, z podaniem przyczyny uzasadniającej rozwiązanie umowy. Przepis art. 52 § 2 stosuje się odpowiednio. - -§ 3. Rozwiązanie umowy o pracę z przyczyn określonych w § 1 i 11 pociąga za sobą skutki, jakie przepisy prawa wiążą z rozwiązaniem umowy przez pracodawcę za wypowiedzeniem. - -Oddział 6 -Uprawnienia pracownika w razie niezgodnego z prawem rozwiązania przez pracodawcę umowy o pracę bez wypowiedzenia - -Art. 56. § 1. Pracownikowi, z którym rozwiązano umowę o pracę bez wypowiedzenia z naruszeniem przepisów o rozwiązywaniu umów o pracę w tym trybie, przysługuje roszczenie o przywrócenie do pracy na poprzednich warunkach albo o odszkodowanie. O przywróceniu do pracy lub odszkodowaniu orzeka sąd pracy. - -§ 2. Przepisy art. 45 § 2 i 3 stosuje się odpowiednio. - -Art. 57. § 1. Pracownikowi, który podjął pracę w wyniku przywrócenia do pracy, przysługuje wynagrodzenie za czas pozostawania bez pracy, nie więcej jednak niż za 3 miesiące i nie mniej niż za 1 miesiąc. - -§ 2. Jeżeli umowę o pracę rozwiązano z pracownikiem, o którym mowa w art. 39, albo z pracownicą w okresie ciąży oraz w okresie urlopu macierzyńskiego lub od dnia złożenia przez pracownika wniosku o udzielenie urlopu macierzyńskiego albo jego części - do dnia zakończenia tego urlopu, wynagrodzenie przysługuje za cały czas pozostawania bez pracy. Dotyczy to także przypadku, gdy rozwiązanie umowy o pracę podlega ograniczeniu z mocy przepisu szczególnego. - -§ 3. (skreślony). - -§ 4. Przepisy art. 48 i 51 § 1 stosuje się odpowiednio. - -Art. 58. Odszkodowanie, o którym mowa w art. 56, przysługuje w wysokości wynagrodzenia za okres wypowiedzenia. W przypadku rozwiązania umowy o pracę zawartej na czas określony odszkodowanie przysługuje w wysokości wynagrodzenia za czas, do którego umowa miała trwać, nie więcej jednak niż za okres wypowiedzenia. - -Art. 59. W razie rozwiązania przez pracodawcę umowy o pracę zawartej na czas określony z naruszeniem przepisów o rozwiązywaniu umów o pracę bez wypowiedzenia pracownikowi przysługuje wyłącznie odszkodowanie, jeżeli upłynął już termin, do którego umowa miała trwać, lub gdy przywrócenie do pracy byłoby niewskazane ze względu na krótki okres, jaki pozostał do upływu tego terminu. W tym przypadku odszkodowanie przysługuje w wysokości określonej w art. 58. - -Art. 60. Jeżeli pracodawca rozwiązał umowę o pracę w okresie wypowiedzenia z naruszeniem przepisów o rozwiązywaniu umów o pracę bez wypowiedzenia, pracownikowi przysługuje wyłącznie odszkodowanie. Odszkodowanie przysługuje w wysokości wynagrodzenia za czas do upływu okresu wypowiedzenia. - -Art. 61. Do pracownika, któremu przyznano odszkodowanie na podstawie przepisów niniejszego oddziału, stosuje się odpowiednio przepis art. 51 § 2. - -Oddział 6a -Uprawnienia pracodawcy w razie nieuzasadnionego rozwiązania przez pracownika umowy o pracę bez wypowiedzenia - -Art. 611. W razie nieuzasadnionego rozwiązania przez pracownika umowy o pracę bez wypowiedzenia na podstawie art. 55 § 11, pracodawcy przysługuje roszczenie o odszkodowanie. O odszkodowaniu orzeka sąd pracy. - -Art. 612. § 1. Odszkodowanie, o którym mowa w art. 611, przysługuje w wysokości wynagrodzenia pracownika za okres wypowiedzenia. W przypadku rozwiązania umowy o pracę zawartej na czas określony, odszkodowanie przysługuje w wysokości wynagrodzenia za czas, do którego umowa miała trwać, nie więcej jednak niż za okres wypowiedzenia. - -§ 2. W razie orzeczenia przez sąd pracy o odszkodowaniu, przepisu art. 55 § 3 nie stosuje się. - -Art. 62. (skreślony). - -Oddział 7 -Wygaśnięcie umowy o pracę - -Art. 63. Umowa o pracę wygasa w przypadkach określonych w kodeksie oraz w przepisach szczególnych. - -Art. 631. § 1. Z dniem śmierci pracownika stosunek pracy wygasa. - -§ 2. Prawa majątkowe ze stosunku pracy przechodzą po śmierci pracownika, w równych częściach, na małżonka oraz inne osoby spełniające warunki wymagane do uzyskania renty rodzinnej w myśl przepisów o emeryturach i rentach z Funduszu Ubezpieczeń Społecznych. W razie braku takich osób prawa te wchodzą do spadku. - -Art. 632. § 1. Z dniem śmierci pracodawcy umowy o pracę z pracownikami wygasają, z zastrzeżeniem § 3-11. - -§ 2. Pracownikowi, którego umowa o pracę wygasła z przyczyn określonych w § 1, przysługuje odszkodowanie w wysokości wynagrodzenia za okres wypowiedzenia. - -§ 3. Przepis § 1 nie ma zastosowania w przypadku: - -1) przejęcia pracownika przez nowego pracodawcę na zasadach określonych w art. 231; -2) ustanowienia zarządu sukcesyjnego z chwilą śmierci pracodawcy, zgodnie z ustawą z dnia 5 lipca 2018 r. o zarządzie sukcesyjnym przedsiębiorstwem osoby fizycznej i innych ułatwieniach związanych z sukcesją przedsiębiorstw, zwanej dalej „ustawą o zarządzie sukcesyjnym”. -§ 4. W przypadku, o którym mowa w § 3 pkt 2, umowa o pracę z pracownikiem wygasa z dniem wygaśnięcia zarządu sukcesyjnego, chyba że przed tym dniem nastąpiło przejęcie pracownika przez nowego pracodawcę na zasadach określonych w art. 231. - -§ 5. W przypadku gdy zgodnie z ustawą o zarządzie sukcesyjnym nie ustanowiono zarządu sukcesyjnego z chwilą śmierci pracodawcy, umowa o pracę wygasa z upływem 30 dni od dnia śmierci pracodawcy, chyba że przed upływem tego terminu osoba, o której mowa w art. 14 ustawy o zarządzie sukcesyjnym, albo zarządca sukcesyjny uzgodni z pracownikiem, na mocy pisemnego porozumienia stron, że stosunek pracy będzie kontynuowany na dotychczasowych zasadach: - -1) do dnia ustanowienia zarządu sukcesyjnego albo wygaśnięcia uprawnienia do powołania zarządcy sukcesyjnego - jeżeli porozumienie z pracownikiem zawiera osoba, o której mowa w art. 14 ustawy o zarządzie sukcesyjnym; -2) do dnia wygaśnięcia zarządu sukcesyjnego - jeżeli porozumienie z pracownikiem zawiera zarządca sukcesyjny. -§ 6. Strony porozumienia, o którym mowa w § 5, mogą także uzgodnić wcześniejszy termin rozwiązania umowy o pracę. - -§ 7. W przypadku gdy zgodnie z ustawą o zarządzie sukcesyjnym nie ustanowiono zarządu sukcesyjnego z chwilą śmierci pracodawcy, umowa o pracę na czas określony rozwiązuje się z upływem czasu, na który została zawarta, jeżeli termin jej rozwiązania przypada przed upływem 30 dni od dnia śmierci pracodawcy, chyba że strony uzgodnią wcześniejszy termin rozwiązania umowy. Jeżeli termin rozwiązania umowy o pracę na czas określony przypada po upływie 30 dni od dnia śmierci pracodawcy umowa o pracę wygasa z dniem wygaśnięcia zarządu sukcesyjnego albo wygaśnięcia uprawnienia do powołania zarządcy sukcesyjnego, chyba że wcześniej rozwiąże się z upływem czasu, na który została zawarta, albo strony uzgodnią wcześniejszy termin rozwiązania umowy. - -§ 8. Okres od dnia śmierci pracodawcy do dnia wygaśnięcia umowy o pracę albo dokonania uzgodnienia zgodnie z § 5 i 6, albo rozwiązania umowy o pracę zgodnie z § 7 jest okresem usprawiedliwionej nieobecności w pracy, za który pracownik nie zachowuje prawa do wynagrodzenia. - -§ 9. W okresie, o którym mowa w § 8, osoba, o której mowa w art. 14 ustawy o zarządzie sukcesyjnym, a jeżeli został ustanowiony zarząd sukcesyjny - zarządca sukcesyjny, może polecić pracownikowi wykonywanie pracy zgodnej z jego umową o pracę, określając okres wykonywania pracy przez pracownika i wymiar czasu pracy. - -§ 10. Jeżeli zgodnie z ustawą o zarządzie sukcesyjnym nie ustanowiono zarządu sukcesyjnego, w przypadku uzgodnienia, o którym mowa w § 5 pkt 1, umowy o pracę wygasają z dniem wygaśnięcia uprawnienia do powołania zarządcy sukcesyjnego, chyba że strony uzgodniły wcześniejszy termin rozwiązania umowy o pracę. - -§ 11. Jeżeli zgodnie z ustawą o zarządzie sukcesyjnym ustanowiono zarząd sukcesyjny, w przypadku uzgodnienia, o którym mowa w § 5 pkt 1, umowy o pracę wygasają z dniem wygaśnięcia zarządu sukcesyjnego, chyba że wcześniej nastąpiło przejęcie pracownika przez nowego pracodawcę na zasadach określonych w art. 231. - -§ 12. W razie ponownego zatrudniania pracowników w tej samej grupie zawodowej zarządca sukcesyjny zatrudnia na poprzednich warunkach pracownika, którego umowa o pracę wygasła z powodu śmierci pracodawcy, jeżeli pracownik ten zgłosi zamiar podjęcia zatrudnienia w ciągu miesiąca od dnia ustanowienia zarządu sukcesyjnego. - -Art. 64. (skreślony). - -Art. 65. (skreślony). - -Art. 66. § 1. Umowa o pracę wygasa z upływem 3 miesięcy nieobecności pracownika w pracy z powodu tymczasowego aresztowania, chyba że pracodawca rozwiązał wcześniej bez wypowiedzenia umowę o pracę z winy pracownika. - -§ 2. Pracodawca, pomimo wygaśnięcia umowy o pracę z powodu tymczasowego aresztowania, jest obowiązany ponownie zatrudnić pracownika, jeżeli postępowanie karne zostało umorzone lub gdy zapadł wyrok uniewinniający, a pracownik zgłosił swój powrót do pracy w ciągu 7 dni od uprawomocnienia się orzeczenia. Przepisy art. 48 stosuje się odpowiednio. - -§ 3. Przepisów § 2 nie stosuje się w przypadku, gdy postępowanie karne umorzono z powodu przedawnienia albo amnestii, a także w razie warunkowego umorzenia postępowania. - -Art. 67. W razie naruszenia przez pracodawcę przepisów niniejszego oddziału, pracownikowi przysługuje prawo odwołania do sądu pracy. W zakresie roszczeń stosuje się odpowiednio przepisy oddziału 6 niniejszego rozdziału. - - -Rozdział IIa -(uchylony) - - -Art. 671. (uchylony) - - -Art. 672. (uchylony) - - -Art. 673. (uchylony) - - -Art. 674. (uchylony) - - -Rozdział IIb -(uchylony) - - -Art. 675. (uchylony) - - -Art. 676. (uchylony) - - -Art. 677. (uchylony) - - -Art. 678. (uchylony) - - -Art. 679. (uchylony) - - -Art. 6710. (uchylony) - - -Art. 6711. (uchylony) - - -Art. 6712. (uchylony) - - -Art. 6713. (uchylony) - - -Art. 6714. (uchylony) - - -Art. 6715. (uchylony) - - -Art. 6716. (uchylony) - - -Art. 6717. (uchylony) - - -Rozdział IIc -Praca zdalna - - -Art. 6718. Praca może być wykonywana całkowicie lub częściowo w miejscu wskazanym przez pracownika i każdorazowo uzgodnionym z pracodawcą, w tym pod adresem zamieszkania pracownika, w szczególności z wykorzystaniem środków bezpośredniego porozumiewania się na odległość (praca zdalna). - - -Art. 6719. § 1. Uzgodnienie między stronami umowy o pracę dotyczące wykonywania pracy zdalnej przez pracownika może nastąpić: - -1) przy zawieraniu umowy o pracę albo -2) w trakcie zatrudnienia. -§ 2. W przypadku, o którym mowa w § 1 pkt 2, uzgodnienie może być dokonane z inicjatywy pracodawcy albo na wniosek pracownika złożony w postaci papierowej lub elektronicznej. Przepisu art. 29 § 4 nie stosuje się. - -§ 3. Praca zdalna może być wykonywana na polecenie pracodawcy: - -1) w okresie obowiązywania stanu nadzwyczajnego, stanu zagrożenia epidemicznego albo stanu epidemii oraz w okresie 3 miesięcy po ich odwołaniu lub -2) w okresie, w którym zapewnienie przez pracodawcę bezpiecznych i higienicznych warunków pracy w dotychczasowym miejscu pracy pracownika nie jest czasowo możliwe z powodu działania siły wyższej -- jeżeli pracownik złoży bezpośrednio przed wydaniem polecenia oświadczenie w postaci papierowej lub elektronicznej, że posiada warunki lokalowe i techniczne do wykonywania pracy zdalnej. -§ 4. Pracodawca może w każdym czasie cofnąć polecenie wykonywania pracy zdalnej, o którym mowa w § 3, z co najmniej dwudniowym uprzedzeniem. - -§ 5. W przypadku zmiany warunków lokalowych i technicznych uniemożliwiającej wykonywanie pracy zdalnej pracownik informuje o tym niezwłocznie pracodawcę. W takim przypadku pracodawca niezwłocznie cofa polecenie wykonywania pracy zdalnej. - -§ 6. Pracodawca jest obowiązany uwzględnić wniosek pracownika, o którym mowa w art. 1421 § 1 pkt 2 i 3, pracownicy w ciąży, pracownika wychowującego dziecko do ukończenia przez nie 4. roku życia, a także pracownika sprawującego opiekę nad innym członkiem najbliższej rodziny lub inną osobą pozostającą we wspólnym gospodarstwie domowym, posiadającymi orzeczenie o niepełnosprawności albo orzeczenie o znacznym stopniu niepełnosprawności, o wykonywanie pracy zdalnej, chyba że nie jest to możliwe ze względu na organizację pracy lub rodzaj pracy wykonywanej przez pracownika. O przyczynie odmowy uwzględnienia wniosku pracodawca informuje pracownika w postaci papierowej lub elektronicznej w terminie 7 dni roboczych od dnia złożenia wniosku przez pracownika. - -§ 7. Przepis § 6 stosuje się do pracowników, o których mowa w art. 1421 § 1 pkt 2 i 3, również po ukończeniu przez dziecko 18. roku życia. - - -Art. 6720. § 1. Zasady wykonywania pracy zdalnej określa się w porozumieniu zawieranym między pracodawcą i zakładową organizacją związkową, a w przypadku gdy u pracodawcy działa więcej niż jedna zakładowa organizacja związkowa - w porozumieniu między pracodawcą a tymi organizacjami. - -§ 2. Jeżeli nie jest możliwe uzgodnienie treści porozumienia z wszystkimi zakładowymi organizacjami związkowymi, pracodawca uzgadnia treść porozumienia z organizacjami związkowymi reprezentatywnymi w rozumieniu art. 253 ust. 1 lub 2 ustawy o związkach zawodowych, z których każda zrzesza co najmniej 5% pracowników zatrudnionych u pracodawcy. - -§ 3. Jeżeli w terminie 30 dni od dnia przedstawienia projektu porozumienia przez pracodawcę nie dojdzie do zawarcia porozumienia zgodnie z § 1 albo 2, pracodawca określa zasady wykonywania pracy zdalnej w regulaminie, uwzględniając ustalenia podjęte z zakładowymi organizacjami związkowymi w toku uzgadniania porozumienia. - -§ 4. Jeżeli u danego pracodawcy nie działają zakładowe organizacje związkowe, pracodawca określa zasady wykonywania pracy zdalnej w regulaminie po konsultacji z przedstawicielami pracowników wyłonionymi w trybie przyjętym u danego pracodawcy. - -§ 5. Wykonywanie pracy zdalnej jest dopuszczalne także w przypadku, gdy nie zostało zawarte porozumienie, o którym mowa w § 1 albo 2, albo nie został wydany regulamin, o którym mowa w § 3 albo 4. W takim przypadku pracodawca określa zasady wykonywania pracy zdalnej odpowiednio w poleceniu wykonywania pracy zdalnej, o którym mowa w art. 6719 § 3, albo w porozumieniu zawartym z pracownikiem. - -§ 6. W porozumieniu, o którym mowa w § 1 i 2, oraz regulaminie, o którym mowa w § 3 i 4, określa się w szczególności: - -1) grupę lub grupy pracowników, którzy mogą być objęci pracą zdalną; -2) zasady pokrywania przez pracodawcę kosztów, o których mowa w art. 6724 § 1 pkt 2 lub 3; -3) zasady ustalania ekwiwalentu pieniężnego, o którym mowa w art. 6724 § 3, lub ryczałtu, o którym mowa w art. 6724 § 4; -4) zasady porozumiewania się pracodawcy i pracownika wykonującego pracę zdalną, w tym sposób potwierdzania obecności na stanowisku pracy przez pracownika wykonującego pracę zdalną; -5) zasady kontroli wykonywania pracy przez pracownika wykonującego pracę zdalną; -6) zasady kontroli w zakresie bezpieczeństwa i higieny pracy; -7) zasady kontroli przestrzegania wymogów w zakresie bezpieczeństwa i ochrony informacji, w tym procedur ochrony danych osobowych; -8) zasady instalacji, inwentaryzacji, konserwacji, aktualizacji oprogramowania i serwisu powierzonych pracownikowi narzędzi pracy, w tym urządzeń technicznych. -§ 7. Do polecenia, o którym mowa w art. 6719 § 3, oraz porozumienia, o którym mowa w § 5 zdanie drugie, stosuje się odpowiednio § 6 pkt 2-8. - - -Art. 6721. § 1. W przypadku wykonywania pracy zdalnej na podstawie art. 6719 § 1 pkt 1 informacja, o której mowa w art. 29 § 3, obejmuje dodatkowo co najmniej: - -1) określenie jednostki organizacyjnej pracodawcy, w której strukturze znajduje się stanowisko pracy pracownika wykonującego pracę zdalną; -2) wskazanie osoby lub organu, o których mowa w art. 31, odpowiedzialnych za współpracę z pracownikiem wykonującym pracę zdalną oraz upoważnionych do przeprowadzania kontroli w miejscu wykonywania pracy zdalnej. -§ 2. W przypadku wykonywania pracy zdalnej na podstawie art. 6719 § 1 pkt 2 oraz § 3 pracodawca przekazuje pracownikowi informacje określone w § 1, w postaci papierowej lub elektronicznej, najpóźniej w dniu rozpoczęcia przez niego wykonywania pracy zdalnej. - - -Art. 6722. § 1. W przypadku podjęcia pracy zdalnej zgodnie z art. 6719 § 1 pkt 2 każda ze stron umowy o pracę może wystąpić z wiążącym wnioskiem, złożonym w postaci papierowej lub elektronicznej, o zaprzestanie wykonywania pracy zdalnej i przywrócenie poprzednich warunków wykonywania pracy. Strony ustalają termin przywrócenia poprzednich warunków wykonywania pracy, nie dłuższy niż 30 dni od dnia otrzymania wniosku. W razie braku porozumienia przywrócenie poprzednich warunków wykonywania pracy następuje w dniu następującym po upływie 30 dni od dnia otrzymania wniosku. - -§ 2. Pracodawca nie może wystąpić z wiążącym wnioskiem o zaprzestanie wykonywania pracy zdalnej i przywrócenie poprzednich warunków wykonywania pracy przez pracownika, o którym mowa w art. 6719 § 6 i 7, chyba że dalsze wykonywanie pracy zdalnej nie jest możliwe ze względu na organizację pracy lub rodzaj pracy wykonywanej przez pracownika. - - -Art. 6723. Odmowa wyrażenia przez pracownika zgody na zmianę warunków wykonywania pracy w przypadku określonym w art. 6719 § 1 pkt 2, wystąpienie z wnioskiem o wykonywanie pracy zdalnej przez pracownika, o którym mowa w art. 6719 § 6 i 7, a także zaprzestanie wykonywania pracy zdalnej na zasadach określonych w art. 6722 nie mogą stanowić przyczyny uzasadniającej wypowiedzenie przez pracodawcę umowy o pracę. - - -Art. 6724. § 1. Pracodawca jest obowiązany: - -1) zapewnić pracownikowi wykonującemu pracę zdalną materiały i narzędzia pracy, w tym urządzenia techniczne, niezbędne do wykonywania pracy zdalnej; -2) zapewnić pracownikowi wykonującemu pracę zdalną instalację, serwis, konserwację narzędzi pracy, w tym urządzeń technicznych, niezbędnych do wykonywania pracy zdalnej lub pokryć niezbędne koszty związane z instalacją, serwisem, eksploatacją i konserwacją narzędzi pracy, w tym urządzeń technicznych, niezbędnych do wykonywania pracy zdalnej, a także pokryć koszty energii elektrycznej oraz usług telekomunikacyjnych niezbędnych do wykonywania pracy zdalnej; -3) pokryć inne koszty niż koszty określone w pkt 2 bezpośrednio związane z wykonywaniem pracy zdalnej, jeżeli zwrot takich kosztów został określony w porozumieniu, o którym mowa w art. 6720 § 1 i 2, regulaminie, o którym mowa w art. 6720 § 3 i 4, poleceniu, o którym mowa w art. 6719 § 3, albo porozumieniu, o którym mowa w art. 6720 § 5 zdanie drugie; -4) zapewnić pracownikowi wykonującemu pracę zdalną szkolenia i pomoc techniczną niezbędne do wykonywania tej pracy. -§ 2. Strony mogą ustalić zasady wykorzystywania przez pracownika wykonującego pracę zdalną materiałów i narzędzi pracy, w tym urządzeń technicznych, niezbędnych do wykonywania pracy zdalnej, niezapewnionych przez pracodawcę, spełniających wymagania określone w rozdziale IV działu dziesiątego. - -§ 3. W przypadku, o którym mowa w § 2, pracownikowi wykonującemu pracę zdalną przysługuje ekwiwalent pieniężny w wysokości ustalonej z pracodawcą. - -§ 4. Obowiązek pokrycia kosztów, o których mowa w § 1 pkt 2 i 3, albo wypłaty ekwiwalentu, o którym mowa w § 3, może być zastąpiony obowiązkiem wypłaty ryczałtu, którego wysokość odpowiada przewidywanym kosztom ponoszonym przez pracownika w związku z wykonywaniem pracy zdalnej. - -§ 5. Przy ustalaniu wysokości ekwiwalentu albo ryczałtu bierze się pod uwagę w szczególności normy zużycia materiałów i narzędzi pracy, w tym urządzeń technicznych, ich udokumentowane ceny rynkowe oraz ilość materiału wykorzystanego na potrzeby pracodawcy i ceny rynkowe tego materiału, a także normy zużycia energii elektrycznej oraz koszty usług telekomunikacyjnych. - - -Art. 6725. Zapewnienie pracownikowi wykonującemu pracę zdalną przez pracodawcę materiałów i narzędzi pracy, w tym urządzeń technicznych, niezbędnych do wykonywania pracy zdalnej, pokrycie kosztów związanych z wykonywaniem pracy zdalnej przez pracownika i wypłata ekwiwalentu pieniężnego lub ryczałtu nie stanowią przychodu w rozumieniu przepisów ustawy z dnia 26 lipca 1991 r. o podatku dochodowym od osób fizycznych. - - -Art. 6726. § 1. Na potrzeby wykonywania pracy zdalnej pracodawca określa procedury ochrony danych osobowych oraz przeprowadza, w miarę potrzeby, instruktaż i szkolenie w tym zakresie. - -§ 2. Pracownik wykonujący pracę zdalną potwierdza w postaci papierowej lub elektronicznej zapoznanie się z procedurami, o których mowa w § 1, oraz jest obowiązany do ich przestrzegania. - - -Art. 6727. Pracownik wykonujący pracę zdalną i pracodawca przekazują informacje niezbędne do wzajemnego porozumiewania się za pomocą środków bezpośredniego porozumiewania się na odległość lub w inny sposób uzgodniony z pracodawcą. - - -Art. 6728. § 1. Pracodawca ma prawo przeprowadzać kontrolę wykonywania pracy zdalnej przez pracownika, kontrolę w zakresie bezpieczeństwa i higieny pracy lub kontrolę przestrzegania wymogów w zakresie bezpieczeństwa i ochrony informacji, w tym procedur ochrony danych osobowych, na zasadach określonych w porozumieniu, o którym mowa w art. 6720 § 1 i 2, regulaminie, o którym mowa w art. 6720 § 3 i 4, poleceniu, o którym mowa w art. 6719 § 3, albo w porozumieniu, o którym mowa w art. 6720 § 5 zdanie drugie. Kontrolę przeprowadza się w porozumieniu z pracownikiem w miejscu wykonywania pracy zdalnej w godzinach pracy pracownika. - -§ 2. Pracodawca dostosowuje sposób przeprowadzania kontroli do miejsca wykonywania pracy zdalnej i jej rodzaju. Wykonywanie czynności kontrolnych nie może naruszać prywatności pracownika wykonującego pracę zdalną i innych osób ani utrudniać korzystania z pomieszczeń domowych w sposób zgodny z ich przeznaczeniem. - -§ 3. Jeżeli pracodawca w trakcie kontroli pracy zdalnej, o której mowa w art. 6719 § 1 pkt 2, stwierdzi uchybienia w przestrzeganiu przepisów i zasad w zakresie bezpieczeństwa i higieny pracy określonych w informacji, o której mowa w art. 6731 § 5, lub w przestrzeganiu wymogów w zakresie bezpieczeństwa i ochrony informacji, w tym procedur ochrony danych osobowych, zobowiązuje pracownika do usunięcia stwierdzonych uchybień we wskazanym terminie albo cofa zgodę na wykonywanie pracy zdalnej przez tego pracownika. W przypadku wycofania zgody na wykonywanie pracy zdalnej pracownik rozpoczyna pracę w dotychczasowym miejscu pracy w terminie określonym przez pracodawcę. - - -Art. 6729. § 1. Pracownik wykonujący pracę zdalną nie może być traktowany mniej korzystnie w zakresie nawiązania i rozwiązania stosunku pracy, warunków zatrudnienia, awansowania oraz dostępu do szkolenia w celu podnoszenia kwalifikacji zawodowych niż inni pracownicy zatrudnieni przy takiej samej lub podobnej pracy, z uwzględnieniem odrębności związanych z warunkami wykonywania pracy zdalnej. - -§ 2. Pracownik nie może być w jakikolwiek sposób dyskryminowany z powodu wykonywania pracy zdalnej, jak również z powodu odmowy wykonywania takiej pracy. - - -Art. 6730. Pracodawca umożliwia pracownikowi wykonującemu pracę zdalną przebywanie na terenie zakładu pracy, kontaktowanie się z innymi pracownikami oraz korzystanie z pomieszczeń i urządzeń pracodawcy, zakładowych obiektów socjalnych i prowadzonej działalności socjalnej - na zasadach przyjętych dla ogółu pracowników. - - -Art. 6731. § 1. Pracodawca realizuje w stosunku do pracownika w czasie wykonywania przez niego pracy zdalnej obowiązki w zakresie wynikającym z rodzaju i warunków wykonywanej pracy określone w dziale dziesiątym, z wyłączeniem obowiązków określonych w art. 208 § 1, art. 2091, art. 212 pkt 1 i 4, art. 213, art. 214, art. 232 i art. 233. - -§ 2. W przypadku, o którym mowa w art. 6719 § 1 pkt 1, szkolenie wstępne w dziedzinie bezpieczeństwa i higieny pracy osoby przyjmowanej do pracy na stanowisko administracyjno-biurowe może być przeprowadzone w całości za pośrednictwem środków komunikacji elektronicznej. Pracownik potwierdza w postaci papierowej lub elektronicznej ukończenie szkolenia. - -§ 3. W przypadku wykonywania przez pracownika pracy zdalnej przepisu art. 2373 § 22 nie stosuje się. - -§ 4. Praca zdalna nie obejmuje prac: - -1) szczególnie niebezpiecznych; -2) w wyniku których następuje przekroczenie dopuszczalnych norm czynników fizycznych określonych dla pomieszczeń mieszkalnych; -3) z czynnikami chemicznymi stwarzającymi zagrożenie, o których mowa w przepisach w sprawie bezpieczeństwa i higieny pracy związanej z występowaniem czynników chemicznych w miejscu pracy; -4) związanych ze stosowaniem lub wydzielaniem się szkodliwych czynników biologicznych, substancji radioaktywnych oraz innych substancji lub mieszanin wydzielających uciążliwe zapachy; -5) powodujących intensywne brudzenie. -§ 5. Przy ocenie ryzyka zawodowego pracownika wykonującego pracę zdalną uwzględnia się w szczególności wpływ tej pracy na wzrok, układ mięśniowo-szkieletowy oraz uwarunkowania psychospołeczne tej pracy. Na podstawie wyników tej oceny pracodawca opracowuje informację zawierającą: - -1) zasady i sposoby właściwej organizacji stanowiska pracy zdalnej, z uwzględnieniem wymagań ergonomii; -2) zasady bezpiecznego i higienicznego wykonywania pracy zdalnej; -3) czynności do wykonania po zakończeniu wykonywania pracy zdalnej; -4) zasady postępowania w sytuacjach awaryjnych stwarzających zagrożenie dla życia lub zdrowia ludzkiego. -Pracodawca może sporządzić uniwersalną ocenę ryzyka zawodowego dla poszczególnych grup stanowisk pracy zdalnej. -§ 6. Przed dopuszczeniem do wykonywania pracy zdalnej pracownik potwierdza w oświadczeniu składanym w postaci papierowej lub elektronicznej zapoznanie się z przygotowaną przez pracodawcę oceną ryzyka zawodowego oraz informacją zawierającą zasady bezpiecznego i higienicznego wykonywania pracy zdalnej oraz zobowiązuje się do ich przestrzegania. - -§ 7. Dopuszczenie pracownika do wykonywania pracy zdalnej jest uzależnione od złożenia przez pracownika oświadczenia w postaci papierowej lub elektronicznej, zawierającego potwierdzenie, że na stanowisku pracy zdalnej w miejscu wskazanym przez pracownika i uzgodnionym z pracodawcą są zapewnione bezpieczne i higieniczne warunki tej pracy. - -§ 8. Pracownik organizuje stanowisko pracy zdalnej, uwzględniając wymagania ergonomii. - -§ 9. W razie wypadku przy pracy zdalnej art. 234 oraz przepisy wydane na podstawie art. 237 § 1 pkt 1 i 2 stosuje się odpowiednio. - -§ 10. Oględzin miejsca wypadku dokonuje się po zgłoszeniu wypadku przy pracy zdalnej, w terminie uzgodnionym przez pracownika albo jego domownika, w przypadku gdy pracownik ze względu na stan zdrowia nie jest w stanie uzgodnić tego terminu, i członków zespołu powypadkowego. Zespół powypadkowy może odstąpić od dokonywania oględzin miejsca wypadku przy pracy zdalnej, jeżeli uzna, że okoliczności i przyczyny wypadku nie budzą jego wątpliwości. - - -Art. 6732. W przypadku wykonywania pracy zdalnej wnioski pracownika, dla których przepisy kodeksu lub innych ustaw lub aktów wykonawczych, określających prawa i obowiązki z zakresu prawa pracy, wymagają formy pisemnej, mogą być złożone w postaci papierowej lub elektronicznej. - - -Art. 6733. § 1. Praca zdalna może być wykonywana okazjonalnie, na wniosek pracownika złożony w postaci papierowej lub elektronicznej, w wymiarze nieprzekraczającym 24 dni w roku kalendarzowym. - -§ 2. Do pracy zdalnej, o której mowa w § 1, nie stosuje się przepisów art. 6719-6724 oraz art. 6731 § 3. - -§ 3. Kontrola wykonywania pracy zdalnej, o której mowa w § 1, kontrola w zakresie bezpieczeństwa i higieny pracy lub kontrola przestrzegania wymogów w zakresie bezpieczeństwa i ochrony informacji, w tym procedur ochrony danych osobowych, odbywa się na zasadach ustalonych z pracownikiem. - - -Art. 6734. Przepisy niniejszego rozdziału stosuje się także do stosunków pracy nawiązanych na innej podstawie niż umowa o pracę. - -Rozdział III -Stosunek pracy na podstawie powołania, wyboru, mianowania oraz spółdzielczej umowy o pracę - -Oddział 1 -Stosunek pracy na podstawie powołania - -Art. 68. § 1. Stosunek pracy nawiązuje się na podstawie powołania w przypadkach określonych w odrębnych przepisach. - -§ 1. Stosunek pracy, o którym mowa w § 1, nawiązuje się na czas nie określony, a jeżeli na podstawie przepisów szczególnych pracownik został powołany na czas określony, stosunek pracy nawiązuje się na okres objęty powołaniem. - -§ 2. (skreślony). - -Art. 681. Powołanie może być poprzedzone konkursem, choćby przepisy szczególne nie przewidywały wymogu wyłonienia kandydata na stanowisko wyłącznie w wyniku konkursu. - -Art. 682. § 1. Stosunek pracy na podstawie powołania nawiązuje się w terminie określonym w powołaniu, a jeżeli termin ten nie został określony - w dniu doręczenia powołania, chyba że przepisy szczególne stanowią inaczej. - -§ 2. Powołanie powinno być dokonane na piśmie. - -Art. 683. Jeżeli pracownik powołany na stanowisko w wyniku konkursu pozostaje w stosunku pracy z innym pracodawcą i obowiązuje go trzymiesięczny okres wypowiedzenia, może on rozwiązać ten stosunek za jednomiesięcznym wypowiedzeniem. Rozwiązanie stosunku pracy w tym trybie pociąga za sobą skutki, jakie przepisy prawa pracy wiążą z rozwiązaniem umowy o pracę przez pracodawcę za wypowiedzeniem. - -Art. 69. Jeżeli przepisy niniejszego oddziału nie stanowią inaczej, do stosunku pracy na podstawie powołania stosuje się przepisy dotyczące umowy o pracę na czas nie określony, z wyłączeniem przepisów regulujących: - -1) tryb postępowania przy rozwiązywaniu umów o pracę, -2) rozpatrywanie sporów ze stosunku pracy w części dotyczącej orzekania: -a) o bezskuteczności wypowiedzeń, -b) (uchylona), -c) o przywracaniu do pracy. -Art. 70. § 1. Pracownik zatrudniony na podstawie powołania może być w każdym czasie - niezwłocznie lub w określonym terminie - odwołany ze stanowiska przez organ, który go powołał. Dotyczy to również pracownika, który na podstawie przepisów szczególnych został powołany na stanowisko na czas określony. - -§ 11. Odwołanie powinno być dokonane na piśmie. - -§ 12. Stosunek pracy z pracownikiem odwołanym ze stanowiska rozwiązuje się na zasadach określonych w przepisach niniejszego oddziału, chyba że przepisy szczególne stanowią inaczej. - -§ 2. Odwołanie jest równoznaczne z wypowiedzeniem umowy o pracę. W okresie wypowiedzenia pracownik ma prawo do wynagrodzenia w wysokości przysługującej przed odwołaniem. - -§ 3. Odwołanie jest równoznaczne z rozwiązaniem umowy o pracę bez wypowiedzenia, jeżeli nastąpiło z przyczyn, o których mowa w art. 52 lub 53. - -Art. 71. Na wniosek lub za zgodą pracownika pracodawca może zatrudnić go w okresie wypowiedzenia przy innej pracy, odpowiedniej ze względu na jego kwalifikacje zawodowe, a po upływie okresu wypowiedzenia zatrudnić na uzgodnionych przez strony warunkach pracy i płacy. - -Art. 72. § 1. Jeżeli odwołanie nastąpiło w okresie usprawiedliwionej nieobecności w pracy, bieg wypowiedzenia rozpoczyna się po upływie tego okresu. Jeżeli jednak usprawiedliwiona nieobecność trwa dłużej niż okres przewidziany w art. 53 § 1 i 2, organ, który pracownika powołał, może rozwiązać stosunek pracy bez wypowiedzenia. - -§ 2. W razie odwołania pracownicy w okresie ciąży, organ odwołujący jest obowiązany zapewnić jej inną pracę, odpowiednią ze względu na jej kwalifikacje zawodowe, przy czym przez okres równy okresowi wypowiedzenia pracownica ma prawo do wynagrodzenia w wysokości przysługującej przed odwołaniem. Jeżeli jednak pracownica nie wyrazi zgody na podjęcie innej pracy, stosunek pracy ulega rozwiązaniu z upływem okresu równego okresowi wypowiedzenia, którego bieg rozpoczyna się od dnia zaproponowania na piśmie innej pracy. - -§ 3. Przepis § 2 stosuje się odpowiednio w razie odwołania pracownika, któremu brakuje nie więcej niż 2 lata do nabycia prawa do emerytury z Funduszu Ubezpieczeń Społecznych. - -§ 4. W razie naruszenia przepisów § 1-3, pracownikowi przysługuje prawo odwołania do sądu pracy. - -Oddział 2 -Stosunek pracy na podstawie wyboru - -Art. 73. § 1. Nawiązanie stosunku pracy następuje na podstawie wyboru, jeżeli z wyboru wynika obowiązek wykonywania pracy w charakterze pracownika. - -§ 2. Stosunek pracy z wyboru rozwiązuje się z wygaśnięciem mandatu. - -Art. 74. Pracownik pozostający w związku z wyborem na urlopie bezpłatnym ma prawo powrotu do pracy u pracodawcy, który zatrudniał go w chwili wyboru, na stanowisko równorzędne pod względem wynagrodzenia z poprzednio zajmowanym, jeżeli zgłosi swój powrót w ciągu 7 dni od rozwiązania stosunku pracy z wyboru. Niedotrzymanie tego warunku powoduje wygaśnięcie stosunku pracy, chyba że nastąpiło z przyczyn niezależnych od pracownika. - -Art. 75. Pracownikowi, który nie pozostawał w związku z wyborem na urlopie bezpłatnym, przysługuje odprawa w wysokości jednomiesięcznego wynagrodzenia. - -Oddział 3 -Stosunek pracy na podstawie mianowania - -Art. 76. Stosunek pracy nawiązuje się na podstawie mianowania w przypadkach określonych w odrębnych przepisach. - -Oddział 4 -Stosunek pracy na podstawie spółdzielczej umowy o pracę - -Art. 77. § 1. Stosunek pracy między spółdzielnią pracy a jej członkiem nawiązuje się przez spółdzielczą umowę o pracę. - -§ 2. Stosunek pracy na podstawie spółdzielczej umowy o pracę reguluje ustawa - Prawo spółdzielcze, a w zakresie nie uregulowanym odmiennie tą ustawą stosuje się odpowiednio przepisy Kodeksu pracy. - -DZIAŁ TRZECI -Wynagrodzenie za pracę i inne świadczenia - -Rozdział I -Ustalanie wynagrodzenia za pracę i innych świadczeń związanych z pracą - -Art. 771. Warunki wynagradzania za pracę i przyznawania innych świadczeń związanych z pracą ustalają układy zbiorowe pracy, zgodnie z przepisami działu jedenastego, z zastrzeżeniem przepisów art. 772-775. - -Art. 772. § 1. Pracodawca zatrudniający co najmniej 50 pracowników, nieobjętych zakładowym układem zbiorowym pracy ani ponadzakładowym układem zbiorowym pracy odpowiadającym wymaganiom określonym w § 3, ustala warunki wynagradzania za pracę w regulaminie wynagradzania. - -§ 11. Pracodawca zatrudniający mniej niż 50 pracowników, nieobjętych zakładowym układem zbiorowym pracy ani ponadzakładowym układem zbiorowym pracy odpowiadającym wymaganiom określonym w § 3, może ustalić warunki wynagradzania za pracę w regulaminie wynagradzania. - -§ 12. Pracodawca zatrudniający co najmniej 20 i mniej niż 50 pracowników, nieobjętych zakładowym układem zbiorowym pracy ani ponadzakładowym układem zbiorowym pracy odpowiadającym wymaganiom określonym w § 3, ustala warunki wynagradzania za pracę w regulaminie wynagradzania, jeżeli zakładowa organizacja związkowa wystąpi z wnioskiem o jego ustalenie. - -§ 2. W regulaminie wynagradzania pracodawca może ustalić także inne świadczenia związane z pracą i zasady ich przyznawania. - -§ 3. Regulamin wynagradzania obowiązuje do czasu objęcia pracowników zakładowym układem zbiorowym pracy lub ponadzakładowym układem zbiorowym pracy ustalającym warunki wynagradzania za pracę oraz przyznawania innych świadczeń związanych z pracą w zakresie i w sposób umożliwiający określanie, na jego podstawie, indywidualnych warunków umów o pracę. - -§ 4. Regulamin wynagradzania ustala pracodawca. Jeżeli u danego pracodawcy działa zakładowa organizacja związkowa, pracodawca uzgadnia z nią regulamin wynagradzania. - -§ 5. Do regulaminu wynagradzania stosuje się odpowiednio przepisy art. 239 § 3, art. 24112 § 2, art. 24113 oraz art. 24126 § 2. - -§ 6. Regulamin wynagradzania wchodzi w życie po upływie dwóch tygodni od dnia podania go do wiadomości pracowników, w sposób przyjęty u danego pracodawcy. - -Art. 773. § 1. Warunki wynagradzania za pracę i przyznawania innych świadczeń związanych z pracą dla pracowników zatrudnionych w państwowych jednostkach sfery budżetowej, jeżeli nie są oni objęci układem zbiorowym pracy, określi, w drodze rozporządzenia - w zakresie niezastrzeżonym w innych ustawach do właściwości innych organów - minister właściwy do spraw pracy na wniosek właściwego ministra. - -§ 2. Z dniem wejścia w życie układu zbiorowego pracy do pracowników państwowych jednostek sfery budżetowej objętych tym układem nie mają zastosowania przepisy rozporządzenia, o którym mowa w § 1. - -§ 3. Rozporządzenie, o którym mowa w § 1, powinno w szczególności określać warunki ustalania i wypłacania: - -1) wynagrodzenia zasadniczego pracowników, -2) innych, poza wynagrodzeniem zasadniczym, składników uzasadnionych zwłaszcza szczególnymi właściwościami lub warunkami wykonywanej pracy, kwalifikacjami zawodowymi pracowników, z tym że wysokość składnika wynagrodzenia, którego przyznanie uwarunkowane będzie długością przepracowanego okresu, o ile taki składnik zostanie określony, nie może przekroczyć 20% wynagrodzenia zasadniczego, -3) innych świadczeń związanych z pracą, w tym takich, które mogą być uzależnione od okresów przepracowanych przez pracownika; w szczególności może to dotyczyć nagrody jubileuszowej i jednorazowej odprawy pieniężnej przysługującej pracownikowi, którego stosunek pracy ustał w związku z przejściem na rentę z tytułu niezdolności do pracy lub emeryturę. -Art. 774. (skreślony). - - -Art. 775. - -§ 1. Pracownikowi wykonującemu na polecenie pracodawcy zadanie służbowe poza miejscowością, w której znajduje się siedziba pracodawcy, lub poza stałym miejscem pracy przysługują należności na pokrycie kosztów związanych z podróżą służbową. - -§ 2. Minister właściwy do spraw pracy określi, w drodze rozporządzenia, wysokość oraz warunki ustalania należności przysługujących pracownikowi, zatrudnionemu w państwowej lub samorządowej jednostce sfery budżetowej, z tytułu podróży służbowej na obszarze kraju oraz poza granicami kraju. Rozporządzenie powinno w szczególności określać wysokość diet, z uwzględnieniem czasu trwania podróży, a w przypadku podróży poza granicami kraju - walutę, w jakiej będzie ustalana dieta i limit na nocleg w poszczególnych państwach, a także warunki zwrotu kosztów przejazdów, noclegów i innych wydatków. - -§ 3. Warunki wypłacania należności z tytułu podróży służbowej pracownikowi zatrudnionemu u innego pracodawcy niż wymieniony w § 2 określa się w układzie zbiorowym pracy lub w regulaminie wynagradzania albo w umowie o pracę, jeżeli pracodawca nie jest objęty układem zbiorowym pracy lub nie jest obowiązany do ustalenia regulaminu wynagradzania. - -§ 4. Postanowienia układu zbiorowego pracy, regulaminu wynagradzania lub umowy o pracę nie mogą ustalać diety za dobę podróży służbowej na obszarze kraju oraz poza granicami kraju w wysokości niższej niż dieta z tytułu podróży służbowej na obszarze kraju określona dla pracownika, o którym mowa w § 2. - -§ 5. W przypadku gdy układ zbiorowy pracy, regulamin wynagradzania lub umowa o pracę nie zawiera postanowień, o których mowa w § 3, pracownikowi przysługują należności na pokrycie kosztów podróży służbowej odpowiednio według przepisów, o których mowa w § 2. - -Rozdział Ia -Wynagrodzenie za pracę - -Art. 78. § 1. Wynagrodzenie za pracę powinno być tak ustalone, aby odpowiadało w szczególności rodzajowi wykonywanej pracy i kwalifikacjom wymaganym przy jej wykonywaniu, a także uwzględniało ilość i jakość świadczonej pracy. - -§ 2. W celu określenia wynagrodzenia za pracę ustala się, w trybie przewidzianym w art. 771-773, wysokość oraz zasady przyznawania pracownikom stawek wynagrodzenia za pracę określonego rodzaju lub na określonym stanowisku, a także innych (dodatkowych) składników wynagrodzenia, jeżeli zostały one przewidziane z tytułu wykonywania określonej pracy. - -Art. 79. (skreślony). - -Art. 80. Wynagrodzenie przysługuje za pracę wykonaną. Za czas niewykonywania pracy pracownik zachowuje prawo do wynagrodzenia tylko wówczas, gdy przepisy prawa pracy tak stanowią. - -Art. 81. § 1. Pracownikowi za czas niewykonywania pracy, jeżeli był gotów do jej wykonywania, a doznał przeszkód z przyczyn dotyczących pracodawcy, przysługuje wynagrodzenie wynikające z jego osobistego zaszeregowania określonego stawką godzinową lub miesięczną, a jeżeli taki składnik wynagrodzenia nie został wyodrębniony przy określaniu warunków wynagradzania - 60% wynagrodzenia. W każdym przypadku wynagrodzenie to nie może być jednak niższe od wysokości minimalnego wynagrodzenia za pracę, ustalanego na podstawie odrębnych przepisów. - -§ 2. Wynagrodzenie, o którym mowa w § 1, przysługuje pracownikowi za czas niezawinionego przez niego przestoju. Jeżeli przestój nastąpił z winy pracownika, wynagrodzenie nie przysługuje. - -§ 3. Pracodawca może na czas przestoju powierzyć pracownikowi inną odpowiednią pracę, za której wykonanie przysługuje wynagrodzenie przewidziane za tę pracę, nie niższe jednak od wynagrodzenia ustalonego zgodnie z § 1. Jeżeli przestój nastąpił z winy pracownika, przysługuje wyłącznie wynagrodzenie przewidziane za wykonaną pracę. - -§ 4. Wynagrodzenie za czas przestoju spowodowanego warunkami atmosferycznymi przysługuje pracownikowi zatrudnionemu przy pracach uzależnionych od tych warunków, jeżeli przepisy prawa pracy tak stanowią. W razie powierzenia pracownikowi na czas takiego przestoju innej pracy, przysługuje mu wynagrodzenie przewidziane za wykonaną pracę, chyba że przepisy prawa pracy przewidują stosowanie zasad określonych w § 3. - -Art. 82. § 1. Za wadliwe wykonanie z winy pracownika produktów lub usług wynagrodzenie nie przysługuje. Jeżeli wskutek wadliwie wykonanej pracy z winy pracownika nastąpiło obniżenie jakości produktu lub usługi, wynagrodzenie ulega odpowiedniemu zmniejszeniu. - -§ 2. Jeżeli wadliwość produktu lub usługi została usunięta przez pracownika, przysługuje mu wynagrodzenie odpowiednie do jakości produktu lub usługi, z tym że za czas pracy przy usuwaniu wady wynagrodzenie nie przysługuje. - -Art. 83. § 1. Normy pracy, stanowiące miernik nakładu pracy, jej wydajności i jakości, mogą być stosowane, jeżeli jest to uzasadnione rodzajem pracy. - -§ 2. Normy pracy są ustalane z uwzględnieniem osiągniętego poziomu techniki i organizacji pracy. Normy pracy mogą być zmieniane w miarę wdrażania technicznych i organizacyjnych usprawnień zapewniających wzrost wydajności pracy. - -§ 3. Przekraczanie norm pracy nie stanowi podstawy do ich zmiany, jeżeli jest ono wynikiem zwiększonego osobistego wkładu pracy pracownika lub jego sprawności zawodowej. - -§ 4. O zmianie normy pracy pracownicy powinni być zawiadomieni co najmniej na 2 tygodnie przed wprowadzeniem nowej normy. - -Rozdział II -Ochrona wynagrodzenia za pracę - -Art. 84. Pracownik nie może zrzec się prawa do wynagrodzenia ani przenieść tego prawa na inną osobę. - -Art. 85. § 1. Wypłaty wynagrodzenia za pracę dokonuje się co najmniej raz w miesiącu, w stałym i ustalonym z góry terminie. - -§ 2. Wynagrodzenie za pracę płatne raz w miesiącu wypłaca się z dołu, niezwłocznie po ustaleniu jego pełnej wysokości, nie później jednak niż w ciągu pierwszych 10 dni następnego miesiąca kalendarzowego. - -§ 3. Jeżeli ustalony dzień wypłaty wynagrodzenia za pracę jest dniem wolnym od pracy, wynagrodzenie wypłaca się w dniu poprzedzającym. - -§ 4. Składniki wynagrodzenia za pracę, przysługujące pracownikowi za okresy dłuższe niż jeden miesiąc, wypłaca się z dołu w terminach określonych w przepisach prawa pracy. - -§ 5. Pracodawca, na żądanie pracownika, jest obowiązany udostępnić do wglądu dokumenty, na których podstawie zostało obliczone jego wynagrodzenie. - -Art. 86. § 1. Pracodawca jest obowiązany wypłacać wynagrodzenie w miejscu, terminie i czasie określonych w regulaminie pracy lub w innych przepisach prawa pracy. - -§ 2. Wypłaty wynagrodzenia dokonuje się w formie pieniężnej; częściowe spełnienie wynagrodzenia w innej formie niż pieniężna jest dopuszczalne tylko wówczas, gdy przewidują to ustawowe przepisy prawa pracy lub układ zbiorowy pracy. - -§ 3. Wypłata wynagrodzenia jest dokonywana na wskazany przez pracownika rachunek płatniczy, chyba że pracownik złożył w postaci papierowej lub elektronicznej wniosek o wypłatę wynagrodzenia do rąk własnych. - -Art. 87. § 1. Z wynagrodzenia za pracę - po odliczeniu składek na ubezpieczenia społeczne, zaliczki na podatek dochodowy od osób fizycznych oraz wpłat dokonywanych do pracowniczego planu kapitałowego, w rozumieniu ustawy z dnia 4 października 2018 r. o pracowniczych planach kapitałowych, jeżeli pracownik nie zrezygnował z ich dokonywania - podlegają potrąceniu tylko następujące należności: - -1) sumy egzekwowane na mocy tytułów wykonawczych na zaspokojenie świadczeń alimentacyjnych, -2) sumy egzekwowane na mocy tytułów wykonawczych na pokrycie należności innych niż świadczenia alimentacyjne, -3) zaliczki pieniężne udzielone pracownikowi, -4) kary pieniężne przewidziane w art. 108. -§ 2. Potrąceń dokonuje się w kolejności podanej w § 1. - -§ 3. Potrącenia mogą być dokonywane w następujących granicach: - -1) w razie egzekucji świadczeń alimentacyjnych - do wysokości trzech piątych wynagrodzenia, -2) w razie egzekucji innych należności lub potrącania zaliczek pieniężnych - do wysokości połowy wynagrodzenia. -§ 4. Potrącenia, o których mowa w § 1 pkt 2 i 3, nie mogą w sumie przekraczać połowy wynagrodzenia, a łącznie z potrąceniami, o których mowa w § 1 pkt 1 - trzech piątych wynagrodzenia. Niezależnie od tych potrąceń kary pieniężne potrąca się w granicach określonych w art. 108. - -§ 5. Nagroda z zakładowego funduszu nagród, dodatkowe wynagrodzenie roczne oraz należności przysługujące pracownikom z tytułu udziału w zysku lub w nadwyżce bilansowej podlegają egzekucji na zaspokojenie świadczeń alimentacyjnych do pełnej wysokości. - -§ 6. (uchylony). - -§ 7. Z wynagrodzenia za pracę odlicza się, w pełnej wysokości, kwoty wypłacone w poprzednim terminie płatności za okres nieobecności w pracy, za który pracownik nie zachowuje prawa do wynagrodzenia. - -§ 8. Potrąceń należności z wynagrodzenia pracownika w miesiącu, w którym są wypłacane składniki wynagrodzenia za okresy dłuższe niż 1 miesiąc, dokonuje się od łącznej kwoty wynagrodzenia uwzględniającej te składniki wynagrodzenia. - - -Art. 871. § 1. Wolna od potrąceń jest kwota wynagrodzenia za pracę w wysokości: - -1) minimalnego wynagrodzenia za pracę, ustalanego na podstawie odrębnych przepisów, przysługującego pracownikom zatrudnionym w pełnym wymiarze czasu pracy, po odliczeniu składek na ubezpieczenia społeczne, zaliczki na podatek dochodowy od osób fizycznych oraz wpłat dokonywanych do pracowniczego planu kapitałowego, jeżeli pracownik nie zrezygnował z ich dokonywania - przy potrącaniu sum egzekwowanych na mocy tytułów wykonawczych na pokrycie należności innych niż świadczenia alimentacyjne; -2) 75% wynagrodzenia określonego w pkt 1 - przy potrącaniu zaliczek pieniężnych udzielonych pracownikowi, -3) 90% wynagrodzenia określonego w pkt 1 - przy potrącaniu kar pieniężnych przewidzianych w art. 108. -§ 2. Jeżeli pracownik jest zatrudniony w niepełnym wymiarze czasu pracy, kwoty określone w § 1 ulegają zmniejszeniu proporcjonalnie do wymiaru czasu pracy. - -Art. 88. § 1. Przy zachowaniu zasad określonych w art. 87 potrąceń na zaspokojenie świadczeń alimentacyjnych pracodawca dokonuje również bez postępowania egzekucyjnego, z wyjątkiem przypadków gdy: - -1) świadczenia alimentacyjne mają być potrącane na rzecz kilku wierzycieli, a łączna suma, która może być potrącona, nie wystarcza na pełne pokrycie wszystkich należności alimentacyjnych, -2) wynagrodzenie za pracę zostało zajęte w trybie egzekucji sądowej lub administracyjnej. -§ 2. Potrąceń, o których mowa w § 1, pracodawca dokonuje na wniosek wierzyciela na podstawie przedłożonego przez niego tytułu wykonawczego. - -Art. 89. (skreślony). - -Art. 90. W sprawach nie unormowanych w art. 87 i 88 stosuje się odpowiednio przepisy Kodeksu postępowania cywilnego i przepisy o egzekucji administracyjnej świadczeń pieniężnych. - -Art. 91. § 1. Należności inne niż wymienione w art. 87 § 1 i 7 mogą być potrącane z wynagrodzenia pracownika tylko za jego zgodą wyrażoną na piśmie. - -§ 2. W przypadkach określonych w § 1 wolna od potrąceń jest kwota wynagrodzenia za pracę w wysokości: - -1) określonej w art. 871 § 1 pkt 1 - przy potrącaniu należności na rzecz pracodawcy, -2) 80% kwoty określonej w art. 871 § 1 pkt 1 - przy potrącaniu innych należności niż określone w pkt 1. -Rozdział III -Świadczenia przysługujące w okresie czasowej niezdolności do pracy - -Art. 92. § 1. Za czas niezdolności pracownika do pracy wskutek: - -1) choroby lub odosobnienia w związku z chorobą zakaźną - trwającej łącznie do 33 dni w ciągu roku kalendarzowego, a w przypadku pracownika, który ukończył 50 rok życia - trwającej łącznie do 14 dni w ciągu roku kalendarzowego - pracownik zachowuje prawo do 80% wynagrodzenia, chyba że obowiązujące u danego pracodawcy przepisy prawa pracy przewidują wyższe wynagrodzenie z tego tytułu, -2) wypadku w drodze do pracy lub z pracy albo choroby przypadającej w czasie ciąży - w okresie wskazanym w pkt 1 - pracownik zachowuje prawo do 100% wynagrodzenia, -3) poddania się niezbędnym badaniom lekarskim przewidzianym dla kandydatów na dawców komórek, tkanek i narządów oraz poddania się zabiegowi pobrania komórek, tkanek i narządów - w okresie wskazanym w pkt 1 - pracownik zachowuje prawo do 100% wynagrodzenia. -§ 11. (uchylony). - -§ 2. Wynagrodzenie, o którym mowa w § 1, oblicza się według zasad obowiązujących przy ustalaniu podstawy wymiaru zasiłku chorobowego i wypłaca za każdy dzień niezdolności do pracy, nie wyłączając dni wolnych od pracy. - -§ 3. Wynagrodzenie, o którym mowa w § 1: - -1) nie ulega obniżeniu w przypadku ograniczenia podstawy wymiaru zasiłku chorobowego, -2) nie przysługuje w przypadkach, w których pracownik nie ma prawa do zasiłku chorobowego. -§ 4. Za czas niezdolności do pracy, o której mowa w § 1, trwającej łącznie dłużej niż 33 dni w ciągu roku kalendarzowego, a w przypadku pracownika, który ukończył 50 rok życia, trwającej łącznie dłużej niż 14 dni w ciągu roku kalendarzowego, pracownikowi przysługuje zasiłek chorobowy na zasadach określonych w odrębnych przepisach. - -§ 5. Przepisy § 1 pkt 1 i § 4 w części dotyczącej pracownika, który ukończył 50 rok życia, dotyczą niezdolności pracownika do pracy przypadającej po roku kalendarzowym, w którym pracownik ukończył 50 rok życia. - -Rozdział IIIa -Odprawa rentowa lub emerytalna - -Art. 921. § 1. Pracownikowi spełniającemu warunki uprawniające do renty z tytułu niezdolności do pracy lub emerytury, którego stosunek pracy ustał w związku z przejściem na rentę lub emeryturę, przysługuje odprawa pieniężna w wysokości jednomiesięcznego wynagrodzenia. - -§ 2. Pracownik, który otrzymał odprawę, nie może ponownie nabyć do niej prawa. - -Rozdział IV -Odprawa pośmiertna - -Art. 93. § 1. W razie śmierci pracownika w czasie trwania stosunku pracy lub w czasie pobierania po jego rozwiązaniu zasiłku z tytułu niezdolności do pracy wskutek choroby, rodzinie przysługuje od pracodawcy odprawa pośmiertna. - -§ 2. Wysokość odprawy, o której mowa w § 1, jest uzależniona od okresu zatrudnienia pracownika u danego pracodawcy i wynosi: - -1) jednomiesięczne wynagrodzenie, jeżeli pracownik był zatrudniony krócej niż 10 lat, -2) trzymiesięczne wynagrodzenie, jeżeli pracownik był zatrudniony co najmniej 10 lat, -3) sześciomiesięczne wynagrodzenie, jeżeli pracownik był zatrudniony co najmniej 15 lat. -§ 3. Przepis art. 36 § 11 stosuje się odpowiednio. - -§ 4. Odprawa pośmiertna przysługuje następującym członkom rodziny pracownika: - -1) małżonkowi, -2) innym członkom rodziny spełniającym warunki wymagane do uzyskania renty rodzinnej w myśl przepisów o emeryturach i rentach z Funduszu Ubezpieczeń Społecznych. -§ 5. Odprawę pośmiertną dzieli się w częściach równych pomiędzy wszystkich uprawnionych członków rodziny. - -§ 6. Jeżeli po zmarłym pracowniku pozostał tylko jeden członek rodziny uprawniony do odprawy pośmiertnej, przysługuje mu odprawa w wysokości połowy odpowiedniej kwoty określonej w § 2. - -§ 7. Odprawa pośmiertna nie przysługuje członkom rodziny, o których mowa w § 4, jeżeli pracodawca ubezpieczył pracownika na życie, a odszkodowanie wypłacone przez instytucję ubezpieczeniową jest nie niższe niż odprawa pośmiertna przysługująca zgodnie z § 2 i 6. Jeżeli odszkodowanie jest niższe od odprawy pośmiertnej, pracodawca jest obowiązany wypłacić rodzinie kwotę stanowiącą różnicę między tymi świadczeniami. - -DZIAŁ CZWARTY -Obowiązki pracodawcy i pracownika - -Rozdział I -Obowiązki pracodawcy - -Art. 94. Pracodawca jest obowiązany w szczególności: - -1) zaznajamiać pracowników podejmujących pracę z zakresem ich obowiązków, sposobem wykonywania pracy na wyznaczonych stanowiskach oraz ich podstawowymi uprawnieniami, -1a) informować pracowników o warunkach ich zatrudnienia, o których mowa w art. 29 § 3, 32 i 33 lub w art. 291 § 2 i 4; -2) organizować pracę w sposób zapewniający pełne wykorzystanie czasu pracy, jak również osiąganie przez pracowników, przy wykorzystaniu ich uzdolnień i kwalifikacji, wysokiej wydajności i należytej jakości pracy, -2a) organizować pracę w sposób zapewniający zmniejszenie uciążliwości pracy, zwłaszcza pracy monotonnej i pracy w ustalonym z góry tempie, -2b) przeciwdziałać dyskryminacji w zatrudnieniu, w szczególności ze względu na płeć, wiek, niepełnosprawność, rasę, religię, narodowość, przekonania polityczne, przynależność związkową, pochodzenie etniczne, wyznanie, orientację seksualną, a także ze względu na zatrudnienie na czas określony lub nieokreślony albo w pełnym lub w niepełnym wymiarze czasu pracy, -3) (skreślony), -4) zapewniać bezpieczne i higieniczne warunki pracy oraz prowadzić systematyczne szkolenie pracowników w zakresie bezpieczeństwa i higieny pracy, -5) terminowo i prawidłowo wypłacać wynagrodzenie, -6) ułatwiać pracownikom podnoszenie kwalifikacji zawodowych, -7) stwarzać pracownikom podejmującym zatrudnienie po ukończeniu szkoły prowadzącej kształcenie zawodowe lub szkoły wyższej warunki sprzyjające przystosowaniu się do należytego wykonywania pracy, -8) zaspokajać w miarę posiadanych środków socjalne potrzeby pracowników, -9) stosować obiektywne i sprawiedliwe kryteria oceny pracowników oraz wyników ich pracy, -9a) prowadzić i przechowywać w postaci papierowej lub elektronicznej dokumentację w sprawach związanych ze stosunkiem pracy oraz akta osobowe pracowników (dokumentacja pracownicza); -9b) przechowywać dokumentację pracowniczą w sposób gwarantujący zachowanie jej poufności, integralności, kompletności oraz dostępności, w warunkach niegrożących uszkodzeniem lub zniszczeniem przez okres zatrudnienia, a także przez okres 10 lat, licząc od końca roku kalendarzowego, w którym stosunek pracy uległ rozwiązaniu lub wygasł, chyba że odrębne przepisy przewidują dłuższy okres przechowywania dokumentacji pracowniczej; -10) wpływać na kształtowanie w zakładzie pracy zasad współżycia społecznego. - -Art. 941. Pracodawca udostępnia pracownikom tekst przepisów dotyczących równego traktowania w zatrudnieniu w formie pisemnej informacji rozpowszechnionej na terenie zakładu pracy lub zapewnia pracownikom dostęp do tych przepisów w inny sposób przyjęty u danego pracodawcy. - - -Art. 942. Pracodawca jest obowiązany informować pracowników w sposób przyjęty u danego pracodawcy o: - -1) możliwości zatrudnienia w pełnym lub w niepełnym wymiarze czasu pracy; -2) możliwości awansu; -3) wolnych stanowiskach pracy. - -Art. 943. § 1. Pracodawca jest obowiązany przeciwdziałać mobbingowi. - -§ 2. Mobbing oznacza działania lub zachowania dotyczące pracownika lub skierowane przeciwko pracownikowi, polegające na uporczywym i długotrwałym nękaniu lub zastraszaniu pracownika, wywołujące u niego zaniżoną ocenę przydatności zawodowej, powodujące lub mające na celu poniżenie lub ośmieszenie pracownika, izolowanie go lub wyeliminowanie z zespołu współpracowników. - -§ 3. Pracownik, u którego mobbing wywołał rozstrój zdrowia, może dochodzić od pracodawcy odpowiedniej sumy tytułem zadośćuczynienia pieniężnego za doznaną krzywdę. - -§ 4. Pracownik, który doznał mobbingu lub wskutek mobbingu rozwiązał umowę o pracę, ma prawo dochodzić od pracodawcy odszkodowania w wysokości nie niższej niż minimalne wynagrodzenie za pracę, ustalane na podstawie odrębnych przepisów. - -§ 5. Oświadczenie pracownika o rozwiązaniu umowy o pracę powinno nastąpić na piśmie z podaniem przyczyny, o której mowa w § 2, uzasadniającej rozwiązanie umowy. - - -Art. 944. Jeżeli przechowywana dokumentacja pracownicza może stanowić lub stanowi dowód w postępowaniu, a pracodawca: - -1) jest stroną tego postępowania - przechowuje dokumentację pracowniczą do czasu jego prawomocnego zakończenia, nie krócej jednak niż do upływu okresu, o którym mowa w art. 94 pkt 9b; art. 947 stosuje się odpowiednio; -2) powziął wiadomość o wytoczeniu powództwa lub wszczęciu postępowania - okres przechowywania dokumentacji pracowniczej, o którym mowa w art. 94 pkt 9b, przedłuża się o 12 miesięcy, po upływie których pracodawca zawiadamia, w postaci papierowej lub elektronicznej, byłego pracownika o możliwości odbioru tej dokumentacji w terminie 30 dni od dnia otrzymania zawiadomienia oraz, w przypadku jej nieodebrania, o zniszczeniu dokumentacji pracowniczej; art. 947 stosuje się odpowiednio. - -Art. 945. § 1. W przypadku ponownego nawiązania stosunku pracy z tym samym pracownikiem w okresie, o którym mowa w art. 94 pkt 9b, pracodawca kontynuuje prowadzenie dla tego pracownika dotychczasowej dokumentacji pracowniczej. - -§ 2. W przypadku, o którym mowa w § 1, okres przechowywania dokumentacji pracowniczej liczy się od końca roku kalendarzowego, w którym kończący się najpóźniej stosunek pracy rozwiązał się lub wygasł. - - -Art. 946. W przypadku rozwiązania lub wygaśnięcia stosunku pracy pracodawca wraz ze świadectwem pracy wydaje pracownikowi w postaci papierowej lub elektronicznej informację o: - -1) okresie przechowywania dokumentacji pracowniczej, o którym mowa w art. 94 pkt 9b lub w art. 945 § 2; -2) możliwości odbioru przez pracownika dokumentacji pracowniczej do końca miesiąca kalendarzowego następującego po upływie okresu przechowywania dokumentacji pracowniczej, o którym mowa w art. 94 pkt 9b lub w art. 945 § 2; -3) zniszczeniu dokumentacji pracowniczej w przypadku jej nieodebrania w okresie, o którym mowa w pkt 2. - -Art. 947. § 1. Pracodawca niszczy dokumentację pracowniczą w sposób uniemożliwiający odtworzenie jej treści, w terminie do 12 miesięcy po upływie okresu przeznaczonego na odbiór dokumentacji pracowniczej, o którym mowa w art. 946 pkt 2. - -§ 2. W terminie, o którym mowa w § 1, do czasu zniszczenia, pracodawca może wydać dokumentację pracowniczą byłemu pracownikowi. - - -Art. 948. § 1. Pracodawca może zmieniać postać, w której prowadzi i przechowuje dokumentację pracowniczą. - -§ 2. Zmiana postaci dokumentacji pracowniczej z papierowej na elektroniczną następuje przez sporządzenie odwzorowania cyfrowego, w szczególności skanu, i opatrzenie go kwalifikowanym podpisem elektronicznym lub kwalifikowaną pieczęcią elektroniczną pracodawcy lub kwalifikowanym podpisem elektronicznym upoważnionej przez pracodawcę osoby, potwierdzającym zgodność odwzorowania cyfrowego z dokumentem papierowym. - -§ 3. Zmiana postaci dokumentacji pracowniczej z elektronicznej na papierową następuje przez sporządzenie wydruku i opatrzenie go podpisem pracodawcy lub osoby przez niego upoważnionej, potwierdzającym zgodność wydruku z dokumentem elektronicznym. - - -Art. 949. § 1. Pracodawca informuje pracowników w sposób przyjęty u danego pracodawcy o: - -1) zmianie postaci prowadzenia i przechowywania dokumentacji pracowniczej; -2) możliwości odbioru poprzedniej postaci dokumentacji pracowniczej w terminie 30 dni od dnia przekazania informacji, o której mowa w pkt 1. -§ 2. Pracodawca zawiadamia w postaci papierowej lub elektronicznej byłego pracownika o możliwości odbioru poprzedniej postaci dokumentacji pracowniczej w terminie 30 dni od dnia zawiadomienia. - -§ 3. W przypadku śmierci pracownika lub byłego pracownika prawo odbioru poprzedniej postaci dokumentacji pracowniczej przysługuje następującym członkom rodziny: - -1) dzieciom własnym, dzieciom drugiego małżonka oraz dzieciom przysposobionym; -2) przyjętym na wychowanie i utrzymanie przed osiągnięciem pełnoletności wnukom, rodzeństwu i innym dzieciom, z wyłączeniem dzieci przyjętych na wychowanie i utrzymanie w ramach rodziny zastępczej lub rodzinnego domu dziecka; -3) małżonkowi (wdowie i wdowcowi); -4) rodzicom, w tym ojczymowi i macosze oraz osobom przysposabiającym. - -Art. 9410. W przypadku nieodebrania poprzedniej postaci dokumentacji pracowniczej zgodnie z art. 949, pracodawca może zniszczyć poprzednią postać takiej dokumentacji. - - -Art. 9411. Dokumentacja pracownicza prowadzona i przechowywana w postaci elektronicznej jest równoważna z dokumentacją pracowniczą prowadzoną i przechowywaną w postaci papierowej. - - -Art. 9412. Pracodawca wydaje kopię całości lub części dokumentacji pracowniczej na wniosek: - -1) pracownika lub byłego pracownika albo -2) osób, o których mowa w art. 949 § 3, w przypadku śmierci pracownika lub byłego pracownika -- złożony w postaci papierowej lub elektronicznej. - -Art. 9413. Jeżeli obowiązek pracodawcy przeprowadzenia szkoleń pracowników niezbędnych do wykonywania określonego rodzaju pracy lub pracy na określonym stanowisku wynika z postanowień układu zbiorowego pracy lub innego porozumienia zbiorowego, lub z regulaminu, lub przepisów prawa, lub umowy o pracę oraz w przypadku szkoleń odbywanych przez pracownika na podstawie polecenia przełożonego, szkolenia takie odbywają się na koszt pracodawcy oraz, w miarę możliwości, w godzinach pracy pracownika. Czas szkolenia odbywanego poza normalnymi godzinami pracy pracownika wlicza się do czasu pracy. - -Art. 95. (skreślony). - -Art. 96. (skreślony). - -Art. 97. § 1. W związku z rozwiązaniem lub wygaśnięciem stosunku pracy pracodawca jest obowiązany wydać pracownikowi świadectwo pracy w dniu, w którym następuje ustanie stosunku pracy, jeżeli nie zamierza nawiązać z nim kolejnego stosunku pracy w ciągu 7 dni od dnia rozwiązania lub wygaśnięcia poprzedniego stosunku pracy. Jeżeli z przyczyn obiektywnych wydanie świadectwa pracy pracownikowi albo osobie przez niego upoważnionej w tym terminie nie jest możliwe, pracodawca w ciągu 7 dni od dnia upływu tego terminu przesyła świadectwo pracy pracownikowi lub tej osobie za pośrednictwem operatora pocztowego w rozumieniu ustawy z dnia 23 listopada 2012 r. - Prawo pocztowe (Dz. U. z 2018 r. poz. 2188) albo doręcza je w inny sposób. Świadectwo pracy dotyczy okresu lub okresów zatrudnienia, za które dotychczas nie wydano świadectwa pracy. - -§ 11. W przypadku nawiązania z tym samym pracownikiem kolejnego stosunku pracy w ciągu 7 dni od dnia rozwiązania lub wygaśnięcia poprzedniego stosunku pracy, pracodawca jest obowiązany wydać pracownikowi świadectwo pracy wyłącznie na jego wniosek, złożony w postaci papierowej lub elektronicznej; wniosek może być złożony w każdym czasie i dotyczyć wydania świadectwa pracy dotyczącego poprzedniego okresu zatrudnienia albo wszystkich okresów zatrudnienia, za które dotychczas nie wydano świadectwa pracy. - -§ 12. W przypadku, o którym mowa w § 11, pracodawca jest obowiązany wydać pracownikowi świadectwo pracy w ciągu 7 dni od dnia złożenia wniosku. - -§ 13. Wydanie świadectwa pracy nie może być uzależnione od uprzedniego rozliczenia się pracownika z pracodawcą. - -§ 2. W świadectwie pracy należy podać informacje dotyczące okresu i rodzaju wykonywanej pracy, zajmowanych stanowisk, trybu rozwiązania albo okoliczności wygaśnięcia stosunku pracy, a także inne informacje niezbędne do ustalenia uprawnień pracowniczych i uprawnień z ubezpieczenia społecznego. Ponadto w świadectwie pracy zamieszcza się wzmiankę o zajęciu wynagrodzenia za pracę w myśl przepisów o postępowaniu egzekucyjnym. Na żądanie pracownika w świadectwie pracy należy podać także informację o wysokości i składnikach wynagrodzenia oraz o uzyskanych kwalifikacjach. - -§ 21. Pracownik może w ciągu 14 dni od otrzymania świadectwa pracy wystąpić z wnioskiem do pracodawcy o sprostowanie świadectwa pracy. W razie nieuwzględnienia wniosku pracownikowi przysługuje, w ciągu 14 dni od zawiadomienia o odmowie sprostowania świadectwa pracy, prawo wystąpienia z żądaniem jego sprostowania do sądu pracy. W przypadku niezawiadomienia przez pracodawcę o odmowie sprostowania świadectwa pracy, żądanie sprostowania świadectwa pracy wnosi się do sądu pracy. - -§ 3. Jeżeli z orzeczenia sądu pracy wynika, że rozwiązanie z pracownikiem umowy o pracę bez wypowiedzenia z jego winy nastąpiło z naruszeniem przepisów o rozwiązywaniu w tym trybie umów o pracę, pracodawca jest obowiązany zamieścić w świadectwie pracy informację, że rozwiązanie umowy o pracę nastąpiło za wypowiedzeniem dokonanym przez pracodawcę. - -§ 4. Minister właściwy do spraw pracy określi, w drodze rozporządzenia, szczegółową treść świadectwa pracy, sposób i tryb jego wydawania, prostowania i uzupełniania oraz pomocniczy wzór świadectwa pracy, biorąc pod uwagę konieczność zapewnienia właściwej realizacji celów, jakim służą informacje zawarte w świadectwie pracy. - - -Art. 971. § 1. W przypadku niewydania przez pracodawcę świadectwa pracy pracownikowi przysługuje prawo wystąpienia do sądu pracy z żądaniem zobowiązania pracodawcy do wydania świadectwa pracy. - -§ 2. Jeżeli pracodawca nie istnieje albo z innych przyczyn wytoczenie przeciwko niemu powództwa o zobowiązanie pracodawcy do wydania świadectwa pracy jest niemożliwe, pracownikowi przysługuje prawo wystąpienia do sądu pracy z żądaniem ustalenia uprawnienia do otrzymania świadectwa pracy. - -§ 3. Z żądaniem, o którym mowa w § 1 i 2, można wystąpić w każdym czasie przed upływem terminu przedawnienia. - -§ 4. Przepisy § 1-3 stosuje się odpowiednio do żądania sprostowania świadectwa pracy. - -Art. 98. (skreślony). - -Art. 99. § 1. Pracownikowi przysługuje roszczenie o naprawienie szkody wyrządzonej przez pracodawcę wskutek niewydania w terminie lub wydania niewłaściwego świadectwa pracy. - -§ 2. Odszkodowanie, o którym mowa w § 1, przysługuje w wysokości wynagrodzenia za czas pozostawania bez pracy z tego powodu, nie dłuższy jednak niż 6 tygodni. - -§ 3. (skreślony). - -§ 4. Orzeczenie o odszkodowaniu w związku z wydaniem niewłaściwego świadectwa pracy stanowi podstawę do zmiany tego świadectwa. - -Rozdział II -Obowiązki pracownika - -Art. 100. § 1. Pracownik jest obowiązany wykonywać pracę sumiennie i starannie oraz stosować się do poleceń przełożonych, które dotyczą pracy, jeżeli nie są one sprzeczne z przepisami prawa lub umową o pracę. - -§ 2. Pracownik jest obowiązany w szczególności: - -1) przestrzegać czasu pracy ustalonego w zakładzie pracy, -2) przestrzegać regulaminu pracy i ustalonego w zakładzie pracy porządku, -3) przestrzegać przepisów oraz zasad bezpieczeństwa i higieny pracy, a także przepisów przeciwpożarowych, -4) dbać o dobro zakładu pracy, chronić jego mienie oraz zachować w tajemnicy informacje, których ujawnienie mogłoby narazić pracodawcę na szkodę, -5) przestrzegać tajemnicy określonej w odrębnych przepisach, -6) przestrzegać w zakładzie pracy zasad współżycia społecznego. -Art. 101. (skreślony). - -Rozdział IIa -Zakaz konkurencji - -Art. 1011. § 1. W zakresie określonym w odrębnej umowie, pracownik nie może prowadzić działalności konkurencyjnej wobec pracodawcy ani też świadczyć pracy w ramach stosunku pracy lub na innej podstawie na rzecz podmiotu prowadzącego taką działalność (zakaz konkurencji). - -§ 2. Pracodawca, który poniósł szkodę wskutek naruszenia przez pracownika zakazu konkurencji przewidzianego w umowie, może dochodzić od pracownika wyrównania tej szkody na zasadach określonych w przepisach rozdziału I w dziale piątym. - -Art. 1012. § 1. Przepis art. 1011 § 1 stosuje się odpowiednio, gdy pracodawca i pracownik mający dostęp do szczególnie ważnych informacji, których ujawnienie mogłoby narazić pracodawcę na szkodę, zawierają umowę o zakazie konkurencji po ustaniu stosunku pracy. W umowie określa się także okres obowiązywania zakazu konkurencji oraz wysokość odszkodowania należnego pracownikowi od pracodawcy, z zastrzeżeniem przepisów § 2 i 3. - -§ 2. Zakaz konkurencji, o którym mowa w § 1, przestaje obowiązywać przed upływem terminu, na jaki została zawarta umowa przewidziana w tym przepisie, w razie ustania przyczyn uzasadniających taki zakaz lub niewywiązywania się pracodawcy z obowiązku wypłaty odszkodowania. - -§ 3. Odszkodowanie, o którym mowa w § 1, nie może być niższe od 25% wynagrodzenia otrzymanego przez pracownika przed ustaniem stosunku pracy przez okres odpowiadający okresowi obowiązywania zakazu konkurencji; odszkodowanie może być wypłacane w miesięcznych ratach. W razie sporu o odszkodowaniu orzeka sąd pracy. - -Art. 1013. Umowy, o których mowa w art. 1011 § 1 i w art. 1012 § 1, wymagają pod rygorem nieważności formy pisemnej. - -Art. 1014. Przepisy rozdziału nie naruszają zakazu konkurencji przewidzianego w odrębnych przepisach. - -Rozdział III -Kwalifikacje zawodowe pracowników - -Art. 102. Kwalifikacje zawodowe pracowników wymagane do wykonywania pracy określonego rodzaju lub na określonym stanowisku mogą być ustalane w przepisach prawa pracy przewidzianych w art. 771-773, w zakresie nie uregulowanym w przepisach szczególnych. - -Art. 103. (utrata mocy). - - -Art. 1031. § 1. Przez podnoszenie kwalifikacji zawodowych rozumie się zdobywanie lub uzupełnianie wiedzy i umiejętności przez pracownika, z inicjatywy pracodawcy albo za jego zgodą. - -§ 2. Pracownikowi podnoszącemu kwalifikacje zawodowe przysługują: - -1) urlop szkoleniowy, -2) zwolnienie z całości lub części dnia pracy, na czas niezbędny, by punktualnie przybyć na obowiązkowe zajęcia oraz na czas ich trwania. -§ 3. Za czas urlopu szkoleniowego oraz za czas zwolnienia z całości lub części dnia pracy pracownik zachowuje prawo do wynagrodzenia. - - -Art. 1032. § 1. Urlop szkoleniowy, o którym mowa w art. 1031 § 2 pkt 1, przysługuje w wymiarze: - -1) 6 dni - dla pracownika przystępującego do egzaminów eksternistycznych, -2) 6 dni - dla pracownika przystępującego do egzaminu maturalnego, -3) 6 dni - dla pracownika przystępującego do egzaminu potwierdzającego kwalifikacje w zawodzie lub egzaminu zawodowego, -4) 21 dni w ostatnim roku studiów - na przygotowanie pracy dyplomowej oraz przygotowanie się i przystąpienie do egzaminu dyplomowego. -§ 2. Urlopu szkoleniowego udziela się w dni, które są dla pracownika dniami pracy, zgodnie z obowiązującym go rozkładem czasu pracy. - - -Art. 1033. Pracodawca może przyznać pracownikowi podnoszącemu kwalifikacje zawodowe dodatkowe świadczenia, w szczególności pokryć opłaty za kształcenie, przejazd, podręczniki i zakwaterowanie. - - -Art. 1034. § 1. Pracodawca zawiera z pracownikiem podnoszącym kwalifikacje zawodowe umowę określającą wzajemne prawa i obowiązki stron. Umowę zawiera się na piśmie. - -§ 2. Umowa, o której mowa w § 1, nie może zawierać postanowień mniej korzystnych dla pracownika niż przepisy niniejszego rozdziału. - -§ 3. Nie ma obowiązku zawarcia umowy, o której mowa w § 1, jeżeli pracodawca nie zamierza zobowiązać pracownika do pozostawania w zatrudnieniu po ukończeniu podnoszenia kwalifikacji zawodowych. - - -Art. 1035. Pracownik podnoszący kwalifikacje zawodowe: - -1) który bez uzasadnionych przyczyn nie podejmie podnoszenia kwalifikacji zawodowych albo przerwie podnoszenie tych kwalifikacji, -2) z którym pracodawca rozwiąże stosunek pracy bez wypowiedzenia z jego winy, w trakcie podnoszenia kwalifikacji zawodowych lub po jego ukończeniu, w terminie określonym w umowie, o której mowa w art. 1034, nie dłuższym niż 3 lata, -3) który w okresie wskazanym w pkt 2 rozwiąże stosunek pracy za wypowiedzeniem, z wyjątkiem wypowiedzenia umowy o pracę z przyczyn określonych w art. 943, -4) który w okresie wskazanym w pkt 2 rozwiąże stosunek pracy bez wypowiedzenia na podstawie art. 55 lub art. 943, mimo braku przyczyn określonych w tych przepisach -- jest obowiązany do zwrotu kosztów poniesionych przez pracodawcę na ten cel z tytułu dodatkowych świadczeń, w wysokości proporcjonalnej do okresu zatrudnienia po ukończeniu podnoszenia kwalifikacji zawodowych lub okresu zatrudnienia w czasie ich podnoszenia. - -Art. 1036. Pracownikowi zdobywającemu lub uzupełniającemu wiedzę i umiejętności na zasadach innych, niż określone w art. 1031-1035, mogą być przyznane: - -1) zwolnienie z całości lub części dnia pracy bez zachowania prawa do wynagrodzenia, -2) urlop bezpłatny -- w wymiarze ustalonym w porozumieniu zawieranym między pracodawcą i pracownikiem. -Rozdział IV -Regulamin pracy - -Art. 104. § 1. Regulamin pracy ustala organizację i porządek w procesie pracy oraz związane z tym prawa i obowiązki pracodawcy i pracowników. - -§ 11. Pracodawca zatrudniający co najmniej 50 pracowników wprowadza regulamin pracy, chyba że w zakresie przewidzianym w § 1 obowiązują postanowienia układu zbiorowego pracy. - -§ 2. Pracodawca zatrudniający mniej niż 50 pracowników może wprowadzić regulamin pracy, chyba że w zakresie przewidzianym w § 1 obowiązują postanowienia układu zbiorowego pracy. - -§ 3. Pracodawca zatrudniający co najmniej 20 i mniej niż 50 pracowników wprowadza regulamin pracy, jeżeli zakładowa organizacja związkowa wystąpi z wnioskiem o jego wprowadzenie, chyba że w zakresie przewidzianym w § 1 obowiązują postanowienia układu zbiorowego pracy. - -Art. 1041. § 1. Regulamin pracy, określając prawa i obowiązki pracodawcy i pracowników związane z porządkiem w zakładzie pracy, powinien ustalać w szczególności: - -1) organizację pracy, warunki przebywania na terenie zakładu pracy w czasie pracy i po jej zakończeniu, wyposażenie pracowników w narzędzia i materiały, a także w odzież i obuwie robocze oraz w środki ochrony indywidualnej i higieny osobistej, -2) systemy i rozkłady czasu pracy oraz przyjęte okresy rozliczeniowe czasu pracy, -3) (skreślony), -4) porę nocną, -5) termin, miejsce, czas i częstotliwość wypłaty wynagrodzenia, -6) wykazy prac wzbronionych pracownikom młodocianym oraz kobietom, -7) rodzaje prac i wykaz stanowisk pracy dozwolonych pracownikom młodocianym w celu odbywania przygotowania zawodowego, -7a) wykaz lekkich prac dozwolonych pracownikom młodocianym zatrudnionym w innym celu niż przygotowanie zawodowe, -8) obowiązki dotyczące bezpieczeństwa i higieny pracy oraz ochrony przeciwpożarowej, w tym także sposób informowania pracowników o ryzyku zawodowym, które wiąże się z wykonywaną pracą, -9) przyjęty u danego pracodawcy sposób potwierdzania przez pracowników przybycia i obecności w pracy oraz usprawiedliwiania nieobecności w pracy. -§ 2. Regulamin pracy powinien zawierać informacje o karach stosowanych zgodnie z art. 108 z tytułu odpowiedzialności porządkowej pracowników. - -Art. 1042. § 1. Regulamin pracy ustala pracodawca w uzgodnieniu z zakładową organizacją związkową. - -§ 2. W razie nieuzgodnienia treści regulaminu pracy z zakładową organizacją związkową w ustalonym przez strony terminie, a także w przypadku, gdy u danego pracodawcy nie działa zakładowa organizacja związkowa, regulamin pracy ustala pracodawca. - -Art. 1043. § 1. Regulamin pracy wchodzi w życie po upływie 2 tygodni od dnia podania go do wiadomości pracowników, w sposób przyjęty u danego pracodawcy. - -§ 2. Pracodawca jest obowiązany zapoznać pracownika z treścią regulaminu pracy przed dopuszczeniem go do pracy. - - -Art. 1044. (uchylony). - -Rozdział V -Nagrody i wyróżnienia - -Art. 105. Pracownikom, którzy przez wzorowe wypełnianie swoich obowiązków, przejawianie inicjatywy w pracy i podnoszenie jej wydajności oraz jakości przyczyniają się szczególnie do wykonywania zadań zakładu, mogą być przyznawane nagrody i wyróżnienia. Odpis zawiadomienia o przyznaniu nagrody lub wyróżnienia składa się do akt osobowych pracownika. - -Art. 106. (skreślony). - -Art. 107. (uchylony). - -Rozdział VI -Odpowiedzialność porządkowa pracowników - -Art. 108. § 1. Za nieprzestrzeganie przez pracownika ustalonej organizacji i porządku w procesie pracy, przepisów bezpieczeństwa i higieny pracy, przepisów przeciwpożarowych, a także przyjętego sposobu potwierdzania przybycia i obecności w pracy oraz usprawiedliwiania nieobecności w pracy, pracodawca może stosować: - -1) karę upomnienia, -2) karę nagany. -§ 2. Za nieprzestrzeganie przez pracownika przepisów bezpieczeństwa i higieny pracy lub przepisów przeciwpożarowych, opuszczenie pracy bez usprawiedliwienia, stawienie się do pracy w stanie nietrzeźwości albo w stanie po użyciu alkoholu lub środka działającego podobnie do alkoholu lub spożywanie alkoholu lub zażywanie środka działającego podobnie do alkoholu w czasie pracy - pracodawca może również stosować karę pieniężną. - -§ 3. Kara pieniężna za jedno przekroczenie, jak i za każdy dzień nieusprawiedliwionej nieobecności, nie może być wyższa od jednodniowego wynagrodzenia pracownika, a łącznie kary pieniężne nie mogą przewyższać dziesiątej części wynagrodzenia przypadającego pracownikowi do wypłaty, po dokonaniu potrąceń, o których mowa w art. 87 § 1 pkt 1-3. - -§ 4. Wpływy z kar pieniężnych przeznacza się na poprawę warunków bezpieczeństwa i higieny pracy. - -Art. 109. § 1. Kara nie może być zastosowana po upływie 2 tygodni od powzięcia wiadomości o naruszeniu obowiązku pracowniczego i po upływie 3 miesięcy od dopuszczenia się tego naruszenia. - -§ 2. Kara może być zastosowana tylko po uprzednim wysłuchaniu pracownika. - -§ 3. Jeżeli z powodu nieobecności w zakładzie pracy pracownik nie może być wysłuchany, bieg dwutygodniowego terminu przewidzianego w § 1 nie rozpoczyna się, a rozpoczęty ulega zawieszeniu do dnia stawienia się pracownika do pracy. - -Art. 110. O zastosowanej karze pracodawca zawiadamia pracownika na piśmie, wskazując rodzaj naruszenia obowiązków pracowniczych i datę dopuszczenia się przez pracownika tego naruszenia oraz informując go o prawie zgłoszenia sprzeciwu i terminie jego wniesienia. Odpis zawiadomienia składa się do akt osobowych pracownika. - -Art. 111. Przy stosowaniu kary bierze się pod uwagę w szczególności rodzaj naruszenia obowiązków pracowniczych, stopień winy pracownika i jego dotychczasowy stosunek do pracy. - -Art. 112. § 1. Jeżeli zastosowanie kary nastąpiło z naruszeniem przepisów prawa, pracownik może w ciągu 7 dni od dnia zawiadomienia go o ukaraniu wnieść sprzeciw. O uwzględnieniu lub odrzuceniu sprzeciwu decyduje pracodawca po rozpatrzeniu stanowiska reprezentującej pracownika zakładowej organizacji związkowej. Nieodrzucenie sprzeciwu w ciągu 14 dni od dnia jego wniesienia jest równoznaczne z uwzględnieniem sprzeciwu. - -§ 2. Pracownik, który wniósł sprzeciw, może w ciągu 14 dni od dnia zawiadomienia o odrzuceniu tego sprzeciwu wystąpić do sądu pracy o uchylenie zastosowanej wobec niego kary. - -§ 3. W razie uwzględnienia sprzeciwu wobec zastosowanej kary pieniężnej lub uchylenia tej kary przez sąd pracy, pracodawca jest obowiązany zwrócić pracownikowi równowartość kwoty tej kary. - -Art. 113. § 1. Karę uważa się za niebyłą, a odpis zawiadomienia o ukaraniu usuwa z akt osobowych pracownika po roku nienagannej pracy. Pracodawca może, z własnej inicjatywy lub na wniosek reprezentującej pracownika zakładowej organizacji związkowej, uznać karę za niebyłą przed upływem tego terminu. - -§ 2. Przepis § 1 zdanie pierwsze stosuje się odpowiednio w razie uwzględnienia sprzeciwu przez pracodawcę albo wydania przez sąd pracy orzeczenia o uchyleniu kary. - -Art. 1131. (skreślony). - -DZIAŁ PIĄTY -Odpowiedzialność materialna pracowników - -Rozdział I -Odpowiedzialność pracownika za szkodę wyrządzoną pracodawcy - -Art. 114. Pracownik, który wskutek niewykonania lub nienależytego wykonania obowiązków pracowniczych ze swej winy wyrządził pracodawcy szkodę, ponosi odpowiedzialność materialną według zasad określonych w przepisach niniejszego rozdziału. - -Art. 115. Pracownik ponosi odpowiedzialność za szkodę w granicach rzeczywistej straty poniesionej przez pracodawcę i tylko za normalne następstwa działania lub zaniechania, z którego wynikła szkoda. - -Art. 116. Pracodawca jest obowiązany wykazać okoliczności uzasadniające odpowiedzialność pracownika oraz wysokość powstałej szkody. - -Art. 117. § 1. Pracownik nie ponosi odpowiedzialności za szkodę w takim zakresie, w jakim pracodawca lub inna osoba przyczyniły się do jej powstania albo zwiększenia. - -§ 2. Pracownik nie ponosi ryzyka związanego z działalnością pracodawcy, a w szczególności nie odpowiada za szkodę wynikłą w związku z działaniem w granicach dopuszczalnego ryzyka. - -§ 3. (skreślony). - -Art. 118. W razie wyrządzenia szkody przez kilku pracowników każdy z nich ponosi odpowiedzialność za część szkody stosownie do przyczynienia się do niej i stopnia winy. Jeżeli nie jest możliwe ustalenie stopnia winy i przyczynienia się poszczególnych pracowników do powstania szkody, odpowiadają oni w częściach równych. - -Art. 119. Odszkodowanie ustala się w wysokości wyrządzonej szkody, jednak nie może ono przewyższać kwoty trzymiesięcznego wynagrodzenia przysługującego pracownikowi w dniu wyrządzenia szkody. - -Art. 120. § 1. W razie wyrządzenia przez pracownika przy wykonywaniu przez niego obowiązków pracowniczych szkody osobie trzeciej, zobowiązany do naprawienia szkody jest wyłącznie pracodawca. - -§ 2. Wobec pracodawcy, który naprawił szkodę wyrządzoną osobie trzeciej, pracownik ponosi odpowiedzialność przewidzianą w przepisach niniejszego rozdziału. - -Art. 121. § 1. Jeżeli naprawienie szkody następuje na podstawie ugody pomiędzy pracodawcą i pracownikiem, wysokość odszkodowania może być obniżona, przy uwzględnieniu wszystkich okoliczności sprawy, a w szczególności stopnia winy pracownika i jego stosunku do obowiązków pracowniczych. - -§ 2. Przy uwzględnieniu okoliczności wymienionych w § 1 wysokość odszkodowania może być także obniżona przez sąd pracy; dotyczy to również przypadku, gdy naprawienie szkody następuje na podstawie ugody sądowej. - -Art. 1211. § 1. W razie niewykonania ugody przez pracownika, podlega ona wykonaniu w trybie przepisów Kodeksu postępowania cywilnego, po nadaniu jej klauzuli wykonalności przez sąd pracy. - -§ 2. Sąd pracy odmówi nadania klauzuli wykonalności ugodzie, jeżeli ustali, że jest ona sprzeczna z prawem lub zasadami współżycia społecznego. - -Art. 122. Jeżeli pracownik umyślnie wyrządził szkodę, jest obowiązany do jej naprawienia w pełnej wysokości. - -Art. 123. (skreślony). - -Rozdział II -Odpowiedzialność za mienie powierzone pracownikowi - -Art. 124. § 1. Pracownik, któremu powierzono z obowiązkiem zwrotu albo do wyliczenia się: - -1) pieniądze, papiery wartościowe lub kosztowności, -2) narzędzia i instrumenty lub podobne przedmioty, a także środki ochrony indywidualnej oraz odzież i obuwie robocze, -odpowiada w pełnej wysokości za szkodę powstałą w tym mieniu. -§ 2. Pracownik odpowiada w pełnej wysokości również za szkodę w mieniu innym niż wymienione w § 1, powierzonym mu z obowiązkiem zwrotu albo do wyliczenia się. - -§ 3. Od odpowiedzialności określonej w § 1 i 2 pracownik może się uwolnić, jeżeli wykaże, że szkoda powstała z przyczyn od niego niezależnych, a w szczególności wskutek niezapewnienia przez pracodawcę warunków umożliwiających zabezpieczenie powierzonego mienia. - -Art. 125. § 1. Na zasadach określonych w art. 124 pracownicy mogą przyjąć wspólną odpowiedzialność materialną za mienie powierzone im łącznie z obowiązkiem wyliczenia się. Podstawą łącznego powierzenia mienia jest umowa o współodpowiedzialności materialnej, zawarta przez pracowników z pracodawcą na piśmie pod rygorem nieważności. - -§ 2. Pracownicy ponoszący wspólną odpowiedzialność materialną odpowiadają w częściach określonych w umowie. Jednakże w razie ustalenia, że szkoda w całości lub w części została spowodowana przez niektórych pracowników, za całość szkody lub za stosowną jej część odpowiadają tylko sprawcy szkody. - -Art. 126. § 1. Rada Ministrów określi w drodze rozporządzenia zakres i szczegółowe zasady stosowania przepisów art. 125 oraz tryb łącznego powierzania mienia. - -§ 2. Rada Ministrów, w drodze rozporządzenia, może określić warunki odpowiedzialności za szkodę w mieniu, o którym mowa w art. 124 § 2 i w art. 125: - -1) w ograniczonej wysokości, ustalonej tym rozporządzeniem, -2) na zasadach przewidzianych w art. 114-116 i 118. -Art. 127. Do odpowiedzialności określonej w art. 124-126 stosuje się odpowiednio przepisy art. 117, 121, 1211 i 122. - -DZIAŁ SZÓSTY -Czas pracy - -Rozdział I -Przepisy ogólne - -Art. 128. § 1. Czasem pracy jest czas, w którym pracownik pozostaje w dyspozycji pracodawcy w zakładzie pracy lub w innym miejscu wyznaczonym do wykonywania pracy. - -§ 2. Ilekroć w przepisach działu jest mowa o: - -1) pracy zmianowej - należy przez to rozumieć wykonywanie pracy według ustalonego rozkładu czasu pracy przewidującego zmianę pory wykonywania pracy przez poszczególnych pracowników po upływie określonej liczby godzin, dni lub tygodni, -2) pracownikach zarządzających w imieniu pracodawcy zakładem pracy - należy przez to rozumieć pracowników kierujących jednoosobowo zakładem pracy i ich zastępców lub pracowników wchodzących w skład kolegialnego organu zarządzającego zakładem pracy oraz głównych księgowych. -§ 3. Do celów rozliczania czasu pracy pracownika: - -1) przez dobę - należy rozumieć 24 kolejne godziny, poczynając od godziny, w której pracownik rozpoczyna pracę zgodnie z obowiązującym go rozkładem czasu pracy, -2) przez tydzień - należy rozumieć 7 kolejnych dni kalendarzowych, poczynając od pierwszego dnia okresu rozliczeniowego. - -Rozdział II -Normy i ogólny wymiar czasu pracy - -Art. 129. - -§ 1. Czas pracy nie może przekraczać 8 godzin na dobę i przeciętnie 40 godzin w przeciętnie pięciodniowym tygodniu pracy w przyjętym okresie rozliczeniowym nieprzekraczającym 4 miesięcy, z zastrzeżeniem art. 135-138, 143 i 144. - -§ 2. W każdym systemie czasu pracy, jeżeli jest to uzasadnione przyczynami obiektywnymi lub technicznymi lub dotyczącymi organizacji pracy, okres rozliczeniowy może być przedłużony, nie więcej jednak niż do 12 miesięcy, przy zachowaniu ogólnych zasad dotyczących ochrony bezpieczeństwa i zdrowia pracowników. - -§ 3. Rozkład czasu pracy danego pracownika może być sporządzony - w formie pisemnej lub elektronicznej - na okres krótszy niż okres rozliczeniowy, obejmujący jednak co najmniej 1 miesiąc. Pracodawca przekazuje pracownikowi rozkład czasu pracy co najmniej na 1 tydzień przed rozpoczęciem pracy w okresie, na który został sporządzony ten rozkład. - -§ 4. Pracodawca nie ma obowiązku sporządzania rozkładu czasu pracy, jeżeli: - -1) rozkład czasu pracy pracownika wynika z prawa pracy, obwieszczenia, o którym mowa w art. 150 § 1, albo z umowy o pracę, -2) w porozumieniu z pracownikiem ustali czas niezbędny do wykonania powierzonych zadań, uwzględniając wymiar czasu pracy wynikający z norm określonych w § 1; w takim przypadku rozkład czasu pracy ustala pracownik, -3) na pisemny wniosek pracownika stosuje do niego rozkłady czasu pracy, o których mowa w art. 1401, -4) na pisemny wniosek pracownika ustali mu indywidualny rozkład czasu pracy. -§ 5. Jeżeli w danym miesiącu, ze względu na rozkład czasu pracy w przyjętym okresie rozliczeniowym, pracownik nie ma obowiązku wykonywania pracy, przysługuje mu wynagrodzenie w wysokości nie niższej niż minimalne wynagrodzenie za pracę ustalane na podstawie odrębnych przepisów; w przypadku pracownika zatrudnionego w niepełnym wymiarze czasu pracy wysokość tego wynagrodzenia ustala się proporcjonalnie do tego wymiaru czasu pracy. - -Art. 130. - -§ 1. Obowiązujący pracownika wymiar czasu pracy w przyjętym okresie rozliczeniowym, ustalany zgodnie z art. 129 § 1, oblicza się: - -1) mnożąc 40 godzin przez liczbę tygodni przypadających w okresie rozliczeniowym, a następnie -2) dodając do otrzymanej liczby godzin iloczyn 8 godzin i liczby dni pozostałych do końca okresu rozliczeniowego, przypadających od poniedziałku do piątku. -§ 2. Każde święto występujące w okresie rozliczeniowym i przypadające w innym dniu niż niedziela obniża wymiar czasu pracy o 8 godzin. - -§ 21. (utrata mocy). - -§ 3. Wymiar czasu pracy pracownika w okresie rozliczeniowym, ustalony zgodnie z art. 129 § 1, ulega w tym okresie obniżeniu o liczbę godzin usprawiedliwionej nieobecności w pracy, przypadających do przepracowania w czasie tej nieobecności, zgodnie z przyjętym rozkładem czasu pracy. - -Art. 131. § 1. Tygodniowy czas pracy łącznie z godzinami nadliczbowymi nie może przekraczać przeciętnie 48 godzin w przyjętym okresie rozliczeniowym. - -§ 2. Ograniczenie przewidziane w § 1 nie dotyczy pracowników zarządzających w imieniu pracodawcy zakładem pracy. - - -Rozdział III -Okresy odpoczynku - -Art. 132. - -§ 1. Pracownikowi przysługuje w każdej dobie prawo do co najmniej 11 godzin nieprzerwanego odpoczynku, z zastrzeżeniem § 3 oraz art. 136 § 2 i art. 137. - -§ 2. Przepis § 1 nie dotyczy: - -1) pracowników zarządzających w imieniu pracodawcy zakładem pracy, -2) przypadków konieczności prowadzenia akcji ratowniczej w celu ochrony życia lub zdrowia ludzkiego, ochrony mienia lub środowiska albo usunięcia awarii. -§ 3. W przypadkach określonych w § 2 pracownikowi przysługuje, w okresie rozliczeniowym, równoważny okres odpoczynku. - -Art. 133. - -§ 1. Pracownikowi przysługuje w każdym tygodniu prawo do co najmniej 35 godzin nieprzerwanego odpoczynku, obejmującego co najmniej 11 godzin nieprzerwanego odpoczynku dobowego. - -§ 2. W przypadkach określonych w art. 132 § 2 oraz w przypadku zmiany pory wykonywania pracy przez pracownika w związku z jego przejściem na inną zmianę, zgodnie z ustalonym rozkładem czasu pracy, tygodniowy nieprzerwany odpoczynek może obejmować mniejszą liczbę godzin, nie może być jednak krótszy niż 24 godziny. - -§ 3. Odpoczynek, o którym mowa w § 1 i 2, powinien przypadać w niedzielę. Niedziela obejmuje 24 kolejne godziny, poczynając od godziny 6.00 w tym dniu, chyba że u danego pracodawcy została ustalona inna godzina. - -§ 4. W przypadkach dozwolonej pracy w niedzielę odpoczynek, o którym mowa w § 1 i 2, może przypadać w innym dniu niż niedziela. - -Art. 134. - -§ 1. Jeżeli dobowy wymiar czasu pracy pracownika: - -1) wynosi co najmniej 6 godzin - pracownik ma prawo do przerwy w pracy trwającej co najmniej 15 minut; -2) jest dłuższy niż 9 godzin - pracownik ma prawo do dodatkowej przerwy w pracy trwającej co najmniej 15 minut; -3) jest dłuższy niż 16 godzin - pracownik ma prawo do kolejnej przerwy w pracy trwającej co najmniej 15 minut. -§ 2. Przerwy, o których mowa w § 1, wlicza się do czasu pracy. - - -Rozdział IV -Systemy i rozkłady czasu pracy - -Art. 135. - -§ 1. Jeżeli jest to uzasadnione rodzajem pracy lub jej organizacją, może być stosowany system równoważnego czasu pracy, w którym jest dopuszczalne przedłużenie dobowego wymiaru czasu pracy, nie więcej jednak niż do 12 godzin, w okresie rozliczeniowym nieprzekraczającym 1 miesiąca. Przedłużony dobowy wymiar czasu pracy jest równoważony krótszym dobowym wymiarem czasu pracy w niektórych dniach lub dniami wolnymi od pracy. - -§ 2. W szczególnie uzasadnionych przypadkach okres rozliczeniowy, o którym mowa w § 1, może być przedłużony, nie więcej jednak niż do 3 miesięcy. - -§ 3. Przy pracach uzależnionych od pory roku lub warunków atmosferycznych okres rozliczeniowy, o którym mowa w § 1, może być przedłużony, nie więcej jednak niż do 4 miesięcy. - -Art. 136. § 1. Przy pracach polegających na dozorze urządzeń lub związanych z częściowym pozostawaniem w pogotowiu do pracy może być stosowany system równoważnego czasu pracy, w którym jest dopuszczalne przedłużenie dobowego wymiaru czasu pracy, nie więcej jednak niż do 16 godzin, w okresie rozliczeniowym nieprzekraczającym 1 miesiąca. - -§ 2. W systemie czasu pracy, o którym mowa w § 1, pracownikowi przysługuje, bezpośrednio po każdym okresie wykonywania pracy w przedłużonym dobowym wymiarze czasu pracy, odpoczynek przez czas odpowiadający co najmniej liczbie przepracowanych godzin, niezależnie od odpoczynku przewidzianego w art. 133. - -Art. 137. Do pracowników zatrudnionych przy pilnowaniu mienia lub ochronie osób, a także pracowników zakładowych straży pożarnych i zakładowych służb ratowniczych może być stosowany system równoważnego czasu pracy, w którym jest dopuszczalne przedłużenie dobowego wymiaru czasu pracy do 24 godzin, w okresie rozliczeniowym nieprzekraczającym 1 miesiąca. Przepisy art. 135 § 2 i 3 oraz art. 136 § 2 stosuje się odpowiednio. - -Art. 138. - -§ 1. Przy pracach, które ze względu na technologię produkcji nie mogą być wstrzymane (praca w ruchu ciągłym), może być stosowany system czasu pracy, w którym jest dopuszczalne przedłużenie czasu pracy do 43 godzin przeciętnie na tydzień w okresie rozliczeniowym nieprzekraczającym 4 tygodni, a jednego dnia w niektórych tygodniach w tym okresie dobowy wymiar czasu pracy może być przedłużony do 12 godzin. Za każdą godzinę pracy powyżej 8 godzin na dobę w dniu wykonywania pracy w przedłużonym wymiarze czasu pracy pracownikowi przysługuje dodatek do wynagrodzenia, o którym mowa w art. 1511 § 1 pkt 1. - -§ 2. Przepis § 1 stosuje się także w przypadku, gdy praca nie może być wstrzymana ze względu na konieczność ciągłego zaspokajania potrzeb ludności. - -§ 3. W przypadkach określonych w § 1 i 2 obowiązujący pracownika wymiar czasu pracy w przyjętym okresie rozliczeniowym oblicza się: - -1) mnożąc 8 godzin przez liczbę dni kalendarzowych przypadających w okresie rozliczeniowym, z wyłączeniem niedziel, świąt oraz dni wolnych od pracy wynikających z rozkładu czasu pracy w przeciętnie pięciodniowym tygodniu pracy, a następnie -2) dodając do otrzymanej liczby liczbę godzin odpowiadającą przedłużonemu u danego pracodawcy tygodniowemu wymiarowi czasu pracy. -§ 4. Liczba godzin odpowiadająca przedłużonemu u danego pracodawcy tygodniowemu wymiarowi czasu pracy nie może przekraczać 4 godzin na każdy tydzień okresu rozliczeniowego, w którym następuje przedłużenie czasu pracy. - -§ 5. Przepisy art. 130 § 2 zdanie drugie i § 3 stosuje się odpowiednio. - -Art. 139. § 1. Jeżeli jest to uzasadnione rodzajem pracy lub jej organizacją, może być stosowany system przerywanego czasu pracy według z góry ustalonego rozkładu przewidującego nie więcej niż jedną przerwę w pracy w ciągu doby, trwającą nie dłużej niż 5 godzin. Przerwy nie wlicza się do czasu pracy, jednakże za czas tej przerwy pracownikowi przysługuje prawo do wynagrodzenia w wysokości połowy wynagrodzenia należnego za czas przestoju. - -§ 2. Systemu przerywanego czasu pracy nie stosuje się do pracownika objętego systemem czasu pracy, o którym mowa w art. 135-138, 143 i 144. - -§ 3. System przerywanego czasu pracy wprowadza się w układzie zbiorowym pracy lub w porozumieniu z zakładową organizacją związkową, a jeżeli u danego pracodawcy nie działa zakładowa organizacja związkowa - w porozumieniu z przedstawicielami pracowników wyłonionymi w trybie przyjętym u tego pracodawcy, z zastrzeżeniem § 4. - -§ 4. U pracodawcy będącego osobą fizyczną, prowadzącego działalność w zakresie rolnictwa i hodowli, u którego nie działa zakładowa organizacja związkowa, system przerywanego czasu pracy może być stosowany na podstawie umowy o pracę. Pracownikowi przysługuje wynagrodzenie za czas przerwy, o której mowa w § 1, jeżeli wynika to z umowy o pracę. - -§ 5. Jeżeli nie jest możliwe uzgodnienie treści porozumienia, o którym mowa w § 3, ze wszystkimi zakładowymi organizacjami związkowymi, pracodawca uzgadnia treść porozumienia z organizacjami związkowymi reprezentatywnymi w rozumieniu art. 253 ust. 1 lub 2 ustawy o związkach zawodowych, z których każda zrzesza co najmniej 5% pracowników zatrudnionych u pracodawcy. - -Art. 140. W przypadkach uzasadnionych rodzajem pracy lub jej organizacją albo miejscem wykonywania pracy może być stosowany system zadaniowego czasu pracy. Pracodawca, po porozumieniu z pracownikiem, ustala czas niezbędny do wykonania powierzonych zadań, uwzględniając wymiar czasu pracy wynikający z norm określonych w art. 129. - -Art. 1401. § 1. Rozkład czasu pracy może przewidywać różne godziny rozpoczynania pracy w dniach, które zgodnie z tym rozkładem są dla pracowników dniami pracy. - -§ 2. Rozkład czasu pracy może przewidywać przedział czasu, w którym pracownik decyduje o godzinie rozpoczęcia pracy w dniu, który zgodnie z tym rozkładem jest dla pracownika dniem pracy. - -§ 3. Wykonywanie pracy zgodnie z rozkładami czasu pracy, o których mowa w § 1 i 2, nie może naruszać prawa pracownika do odpoczynku, o którym mowa w art. 132 i 133. - -§ 4. W rozkładach czasu pracy, o których mowa w § 1 i 2, ponowne wykonywanie pracy w tej samej dobie nie stanowi pracy w godzinach nadliczbowych. - -Art. 141. § 1. Pracodawca może wprowadzić jedną przerwę w pracy niewliczaną do czasu pracy, w wymiarze nieprzekraczającym 60 minut, przeznaczoną na spożycie posiłku lub załatwienie spraw osobistych. - -§ 2. Przerwę w pracy, o której mowa w § 1, wprowadza się w układzie zbiorowym pracy lub regulaminie pracy albo w umowie o pracę, jeżeli pracodawca nie jest objęty układem zbiorowym pracy lub nie jest obowiązany do ustalenia regulaminu pracy. - -Art. 142. Na pisemny wniosek pracownika pracodawca może ustalić indywidualny rozkład jego czasu pracy w ramach systemu czasu pracy, którym pracownik jest objęty. - - -Art. 1421. § 1. Pracodawca jest obowiązany uwzględnić wniosek: - -1) pracownika-małżonka albo pracownika-rodzica dziecka w fazie prenatalnej, w przypadku ciąży powikłanej, -2) pracownika-rodzica dziecka posiadającego zaświadczenie, o którym mowa w art. 4 ust. 3 ustawy z dnia 4 listopada 2016 r. o wsparciu kobiet w ciąży i rodzin „Za życiem”, -3) pracownika-rodzica: -a) dziecka legitymującego się orzeczeniem o niepełnosprawności albo orzeczeniem o umiarkowanym lub znacznym stopniu niepełnosprawności określonym w przepisach o rehabilitacji zawodowej i społecznej oraz zatrudnianiu osób niepełnosprawnych oraz -b) dziecka posiadającego odpowiednio opinię o potrzebie wczesnego wspomagania rozwoju dziecka, orzeczenie o potrzebie kształcenia specjalnego lub orzeczenie o potrzebie zajęć rewalidacyjno-wychowawczych, o których mowa w przepisach ustawy z dnia 14 grudnia 2016 r. - Prawo oświatowe -- o wykonywanie pracy w systemie czasu pracy, o którym mowa w art. 139, lub rozkładzie czasu pracy, o którym mowa w art. 1401 albo w art. 142, złożony w postaci papierowej lub elektronicznej. -§ 2. Pracodawca może odmówić uwzględnienia wniosku, o którym mowa w § 1, jeżeli jego uwzględnienie nie jest możliwe ze względu na organizację pracy lub rodzaj pracy wykonywanej przez pracownika. O przyczynie odmowy uwzględnienia wniosku pracodawca informuje pracownika w postaci papierowej lub elektronicznej. - -§ 3. Przepisy § 1 i 2 stosuje się do pracowników, o których mowa w § 1 pkt 2 i 3, również po ukończeniu przez dziecko 18 roku życia. - -Art. 143. Na pisemny wniosek pracownika może być do niego stosowany system skróconego tygodnia pracy. W tym systemie jest dopuszczalne wykonywanie pracy przez pracownika przez mniej niż 5 dni w ciągu tygodnia, przy równoczesnym przedłużeniu dobowego wymiaru czasu pracy, nie więcej niż do 12 godzin, w okresie rozliczeniowym nieprzekraczającym 1 miesiąca. - -Art. 144. Na pisemny wniosek pracownika może być do niego stosowany system czasu pracy, w którym praca jest świadczona wyłącznie w piątki, soboty, niedziele i święta. W tym systemie jest dopuszczalne przedłużenie dobowego wymiaru czasu pracy, nie więcej jednak niż do 12 godzin, w okresie rozliczeniowym nieprzekraczającym 1 miesiąca. - -Art. 145. § 1. Skrócenie czasu pracy poniżej norm określonych w art. 129 § 1 dla pracowników zatrudnionych w warunkach szczególnie uciążliwych lub szczególnie szkodliwych dla zdrowia może polegać na ustanowieniu przerw w pracy wliczanych do czasu pracy albo na obniżeniu tych norm, a w przypadku pracy monotonnej lub pracy w ustalonym z góry tempie polega na wprowadzeniu przerw w pracy wliczanych do czasu pracy. - -§ 2. Wykaz prac, o których mowa w § 1, ustala pracodawca po konsultacji z pracownikami lub ich przedstawicielami w trybie i na zasadach określonych w art. 23711a i art. 23713a oraz po zasięgnięciu opinii lekarza sprawującego profilaktyczną opiekę zdrowotną nad pracownikami. - -Art. 146. Praca zmianowa jest dopuszczalna bez względu na stosowany system czasu pracy. - -Art. 147. W każdym systemie czasu pracy, jeżeli przewiduje on rozkład czasu pracy obejmujący pracę w niedziele i święta, pracownikom zapewnia się łączną liczbę dni wolnych od pracy w przyjętym okresie rozliczeniowym odpowiadającą co najmniej liczbie niedziel, świąt oraz dni wolnych od pracy w przeciętnie pięciodniowym tygodniu pracy przypadających w tym okresie. - -Art. 148. W systemach i rozkładach czasu pracy, o których mowa w art. 135-138, 143 i 144, czas pracy: - -1) pracowników zatrudnionych na stanowiskach pracy, na których występują przekroczenia najwyższych dopuszczalnych stężeń lub natężeń czynników szkodliwych dla zdrowia, -2) pracownic w ciąży, -3) pracowników opiekujących się dzieckiem do ukończenia przez nie 4 roku życia, bez ich zgody -- nie może przekraczać 8 godzin. Pracownik zachowuje prawo do wynagrodzenia za czas nieprzepracowany w związku ze zmniejszeniem z tego powodu wymiaru jego czasu pracy. - -Art. 1481. § 1. Pracownikowi przysługuje w ciągu roku kalendarzowego zwolnienie od pracy, w wymiarze 2 dni albo 16 godzin, z powodu działania siły wyższej w pilnych sprawach rodzinnych spowodowanych chorobą lub wypadkiem, jeżeli jest niezbędna natychmiastowa obecność pracownika. W okresie tego zwolnienia od pracy pracownik zachowuje prawo do wynagrodzenia w wysokości połowy wynagrodzenia. - -§ 2. O sposobie wykorzystania w danym roku kalendarzowym zwolnienia od pracy, o którym mowa w § 1, decyduje pracownik w pierwszym wniosku o udzielenie takiego zwolnienia złożonym w danym roku kalendarzowym. - -§ 3. Pracodawca jest obowiązany udzielić zwolnienia od pracy, o którym mowa w § 1, na wniosek zgłoszony przez pracownika najpóźniej w dniu korzystania z tego zwolnienia. - -§ 4. Zwolnienie od pracy, o którym mowa w § 1, udzielane w wymiarze godzinowym, dla pracownika zatrudnionego w niepełnym wymiarze czasu pracy ustala się proporcjonalnie do wymiaru czasu pracy tego pracownika. Niepełną godzinę zwolnienia od pracy zaokrągla się w górę do pełnej godziny. - -§ 5. Przepis § 1 w zakresie zwolnienia od pracy udzielanego w wymiarze godzinowym stosuje się odpowiednio do pracownika, dla którego dobowa norma czasu pracy, wynikająca z odrębnych przepisów, jest niższa niż 8 godzin. - -§ 6. Do pracownika, o którym mowa w § 1, stosuje się odpowiednio art. 1864. - -Art. 149. § 1. Pracodawca prowadzi ewidencję czasu pracy pracownika do celów prawidłowego ustalenia jego wynagrodzenia i innych świadczeń związanych z pracą. Pracodawca udostępnia tę ewidencję pracownikowi, na jego żądanie. - -§ 2. W stosunku do pracowników objętych systemem zadaniowego czasu pracy, pracowników zarządzających w imieniu pracodawcy zakładem pracy oraz pracowników otrzymujących ryczałt za godziny nadliczbowe lub za pracę w porze nocnej nie ewidencjonuje się godzin pracy. - -Art. 150. - -§ 1. Systemy i rozkłady czasu pracy oraz przyjęte okresy rozliczeniowe czasu pracy ustala się w układzie zbiorowym pracy lub w regulaminie pracy albo w obwieszczeniu, jeżeli pracodawca nie jest objęty układem zbiorowym pracy lub nie jest obowiązany do ustalenia regulaminu pracy, z zastrzeżeniem § 2-5 oraz art. 139 § 3 i 4. - -§ 2. Pracodawca, u którego nie działa zakładowa organizacja związkowa, a także pracodawca, u którego zakładowa organizacja związkowa nie wyraża zgody na ustalenie lub zmianę systemów i rozkładów czasu pracy oraz okresów rozliczeniowych czasu pracy, może stosować okres rozliczeniowy czasu pracy, o którym mowa w art. 135 § 2 i 3 - po uprzednim zawiadomieniu właściwego okręgowego inspektora pracy. - -§ 3. Przedłużenie okresu rozliczeniowego czasu pracy zgodnie z art. 129 § 2 oraz rozkłady czasu pracy, o których mowa w art. 1401, ustala się: - -1) w układzie zbiorowym pracy lub w porozumieniu z zakładowymi organizacjami związkowymi; jeżeli nie jest możliwe uzgodnienie treści porozumienia ze wszystkimi zakładowymi organizacjami związkowymi, pracodawca uzgadnia treść porozumienia z organizacjami związkowymi reprezentatywnymi w rozumieniu art. 253 ust. 1 lub 2 ustawy o związkach zawodowych, z których każda zrzesza co najmniej 5% pracowników zatrudnionych u pracodawcy, albo -2) w porozumieniu zawieranym z przedstawicielami pracowników, wyłonionymi w trybie przyjętym u danego pracodawcy - jeżeli u pracodawcy nie działają zakładowe organizacje związkowe. -§ 4. Pracodawca przekazuje kopię porozumienia w sprawie przedłużenia okresu rozliczeniowego czasu pracy, o którym mowa w § 3, właściwemu okręgowemu inspektorowi pracy w terminie 5 dni roboczych od dnia zawarcia porozumienia. - -§ 5. Rozkłady czasu pracy, o których mowa w art. 1401, mogą być także stosowane na pisemny wniosek pracownika, niezależnie od ustalenia takich rozkładów czasu pracy w trybie określonym w § 3. - -§ 6. Zastosowanie do pracownika systemów czasu pracy, o których mowa w art. 143 i 144, następuje na podstawie umowy o pracę. - -§ 7. Do obwieszczenia, o którym mowa w § 1, stosuje się odpowiednio art. 1043. - - -Rozdział V -Praca w godzinach nadliczbowych - -Art. 151. § 1. Praca wykonywana ponad obowiązujące pracownika normy czasu pracy, a także praca wykonywana ponad przedłużony dobowy wymiar czasu pracy, wynikający z obowiązującego pracownika systemu i rozkładu czasu pracy, stanowi pracę w godzinach nadliczbowych. Praca w godzinach nadliczbowych jest dopuszczalna w razie: - -1) konieczności prowadzenia akcji ratowniczej w celu ochrony życia lub zdrowia ludzkiego, ochrony mienia lub środowiska albo usunięcia awarii, -2) szczególnych potrzeb pracodawcy. -§ 2. Przepisu § 1 pkt 2 nie stosuje się do pracowników zatrudnionych na stanowiskach pracy, na których występują przekroczenia najwyższych dopuszczalnych stężeń lub natężeń czynników szkodliwych dla zdrowia. - -§ 21. Nie stanowi pracy w godzinach nadliczbowych czas odpracowania zwolnienia od pracy, udzielonego pracownikowi, na jego pisemny wniosek, w celu załatwienia spraw osobistych. Odpracowanie zwolnienia od pracy nie może naruszać prawa pracownika do odpoczynku, o którym mowa w art. 132 i 133. - -§ 3. Liczba godzin nadliczbowych przepracowanych w związku z okolicznościami określonymi w § 1 pkt 2 nie może przekroczyć dla poszczególnego pracownika 150 godzin w roku kalendarzowym. - -§ 4. W układzie zbiorowym pracy lub w regulaminie pracy albo w umowie o pracę, jeżeli pracodawca nie jest objęty układem zbiorowym pracy lub nie jest obowiązany do ustalenia regulaminu pracy, jest dopuszczalne ustalenie innej liczby godzin nadliczbowych w roku kalendarzowym niż określona w § 3. - -§ 5. Strony ustalają w umowie o pracę dopuszczalną liczbę godzin pracy ponad określony w umowie wymiar czasu pracy pracownika zatrudnionego w niepełnym wymiarze czasu pracy, których przekroczenie uprawnia pracownika, oprócz normalnego wynagrodzenia, do dodatku do wynagrodzenia, o którym mowa w art. 1511 § 1. - - -Art. 1511. § 1. Za pracę w godzinach nadliczbowych, oprócz normalnego wynagrodzenia, przysługuje dodatek w wysokości: - -1) 100% wynagrodzenia - za pracę w godzinach nadliczbowych przypadających: -a) w nocy, -b) w niedziele i święta niebędące dla pracownika dniami pracy, zgodnie z obowiązującym go rozkładem czasu pracy, -c) w dniu wolnym od pracy udzielonym pracownikowi w zamian za pracę w niedzielę lub w święto, zgodnie z obowiązującym go rozkładem czasu pracy, -2) 50% wynagrodzenia - za pracę w godzinach nadliczbowych przypadających w każdym innym dniu niż określony w pkt 1. -§ 2. Dodatek w wysokości określonej w § 1 pkt 1 przysługuje także za każdą godzinę pracy nadliczbowej z tytułu przekroczenia przeciętnej tygodniowej normy czasu pracy w przyjętym okresie rozliczeniowym, chyba że przekroczenie tej normy nastąpiło w wyniku pracy w godzinach nadliczbowych, za które pracownikowi przysługuje prawo do dodatku w wysokości określonej w § 1. - -§ 3. Wynagrodzenie stanowiące podstawę obliczania dodatku, o którym mowa w § 1, obejmuje wynagrodzenie pracownika wynikające z jego osobistego zaszeregowania określonego stawką godzinową lub miesięczną, a jeżeli taki składnik wynagrodzenia nie został wyodrębniony przy określaniu warunków wynagradzania - 60% wynagrodzenia. - -§ 4. W stosunku do pracowników wykonujących stale pracę poza zakładem pracy wynagrodzenie wraz z dodatkiem, o którym mowa w § 1, może być zastąpione ryczałtem, którego wysokość powinna odpowiadać przewidywanemu wymiarowi pracy w godzinach nadliczbowych. - - -Art. 1512. § 1. W zamian za czas przepracowany w godzinach nadliczbowych pracodawca, na pisemny wniosek pracownika, może udzielić mu w tym samym wymiarze czasu wolnego od pracy. - -§ 2. Udzielenie czasu wolnego w zamian za czas przepracowany w godzinach nadliczbowych może nastąpić także bez wniosku pracownika. W takim przypadku pracodawca udziela czasu wolnego od pracy, najpóźniej do końca okresu rozliczeniowego, w wymiarze o połowę wyższym niż liczba przepracowanych godzin nadliczbowych, jednakże nie może to spowodować obniżenia wynagrodzenia należnego pracownikowi za pełny miesięczny wymiar czasu pracy. - -§ 3. W przypadkach określonych w § 1 i 2 pracownikowi nie przysługuje dodatek za pracę w godzinach nadliczbowych. - - -Art. 1513. Pracownikowi, który ze względu na okoliczności przewidziane w art. 151 § 1 wykonywał pracę w dniu wolnym od pracy wynikającym z rozkładu czasu pracy w przeciętnie pięciodniowym tygodniu pracy, przysługuje w zamian inny dzień wolny od pracy udzielony pracownikowi do końca okresu rozliczeniowego, w terminie z nim uzgodnionym. - - -Art. 1514. § 1. Pracownicy zarządzający w imieniu pracodawcy zakładem pracy i kierownicy wyodrębnionych komórek organizacyjnych wykonują, w razie konieczności, pracę poza normalnymi godzinami pracy bez prawa do wynagrodzenia oraz dodatku z tytułu pracy w godzinach nadliczbowych, z zastrzeżeniem § 2. - -§ 2. Kierownikom wyodrębnionych komórek organizacyjnych za pracę w godzinach nadliczbowych przypadających w niedzielę i święto przysługuje prawo do wynagrodzenia oraz dodatku z tytułu pracy w godzinach nadliczbowych w wysokości określonej w art. 1511 § 1, jeżeli w zamian za pracę w takim dniu nie otrzymali innego dnia wolnego od pracy. - - -Art. 1515. § 1. Pracodawca może zobowiązać pracownika do pozostawania poza normalnymi godzinami pracy w gotowości do wykonywania pracy wynikającej z umowy o pracę w zakładzie pracy lub w innym miejscu wyznaczonym przez pracodawcę (dyżur). - -§ 2. Czasu dyżuru nie wlicza się do czasu pracy, jeżeli podczas dyżuru pracownik nie wykonywał pracy. Czas pełnienia dyżuru nie może naruszać prawa pracownika do odpoczynku, o którym mowa w art. 132 i 133. - -§ 3. Za czas dyżuru, z wyjątkiem dyżuru pełnionego w domu, pracownikowi przysługuje czas wolny od pracy w wymiarze odpowiadającym długości dyżuru, a w razie braku możliwości udzielenia czasu wolnego - wynagrodzenie wynikające z jego osobistego zaszeregowania, określonego stawką godzinową lub miesięczną, a jeżeli taki składnik wynagrodzenia nie został wyodrębniony przy określaniu warunków wynagradzania - 60% wynagrodzenia. - -§ 4. Przepisu § 2 zdanie drugie oraz § 3 nie stosuje się do pracowników zarządzających w imieniu pracodawcy zakładem pracy. - - -Art. 1516. § 1. W razie ustania stosunku pracy przed upływem okresu rozliczeniowego pracownikowi przysługuje, oprócz normalnego wynagrodzenia, prawo do dodatku, o którym mowa w art. 1511 § 1, jeżeli w okresie od początku okresu rozliczeniowego do dnia ustania stosunku pracy pracował w wymiarze godzin przekraczającym normy czasu pracy, o których mowa w art. 129. - -§ 2. Przepis § 1 stosuje się odpowiednio w razie nawiązania stosunku pracy w trakcie okresu rozliczeniowego. - - -Rozdział VI -Praca w porze nocnej - - -Art. 1517. § 1. Pora nocna obejmuje 8 godzin między godzinami 21.00 a 7.00. - -§ 2. Pracownik, którego rozkład czasu pracy obejmuje w każdej dobie co najmniej 3 godziny pracy w porze nocnej lub którego co najmniej 1/4 czasu pracy w okresie rozliczeniowym przypada na porę nocną, jest pracującym w nocy. - -§ 3. Czas pracy pracującego w nocy nie może przekraczać 8 godzin na dobę, jeżeli wykonuje prace szczególnie niebezpieczne albo związane z dużym wysiłkiem fizycznym lub umysłowym. - -§ 4. Wykaz prac, o których mowa w § 3, określa pracodawca w porozumieniu z zakładową organizacją związkową, a jeżeli u pracodawcy nie działa zakładowa organizacja związkowa - z przedstawicielami pracowników wybranymi w trybie przyjętym u danego pracodawcy, oraz po zasięgnięciu opinii lekarza sprawującego profilaktyczną opiekę zdrowotną nad pracownikami, uwzględniając konieczność zapewnienia bezpieczeństwa pracy i ochrony zdrowia pracowników. - -§ 5. Przepis § 3 nie dotyczy: - -1) pracowników zarządzających w imieniu pracodawcy zakładem pracy, -2) przypadków konieczności prowadzenia akcji ratowniczej w celu ochrony życia lub zdrowia ludzkiego, ochrony mienia lub środowiska albo usunięcia awarii. -§ 6. Na pisemny wniosek pracownika, o którym mowa w § 2, pracodawca informuje właściwego okręgowego inspektora pracy o zatrudnianiu pracowników pracujących w nocy. - - -Art. 1518. § 1. Pracownikowi wykonującemu pracę w porze nocnej przysługuje dodatek do wynagrodzenia za każdą godzinę pracy w porze nocnej w wysokości 20% stawki godzinowej wynikającej z minimalnego wynagrodzenia za pracę, ustalanego na podstawie odrębnych przepisów. - -§ 2. W stosunku do pracowników wykonujących pracę w porze nocnej stale poza zakładem pracy dodatek, o którym mowa w § 1, może być zastąpiony ryczałtem, którego wysokość odpowiada przewidywanemu wymiarowi pracy w porze nocnej. - - -Rozdział VII -Praca w niedziele i święta - - -Art. 1519. § 1. Dniami wolnymi od pracy są niedziele i święta określone w przepisach o dniach wolnych od pracy. - -§ 2. Za pracę w niedzielę i święto, w przypadkach, o których mowa w art. 15110, uważa się pracę wykonywaną między godziną 600 w tym dniu a godziną 600 w następnym dniu, chyba że u danego pracodawcy została ustalona inna godzina. - - -Art. 1519a. (uchylony) - - -Art. 1519b. Ograniczenia w wykonywaniu pracy w placówkach handlowych w niedziele i święta oraz w sobotę bezpośrednio poprzedzającą pierwszy dzień Wielkiej Nocy określają przepisy ustawy z dnia 10 stycznia 2018 r. o ograniczeniu handlu w niedziele i święta oraz w niektóre inne dni. - - -Art. 15110. Praca w niedziele i święta jest dozwolona: - -1) w razie konieczności prowadzenia akcji ratowniczej w celu ochrony życia lub zdrowia ludzkiego, ochrony mienia lub środowiska albo usunięcia awarii, -2) w ruchu ciągłym, -3) przy pracy zmianowej, -4) przy niezbędnych remontach, -5) w transporcie i w komunikacji, -6) w zakładowych strażach pożarnych i w zakładowych służbach ratowniczych, -7) przy pilnowaniu mienia lub ochronie osób, -8) w rolnictwie i hodowli, -9) przy wykonywaniu prac koniecznych ze względu na ich użyteczność społeczną i codzienne potrzeby ludności, w szczególności w: -a) (uchylona), -b) zakładach świadczących usługi dla ludności, -c) gastronomii, -d) zakładach hotelarskich, -e) jednostkach gospodarki komunalnej, -f) zakładach opieki zdrowotnej i innych placówkach służby zdrowia przeznaczonych dla osób, których stan zdrowia wymaga całodobowych lub całodziennych świadczeń zdrowotnych, -g) jednostkach organizacyjnych pomocy społecznej oraz jednostkach organizacyjnych wspierania rodziny i systemu pieczy zastępczej zapewniających całodobową opiekę, -h) zakładach prowadzących działalność w zakresie kultury, oświaty, turystyki i wypoczynku, -10) w stosunku do pracowników zatrudnionych w systemie czasu pracy, w którym praca jest świadczona wyłącznie w piątki, soboty, niedziele i święta, -11) przy wykonywaniu prac: -a) polegających na świadczeniu usług z wykorzystaniem środków komunikacji elektronicznej w rozumieniu przepisów o świadczeniu usług drogą elektroniczną lub urządzeń telekomunikacyjnych w rozumieniu przepisów prawa komunikacji elektronicznej, odbieranych poza terytorium Rzeczypospolitej Polskiej, jeżeli zgodnie z przepisami obowiązującymi odbiorcę usługi, dni, o których mowa w art. 1519 § 1, są u niego dniami pracy, -b) zapewniających możliwość świadczenia usług, o których mowa w lit. a. - -Art. 15111. § 1. Pracownikowi wykonującemu pracę w niedziele i święta, w przypadkach, o których mowa w art. 15110 pkt 1-9 i 11 oraz w przepisach ustawy, o której mowa w art. 1519b, pracodawca jest obowiązany zapewnić inny dzień wolny od pracy: - -1) w zamian za pracę w niedzielę - w okresie 6 dni kalendarzowych poprzedzających lub następujących po takiej niedzieli, -2) w zamian za pracę w święto - w ciągu okresu rozliczeniowego. -§ 2. Jeżeli nie jest możliwe wykorzystanie w terminie wskazanym w § 1 pkt 1 dnia wolnego od pracy w zamian za pracę w niedzielę, pracownikowi przysługuje dzień wolny od pracy do końca okresu rozliczeniowego, a w razie braku możliwości udzielenia dnia wolnego od pracy w tym terminie - dodatek do wynagrodzenia w wysokości określonej w art. 1511 § 1 pkt 1, za każdą godzinę pracy w niedzielę. - -§ 3. Jeżeli nie jest możliwe wykorzystanie w terminie wskazanym w § 1 pkt 2 dnia wolnego od pracy w zamian za pracę w święto, pracownikowi przysługuje dodatek do wynagrodzenia w wysokości określonej w art. 1511 § 1 pkt 1, za każdą godzinę pracy w święto. - -§ 4. Do pracy w święto przypadające w niedzielę stosuje się przepisy dotyczące pracy w niedzielę. - - -Art. 15112. Pracownik pracujący w niedziele powinien korzystać co najmniej raz na 4 tygodnie z niedzieli wolnej od pracy. Nie dotyczy to pracownika zatrudnionego w systemie czasu pracy, o którym mowa w art. 144. - -DZIAŁ SIÓDMY -Urlopy pracownicze - -Rozdział I -Urlopy wypoczynkowe - -Art. 152. § 1. Pracownikowi przysługuje prawo do corocznego, nieprzerwanego, płatnego urlopu wypoczynkowego, zwanego dalej „urlopem”. - -§ 2. Pracownik nie może zrzec się prawa do urlopu. - -Art. 153. - -§ 1. Pracownik podejmujący pracę po raz pierwszy, w roku kalendarzowym, w którym podjął pracę, uzyskuje prawo do urlopu z upływem każdego miesiąca pracy, w wymiarze 1/12 wymiaru urlopu przysługującego mu po przepracowaniu roku. - -§ 2. Prawo do kolejnych urlopów pracownik nabywa w każdym następnym roku kalendarzowym. - -Art. 154. - -§ 1. Wymiar urlopu wynosi: - -1) 20 dni - jeżeli pracownik jest zatrudniony krócej niż 10 lat, -2) 26 dni - jeżeli pracownik jest zatrudniony co najmniej 10 lat. -§ 2. Wymiar urlopu dla pracownika zatrudnionego w niepełnym wymiarze czasu pracy ustala się proporcjonalnie do wymiaru czasu pracy tego pracownika, biorąc za podstawę wymiar urlopu określony w § 1; niepełny dzień urlopu zaokrągla się w górę do pełnego dnia. - -§ 3. Wymiar urlopu w danym roku kalendarzowym, ustalony na podstawie § 1 i 2, nie może przekroczyć wymiaru określonego w § 1. - -Art. 1541. § 1. Do okresu zatrudnienia, od którego zależy prawo do urlopu i wymiar urlopu, wlicza się okresy poprzedniego zatrudnienia, bez względu na przerwy w zatrudnieniu oraz sposób ustania stosunku pracy. - -§ 2. W przypadku jednoczesnego pozostawania w dwóch lub więcej stosunkach pracy wliczeniu podlega także okres poprzedniego niezakończonego zatrudnienia w części przypadającej przed nawiązaniem drugiego lub kolejnego stosunku pracy. - - -Art. 1542. § 1. Urlopu udziela się w dni, które są dla pracownika dniami pracy, zgodnie z obowiązującym go rozkładem czasu pracy, w wymiarze godzinowym, odpowiadającym dobowemu wymiarowi czasu pracy pracownika w danym dniu, z zastrzeżeniem § 4. - -§ 2. Przy udzielaniu urlopu zgodnie z § 1, jeden dzień urlopu odpowiada 8 godzinom pracy. - -§ 3. Przepis § 1 i 2 stosuje się odpowiednio do pracownika, dla którego dobowa norma czasu pracy, wynikająca z odrębnych przepisów, jest niższa niż 8 godzin. - -§ 4. Udzielenie pracownikowi urlopu w dniu pracy w wymiarze godzinowym odpowiadającym części dobowego wymiaru czasu pracy jest dopuszczalne jedynie w przypadku, gdy część urlopu pozostała do wykorzystania jest niższa niż pełny dobowy wymiar czasu pracy pracownika w dniu, na który ma być udzielony urlop. - -Art. 155. § 1. Do okresu pracy, od którego zależy wymiar urlopu, wlicza się z tytułu ukończenia: - -1) zasadniczej lub innej równorzędnej szkoły zawodowej - przewidziany programem nauczania czas trwania nauki, nie więcej jednak niż 3 lata, -2) średniej szkoły zawodowej - przewidziany programem nauczania czas trwania nauki, nie więcej jednak niż 5 lat, -3) średniej szkoły zawodowej dla absolwentów zasadniczych (równorzędnych) szkół zawodowych - 5 lat, -4) średniej szkoły ogólnokształcącej - 4 lata, -5) szkoły policealnej - 6 lat, -6) szkoły wyższej - 8 lat. -Okresy nauki, o których mowa w pkt 1-6, nie podlegają sumowaniu. -§ 2. Jeżeli pracownik pobierał naukę w czasie zatrudnienia, do okresu pracy, od którego zależy wymiar urlopu, wlicza się bądź okres zatrudnienia, w którym była pobierana nauka, bądź okres nauki, zależnie od tego, co jest korzystniejsze dla pracownika. - -Art. 1551. § 1. W roku kalendarzowym, w którym ustaje stosunek pracy z pracownikiem uprawnionym do kolejnego urlopu, pracownikowi przysługuje urlop: - -1) u dotychczasowego pracodawcy - w wymiarze proporcjonalnym do okresu przepracowanego u tego pracodawcy w roku ustania stosunku pracy, chyba że przed ustaniem tego stosunku pracownik wykorzystał urlop w przysługującym mu lub w wyższym wymiarze, -2) u kolejnego pracodawcy - w wymiarze: -a) proporcjonalnym do okresu pozostałego do końca danego roku kalendarzowego - w razie zatrudnienia na czas nie krótszy niż do końca danego roku kalendarzowego, -b) proporcjonalnym do okresu zatrudnienia w danym roku kalendarzowym - w razie zatrudnienia na czas krótszy niż do końca danego roku kalendarzowego, -z zastrzeżeniem § 2. -§ 2. Pracownikowi, który przed ustaniem stosunku pracy w ciągu roku kalendarzowego wykorzystał urlop w wymiarze wyższym niż wynikający z § 1 pkt 1, przysługuje u kolejnego pracodawcy urlop w odpowiednio niższym wymiarze; łączny wymiar urlopu w roku kalendarzowym nie może być jednak niższy niż wynikający z okresu przepracowanego w tym roku u wszystkich pracodawców. - -§ 21. Przepis § 1 pkt 2 stosuje się odpowiednio do pracownika podejmującego pracę u kolejnego pracodawcy w ciągu innego roku kalendarzowego niż rok, w którym ustał jego stosunek pracy z poprzednim pracodawcą. - -§ 3. (skreślony). - -Art. 1552. - -§ 1. Przepis art. 1551 § 1 pkt 2 stosuje się odpowiednio do pracownika powracającego do pracy u dotychczasowego pracodawcy w ciągu roku kalendarzowego po trwającym co najmniej 1 miesiąc okresie: - -1) urlopu bezpłatnego, -2) urlopu wychowawczego, -3) pełnienia zasadniczej służby wojskowej, pełnienia terytorialnej służby wojskowej rotacyjnie, pełnienia służby w aktywnej rezerwie w dniach tej służby, odbywania ćwiczeń wojskowych w ramach pasywnej rezerwy albo pełnienia służby zastępczej; -4) tymczasowego aresztowania, -5) odbywania kary pozbawienia wolności, -6) nieusprawiedliwionej nieobecności w pracy. -§ 2. Jeżeli okres, o którym mowa w § 1 pkt 1 i 3-6, przypada po nabyciu przez pracownika prawa do urlopu w danym roku kalendarzowym, wymiar urlopu pracownika powracającego do pracy w ciągu tego samego roku kalendarzowego ulega proporcjonalnemu obniżeniu, chyba że przed rozpoczęciem tego okresu pracownik wykorzystał urlop w przysługującym mu lub w wyższym wymiarze. - - -Art. 1552a. § 1. Przy ustalaniu wymiaru urlopu na podstawie art. 1551 i 1552 kalendarzowy miesiąc pracy odpowiada 1/12 wymiaru urlopu przysługującego pracownikowi zgodnie z art. 154 § 1 i 2. - -§ 2. Niepełny kalendarzowy miesiąc pracy zaokrągla się w górę do pełnego miesiąca. - -§ 3. Jeżeli ustanie stosunku pracy u dotychczasowego pracodawcy i nawiązanie takiego stosunku u kolejnego pracodawcy następuje w tym samym miesiącu kalendarzowym, zaokrąglenia do pełnego miesiąca dokonuje dotychczasowy pracodawca. - -Art. 1553. § 1. Przy ustalaniu wymiaru urlopu na podstawie art. 1551 i 1552 niepełny dzień urlopu zaokrągla się w górę do pełnego dnia. - -§ 2. Wymiar urlopu należny pracownikowi w danym roku kalendarzowym nie może przekroczyć wymiaru wynikającego z art. 154 § 1 i 2. - -Art. 156. (skreślony). - -Art. 157. (skreślony). - -Art. 158. Pracownikowi, który wykorzystał urlop za dany rok kalendarzowy, a następnie uzyskał w ciągu tego roku prawo do urlopu w wyższym wymiarze, przysługuje urlop uzupełniający. - -Art. 159. (uchylony). - -Art. 160. (skreślony). - -Art. 161. Pracodawca jest obowiązany udzielić pracownikowi urlopu w tym roku kalendarzowym, w którym pracownik uzyskał do niego prawo. - -Art. 162. Na wniosek pracownika urlop może być podzielony na części. W takim jednak przypadku co najmniej jedna część wypoczynku powinna trwać nie mniej niż 14 kolejnych dni kalendarzowych. - -Art. 163. § 1. Urlopy powinny być udzielane zgodnie z planem urlopów. Plan urlopów ustala pracodawca, biorąc pod uwagę wnioski pracowników i konieczność zapewnienia normalnego toku pracy. Planem urlopów nie obejmuje się części urlopu udzielanego pracownikowi zgodnie z art. 1672. - -§ 11. Pracodawca nie ustala planu urlopów, jeżeli zakładowa organizacja związkowa wyraziła na to zgodę; dotyczy to także pracodawcy, u którego nie działa zakładowa organizacja związkowa. W takich przypadkach pracodawca ustala termin urlopu po porozumieniu z pracownikiem. Przepis § 1 zdanie drugie i trzecie stosuje się odpowiednio. - -§ 2. Plan urlopów podaje się do wiadomości pracowników w sposób przyjęty u danego pracodawcy. - -§ 3. Na wniosek pracownicy udziela się jej urlopu bezpośrednio po urlopie macierzyńskim; dotyczy to także pracownika - ojca wychowującego dziecko lub pracownika - innego członka najbliższej rodziny, o którym mowa w art. 1751 pkt 3, który korzysta z urlopu macierzyńskiego. - -Art. 164. § 1. Przesunięcie terminu urlopu może nastąpić na wniosek pracownika umotywowany ważnymi przyczynami. - -§ 2. Przesunięcie terminu urlopu jest także dopuszczalne z powodu szczególnych potrzeb pracodawcy, jeżeli nieobecność pracownika spowodowałaby poważne zakłócenia toku pracy. - -Art. 165. Jeżeli pracownik nie może rozpocząć urlopu w ustalonym terminie z przyczyn usprawiedliwiających nieobecność w pracy, a w szczególności z powodu: - -1) czasowej niezdolności do pracy wskutek choroby, -2) odosobnienia w związku z chorobą zakaźną, -3) powołania na ćwiczenia wojskowe w ramach pasywnej rezerwy, stawienia się do pełnienia terytorialnej służby wojskowej rotacyjnie albo stawienia się do pełnienia służby w aktywnej rezerwie, na czas do 3 miesięcy, -4) urlopu macierzyńskiego, -pracodawca jest obowiązany przesunąć urlop na termin późniejszy. -Art. 166. Część urlopu nie wykorzystaną z powodu: - -1) czasowej niezdolności do pracy wskutek choroby, -2) odosobnienia w związku z chorobą zakaźną, -3) odbywania ćwiczeń wojskowych w ramach pasywnej rezerwy, pełnienia terytorialnej służby wojskowej rotacyjnie albo pełnienia służby w aktywnej rezerwie, przez czas do 3 miesięcy, -4) urlopu macierzyńskiego, -pracodawca jest obowiązany udzielić w terminie późniejszym. -Art. 167. § 1. Pracodawca może odwołać pracownika z urlopu tylko wówczas, gdy jego obecności w zakładzie wymagają okoliczności nieprzewidziane w chwili rozpoczynania urlopu. - -§ 2. Pracodawca jest obowiązany pokryć koszty poniesione przez pracownika w bezpośrednim związku z odwołaniem go z urlopu. - - -Art. 1671. W okresie wypowiedzenia umowy o pracę pracownik jest obowiązany wykorzystać przysługujący mu urlop, jeżeli w tym okresie pracodawca udzieli mu urlopu. W takim przypadku wymiar udzielonego urlopu, z wyłączeniem urlopu zaległego, nie może przekraczać wymiaru wynikającego z przepisów art. 1551. - - -Art. 1672. Pracodawca jest obowiązany udzielić na żądanie pracownika i w terminie przez niego wskazanym nie więcej niż 4 dni urlopu w każdym roku kalendarzowym. Pracownik zgłasza żądanie udzielenia urlopu najpóźniej w dniu rozpoczęcia urlopu. - - -Art. 1673. Łączny wymiar urlopu wykorzystanego przez pracownika na zasadach i w trybie określonych w art. 1672 nie może przekroczyć w roku kalendarzowym 4 dni, niezależnie od liczby pracodawców, z którymi pracownik pozostaje w danym roku w kolejnych stosunkach pracy. - -Art. 168. Urlopu niewykorzystanego w terminie ustalonym zgodnie z art. 163 należy pracownikowi udzielić najpóźniej do dnia 30 września następnego roku kalendarzowego; nie dotyczy to części urlopu udzielanego zgodnie z art. 1672. - -Art. 169. (skreślony). - -Art. 170. (skreślony). - -Art. 171. § 1. W przypadku niewykorzystania przysługującego urlopu w całości lub w części z powodu rozwiązania lub wygaśnięcia stosunku pracy pracownikowi przysługuje ekwiwalent pieniężny. - -§ 2. (uchylony). - -§ 3. Pracodawca nie ma obowiązku wypłacenia ekwiwalentu pieniężnego, o którym mowa w § 1, w przypadku gdy strony postanowią o wykorzystaniu urlopu w czasie pozostawania pracownika w stosunku pracy na podstawie kolejnej umowy o pracę zawartej z tym samym pracodawcą bezpośrednio po rozwiązaniu lub wygaśnięciu poprzedniej umowy o pracę z tym pracodawcą. - -Art. 172. Za czas urlopu pracownikowi przysługuje wynagrodzenie, jakie by otrzymał, gdyby w tym czasie pracował. Zmienne składniki wynagrodzenia mogą być obliczane na podstawie przeciętnego wynagrodzenia z okresu 3 miesięcy poprzedzających miesiąc rozpoczęcia urlopu; w przypadkach znacznego wahania wysokości wynagrodzenia okres ten może być przedłużony do 12 miesięcy. - - -Art. 1721. § 1. Jeżeli pracodawca na podstawie odrębnych przepisów jest obowiązany objąć pracownika ubezpieczeniem gwarantującym mu otrzymanie świadczenia pieniężnego za czas urlopu, pracownikowi nie przysługuje wynagrodzenie przewidziane w art. 172 lub ekwiwalent pieniężny, o którym mowa w art. 171. - -§ 2. Jeżeli świadczenie pieniężne za czas urlopu, o którym mowa w § 1, jest niższe od wynagrodzenia przewidzianego w art. 172 lub od ekwiwalentu pieniężnego, o którym mowa w art. 171, pracodawca jest obowiązany wypłacić pracownikowi kwotę stanowiącą różnicę między tymi należnościami. - -Art. 173. Minister Pracy i Polityki Socjalnej określi, w drodze rozporządzenia, szczegółowe zasady udzielania urlopu wypoczynkowego, ustalania i wypłacania wynagrodzenia za czas urlopu oraz ekwiwalentu pieniężnego za urlop. - - -Rozdział Ia -Urlop opiekuńczy - - -Art. 1731. § 1. Pracownikowi przysługuje w ciągu roku kalendarzowego urlop opiekuńczy, w wymiarze 5 dni, w celu zapewnienia osobistej opieki lub wsparcia osobie będącej członkiem rodziny lub zamieszkującej w tym samym gospodarstwie domowym, która wymaga opieki lub wsparcia z poważnych względów medycznych. - -§ 2. Za członka rodziny, o którym mowa w § 1, uważa się syna, córkę, matkę, ojca lub małżonka. - -§ 3. Urlopu, o którym mowa w § 1, udziela się w dni, które są dla pracownika dniami pracy, zgodnie z obowiązującym go rozkładem czasu pracy. - -§ 4. Urlopu, o którym mowa w § 1, udziela się na wniosek pracownika złożony w postaci papierowej lub elektronicznej w terminie nie krótszym niż 1 dzień przed rozpoczęciem korzystania z tego urlopu. - -§ 5. We wniosku wskazuje się imię i nazwisko osoby, która wymaga opieki lub wsparcia z poważnych względów medycznych, przyczynę konieczności zapewnienia osobistej opieki lub wsparcia przez pracownika oraz w przypadku członka rodziny - stopień pokrewieństwa z pracownikiem lub w przypadku osoby niebędącej członkiem rodziny - adres zamieszkania tej osoby. - - -Art. 1732. Okres urlopu opiekuńczego wlicza się do okresu zatrudnienia, od którego zależą uprawnienia pracownicze. - - -Art. 1733. Do pracownika, o którym mowa w art. 1731 § 1, stosuje się odpowiednio przepisy art. 177 § 1, 11, 4 i 41, art. 1864 i art. 1881. - -Rozdział II -Urlopy bezpłatne - -Art. 174. § 1. Na pisemny wniosek pracownika pracodawca może udzielić mu urlopu bezpłatnego. - -§ 2. Okresu urlopu bezpłatnego nie wlicza się do okresu pracy, od którego zależą uprawnienia pracownicze. - -§ 3. Przy udzielaniu urlopu bezpłatnego, dłuższego niż 3 miesiące, strony mogą przewidzieć dopuszczalność odwołania pracownika z urlopu z ważnych przyczyn. - -§ 4. Przepisów § 2 i 3 nie stosuje się w przypadkach uregulowanych odmiennie przepisami szczególnymi. - -Art. 1741. § 1. Za zgodą pracownika, wyrażoną na piśmie, pracodawca może udzielić pracownikowi urlopu bezpłatnego w celu wykonywania pracy u innego pracodawcy przez okres ustalony w zawartym w tej sprawie porozumieniu między pracodawcami. - -§ 2. Okres urlopu bezpłatnego, o którym mowa w § 1, wlicza się do okresu pracy, od którego zależą uprawnienia pracownicze u dotychczasowego pracodawcy. - -Art. 175. (skreślony). - -DZIAŁ ÓSMY -Uprawnienia pracowników związane z rodzicielstwem - - -Art. 1751. Ilekroć w przepisach działu jest mowa o: - -1) ubezpieczonej - matce dziecka - należy przez to rozumieć matkę dziecka niebędącą pracownicą, objętą ubezpieczeniem społecznym w razie choroby i macierzyństwa, określonym w ustawie z dnia 13 października 1998 r. o systemie ubezpieczeń społecznych; -2) ubezpieczonym - ojcu dziecka - należy przez to rozumieć ojca dziecka niebędącego pracownikiem, objętego ubezpieczeniem społecznym w razie choroby i macierzyństwa, określonym w ustawie z dnia 13 października 1998 r. o systemie ubezpieczeń społecznych; -3) pracowniku - innym członku najbliższej rodziny - należy przez to rozumieć będącego pracownikiem, innego niż pracownik - ojciec wychowujący dziecko, członka najbliższej rodziny, o którym mowa w art. 29 ust. 5 ustawy z dnia 25 czerwca 1999 r. o świadczeniach pieniężnych z ubezpieczenia społecznego w razie choroby i macierzyństwa; -4) ubezpieczonym - innym członku najbliższej rodziny - należy przez to rozumieć niebędącego pracownikiem, innego niż ubezpieczony - ojciec dziecka, ubezpieczonego członka najbliższej rodziny, o którym mowa w art. 29 ust. 5 ustawy z dnia 25 czerwca 1999 r. o świadczeniach pieniężnych z ubezpieczenia społecznego w razie choroby i macierzyństwa. -Art. 176. § 1. Kobiety w ciąży i kobiety karmiące dziecko piersią nie mogą wykonywać prac uciążliwych, niebezpiecznych lub szkodliwych dla zdrowia, mogących mieć niekorzystny wpływ na ich zdrowie, przebieg ciąży lub karmienie dziecka piersią. - -§ 2. Rada Ministrów określi, w drodze rozporządzenia, wykaz prac, o których mowa w § 1, obejmujący prace: - -1) związane z nadmiernym wysiłkiem fizycznym, w tym ręcznym transportem ciężarów, -2) mogące mieć niekorzystny wpływ ze względu na sposób i warunki ich wykonywania, z uwzględnieniem rodzajów czynników występujących w środowisku pracy i poziomu ich występowania -- kierując się aktualną wiedzą na temat wpływu warunków wykonywania pracy i czynników występujących w środowisku pracy na zdrowie kobiet, przebieg ciąży lub karmienie dziecka piersią. -Art. 177. § 1. W okresie ciąży oraz w okresie urlopu macierzyńskiego, a także od dnia złożenia przez pracownika wniosku o udzielenie urlopu macierzyńskiego albo jego części, urlopu na warunkach urlopu macierzyńskiego albo jego części, urlopu ojcowskiego albo jego części, urlopu rodzicielskiego albo jego części - do dnia zakończenia tego urlopu pracodawca nie może: - -1) prowadzić przygotowań do wypowiedzenia lub rozwiązania bez wypowiedzenia stosunku pracy z tą pracownicą lub tym pracownikiem; -2) wypowiedzieć ani rozwiązać stosunku pracy z tą pracownicą lub tym pracownikiem, chyba że zachodzą przyczyny uzasadniające rozwiązanie umowy bez wypowiedzenia z ich winy i reprezentująca pracownicę lub pracownika zakładowa organizacja związkowa wyraziła zgodę na rozwiązanie umowy. -§ 11. W przypadku złożenia przez pracownika wniosku, o którym mowa w § 1, wcześniej niż w terminach określonych w art. 180 § 9, art. 1821d § 1 oraz art. 1823 § 2 zakaz, o którym mowa w § 1, zaczyna obowiązywać na: - -1) 14 dni przed rozpoczęciem korzystania z części urlopu macierzyńskiego oraz części urlopu na warunkach urlopu macierzyńskiego; -2) 21 dni przed rozpoczęciem korzystania z urlopu rodzicielskiego albo jego części; -3) 7 dni przed rozpoczęciem korzystania z urlopu ojcowskiego albo jego części. -§ 2. (uchylony) - -§ 3. Umowa o pracę zawarta na czas określony albo na okres próbny przekraczający jeden miesiąc, która uległaby rozwiązaniu po upływie trzeciego miesiąca ciąży, ulega przedłużeniu do dnia porodu. - -§ 31. Przepisu § 3 nie stosuje się do umowy o pracę na czas określony zawartej w celu zastępstwa pracownika w czasie jego usprawiedliwionej nieobecności w pracy. - -§ 4. Rozwiązanie przez pracodawcę umowy o pracę za wypowiedzeniem w okresie ciąży oraz w okresie urlopu macierzyńskiego, a także od dnia złożenia przez pracownika wniosku o udzielenie urlopu macierzyńskiego albo jego części, urlopu na warunkach urlopu macierzyńskiego albo jego części, urlopu ojcowskiego albo jego części, urlopu rodzicielskiego albo jego części - do dnia zakończenia tego urlopu może nastąpić tylko w razie ogłoszenia upadłości lub likwidacji pracodawcy. Pracodawca jest obowiązany uzgodnić z reprezentującą pracownicę lub pracownika zakładową organizacją związkową termin rozwiązania umowy o pracę. W razie niemożności zapewnienia w tym okresie innego zatrudnienia, pracownicy lub pracownikowi przysługują świadczenia określone w odrębnych przepisach. Okres pobierania tych świadczeń wlicza się do okresu zatrudnienia, od którego zależą uprawnienia pracownicze. - -§ 41. Istnienie przyczyn, o których mowa w § 1 pkt 2 i § 4, udowodni pracodawca. - -§ 5. (uchylony) - -Art. 178. - -§ 1. Pracownicy w ciąży nie wolno zatrudniać w godzinach nadliczbowych ani w porze nocnej. Pracownicy w ciąży nie wolno bez jej zgody delegować poza stałe miejsce pracy ani zatrudniać w systemie czasu pracy, o którym mowa w art. 139. - -§ 2. Pracownika wychowującego dziecko do ukończenia przez nie 8 roku życia nie wolno bez jego zgody zatrudniać w godzinach nadliczbowych, w porze nocnej, w systemie czasu pracy, o którym mowa w art. 139, oraz delegować poza stałe miejsce pracy. - - -Art. 1781. Pracodawca zatrudniający pracownicę w porze nocnej jest obowiązany na okres jej ciąży zmienić rozkład czasu pracy w sposób umożliwiający wykonywanie pracy poza porą nocną, a jeżeli jest to niemożliwe lub niecelowe, przenieść pracownicę do innej pracy, której wykonywanie nie wymaga pracy w porze nocnej; w razie braku takich możliwości pracodawca jest obowiązany zwolnić pracownicę na czas niezbędny z obowiązku świadczenia pracy. Przepisy art. 179 § 4-6 stosuje się odpowiednio. - -Art. 179. - -§ 1. Pracodawca zatrudniający pracownicę w ciąży lub karmiącą dziecko piersią przy pracy wymienionej w przepisach wydanych na podstawie art. 176 § 2, wzbronionej takiej pracownicy bez względu na stopień narażenia na czynniki szkodliwe dla zdrowia lub niebezpieczne, jest obowiązany przenieść pracownicę do innej pracy, a jeżeli jest to niemożliwe, zwolnić ją na czas niezbędny z obowiązku świadczenia pracy. - -§ 2. Pracodawca zatrudniający pracownicę w ciąży lub karmiącą dziecko piersią przy pozostałych pracach wymienionych w przepisach wydanych na podstawie art. 176 § 2 jest obowiązany dostosować warunki pracy do wymagań określonych w tych przepisach lub tak ograniczyć czas pracy, aby wyeliminować zagrożenia dla zdrowia lub bezpieczeństwa pracownicy. Jeżeli dostosowanie warunków pracy na dotychczasowym stanowisku pracy lub skrócenie czasu pracy jest niemożliwe lub niecelowe, pracodawca jest obowiązany przenieść pracownicę do innej pracy, a w razie braku takiej możliwości zwolnić pracownicę na czas niezbędny z obowiązku świadczenia pracy. - -§ 3. Przepis § 2 stosuje się odpowiednio do pracodawcy w przypadku, gdy przeciwwskazania zdrowotne do wykonywania dotychczasowej pracy przez pracownicę w ciąży lub karmiącą dziecko piersią wynikają z orzeczenia lekarskiego. - -§ 4. W razie gdy zmiana warunków pracy na dotychczas zajmowanym stanowisku pracy, skrócenie czasu pracy lub przeniesienie pracownicy do innej pracy powoduje obniżenie wynagrodzenia, pracownicy przysługuje dodatek wyrównawczy. - -§ 5. Pracownica w okresie zwolnienia z obowiązku świadczenia pracy zachowuje prawo do dotychczasowego wynagrodzenia. - -§ 6. Po ustaniu przyczyn uzasadniających przeniesienie pracownicy do innej pracy, skrócenie jej czasu pracy lub zwolnienie z obowiązku świadczenia pracy, pracodawca jest obowiązany zatrudnić pracownicę przy pracy i w wymiarze czasu pracy określonych w umowie o pracę. - -§ 7. Minister właściwy do spraw zdrowia określi, w drodze rozporządzenia, sposób i tryb wydawania zaświadczeń lekarskich stwierdzających przeciwwskazania zdrowotne do wykonywania dotychczasowej pracy przez pracownicę w ciąży lub karmiącą dziecko piersią, uwzględniając zagrożenia dla jej zdrowia lub bezpieczeństwa występujące w środowisku pracy. - - -Art. 1791. (uchylony) - - -Art. 1792. (uchylony). - - -Art. 1793. (uchylony). - - -Art. 1794. (uchylony). - - -Art. 1795. (uchylony). - -Art. 180. - -§ 1. Pracownicy przysługuje urlop macierzyński w wymiarze: - -1) 20 tygodni - w przypadku urodzenia jednego dziecka przy jednym porodzie; -2) 31 tygodni - w przypadku urodzenia dwojga dzieci przy jednym porodzie; -3) 33 tygodni - w przypadku urodzenia trojga dzieci przy jednym porodzie; -4) 35 tygodni - w przypadku urodzenia czworga dzieci przy jednym porodzie; -5) 37 tygodni - w przypadku urodzenia pięciorga i więcej dzieci przy jednym porodzie. -§ 2. Przed przewidywaną datą porodu pracownica może wykorzystać nie więcej niż 6 tygodni urlopu macierzyńskiego. - -§ 3. Po porodzie przysługuje urlop macierzyński niewykorzystany przed porodem aż do wyczerpania wymiaru, o którym mowa w § 1. - -§ 4. Pracownica, po wykorzystaniu po porodzie co najmniej 14 tygodni urlopu macierzyńskiego, ma prawo zrezygnować z pozostałej części tego urlopu i powrócić do pracy, jeżeli: - -1) pozostałą część urlopu macierzyńskiego wykorzysta pracownik - ojciec wychowujący dziecko; -2) przez okres odpowiadający okresowi, który pozostał do końca urlopu macierzyńskiego, osobistą opiekę nad dzieckiem będzie sprawował ubezpieczony - ojciec dziecka, który w celu sprawowania tej opieki przerwał działalność zarobkową. -§ 5. Pracownikowi - ojcu wychowującemu dziecko przysługuje, w przypadku rezygnacji przez ubezpieczoną - matkę dziecka z pobierania zasiłku macierzyńskiego po wykorzystaniu przez nią tego zasiłku za okres co najmniej 14 tygodni po porodzie, prawo do części urlopu macierzyńskiego przypadającej po dniu rezygnacji przez ubezpieczoną - matkę dziecka z pobierania zasiłku macierzyńskiego. - -§ 6. Pracownica legitymująca się orzeczeniem o niezdolności do samodzielnej egzystencji, po wykorzystaniu po porodzie co najmniej 8 tygodni urlopu macierzyńskiego, ma prawo zrezygnować z pozostałej części tego urlopu, jeżeli: - -1) pozostałą część urlopu macierzyńskiego wykorzysta pracownik - ojciec wychowujący dziecko albo pracownik - inny członek najbliższej rodziny; -2) przez okres odpowiadający okresowi, który pozostał do końca urlopu macierzyńskiego, osobistą opiekę nad dzieckiem będzie sprawował ubezpieczony - ojciec dziecka albo ubezpieczony - inny członek najbliższej rodziny, który w celu sprawowania tej opieki przerwał działalność zarobkową. -§ 7. Pracownikowi - ojcu wychowującemu dziecko albo pracownikowi - innemu członkowi najbliższej rodziny przysługuje, w przypadku rezygnacji przez ubezpieczoną - matkę dziecka, legitymującą się orzeczeniem o niezdolności do samodzielnej egzystencji, z pobierania zasiłku macierzyńskiego po wykorzystaniu przez nią tego zasiłku za okres co najmniej 8 tygodni po porodzie, prawo do części urlopu macierzyńskiego przypadającej po dniu rezygnacji przez ubezpieczoną - matkę dziecka z pobierania zasiłku macierzyńskiego. - -§ 8. W przypadkach, o których mowa w § 4 i 6, pracownica składa pracodawcy wniosek w postaci papierowej lub elektronicznej w sprawie rezygnacji z korzystania z części urlopu macierzyńskiego w terminie nie krótszym niż 7 dni przed przystąpieniem do pracy. Do wniosku dołącza się dokumenty określone w przepisach wydanych na podstawie art. 1868a. Pracodawca jest obowiązany uwzględnić wniosek pracownicy. - -§ 9. Części urlopu macierzyńskiego, o której mowa w § 4 pkt 1, § 5, § 6 pkt 1 i § 7, pracodawca udziela, odpowiednio, pracownikowi - ojcu wychowującemu dziecko albo pracownikowi - innemu członkowi najbliższej rodziny, na wniosek w postaci papierowej lub elektronicznej składany w terminie nie krótszym niż 14 dni przed rozpoczęciem korzystania z części urlopu. Do wniosku dołącza się dokumenty określone w przepisach wydanych na podstawie art. 1868a. Pracodawca jest obowiązany uwzględnić wniosek pracownika - ojca wychowującego dziecko albo pracownika - innego członka najbliższej rodziny. - -§ 10. Pracownica, która przebywa w szpitalu albo innym zakładzie leczniczym podmiotu leczniczego wykonującego działalność leczniczą w rodzaju stacjonarne i całodobowe świadczenia zdrowotne ze względu na stan zdrowia uniemożliwiający jej sprawowanie osobistej opieki nad dzieckiem, po wykorzystaniu po porodzie co najmniej 8 tygodni urlopu macierzyńskiego, może przerwać urlop macierzyński na okres pobytu w tym szpitalu albo zakładzie leczniczym, jeżeli: - -1) część urlopu macierzyńskiego za ten okres wykorzysta pracownik - ojciec wychowujący dziecko albo pracownik - inny członek najbliższej rodziny; -2) osobistą opiekę nad dzieckiem w tym okresie będzie sprawował ubezpieczony - ojciec dziecka albo ubezpieczony - inny członek najbliższej rodziny, który w celu sprawowania tej opieki przerwał działalność zarobkową. -§ 11. Pracownikowi - ojcu wychowującemu dziecko albo pracownikowi - innemu członkowi najbliższej rodziny przysługuje, w przypadku przerwania przez ubezpieczoną - matkę dziecka pobierania zasiłku macierzyńskiego po wykorzystaniu przez nią tego zasiłku za okres co najmniej 8 tygodni po porodzie, prawo do części urlopu macierzyńskiego odpowiadającej okresowi, w którym ubezpieczona - matka dziecka przebywa w szpitalu albo innym zakładzie leczniczym podmiotu leczniczego wykonującego działalność leczniczą w rodzaju stacjonarne i całodobowe świadczenia zdrowotne ze względu na stan zdrowia uniemożliwiający jej sprawowanie osobistej opieki nad dzieckiem. - -§ 12. W przypadku zgonu pracownicy w czasie urlopu macierzyńskiego albo ubezpieczonej - matki dziecka w czasie pobierania zasiłku macierzyńskiego za okres odpowiadający okresowi tego urlopu, pracownikowi - ojcu wychowującemu dziecko albo pracownikowi - innemu członkowi najbliższej rodziny, przysługuje prawo do części urlopu macierzyńskiego przypadającej po dniu zgonu pracownicy albo ubezpieczonej - matki dziecka. - -§ 13. W przypadku porzucenia dziecka przez pracownicę w czasie urlopu macierzyńskiego albo ubezpieczoną - matkę dziecka w czasie pobierania zasiłku macierzyńskiego za okres odpowiadający okresowi tego urlopu, pracownikowi - ojcu wychowującemu dziecko albo pracownikowi - innemu członkowi najbliższej rodziny, przysługuje prawo do części urlopu macierzyńskiego przypadającej po dniu porzucenia dziecka, nie wcześniej jednak niż po wykorzystaniu przez: - -1) pracownicę, po porodzie, co najmniej 8 tygodni urlopu macierzyńskiego; -2) ubezpieczoną - matkę dziecka, zasiłku macierzyńskiego za okres co najmniej 8 tygodni po porodzie. -§ 14. Łączny wymiar urlopu macierzyńskiego oraz urlopu macierzyńskiego i okresu pobierania zasiłku macierzyńskiego za okres odpowiadający okresowi tego urlopu w okolicznościach, o których mowa w § 4-7 i § 10-13, nie może przekroczyć wymiaru urlopu macierzyńskiego, o którym mowa w § 1. - -§ 15. W przypadku: - -1) zgonu matki dziecka nieobjętej ubezpieczeniem społecznym w razie choroby i macierzyństwa, określonym w ustawie z dnia 13 października 1998 r. o systemie ubezpieczeń społecznych, albo nieposiadającej tytułu do objęcia takim ubezpieczeniem, -2) porzucenia dziecka przez matkę nieobjętą ubezpieczeniem, o którym mowa w pkt 1, albo nieposiadającą tytułu do objęcia takim ubezpieczeniem, -3) niemożności sprawowania osobistej opieki nad dzieckiem przez matkę nieobjętą ubezpieczeniem, o którym mowa w pkt 1, albo nieposiadającą tytułu do objęcia takim ubezpieczeniem, legitymującą się orzeczeniem o niezdolności do samodzielnej egzystencji -- pracownikowi - ojcu wychowującemu dziecko albo pracownikowi - innemu członkowi najbliższej rodziny przysługuje prawo do części urlopu macierzyńskiego przypadającej po dniu zgonu matki dziecka, porzucenia przez nią dziecka albo powstania niezdolności do samodzielnej egzystencji. -§ 16. W okolicznościach, o których mowa w § 10 pkt 1 i § 11-13 i 15, części urlopu macierzyńskiego udziela się na wniosek składany w postaci papierowej lub elektronicznej przez pracownika - ojca wychowującego dziecko albo pracownika - innego członka najbliższej rodziny. Do wniosku dołącza się dokumenty określone w przepisach wydanych na podstawie art. 1868a. Pracodawca jest obowiązany uwzględnić wniosek pracownika - ojca wychowującego dziecko albo pracownika - innego członka najbliższej rodziny. - -§ 17. W przypadku podjęcia przez matkę dziecka nieposiadającą tytułu do objęcia ubezpieczeniem społecznym w razie choroby i macierzyństwa, określonym w ustawie z dnia 13 października 1998 r. o systemie ubezpieczeń społecznych, zatrudnienia w wymiarze nie niższym niż połowa pełnego wymiaru czasu pracy, pracownikowi - ojcu wychowującemu dziecko przysługuje, w okresie trwania zatrudnienia matki dziecka, prawo do części urlopu macierzyńskiego przypadającej od dnia podjęcia zatrudnienia przez matkę dziecka aż do wyczerpania wymiaru, o którym mowa w § 1. Przepis § 9 stosuje się odpowiednio. - - -Art. 1801. § 1. W razie urodzenia martwego dziecka lub zgonu dziecka przed upływem 8 tygodni życia, pracownicy przysługuje urlop macierzyński w wymiarze 8 tygodni po porodzie, nie krócej jednak niż przez okres 7 dni od dnia zgonu dziecka. Pracownicy, która urodziła więcej niż jedno dziecko przy jednym porodzie, przysługuje w takim przypadku urlop macierzyński w wymiarze stosownym do liczby dzieci pozostałych przy życiu. - -§ 2. W przypadku zgonu dziecka po upływie 8 tygodni życia, pracownica zachowuje prawo do urlopu macierzyńskiego przez okres 7 dni od dnia zgonu dziecka. Pracownicy, która urodziła więcej niż jedno dziecko przy jednym porodzie, przysługuje w takim przypadku urlop macierzyński w wymiarze stosownym do liczby dzieci pozostałych przy życiu, nie krócej jednak niż przez okres 7 dni od dnia zgonu dziecka. - -Art. 181. W razie urodzenia dziecka wymagającego opieki szpitalnej pracownica, która wykorzystała po porodzie 8 tygodni urlopu macierzyńskiego, pozostałą część tego urlopu może wykorzystać w terminie późniejszym, po wyjściu dziecka ze szpitala. - -Art. 182. W przypadku porzucenia dziecka przez pracownicę lub umieszczenia dziecka, na podstawie orzeczenia sądu, w pieczy zastępczej, w zakładzie opiekuńczo-leczniczym, w zakładzie pielęgnacyjno-opiekuńczym albo w zakładzie rehabilitacji leczniczej, pracownicy nie przysługuje część urlopu macierzyńskiego przypadająca po dniu porzucenia dziecka albo umieszczenia dziecka w pieczy zastępczej, w zakładzie opiekuńczo-leczniczym, w zakładzie pielęgnacyjno-opiekuńczym albo w zakładzie rehabilitacji leczniczej. Jednakże urlop macierzyński po porodzie nie może wynosić mniej niż 8 tygodni. - - -Art. 1821. (uchylony). - - -Art. 1821a. - -§ 1. Pracownicy - rodzice dziecka mają prawo do urlopu rodzicielskiego w celu sprawowania opieki nad dzieckiem w wymiarze do: - -1) 41 tygodni - w przypadku, o którym mowa w art. 180 § 1 pkt 1; -2) 43 tygodni - w przypadkach, o których mowa w art. 180 § 1 pkt 2-5. -§ 2. Pracownicy - rodzice dziecka posiadającego zaświadczenie, o którym mowa w art. 4 ust. 3 ustawy z dnia 4 listopada 2016 r. o wsparciu kobiet w ciąży i rodzin „Za życiem”, mają prawo do urlopu rodzicielskiego w celu sprawowania opieki nad tym dzieckiem w wymiarze do: - -1) 65 tygodni - w przypadku, o którym mowa w art. 180 § 1 pkt 1; -2) 67 tygodni - w przypadkach, o których mowa w art. 180 § 1 pkt 2-5. -§ 3. Urlop rodzicielski w wymiarze, o którym mowa w § 1 i 2, przysługuje łącznie obojgu pracownikom - rodzicom dziecka. - -§ 4. Każdemu z pracowników - rodziców dziecka przysługuje wyłączne prawo do 9 tygodni urlopu rodzicielskiego z wymiaru urlopu określonego w § 1 i 2. Prawa tego nie można przenieść na drugiego z pracowników - rodziców dziecka. - -§ 5. Skorzystanie z urlopu rodzicielskiego w wymiarze co najmniej 9 tygodni oznacza wykorzystanie przez pracownika - rodzica dziecka urlopu, o którym mowa w § 4. - -§ 6. Z urlopu rodzicielskiego mogą jednocześnie korzystać oboje pracownicy - rodzice dziecka. W takim przypadku łączny wymiar urlopu rodzicielskiego nie może przekraczać wymiaru, o którym mowa w § 1 albo 2. - -§ 7. W okresie pobierania przez jednego z rodziców dziecka zasiłku macierzyńskiego za okres odpowiadający okresowi urlopu rodzicielskiego drugi rodzic może korzystać z urlopu rodzicielskiego. W takim przypadku łączny wymiar urlopu rodzicielskiego i okresu pobierania zasiłku macierzyńskiego za okres odpowiadający okresowi urlopu rodzicielskiego nie może przekraczać wymiaru, o którym mowa w § 1 albo 2. - - -Art. 1821b. (uchylony). - - -Art. 1821c. Urlop rodzicielski jest udzielany jednorazowo albo nie więcej niż w 5 częściach nie później niż do zakończenia roku kalendarzowego, w którym dziecko kończy 6 rok życia. - - -Art. 1821d. § 1. Urlop rodzicielski jest udzielany na wniosek w postaci papierowej lub elektronicznej składany przez pracownika - rodzica dziecka w terminie nie krótszym niż 21 dni przed rozpoczęciem korzystania z urlopu. Pracodawca jest obowiązany uwzględnić wniosek pracownika. - -§ 2. Liczbę części urlopu ustala się w oparciu o liczbę złożonych wniosków o udzielenie urlopu. W liczbie wykorzystanych części urlopu uwzględnia się także liczbę wniosków o zasiłek macierzyński za okres odpowiadający okresowi urlopu rodzicielskiego albo jego części, złożonych przez ubezpieczoną - matkę dziecka lub ubezpieczonego-ojca dziecka. - -§ 3. Pracownik może zrezygnować z korzystania z urlopu rodzicielskiego w każdym czasie za zgodą pracodawcy i powrócić do pracy. - - -Art. 1821e. § 1. Pracownik może łączyć korzystanie z urlopu rodzicielskiego z wykonywaniem pracy u pracodawcy udzielającego tego urlopu w wymiarze nie wyższym niż połowa pełnego wymiaru czasu pracy. W takim przypadku urlopu rodzicielskiego udziela się na pozostałą część wymiaru czasu pracy. - -§ 2. W przypadku, o którym mowa w § 1, podjęcie pracy następuje na wniosek w postaci papierowej lub elektronicznej składany przez pracownika w terminie nie krótszym niż 21 dni przed rozpoczęciem wykonywania pracy. Pracodawca jest obowiązany uwzględnić wniosek pracownika, chyba że nie jest to możliwe ze względu na organizację pracy lub rodzaj pracy wykonywanej przez pracownika. O przyczynie odmowy uwzględnienia wniosku pracodawca informuje pracownika w postaci papierowej lub elektronicznej w terminie 7 dni od dnia otrzymania wniosku. - - -Art. 1821f. § 1. W przypadku łączenia przez pracownika - rodzica dziecka korzystania z urlopu rodzicielskiego z wykonywaniem pracy u pracodawcy udzielającego tego urlopu wymiar urlopu rodzicielskiego ulega wydłużeniu proporcjonalnie do wymiaru czasu pracy wykonywanej przez pracownika w trakcie korzystania z urlopu lub jego części, nie dłużej jednak niż do: - -1) 82 tygodni - w przypadku, o którym mowa w art. 180 § 1 pkt 1; -2) 86 tygodni - w przypadkach, o których mowa w art. 180 § 1 pkt 2-5. -§ 11. W przypadku łączenia przez pracownika - rodzica dziecka posiadającego zaświadczenie, o którym mowa w art. 4 ust. 3 ustawy z dnia 4 listopada 2016 r. o wsparciu kobiet w ciąży i rodzin „Za życiem”, korzystania z urlopu rodzicielskiego z wykonywaniem pracy u pracodawcy udzielającego tego urlopu wymiar urlopu rodzicielskiego ulega wydłużeniu proporcjonalnie do wymiaru czasu pracy wykonywanej przez pracownika - rodzica dziecka w trakcie korzystania z urlopu lub jego części, nie dłużej jednak niż do: - -1) 130 tygodni - w przypadku, o którym mowa w art. 180 § 1 pkt 1; -2) 134 tygodni - w przypadkach, o których mowa w art. 180 § 1 pkt 2-5. -§ 2. Okres, o który urlop rodzicielski ulega wydłużeniu, stanowi iloczyn liczby tygodni, przez jaką pracownik łączy korzystanie z urlopu rodzicielskiego z wykonywaniem pracy u pracodawcy udzielającego tego urlopu i wymiaru czasu pracy wykonywanej przez pracownika w trakcie korzystania z urlopu rodzicielskiego. - -§ 3. W przypadku gdy łączenie korzystania z urlopu z wykonywaniem pracy, o którym mowa w § 1 albo § 11, odbywa się przez część urlopu rodzicielskiego, proporcjonalne wydłużenie wymiaru tego urlopu, następuje wyłącznie w odniesieniu do tej części urlopu rodzicielskiego. - -§ 4. W przypadku gdy powstała w wyniku wydłużenia wymiaru urlopu rodzicielskiego część urlopu rodzicielskiego nie odpowiada wielokrotności tygodnia, jest ona udzielana w dniach. Przy udzielaniu urlopu niepełny dzień pomija się. - -§ 5. Część urlopu rodzicielskiego, o którą urlop został proporcjonalnie wydłużony zgodnie z § 1-4, wydłuża część urlopu rodzicielskiego, podczas której pracownik łączył korzystanie z urlopu z wykonywaniem pracy w niepełnym wymiarze czasu pracy u pracodawcy udzielającego urlopu. - -§ 6. We wniosku, o którym mowa w art. 1821e § 2, pracownik określa sposób wykorzystania części urlopu rodzicielskiego, o którą urlop zostanie proporcjonalnie wydłużony. - -§ 7. W przypadku gdy pracownik zamierza łączyć korzystanie z części urlopu rodzicielskiego powstałej w wyniku proporcjonalnego wydłużenia tego urlopu, obliczonej zgodnie z § 2, z wykonywaniem pracy w niepełnym wymiarze czasu pracy, wymiar tej części urlopu oblicza się dzieląc długość części urlopu powstałej w wyniku proporcjonalnego wydłużenia przez różnicę liczby 1 i wymiaru czasu pracy, w jakim pracownik zamierza łączyć korzystanie z tej części urlopu z wykonywaniem pracy. Przepis § 4 stosuje się odpowiednio. - - -Art. 18216. Do urlopu rodzicielskiego stosuje się odpowiednio przepisy art. 45 § 3, art. 47, art. 57 § 2, art. 163 § 3, art. 165 pkt 4, art. 166 pkt 4, art. 180 § 6-17, art. 1801 § 2, art. 181, art. 182 zdanie pierwsze i art. 1831 § 1. - - -Art. 1822. (uchylony). - - -Art. 1823. § 1. W celu sprawowania opieki nad dzieckiem pracownik - ojciec ma prawo do urlopu ojcowskiego w wymiarze do 2 tygodni, nie dłużej jednak niż do: - -1) ukończenia przez dziecko 12 miesiąca życia albo -2) upływu 12 miesięcy od dnia uprawomocnienia się postanowienia orzekającego przysposobienie dziecka i nie dłużej niż do ukończenia przez dziecko 14 roku życia. -§ 11. Urlop ojcowski może być wykorzystany jednorazowo albo nie więcej niż w 2 częściach, z których żadna nie może być krótsza niż tydzień. - -§ 2. Urlop ojcowski jest udzielany na wniosek w postaci papierowej lub elektronicznej składany przez pracownika - ojca w terminie nie krótszym niż 7 dni przed rozpoczęciem korzystania z urlopu. Pracodawca jest obowiązany uwzględnić wniosek pracownika. - -§ 3. Do urlopu ojcowskiego stosuje się odpowiednio przepisy art. 45 § 3, art. 47, art. 57 § 2, art. 163 § 3, art. 165 pkt 4, art. 166 pkt 4, art. 181 i art. 1831 § 1. - - -Art. 1824. (uchylony) - -Art. 183. - -§ 1. Pracownik, który przyjął dziecko na wychowanie jako rodzina zastępcza, z wyjątkiem rodziny zastępczej zawodowej, ma prawo do urlopu na warunkach urlopu macierzyńskiego w wymiarze: - -1) 20 tygodni - w przypadku przyjęcia jednego dziecka, -2) 31 tygodni - w przypadku jednoczesnego przyjęcia dwojga dzieci, -3) 33 tygodni - w przypadku jednoczesnego przyjęcia trojga dzieci, -4) 35 tygodni - w przypadku jednoczesnego przyjęcia czworga dzieci, -5) 37 tygodni - w przypadku jednoczesnego przyjęcia pięciorga i więcej dzieci -- nie dłużej jednak niż do ukończenia przez dziecko 7 roku życia, a w przypadku dziecka, wobec którego podjęto decyzję o odroczeniu obowiązku szkolnego, nie dłużej niż do ukończenia przez nie 10 roku życia. -§ 11. Pracownik, który przyjął dziecko na wychowanie i wystąpił do sądu opiekuńczego z wnioskiem o wszczęcie postępowania w sprawie przysposobienia dziecka, ma prawo do urlopu na warunkach urlopu macierzyńskiego w wymiarze: - -1) 20 tygodni - w przypadku przyjęcia jednego dziecka, -2) 31 tygodni - w przypadku jednoczesnego przyjęcia dwojga dzieci, -3) 33 tygodni - w przypadku jednoczesnego przyjęcia trojga dzieci, -4) 35 tygodni - w przypadku jednoczesnego przyjęcia czworga dzieci, -5) 37 tygodni - w przypadku jednoczesnego przyjęcia pięciorga i więcej dzieci -- nie dłużej jednak niż do ukończenia przez dziecko 14 roku życia. -§ 2. Do urlopu na warunkach urlopu macierzyńskiego przepisy art. 45 § 3, art. 47, art. 57 § 2, art. 163 § 3, art. 165 pkt 4, art. 166 pkt 4, art. 180 § 4-17, art. 1801 § 2 i art. 181 stosuje się odpowiednio. - -§ 3. Pracownik, o którym mowa w § 1, który przyjął dziecko w wieku do 7 roku życia, a w przypadku dziecka, wobec którego podjęto decyzję o odroczeniu obowiązku szkolnego, do 10 roku życia, oraz pracownik, o którym mowa w § 11, który przyjął dziecko w wieku do 14 roku życia - ma prawo do 9 tygodni urlopu na warunkach urlopu macierzyńskiego. - -§ 4. Pracownicy, którzy przyjęli dziecko na wychowanie jako rodzina zastępcza, z wyjątkiem rodziny zastępczej zawodowej, mają prawo do urlopu rodzicielskiego w celu sprawowania opieki nad tym dzieckiem w wymiarze do: - -1) 41 tygodni - w przypadku, o którym mowa w § 1 pkt 1; -2) 43 tygodni - w przypadkach, o których mowa w § 1 pkt 2-5; -3) 38 tygodni - w przypadku, o którym mowa w § 3. -§ 41. Pracownicy, którzy przyjęli dziecko na wychowanie i wystąpili do sądu opiekuńczego z wnioskiem o wszczęcie postępowania w sprawie przysposobienia dziecka, mają prawo do urlopu rodzicielskiego w celu sprawowania opieki nad tym dzieckiem w wymiarze do: - -1) 41 tygodni - w przypadku, o którym mowa w § 11 pkt 1, -2) 43 tygodni - w przypadkach, o których mowa w § 11 pkt 2-5 -- nie dłużej jednak niż do ukończenia przez dziecko 14 roku życia. -§ 42. Pracownicy, o których mowa w § 3, którzy przyjęli na wychowanie dziecko w wieku do ukończenia 14 roku życia, mają prawo do 38 tygodni urlopu rodzicielskiego. - -§ 43. Pracownicy, o których mowa w § 4, w przypadku dziecka posiadającego zaświadczenie, o którym mowa w art. 4 ust. 3 ustawy z dnia 4 listopada 2016 r. o wsparciu kobiet w ciąży i rodzin „Za życiem”, mają prawo do urlopu rodzicielskiego w celu sprawowania opieki nad tym dzieckiem w wymiarze do: - -1) 65 tygodni - w przypadku, o którym mowa w § 1 pkt 1; -2) 67 tygodni - w przypadkach, o których mowa w § 1 pkt 2-5; -3) 62 tygodni - w przypadku, o którym mowa w § 3. -§ 44. Pracownicy, o których mowa w § 41, w przypadku dziecka posiadającego zaświadczenie, o którym mowa w art. 4 ust. 3 ustawy z dnia 4 listopada 2016 r. o wsparciu kobiet w ciąży i rodzin „Za życiem”, mają prawo do urlopu rodzicielskiego w celu sprawowania opieki nad tym dzieckiem w wymiarze do: - -1) 65 tygodni - w przypadku, o którym mowa w § 11 pkt 1, -2) 67 tygodni - w przypadkach, o których mowa w § 11 pkt 2-5 -- nie dłużej jednak niż do ukończenia przez dziecko 14 roku życia. -§ 45. Pracownicy, o których mowa w § 3, którzy przyjęli na wychowanie dziecko w wieku do ukończenia 14 roku życia, w przypadku dziecka posiadającego zaświadczenie, o którym mowa w art. 4 ust. 3 ustawy z dnia 4 listopada 2016 r. o wsparciu kobiet w ciąży i rodzin „Za życiem”, mają prawo do 62 tygodni urlopu rodzicielskiego. - -§ 46. Urlop rodzicielski jest udzielany jednorazowo albo nie więcej niż w 5 częściach. - -§ 5. Do urlopu rodzicielskiego stosuje się odpowiednio przepisy art. 1821a § 3-7 i art. 1821c-1821g. - -§ 6. Urlop na warunkach urlopu macierzyńskiego jest udzielany na wniosek w postaci papierowej lub elektronicznej składany przez pracownika w terminie 7 dni od dnia przyjęcia dziecka na wychowanie jako rodzina zastępcza albo przyjęcia dziecka na wychowanie i wystąpienia do sądu opiekuńczego z wnioskiem o wszczęcie postępowania w sprawie przysposobienia dziecka. Urlop rozpoczyna się w terminie określonym we wniosku pracownika, jednak nie później niż 21 dni od dnia odpowiednio przyjęcia dziecka na wychowanie jako rodzina zastępcza albo przyjęcia dziecka na wychowanie i wystąpienia do sądu opiekuńczego z wnioskiem o wszczęcie postępowania w sprawie przysposobienia dziecka. Do wniosku dołącza się dokumenty określone w przepisach wydanych na podstawie art. 1868a. Pracodawca jest obowiązany uwzględnić wniosek pracownika. - -§ 7. Pracownik, który korzysta lub korzystał z urlopu na warunkach urlopu macierzyńskiego w związku z przyjęciem dziecka na wychowanie jako rodzina zastępcza, a następnie wystąpił do sądu opiekuńczego z wnioskiem o wszczęcie postępowania w sprawie przysposobienia dziecka, ma prawo do urlopu na warunkach urlopu macierzyńskiego w związku z wystąpieniem do sądu opiekuńczego z wnioskiem o wszczęcie postępowania w sprawie przysposobienia dziecka w wymiarze określonym w § 11 obniżonym o wykorzystany urlop na warunkach urlopu macierzyńskiego w związku z przyjęciem dziecka na wychowanie jako rodzina zastępcza. - -§ 8. Pracownik, który korzysta lub korzystał z urlopu rodzicielskiego w związku z przyjęciem dziecka na wychowanie jako rodzina zastępcza, a następnie wystąpił do sądu opiekuńczego z wnioskiem o wszczęcie postępowania w sprawie przysposobienia dziecka, ma prawo do urlopu rodzicielskiego w związku z wystąpieniem do sądu opiekuńczego z wnioskiem o wszczęcie postępowania w sprawie przysposobienia dziecka w wymiarze określonym w § 41 albo 42 albo § 44 albo 45, obniżonym o wykorzystany urlop rodzicielski w związku z przyjęciem dziecka na wychowanie jako rodzina zastępcza. - - -Art. 1831. § 1. Przy udzielaniu urlopu macierzyńskiego i urlopu na warunkach urlopu macierzyńskiego tydzień urlopu odpowiada 7 dniom kalendarzowym. - -§ 2. Jeżeli pracownica nie korzysta z urlopu macierzyńskiego przed przewidywaną datą porodu, pierwszym dniem urlopu macierzyńskiego jest dzień porodu. - - -Art. 1832. (uchylony) - -Art. 184. Za okres urlopu macierzyńskiego, urlopu na warunkach urlopu macierzyńskiego, urlopu rodzicielskiego oraz urlopu ojcowskiego przysługuje zasiłek macierzyński na zasadach określonych w ustawie z dnia 25 czerwca 1999 r. o świadczeniach pieniężnych z ubezpieczenia społecznego w razie choroby i macierzyństwa. - -Art. 185. § 1. Stan ciąży powinien być stwierdzony świadectwem lekarskim. - -§ 2. Pracodawca jest obowiązany udzielać pracownicy ciężarnej zwolnień od pracy na zalecone przez lekarza badania lekarskie przeprowadzane w związku z ciążą, jeżeli badania te nie mogą być przeprowadzone poza godzinami pracy. Za czas nieobecności w pracy z tego powodu pracownica zachowuje prawo do wynagrodzenia. - -Art. 186. - -§ 1. Pracownik zatrudniony co najmniej 6 miesięcy ma prawo do urlopu wychowawczego w celu sprawowania osobistej opieki nad dzieckiem. Do sześciomiesięcznego okresu zatrudnienia wlicza się poprzednie okresy zatrudnienia. - -§ 2. Wymiar urlopu wychowawczego wynosi do 36 miesięcy. Urlop jest udzielany na okres nie dłuższy niż do zakończenia roku kalendarzowego, w którym dziecko kończy 6 rok życia. - -§ 3. Jeżeli z powodu stanu zdrowia potwierdzonego orzeczeniem o niepełnosprawności lub stopniu niepełnosprawności dziecko wymaga osobistej opieki pracownika, niezależnie od urlopu, o którym mowa w § 2, może być udzielony urlop wychowawczy w wymiarze do 36 miesięcy, jednak na okres nie dłuższy niż do ukończenia przez dziecko 18 roku życia. - -§ 31. Urlopy w wymiarach, o których mowa w § 2 i 3, przysługują łącznie obojgu rodzicom lub opiekunom dziecka. - -§ 4. Każdemu z rodziców lub opiekunów dziecka przysługuje wyłączne prawo do jednego miesiąca urlopu wychowawczego z wymiaru urlopu określonego w § 2 i 3. Prawa tego nie można przenieść na drugiego z rodziców lub opiekunów dziecka. - -§ 5. Skorzystanie z urlopu wychowawczego w wymiarze co najmniej jednego miesiąca oznacza wykorzystanie przez rodzica lub opiekuna dziecka urlopu, o którym mowa w § 4. - -§ 6. Z urlopu wychowawczego mogą jednocześnie korzystać oboje rodzice lub opiekunowie dziecka. W takim przypadku łączny wymiar urlopu wychowawczego nie może przekraczać wymiaru, o którym mowa w § 2 i 3. - -§ 7. Urlop wychowawczy jest udzielany na wniosek w postaci papierowej lub elektronicznej składany przez pracownika w terminie nie krótszym niż 21 dni przed rozpoczęciem korzystania z urlopu. Do wniosku dołącza się dokumenty określone w przepisach wydanych na podstawie art. 1868a. Pracodawca jest obowiązany uwzględnić wniosek pracownika. Pracownik może wycofać wniosek o udzielenie urlopu wychowawczego nie później niż na 7 dni przed rozpoczęciem korzystania z urlopu, składając pracodawcy w postaci papierowej lub elektronicznej oświadczenie w tej sprawie. - -§ 71. Jeżeli wniosek, o którym mowa w § 7, został złożony bez zachowania terminu pracodawca udziela urlopu wychowawczego nie później niż z dniem upływu 21 dni od dnia złożenia wniosku. - -§ 8. Urlop wychowawczy jest udzielany nie więcej niż w 5 częściach. Liczbę części urlopu ustala się w oparciu o liczbę złożonych wniosków o udzielenie urlopu. - -§ 9. Rodzic dziecka ma prawo do urlopu wychowawczego w wymiarze do 36 miesięcy, jeżeli: - -1) drugi rodzic dziecka nie żyje, -2) drugiemu rodzicowi dziecka nie przysługuje władza rodzicielska, -3) drugi rodzic dziecka został pozbawiony władzy rodzicielskiej albo taka władza uległa ograniczeniu lub zawieszeniu. -Przepisy § 1, § 2 zdanie drugie, § 3, 7 i 8 stosuje się. -§ 10. Jeżeli dziecko pozostaje pod opieką jednego opiekuna przysługuje mu urlop wychowawczy w wymiarze do 36 miesięcy. Przepisy § 1, § 2 zdanie drugie, § 3, 7, 71 i 8 stosuje się. - - -Art. 1861. (uchylony). - - -Art. 1862. § 1. W czasie urlopu wychowawczego pracownik ma prawo podjąć pracę zarobkową u dotychczasowego lub innego pracodawcy albo inną działalność, a także naukę lub szkolenie, jeżeli nie wyłącza to możliwości sprawowania osobistej opieki nad dzieckiem. - -§ 2. W razie ustalenia, że pracownik trwale zaprzestał sprawowania osobistej opieki nad dzieckiem, pracodawca wzywa pracownika do stawienia się do pracy w terminie przez siebie wskazanym, nie później jednak niż w ciągu 30 dni od dnia powzięcia takiej wiadomości i nie wcześniej niż po upływie 3 dni od dnia wezwania. - -§ 3. (uchylony). - - -Art. 1863. Pracownik może zrezygnować z urlopu wychowawczego: - -1) w każdym czasie - za zgodą pracodawcy, -2) po uprzednim zawiadomieniu pracodawcy - najpóźniej na 30 dni przed terminem zamierzonego podjęcia pracy. - -Art. 1864. Pracodawca dopuszcza pracownika po zakończeniu urlopu macierzyńskiego, urlopu na warunkach urlopu macierzyńskiego, urlopu rodzicielskiego, urlopu ojcowskiego oraz urlopu wychowawczego do pracy na dotychczasowym stanowisku, a jeżeli nie jest to możliwe - na stanowisku równorzędnym z zajmowanym przed rozpoczęciem urlopu na warunkach nie mniej korzystnych od tych, które obowiązywałyby, gdyby pracownik nie korzystał z urlopu. - - -Art. 1865. Okres urlopu wychowawczego, w dniu jego zakończenia, wlicza się do okresu zatrudnienia, od którego zależą uprawnienia pracownicze. - - -Art. 1866. (uchylony). - - -Art. 1867. § 1. Pracownik uprawniony do urlopu wychowawczego może złożyć pracodawcy wniosek w postaci papierowej lub elektronicznej o obniżenie jego wymiaru czasu pracy do wymiaru nie niższego niż połowa pełnego wymiaru czasu pracy w okresie, w którym mógłby korzystać z takiego urlopu. Pracodawca jest obowiązany uwzględnić wniosek pracownika. - -§ 2. Wniosek, o którym mowa w § 1, składa się na 21 dni przed rozpoczęciem wykonywania pracy w obniżonym wymiarze czasu pracy. Do wniosku dołącza się dokumenty określone w przepisach wydanych na podstawie art. 1868a. Jeżeli wniosek został złożony bez zachowania terminu, pracodawca obniża wymiar czasu pracy nie później niż z upływem 21 dni od dnia złożenia wniosku. - -§ 3. W przypadku skorzystania przez pracownika z części urlopu wychowawczego pracownik ten może korzystać z obniżonego wymiaru czasu pracy, o którym mowa w § 1, przez okres odpowiadający pozostałemu do wykorzystania wymiarowi urlopu wychowawczego, nie dłużej jednak niż do zakończenia roku kalendarzowego, w którym dziecko kończy 6 rok życia. - -§ 4. Korzystanie z obniżonego wymiaru czasu pracy, o którym mowa w § 1, nie obniża wymiaru urlopu wychowawczego. - - -Art. 1868. - -§ 1. Pracodawca nie może wypowiedzieć ani rozwiązać umowy o pracę w okresie od dnia złożenia przez pracownika uprawnionego do urlopu wychowawczego wniosku o: - -1) udzielenie urlopu wychowawczego - do dnia zakończenia tego urlopu; -2) obniżenie wymiaru czasu pracy - do dnia powrotu do nieobniżonego wymiaru czasu pracy, nie dłużej jednak niż przez łączny okres 12 miesięcy. -§ 2. W przypadkach, o których mowa w § 1, rozwiązanie przez pracodawcę umowy jest dopuszczalne tylko w razie ogłoszenia upadłości lub likwidacji pracodawcy, a także gdy zachodzą przyczyny uzasadniające rozwiązanie umowy o pracę bez wypowiedzenia z winy pracownika. - -§ 3. W przypadku złożenia przez pracownika wniosku, o którym mowa w § 1, wcześniej niż 21 dni przed rozpoczęciem korzystania z urlopu wychowawczego albo obniżonego wymiaru czasu pracy, zakaz, o którym mowa w § 1, zaczyna obowiązywać na 21 dni przed rozpoczęciem korzystania z urlopu albo obniżonego wymiaru czasu pracy. - -§ 4. W przypadku złożenia przez pracownika wniosku, o którym mowa w § 1, po dokonaniu czynności zmierzającej do rozwiązania umowy o pracę, umowa rozwiązuje się w terminie wynikającym z tej czynności. - - -Art. 1868a. Minister właściwy do spraw pracy określi, w drodze rozporządzenia: - -1) treść wniosku o udzielenie części urlopu macierzyńskiego, urlopu na warunkach urlopu macierzyńskiego lub jego części, urlopu rodzicielskiego lub jego części i urlopu ojcowskiego lub jego części, -2) dokumenty dołączane do wniosków, o których mowa w pkt 1, -3) treść wniosku w sprawie rezygnacji z części urlopu macierzyńskiego i części urlopu na warunkach urlopu macierzyńskiego, -4) dokumenty dołączane do wniosków, o których mowa w pkt 3, -5) treść wniosku o łączenie korzystania z urlopu rodzicielskiego lub jego części z wykonywaniem pracy u pracodawcy udzielającego takiego urlopu, -6) treść wniosku o udzielenie urlopu wychowawczego lub jego części, -7) dokumenty dołączane do wniosku, o którym mowa w pkt 6, -8) treść wniosku o obniżenie wymiaru czasu pracy pracownika uprawnionego do urlopu wychowawczego, -9) dokumenty dołączane do wniosku, o którym mowa w pkt 8 -- biorąc pod uwagę potrzebę zapewnienia prawidłowej realizacji uprawnień pracowników do urlopów związanych z rodzicielstwem i obniżenia wymiaru czasu pracy oraz zapewnienia właściwej organizacji czasu pracy. -Art. 187. § 1. Pracownica karmiąca dziecko piersią ma prawo do dwóch półgodzinnych przerw w pracy wliczanych do czasu pracy. Pracownica karmiąca więcej niż jedno dziecko ma prawo do dwóch przerw w pracy, po 45 minut każda. Przerwy na karmienie mogą być na wniosek pracownicy udzielane łącznie. - -§ 2. Pracownicy zatrudnionej przez czas krótszy niż 4 godziny dziennie przerwy na karmienie nie przysługują. Jeżeli czas pracy pracownicy nie przekracza 6 godzin dziennie, przysługuje jej jedna przerwa na karmienie. - -Art. 188. § 1. Pracownikowi wychowującemu przynajmniej jedno dziecko w wieku do 14 lat przysługuje w ciągu roku kalendarzowego zwolnienie od pracy w wymiarze 16 godzin albo 2 dni, z zachowaniem prawa do wynagrodzenia. - -§ 2. O sposobie wykorzystania w danym roku kalendarzowym zwolnienia, o którym mowa w § 1, decyduje pracownik w pierwszym wniosku składanym w postaci papierowej lub elektronicznej o udzielenie takiego zwolnienia w danym roku kalendarzowym. - -§ 3. Zwolnienie od pracy, o którym mowa w § 1, udzielane w wymiarze godzinowym, dla pracownika zatrudnionego w niepełnym wymiarze czasu pracy ustala się proporcjonalnie do wymiaru czasu pracy tego pracownika. Niepełną godzinę zwolnienia od pracy zaokrągla się w górę do pełnej godziny. - -§ 4. Przepisy § 1 i 3 w zakresie zwolnienia od pracy udzielanego w wymiarze godzinowym stosuje się odpowiednio do pracownika, dla którego dobowa norma czasu pracy, wynikająca z odrębnych przepisów, jest niższa niż 8 godzin. - - -Art. 1881. § 1. Pracownik wychowujący dziecko, do ukończenia przez nie 8 roku życia, może złożyć wniosek w postaci papierowej lub elektronicznej o zastosowanie do niego elastycznej organizacji pracy. Wniosek składa się w terminie nie krótszym niż 21 dni przed planowanym rozpoczęciem korzystania z elastycznej organizacji pracy. - -§ 2. Za elastyczną organizację pracy, o której mowa w § 1, uważa się pracę zdalną, system czasu pracy, o którym mowa w art. 139, art. 143 i art. 144, rozkłady czasu pracy, o których mowa w art. 1401 lub art. 142, oraz obniżenie wymiaru czasu pracy. - -§ 3. We wniosku wskazuje się: - -1) imię i nazwisko oraz datę urodzenia dziecka; -2) przyczynę konieczności skorzystania z elastycznej organizacji pracy; -3) termin rozpoczęcia i zakończenia korzystania z elastycznej organizacji pracy; -4) rodzaj elastycznej organizacji pracy, z której pracownik planuje korzystać. -§ 4. Pracodawca rozpatruje wniosek, uwzględniając potrzeby pracownika, w tym termin oraz przyczynę konieczności korzystania z elastycznej organizacji pracy, a także potrzeby i możliwości pracodawcy, w tym konieczność zapewnienia normalnego toku pracy, organizację pracy lub rodzaj pracy wykonywanej przez pracownika. - -§ 5. Pracodawca informuje pracownika w postaci papierowej lub elektronicznej o uwzględnieniu wniosku albo o przyczynie odmowy uwzględnienia wniosku, albo o innym możliwym terminie zastosowania elastycznej organizacji pracy niż wskazany we wniosku, w terminie 7 dni od dnia otrzymania wniosku. - -§ 6. Pracownik korzystający z elastycznej organizacji pracy, o której mowa w § 1, może w każdym czasie złożyć wniosek w postaci papierowej lub elektronicznej o powrót do poprzedniej organizacji pracy przed upływem terminu, o którym mowa w § 3 pkt 3, gdy uzasadnia to zmiana okoliczności będąca podstawą do korzystania przez pracownika z elastycznej organizacji pracy. Pracodawca, po rozpatrzeniu wniosku, z uwzględnieniem okoliczności, o których mowa w § 4, informuje pracownika w postaci papierowej lub elektronicznej o uwzględnieniu albo przyczynie odmowy uwzględnienia wniosku, albo o możliwym terminie powrotu do pracy, w terminie 7 dni od dnia otrzymania wniosku. - -§ 7. Złożenie przez pracownika wniosku, o którym mowa w § 1, nie może stanowić przyczyny uzasadniającej wypowiedzenie umowy o pracę lub jej rozwiązanie bez wypowiedzenia przez pracodawcę i przyczyny uzasadniającej prowadzenie przygotowania do wypowiedzenia lub rozwiązania stosunku pracy bez wypowiedzenia. - -§ 8. Pracodawca udowodni, że przy rozwiązywaniu umowy o pracę kierował się powodem innym niż wskazany w § 7. - -Art. 189. Prawo do zasiłku za czas nieobecności w pracy z powodu konieczności sprawowania osobistej opieki nad dzieckiem regulują odrębne przepisy. - -Art. 1891. Jeżeli oboje rodzice lub opiekunowie dziecka są zatrudnieni, z uprawnień określonych w art. 148 pkt 3, art. 178 § 2, art. 1867 § 1 i art. 188 może korzystać jedno z nich. - -DZIAŁ DZIEWIĄTY -Zatrudnianie młodocianych - -Rozdział I -Przepisy ogólne - -Art. 190. - -§ 1. Młodocianym w rozumieniu kodeksu jest osoba, która ukończyła 15 lat, a nie przekroczyła 18 lat. - -§ 2. Zabronione jest zatrudnianie osoby, która nie ukończyła 15 lat, z zastrzeżeniem art. 191 § 21-23. - -Art. 191. § 1. Wolno zatrudniać tylko tych młodocianych, którzy: - -1) ukończyli co najmniej ośmioletnią szkołę podstawową, -2) przedstawią świadectwo lekarskie stwierdzające, że praca danego rodzaju nie zagraża ich zdrowiu. -§ 2. Młodociany nie posiadający kwalifikacji zawodowych może być zatrudniony tylko w celu przygotowania zawodowego. - -§ 21. Osoba, która ukończyła ośmioletnią szkołą podstawową, niemająca 15 lat, może być zatrudniona na zasadach określonych dla młodocianych w roku kalendarzowym, w którym kończy 15 lat. - -§ 22. Osoba, która ukończyła ośmioletnią szkołę podstawową, niemająca 15 lat, z wyjątkiem osoby, o której mowa w § 21, może być zatrudniona na zasadach określonych dla młodocianych w celu przygotowania zawodowego w formie nauki zawodu. - -§ 23. Osoba, która nie ukończyła ośmioletniej szkoły podstawowej, niemająca 15 lat, może być zatrudniona na zasadach określonych dla młodocianych w celu przygotowania zawodowego w formie przyuczenia do wykonywania określonej pracy. - -§ 24. Zawarcie umowy o pracę w celu przygotowania zawodowego z osobą, o której mowa w § 22 i 23, jest dopuszczalne w przypadku wyrażenia na to zgody przez przedstawiciela ustawowego lub opiekuna prawnego tej osoby oraz uzyskania pozytywnej opinii poradni psychologiczno-pedagogicznej. - -§ 25. W przypadku osoby, o której mowa w § 23, wymagane jest również uzyskanie zezwolenia dyrektora ośmioletniej szkoły podstawowej, w której obwodzie mieszka ta osoba, na spełnianie obowiązku szkolnego poza szkołą. - -§ 26. Z osobą, która ukończyła 15 lat i nie ukończyła ośmioletniej szkoły podstawowej, może być, na wniosek jej przedstawiciela ustawowego lub opiekuna, zawarta umowa o pracę w celu przygotowania zawodowego odbywanego w formie przyuczenia do wykonywania określonej pracy, jeżeli: - -1) została ona przyjęta do oddziału przysposabiającego do pracy utworzonego w ośmioletniej szkole podstawowej albo -2) uzyskała zezwolenie dyrektora ośmioletniej szkoły podstawowej, w której obwodzie mieszka, na spełnianie obowiązku szkolnego poza szkołą oraz uzyskała pozytywną opinię poradni psychologiczno-pedagogicznej. -§ 27. Z osobą, która ukończyła 15 lat i nie ukończyła ośmioletniej szkoły podstawowej, spełniającą obowiązek szkolny poza szkołą, może być, po ukończeniu przez nią przygotowania zawodowego w formie przyuczenia do wykonywania określonej pracy, zawarta umowa o pracę w celu przygotowania zawodowego w formie nauki zawodu. Przepis § 26 pkt 2 stosuje się odpowiednio. - -§ 3. Rada Ministrów określi w drodze rozporządzenia zasady i warunki odbywania przygotowania zawodowego oraz zasady wynagradzania młodocianych w tym okresie. - -§ 4. (skreślony). - -§ 5. (uchylony) - - -Art. 1911. Osoba, która ukończyła 18 lat w trakcie nauki w ośmioletniej szkole podstawowej, może być zatrudniona na zasadach określonych dla młodocianych w roku kalendarzowym, w którym ukończyła tę szkołę. - -Art. 192. Pracodawca jest obowiązany zapewnić młodocianym pracownikom opiekę i pomoc, niezbędną dla ich przystosowania się do właściwego wykonywania pracy. - -Art. 193. Pracodawca jest obowiązany prowadzić ewidencję pracowników młodocianych. - -Rozdział II -Zawieranie i rozwiązywanie umów o pracę w celu przygotowania zawodowego - -Art. 194. Do zawierania i rozwiązywania z młodocianymi umów o pracę w celu przygotowania zawodowego mają zastosowanie przepisy kodeksu dotyczące umów o pracę na czas nie określony ze zmianami przewidzianymi w art. 195 i 196. - -Art. 195. § 1. Umowa o pracę w celu przygotowania zawodowego powinna określać w szczególności: - -1) rodzaj przygotowania zawodowego (nauka zawodu lub przyuczenie do wykonywania określonej pracy), -2) czas trwania i miejsce odbywania przygotowania zawodowego, -3) sposób dokształcania teoretycznego, -4) wysokość wynagrodzenia. -§ 2. Rada Ministrów może w drodze rozporządzenia określić przypadki, w których jest dopuszczalne zawieranie na czas określony umów o pracę w celu przygotowania zawodowego. - -Art. 196. Rozwiązanie za wypowiedzeniem umowy o pracę zawartej w celu przygotowania zawodowego dopuszczalne jest tylko w razie: - -1) niewypełniania przez młodocianego obowiązków wynikających z umowy o pracę lub obowiązku dokształcania się, pomimo stosowania wobec niego środków wychowawczych, -2) ogłoszenia upadłości lub likwidacji pracodawcy, -3) reorganizacji zakładu pracy uniemożliwiającej kontynuowanie przygotowania zawodowego, -4) stwierdzenia nieprzydatności młodocianego do pracy, w zakresie której odbywa przygotowanie zawodowe. -Rozdział III -Dokształcanie - -Art. 197. § 1. Pracownik młodociany jest obowiązany dokształcać się do ukończenia 18 lat. - -§ 2. W szczególności pracownik młodociany jest obowiązany: - -1) do dokształcania się w zakresie ośmioletniej szkoły podstawowej, jeżeli szkoły takiej nie ukończył, -2) do dokształcania się w zakresie szkoły ponadpodstawowej lub w formach pozaszkolnych. -Art. 198. Pracodawca jest obowiązany zwolnić młodocianego od pracy na czas potrzebny do wzięcia udziału w zajęciach szkoleniowych w związku z dokształcaniem się. - -Art. 199. Jeżeli młodociany nie ukończył przygotowania zawodowego przed osiągnięciem 18 lat, obowiązek dokształcania się, stosownie do przepisów art. 197, może być przedłużony do czasu ukończenia przygotowania zawodowego. - -Art. 200. Minister Pracy i Polityki Socjalnej w porozumieniu z Ministrem Edukacji Narodowej może w drodze rozporządzenia określić przypadki, w których wyjątkowo jest dopuszczalne zwolnienie młodocianych od obowiązku dokształcania się. - - -Rozdział IIIa -Zatrudnianie młodocianych w innym celu niż przygotowanie zawodowe - - -Art. 2001. § 1. Młodociany może być zatrudniony na podstawie umowy o pracę przy wykonywaniu lekkich prac. - -§ 2. Praca lekka nie może powodować zagrożenia dla życia, zdrowia i rozwoju psychofizycznego młodocianego, a także nie może utrudniać młodocianemu wypełniania obowiązku szkolnego. - -§ 3. Wykaz lekkich prac określa pracodawca po uzyskaniu zgody lekarza wykonującego zadania służby medycyny pracy. Wykaz ten wymaga zatwierdzenia przez właściwego inspektora pracy. Wykaz lekkich prac nie może zawierać prac wzbronionych młodocianym, określonych w przepisach wydanych na podstawie art. 204. - -§ 4. Wykaz lekkich prac ustala pracodawca w regulaminie pracy. Pracodawca, który nie ma obowiązku wydania regulaminu, ustala wykaz lekkich prac w osobnym akcie. - -§ 5. Pracodawca jest obowiązany zapoznać młodocianego z wykazem lekkich prac przed dopuszczeniem go do pracy. - - -Art. 2002. § 1. Pracodawca ustala wymiar i rozkład czasu pracy młodocianego zatrudnionego przy lekkiej pracy, uwzględniając tygodniową liczbę godzin nauki wynikającą z programu nauczania, a także z rozkładu zajęć szkolnych młodocianego. - -§ 2. Tygodniowy wymiar czasu pracy młodocianego w okresie odbywania zajęć szkolnych nie może przekraczać 12 godzin. W dniu uczestniczenia w zajęciach szkolnych wymiar czasu pracy młodocianego nie może przekraczać 2 godzin. - -§ 3. Wymiar czasu pracy młodocianego w okresie ferii szkolnych nie może przekraczać 7 godzin na dobę i 35 godzin w tygodniu. Dobowy wymiar czasu pracy młodocianego w wieku do 16 lat nie może jednak przekraczać 6 godzin. - -§ 4. Wymiar czasu pracy określony w § 2 i 3 obowiązuje także w przypadku, gdy młodociany jest zatrudniony u więcej niż jednego pracodawcy. Przed nawiązaniem stosunku pracy pracodawca ma obowiązek uzyskania od młodocianego oświadczenia o zatrudnieniu albo o niepozostawaniu w zatrudnieniu u innego pracodawcy. - -Rozdział IV -Szczególna ochrona zdrowia - -Art. 201. § 1. Młodociany podlega wstępnym badaniom lekarskim przed przyjęciem do pracy oraz badaniom okresowym i kontrolnym w czasie zatrudnienia. - -§ 2. Jeżeli lekarz orzeknie, że dana praca zagraża zdrowiu młodocianego, pracodawca jest obowiązany zmienić rodzaj pracy, a gdy nie ma takiej możliwości, niezwłocznie rozwiązać umowę o pracę i wypłacić odszkodowanie w wysokości wynagrodzenia za okres wypowiedzenia. Przepis art. 51 § 2 stosuje się odpowiednio. - -§ 3. Pracodawca jest obowiązany przekazać informacje o ryzyku zawodowym, które wiąże się z pracą wykonywaną przez młodocianego, oraz o zasadach ochrony przed zagrożeniami również przedstawicielowi ustawowemu młodocianego. - -Art. 202. § 1. Czas pracy młodocianego w wieku do 16 lat nie może przekraczać 6 godzin na dobę. - -§ 2. Czas pracy młodocianego w wieku powyżej 16 lat nie może przekraczać 8 godzin na dobę. - -§ 3. Do czasu pracy młodocianego wlicza się czas nauki w wymiarze wynikającym z obowiązkowego programu zajęć szkolnych, bez względu na to, czy odbywa się ona w godzinach pracy. - -§ 31. Jeżeli dobowy wymiar czasu pracy młodocianego jest dłuższy niż 4,5 godziny, pracodawca jest obowiązany wprowadzić przerwę w pracy trwającą nieprzerwanie 30 minut, wliczaną do czasu pracy. - -§ 4. (skreślony). - -Art. 203. § 1. Młodocianego nie wolno zatrudniać w godzinach nadliczbowych ani w porze nocnej. - -§ 11. Pora nocna dla młodocianego przypada pomiędzy godzinami 2200 a 600. W przypadkach określonych w art. 191 § 21-23 i 26 pora nocna przypada pomiędzy godzinami 2000 a 600. - -§ 2. Przerwa w pracy młodocianego obejmująca porę nocną powinna trwać nieprzerwanie nie mniej niż 14 godzin. - -§ 3. Młodocianemu przysługuje w każdym tygodniu prawo do co najmniej 48 godzin nieprzerwanego odpoczynku, który powinien obejmować niedzielę. - -Art. 204. § 1. Nie wolno zatrudniać młodocianych przy pracach wzbronionych, których wykaz ustala w drodze rozporządzenia Rada Ministrów. - -§ 2. (skreślony). - -§ 3. Rada Ministrów, w drodze rozporządzenia, może zezwolić na zatrudnianie młodocianych w wieku powyżej 16 lat przy niektórych rodzajach prac wzbronionych, jeżeli jest to potrzebne do odbycia przygotowania zawodowego, określając jednocześnie warunki zapewniające szczególną ochronę zdrowia młodocianych zatrudnionych przy tych pracach. - -Rozdział V -Urlopy wypoczynkowe - -Art. 205. § 1. Młodociany uzyskuje z upływem 6 miesięcy od rozpoczęcia pierwszej pracy prawo do urlopu w wymiarze 12 dni roboczych. - -§ 2. Z upływem roku pracy młodociany uzyskuje prawo do urlopu w wymiarze 26 dni roboczych. Jednakże w roku kalendarzowym, w którym kończy on 18 lat, ma prawo do urlopu w wymiarze 20 dni roboczych, jeżeli prawo do urlopu uzyskał przed ukończeniem 18 lat. - -§ 3. Młodocianemu uczęszczającemu do szkoły należy udzielić urlopu w okresie ferii szkolnych. Młodocianemu, który nie nabył prawa do urlopu, o którym mowa w § 1 i 2, pracodawca może, na jego wniosek, udzielić zaliczkowo urlopu w okresie ferii szkolnych. - -§ 4. Pracodawca jest obowiązany na wniosek młodocianego, ucznia szkoły dla pracujących, udzielić mu w okresie ferii szkolnych urlopu bezpłatnego w wymiarze nie przekraczającym łącznie z urlopem wypoczynkowym 2 miesięcy. Okres urlopu bezpłatnego wlicza się do okresu pracy, od którego zależą uprawnienia pracownicze. - -§ 5. W sprawach nie uregulowanych przepisami niniejszego rozdziału do urlopów przysługujących młodocianym stosuje się przepisy działu siódmego. - -Rozdział VI -Rzemieślnicze przygotowanie zawodowe - -Art. 206. Przepisy art. 190-205 stosuje się odpowiednio do młodocianych zatrudnionych na podstawie umowy o przygotowanie zawodowe u pracodawców będących rzemieślnikami. - -DZIAŁ DZIESIĄTY -Bezpieczeństwo i higiena pracy - -Rozdział I -Podstawowe obowiązki pracodawcy - -Art. 207. § 1. Pracodawca ponosi odpowiedzialność za stan bezpieczeństwa i higieny pracy w zakładzie pracy. Na zakres odpowiedzialności pracodawcy nie wpływają obowiązki pracowników w dziedzinie bezpieczeństwa i higieny pracy oraz powierzenie wykonywania zadań służby bezpieczeństwa i higieny pracy specjalistom spoza zakładu pracy, o których mowa w art. 23711 § 2. - -§ 2. Pracodawca jest obowiązany chronić zdrowie i życie pracowników przez zapewnienie bezpiecznych i higienicznych warunków pracy przy odpowiednim wykorzystaniu osiągnięć nauki i techniki. W szczególności pracodawca jest obowiązany: - -1) organizować pracę w sposób zapewniający bezpieczne i higieniczne warunki pracy, -2) zapewniać przestrzeganie w zakładzie pracy przepisów oraz zasad bezpieczeństwa i higieny pracy, wydawać polecenia usunięcia uchybień w tym zakresie oraz kontrolować wykonanie tych poleceń, -3) reagować na potrzeby w zakresie zapewnienia bezpieczeństwa i higieny pracy oraz dostosowywać środki podejmowane w celu doskonalenia istniejącego poziomu ochrony zdrowia i życia pracowników, biorąc pod uwagę zmieniające się warunki wykonywania pracy, -4) zapewnić rozwój spójnej polityki zapobiegającej wypadkom przy pracy i chorobom zawodowym uwzględniającej zagadnienia techniczne, organizację pracy, warunki pracy, stosunki społeczne oraz wpływ czynników środowiska pracy, -5) uwzględniać ochronę zdrowia młodocianych, pracownic w ciąży lub karmiących dziecko piersią oraz pracowników niepełnosprawnych w ramach podejmowanych działań profilaktycznych, -6) zapewniać wykonanie nakazów, wystąpień, decyzji i zarządzeń wydawanych przez organy nadzoru nad warunkami pracy, -7) zapewniać wykonanie zaleceń społecznego inspektora pracy. -§ 21. Koszty działań podejmowanych przez pracodawcę w zakresie bezpieczeństwa i higieny pracy w żaden sposób nie mogą obciążać pracowników. - -§ 3. Pracodawca oraz osoba kierująca pracownikami są obowiązani znać, w zakresie niezbędnym do wykonywania ciążących na nich obowiązków, przepisy o ochronie pracy, w tym przepisy oraz zasady bezpieczeństwa i higieny pracy. - - -Art. 2071. § 1. Pracodawca jest obowiązany przekazywać pracownikom informacje o: - -1) zagrożeniach dla zdrowia i życia występujących w zakładzie pracy, na poszczególnych stanowiskach pracy i przy wykonywanych pracach, w tym o zasadach postępowania w przypadku awarii i innych sytuacji zagrażających zdrowiu i życiu pracowników. -2) działaniach ochronnych i zapobiegawczych podjętych w celu wyeliminowania lub ograniczenia zagrożeń, o których mowa w pkt 1, -3) pracownikach wyznaczonych do: -a) udzielania pierwszej pomocy, -b) wykonywania działań w zakresie zwalczania pożarów i ewakuacji pracowników. -§ 2. Informacja o pracownikach, o których mowa w § 1 pkt 3, obejmuje: - -1) imię i nazwisko, -2) miejsce wykonywania pracy, -3) numer telefonu służbowego lub innego środka komunikacji elektronicznej. -Art. 208. § 1. W razie gdy jednocześnie w tym samym miejscu wykonują pracę pracownicy zatrudnieni przez różnych pracodawców, pracodawcy ci mają obowiązek: - -1) współpracować ze sobą, -2) wyznaczyć koordynatora sprawującego nadzór nad bezpieczeństwem i higieną pracy wszystkich pracowników zatrudnionych w tym samym miejscu, -3) ustalić zasady współdziałania uwzględniające sposoby postępowania w przypadku wystąpienia zagrożeń dla zdrowia lub życia pracowników, -4) informować siebie nawzajem oraz pracowników lub ich przedstawicieli o działaniach w zakresie zapobiegania zagrożeniom zawodowym występującym podczas wykonywanych przez nich prac. -§ 2. Wyznaczenie koordynatora, o którym mowa w § 1, nie zwalnia poszczególnych pracodawców z obowiązku zapewnienia bezpieczeństwa i higieny pracy zatrudnionym przez nich pracownikom. - -§ 3. Pracodawca, na którego terenie wykonują prace pracownicy zatrudnieni przez różnych pracodawców, jest obowiązany dostarczać tym pracodawcom, w celu przekazania pracownikom, informacje, o których mowa w art. 2071. - -Art. 209. (uchylony). - - -Art. 2091. § 1. Pracodawca jest obowiązany: - -1) zapewnić środki niezbędne do udzielania pierwszej pomocy w nagłych wypadkach, zwalczania pożarów i ewakuacji pracowników, -2) wyznaczyć pracowników do: -a) udzielania pierwszej pomocy, -b) wykonywania działań w zakresie zwalczania pożarów i ewakuacji pracowników, -3) zapewnić łączność ze służbami zewnętrznymi wyspecjalizowanymi w szczególności w zakresie udzielania pierwszej pomocy w nagłych wypadkach, ratownictwa medycznego oraz ochrony przeciwpożarowej. -§ 2. Działania, o których mowa w § 1, powinny być dostosowane do rodzaju i zakresu prowadzonej działalności, liczby zatrudnionych pracowników i innych osób przebywających na terenie zakładu pracy oraz rodzaju i poziomu występujących zagrożeń. - -§ 3. Liczba pracowników, o których mowa w § 1 pkt 2, ich szkolenie oraz wyposażenie powinny uwzględniać rodzaj i poziom występujących zagrożeń. - -§ 4. W przypadku zatrudniania przez pracodawcę wyłącznie pracowników młodocianych lub niepełnosprawnych - działania, o których mowa w § 1 pkt 2, może wykonywać sam pracodawca. Przepis § 3 stosuje się odpowiednio. - - -Art. 2092. § 1. W przypadku możliwości wystąpienia zagrożenia dla zdrowia lub życia pracodawca jest obowiązany: - -1) niezwłocznie poinformować pracowników o tych zagrożeniach oraz podjąć działania w celu zapewnienia im odpowiedniej ochrony, -2) niezwłocznie dostarczyć pracownikom instrukcje umożliwiające, w przypadku wystąpienia bezpośredniego zagrożenia, przerwanie pracy i oddalenie się z miejsca zagrożenia w miejsce bezpieczne. -§ 2. W razie wystąpienia bezpośredniego zagrożenia dla zdrowia lub życia pracodawca jest obowiązany: - -1) wstrzymać pracę i wydać pracownikom polecenie oddalenia się w miejsce bezpieczne, -2) do czasu usunięcia zagrożenia nie wydawać polecenia wznowienia pracy. - -Art. 2093. § 1. Pracodawca jest obowiązany umożliwić pracownikom, w przypadku wystąpienia bezpośredniego zagrożenia dla ich zdrowia lub życia albo dla zdrowia lub życia innych osób, podjęcie działań w celu uniknięcia niebezpieczeństwa - nawet bez porozumienia z przełożonym - na miarę ich wiedzy i dostępnych środków technicznych. - -§ 2. Pracownicy, którzy podjęli działania, o których mowa w § 1, nie mogą ponosić jakichkolwiek niekorzystnych konsekwencji tych działań, pod warunkiem że nie zaniedbali swoich obowiązków. - -Rozdział II -Prawa i obowiązki pracownika - -Art. 210. § 1. W razie gdy warunki pracy nie odpowiadają przepisom bezpieczeństwa i higieny pracy i stwarzają bezpośrednie zagrożenie dla zdrowia lub życia pracownika albo gdy wykonywana przez niego praca grozi takim niebezpieczeństwem innym osobom, pracownik ma prawo powstrzymać się od wykonywania pracy, zawiadamiając o tym niezwłocznie przełożonego. - -§ 2. Jeżeli powstrzymanie się od wykonywania pracy nie usuwa zagrożenia, o którym mowa w § 1, pracownik ma prawo oddalić się z miejsca zagrożenia, zawiadamiając o tym niezwłocznie przełożonego. - -§ 21. Pracownik nie może ponosić jakichkolwiek niekorzystnych dla niego konsekwencji z powodu powstrzymania się od pracy lub oddalenia się z miejsca zagrożenia w przypadkach, o których mowa w § 1 i 2. - -§ 3. Za czas powstrzymania się od wykonywania pracy lub oddalenia się z miejsca zagrożenia w przypadkach, o których mowa w § 1 i 2, pracownik zachowuje prawo do wynagrodzenia. - -§ 4. Pracownik ma prawo, po uprzednim zawiadomieniu przełożonego, powstrzymać się od wykonywania pracy wymagającej szczególnej sprawności psychofizycznej w przypadku, gdy jego stan psychofizyczny nie zapewnia bezpiecznego wykonywania pracy i stwarza zagrożenie dla innych osób. - -§ 5. Przepisy § 1, 2 i 4 nie dotyczą pracownika, którego obowiązkiem pracowniczym jest ratowanie życia ludzkiego lub mienia. - -§ 6. Minister Pracy i Polityki Socjalnej w porozumieniu z Ministrem Zdrowia i Opieki Społecznej określi, w drodze rozporządzenia, rodzaje prac wymagających szczególnej sprawności psychofizycznej. - -Art. 211. Przestrzeganie przepisów i zasad bezpieczeństwa i higieny pracy jest podstawowym obowiązkiem pracownika. W szczególności pracownik jest obowiązany: - -1) znać przepisy i zasady bezpieczeństwa i higieny pracy, brać udział w szkoleniu i instruktażu z tego zakresu oraz poddawać się wymaganym egzaminom sprawdzającym, -2) wykonywać pracę w sposób zgodny z przepisami i zasadami bezpieczeństwa i higieny pracy oraz stosować się do wydawanych w tym zakresie poleceń i wskazówek przełożonych, -3) dbać o należyty stan maszyn, urządzeń, narzędzi i sprzętu oraz o porządek i ład w miejscu pracy, -4) stosować środki ochrony zbiorowej, a także używać przydzielonych środków ochrony indywidualnej oraz odzieży i obuwia roboczego, zgodnie z ich przeznaczeniem, -5) poddawać się wstępnym, okresowym i kontrolnym oraz innym zaleconym badaniom lekarskim i stosować się do wskazań lekarskich, -6) niezwłocznie zawiadomić przełożonego o zauważonym w zakładzie pracy wypadku albo zagrożeniu życia lub zdrowia ludzkiego oraz ostrzec współpracowników, a także inne osoby znajdujące się w rejonie zagrożenia, o grożącym im niebezpieczeństwie, -7) współdziałać z pracodawcą i przełożonymi w wypełnianiu obowiązków dotyczących bezpieczeństwa i higieny pracy. -Art. 212. Osoba kierująca pracownikami jest obowiązana: - -1) organizować stanowiska pracy zgodnie z przepisami i zasadami bezpieczeństwa i higieny pracy, -2) dbać o sprawność środków ochrony indywidualnej oraz ich stosowanie zgodnie z przeznaczeniem, -3) organizować, przygotowywać i prowadzić prace, uwzględniając zabezpieczenie pracowników przed wypadkami przy pracy, chorobami zawodowymi i innymi chorobami związanymi z warunkami środowiska pracy, -4) dbać o bezpieczny i higieniczny stan pomieszczeń pracy i wyposażenia technicznego, a także o sprawność środków ochrony zbiorowej i ich stosowanie zgodnie z przeznaczeniem, -5) egzekwować przestrzeganie przez pracowników przepisów i zasad bezpieczeństwa i higieny pracy, -6) zapewniać wykonanie zaleceń lekarza sprawującego opiekę zdrowotną nad pracownikami. -Rozdział III -Obiekty budowlane i pomieszczenia pracy - -Art. 213. § 1. Pracodawca jest obowiązany zapewniać, aby budowa lub przebudowa obiektu budowlanego, w którym przewiduje się pomieszczenia pracy, była wykonywana na podstawie projektów uwzględniających wymagania bezpieczeństwa i higieny pracy. - -§ 2. Obiekt budowlany, w którym znajdują się pomieszczenia pracy, powinien spełniać wymagania bezpieczeństwa i higieny pracy. - -§ 3. Przebudowa obiektu budowlanego, w którym znajdują się pomieszczenia pracy, powinna uwzględniać poprawę warunków bezpieczeństwa i higieny pracy. - -§ 4. Przepisy § 1-3 stosuje się odpowiednio w przypadku, gdy budowa lub przebudowa dotyczy części obiektu budowlanego, w której znajdują się pomieszczenia pracy. - -Art. 214. § 1. Pracodawca jest obowiązany zapewniać pomieszczenia pracy odpowiednie do rodzaju wykonywanych prac i liczby zatrudnionych pracowników. - -§ 2. Pracodawca jest obowiązany utrzymywać obiekty budowlane i znajdujące się w nich pomieszczenia pracy, a także tereny i urządzenia z nimi związane w stanie zapewniającym bezpieczne i higieniczne warunki pracy. - -Rozdział IV -Maszyny i inne urządzenia techniczne - -Art. 215. Pracodawca jest obowiązany zapewnić, aby stosowane maszyny i inne urządzenia techniczne: - -1) zapewniały bezpieczne i higieniczne warunki pracy, w szczególności zabezpieczały pracownika przed urazami, działaniem niebezpiecznych substancji chemicznych, porażeniem prądem elektrycznym, nadmiernym hałasem, działaniem drgań mechanicznych i promieniowania oraz szkodliwym i niebezpiecznym działaniem innych czynników środowiska pracy, -2) uwzględniały zasady ergonomii. -Art. 216. § 1. Pracodawca wyposaża w odpowiednie zabezpieczenia maszyny i inne urządzenia techniczne, które nie spełniają wymagań określonych w art. 215. - -§ 2. W przypadku gdy konstrukcja zabezpieczenia jest uzależniona od warunków lokalnych, wyposażenie maszyny lub innego urządzenia technicznego w odpowiednie zabezpieczenia należy do obowiązków pracodawcy. - -Art. 217. Niedopuszczalne jest wyposażanie stanowisk pracy w maszyny i inne urządzenia techniczne, które nie spełniają wymagań dotyczących oceny zgodności określonych w odrębnych przepisach. - -Art. 218. Przepisy art. 215 i 217 stosuje się odpowiednio do narzędzi pracy. - -Art. 219. Przepisy art. 215 i 217 nie naruszają wymagań określonych przepisami dotyczącymi maszyn i innych urządzeń technicznych: - -1) będących środkami transportu kolejowego, samochodowego, morskiego, wodnego śródlądowego i lotniczego, -2) podlegających przepisom o dozorze technicznym, -3) podlegających przepisom Prawa geologicznego i górniczego, -4) podlegających przepisom obowiązującym w jednostkach podległych Ministrowi Obrony Narodowej oraz ministrowi właściwemu do spraw wewnętrznych, -5) podlegających przepisom Prawa atomowego. -Rozdział V -Czynniki oraz procesy pracy stwarzające szczególne zagrożenie dla zdrowia lub życia - -Art. 220. § 1. Niedopuszczalne jest stosowanie materiałów i procesów technologicznych bez uprzedniego ustalenia stopnia ich szkodliwości dla zdrowia pracowników i podjęcia odpowiednich środków profilaktycznych. - -§ 2. Minister Zdrowia i Opieki Społecznej w porozumieniu z Ministrem Pracy i Polityki Socjalnej oraz właściwymi ministrami określi, w drodze rozporządzenia: - -1) wykaz jednostek upoważnionych do przeprowadzania badań materiałów i procesów technologicznych w celu ustalenia stopnia ich szkodliwości dla zdrowia oraz zakres tych badań, -2) zakaz albo ograniczenie stosowania, obrotu lub transportu materiałów i procesów technologicznych ze względu na ich szkodliwość dla zdrowia albo uzależnienie ich stosowania, obrotu lub transportu od przestrzegania określonych warunków. -§ 3. Przepisy § 2 nie dotyczą substancji chemicznych i ich mieszanin. - -Art. 221. § 1. Niedopuszczalne jest stosowanie substancji chemicznych i ich mieszanin nieoznakowanych w sposób widoczny, umożliwiający ich identyfikację. - -§ 2. Niedopuszczalne jest stosowanie substancji niebezpiecznej, mieszaniny niebezpiecznej, substancji stwarzającej zagrożenie lub mieszaniny stwarzającej zagrożenie bez posiadania aktualnego spisu tych substancji i mieszanin oraz kart charakterystyki, a także opakowań zabezpieczających przed ich szkodliwym działaniem, pożarem lub wybuchem. - -§ 3. Stosowanie substancji niebezpiecznej, mieszaniny niebezpiecznej, substancji stwarzającej zagrożenie lub mieszaniny stwarzającej zagrożenie jest dopuszczalne pod warunkiem zastosowania środków zapewniających pracownikom ochronę ich zdrowia i życia. - -§ 4. Zasady klasyfikacji substancji chemicznych i ich mieszanin pod względem zagrożeń dla zdrowia lub życia, wykaz substancji chemicznych niebezpiecznych, wymagania dotyczące kart charakterystyki oraz sposób ich oznakowania określają odrębne przepisy. - -§ 5. (skreślony). - -Art. 222. - -§ 1. W razie zatrudniania pracownika w warunkach narażenia na działanie substancji chemicznych, ich mieszanin, czynników lub procesów technologicznych o działaniu rakotwórczym, mutagennym lub reprotoksycznym, pracodawca zastępuje te substancje chemiczne, ich mieszaniny, czynniki lub procesy technologiczne mniej szkodliwymi dla zdrowia lub stosuje inne dostępne środki ograniczające stopień tego narażenia, przy odpowiednim wykorzystaniu osiągnięć nauki i techniki. - -§ 2. Pracodawca rejestruje wszystkie rodzaje prac w kontakcie z substancjami chemicznymi, ich mieszaninami, czynnikami lub procesami technologicznymi o działaniu rakotwórczym, mutagennym lub reprotoksycznym, określonymi w wykazie, o którym mowa w § 3, a także prowadzi rejestr pracowników zatrudnionych przy tych pracach. - -§ 3. Minister właściwy do spraw zdrowia w porozumieniu z ministrem właściwym do spraw pracy określi, w drodze rozporządzenia: - -1) wykaz substancji chemicznych, ich mieszanin, czynników lub procesów technologicznych o działaniu rakotwórczym, mutagennym lub reprotoksycznym i sposób ich rejestrowania, -2) sposób prowadzenia rejestru prac, których wykonywanie powoduje konieczność pozostawania w kontakcie z substancjami chemicznymi, ich mieszaninami, czynnikami lub procesami technologicznymi o działaniu rakotwórczym, mutagennym lub reprotoksycznym, -3) sposób prowadzenia rejestru pracowników zatrudnionych przy pracach, o których mowa w pkt 2, -4) wzory dokumentów dotyczących poziomu narażenia pracowników na substancje chemiczne, ich mieszaniny, czynniki lub procesy technologiczne o działaniu rakotwórczym, mutagennym lub reprotoksycznym oraz sposób przechowywania i przekazywania tych dokumentów do podmiotów właściwych do rozpoznawania lub stwierdzania chorób zawodowych, -5) szczegółowe warunki ochrony pracowników przed zagrożeniami spowodowanymi przez substancje chemiczne, ich mieszaniny, czynniki lub procesy technologiczne o działaniu rakotwórczym, mutagennym lub reprotoksycznym, -6) warunki i sposób monitorowania stanu zdrowia pracowników zatrudnionych przy pracach, których wykonywanie powoduje konieczność pozostawania w kontakcie z substancjami chemicznymi, ich mieszaninami, czynnikami lub procesami technologicznymi o działaniu rakotwórczym, mutagennym lub reprotoksycznym -- uwzględniając zróżnicowane właściwości substancji chemicznych, ich mieszanin, czynników lub procesów technologicznych o działaniu rakotwórczym, mutagennym lub reprotoksycznym, ich zastosowanie oraz konieczność podjęcia niezbędnych środków zabezpieczających przed zagrożeniami wynikającymi z ich stosowania. - -Art. 2221. § 1. W razie zatrudniania pracownika w warunkach narażenia na działanie szkodliwych czynników biologicznych pracodawca stosuje wszelkie dostępne środki eliminujące narażenie, a jeżeli jest to niemożliwe - ograniczające stopień tego narażenia, przy odpowiednim wykorzystaniu osiągnięć nauki i techniki. - -§ 2. Pracodawca prowadzi rejestr prac narażających pracowników na działanie szkodliwych czynników biologicznych oraz rejestr pracowników zatrudnionych przy takich pracach. - -§ 3. Minister właściwy do spraw zdrowia, w porozumieniu z ministrem właściwym do spraw pracy, uwzględniając zróżnicowane działanie czynników biologicznych na organizm człowieka oraz konieczność podjęcia niezbędnych środków zabezpieczających przed zagrożeniami wynikającymi z wykonywania pracy w warunkach narażenia na działanie czynników biologicznych, określi, w drodze rozporządzenia: - -1) klasyfikację i wykaz szkodliwych czynników biologicznych, -2) wykaz prac narażających pracowników na działanie czynników biologicznych, -3) szczegółowe warunki ochrony pracowników przed zagrożeniami spowodowanymi przez szkodliwe czynniki biologiczne, w tym rodzaje środków niezbędnych do zapewnienia ochrony zdrowia i życia pracowników narażonych na działanie tych czynników, zakres stosowania tych środków oraz warunki i sposób monitorowania stanu zdrowia narażonych pracowników, -4) sposób prowadzenia rejestrów prac i pracowników, o których mowa w § 2, oraz sposób przechowywania i przekazywania tych rejestrów do podmiotów właściwych do rozpoznawania lub stwierdzania chorób zawodowych. -Art. 223. § 1. Pracodawca jest obowiązany chronić pracowników przed promieniowaniem jonizującym, pochodzącym ze źródeł sztucznych i naturalnych, występujących w środowisku pracy. - -§ 2. Dawka promieniowania jonizującego pochodzącego ze źródeł naturalnych, otrzymywana przez pracownika przy pracy w warunkach narażenia na to promieniowanie, nie może przekraczać dawek granicznych, określonych w odrębnych przepisach dla sztucznych źródeł promieniowania jonizującego. - -Art. 224. § 1. Pracodawca prowadzący działalność, która stwarza możliwość wystąpienia nagłego niebezpieczeństwa dla zdrowia lub życia pracowników, jest obowiązany podejmować działania zapobiegające takiemu niebezpieczeństwu. - -§ 2. W przypadku, o którym mowa w § 1, pracodawca jest obowiązany zapewnić: - -1) odpowiednie do rodzaju niebezpieczeństwa urządzenia i sprzęt ratowniczy oraz ich obsługę przez osoby należycie przeszkolone, -2) udzielenie pierwszej pomocy poszkodowanym. -§ 3. Przepisy § 1 i 2 nie naruszają wymagań, określonych w odrębnych przepisach, dotyczących katastrof i innych nadzwyczajnych zagrożeń. - -Art. 225. § 1. Pracodawca jest obowiązany zapewnić, aby prace, przy których istnieje możliwość wystąpienia szczególnego zagrożenia dla zdrowia lub życia ludzkiego, były wykonywane przez co najmniej dwie osoby, w celu zapewnienia asekuracji. - -§ 2. Wykaz prac, o których mowa w § 1, ustala pracodawca po konsultacji z pracownikami lub ich przedstawicielami, uwzględniając przepisy wydane na podstawie art. 23715. - -Rozdział VI -Profilaktyczna ochrona zdrowia - -Art. 226. Pracodawca: - -1) ocenia i dokumentuje ryzyko zawodowe związane z wykonywaną pracą oraz stosuje niezbędne środki profilaktyczne zmniejszające ryzyko, -2) informuje pracowników o ryzyku zawodowym, które wiąże się z wykonywaną pracą, oraz o zasadach ochrony przed zagrożeniami. -Art. 227. § 1. Pracodawca jest obowiązany stosować środki zapobiegające chorobom zawodowym i innym chorobom związanym z wykonywaną pracą, w szczególności: - -1) utrzymywać w stanie stałej sprawności urządzenia ograniczające lub eliminujące szkodliwe dla zdrowia czynniki środowiska pracy oraz urządzenia służące do pomiarów tych czynników, -2) przeprowadzać, na swój koszt, badania i pomiary czynników szkodliwych dla zdrowia, rejestrować i przechowywać wyniki tych badań i pomiarów oraz udostępniać je pracownikom. -§ 2. Minister właściwy do spraw zdrowia, uwzględniając zróżnicowane działanie na organizm człowieka czynników szkodliwych występujących w środowisku pracy oraz konieczność podjęcia niezbędnych środków zabezpieczających przed ich działaniem, określi, w drodze rozporządzenia: - -1) tryb, metody, rodzaj i częstotliwość wykonywania badań i pomiarów, o których mowa w § 1 pkt 2, -2) przypadki, w których jest konieczne prowadzenie pomiarów ciągłych, -3) wymagania, jakie powinny spełniać laboratoria wykonujące badania i pomiary, -4) sposób rejestrowania i przechowywania wyników tych badań i pomiarów, -5) wzory dokumentów oraz sposób udostępniania wyników badań i pomiarów pracownikom. -Art. 228. § 1. Prezes Rady Ministrów powoła, w drodze rozporządzenia, Międzyresortową Komisję do Spraw Najwyższych Dopuszczalnych Stężeń i Natężeń Czynników Szkodliwych dla Zdrowia w Środowisku Pracy, określi jej uprawnienia oraz sposób wykonywania zadań. - -§ 2. Do zadań Komisji, o której mowa w § 1, należy: - -1) przedkładanie Ministrowi Pracy i Polityki Socjalnej wniosków dotyczących wartości najwyższych dopuszczalnych stężeń i natężeń czynników szkodliwych dla zdrowia w środowisku pracy - do celów określonych w § 3, -2) inicjowanie prac badawczych niezbędnych do realizacji zadań, o których mowa w pkt 1. -§ 3. Minister Pracy i Polityki Socjalnej w porozumieniu z Ministrem Zdrowia i Opieki Społecznej określi, w drodze rozporządzenia, wykaz najwyższych dopuszczalnych stężeń i natężeń czynników szkodliwych dla zdrowia w środowisku pracy. - -Art. 229. § 1. Wstępnym badaniom lekarskim, z zastrzeżeniem § 11, podlegają: - -1) osoby przyjmowane do pracy; -2) pracownicy młodociani przenoszeni na inne stanowiska pracy i inni pracownicy przenoszeni na stanowiska pracy, na których występują czynniki szkodliwe dla zdrowia lub warunki uciążliwe. -§ 11. Wstępnym badaniom lekarskim nie podlegają osoby: - -1) przyjmowane ponownie do pracy u tego samego pracodawcy na to samo stanowisko lub na stanowisko o takich samych warunkach pracy w ciągu 30 dni po rozwiązaniu lub wygaśnięciu poprzedniego stosunku pracy z tym pracodawcą; -2) przyjmowane do pracy u innego pracodawcy na dane stanowisko w ciągu 30 dni po rozwiązaniu lub wygaśnięciu poprzedniego stosunku pracy, jeżeli posiadają aktualne orzeczenie lekarskie stwierdzające brak przeciwwskazań do pracy w warunkach pracy opisanych w skierowaniu na badania lekarskie i pracodawca ten stwierdzi, że warunki te odpowiadają warunkom występującym na danym stanowisku pracy, z wyłączeniem osób przyjmowanych do wykonywania prac szczególnie niebezpiecznych. -§ 12. Przepis § 11 pkt 2 stosuje się odpowiednio w przypadku przyjmowania do pracy osoby pozostającej jednocześnie w stosunku pracy z innym pracodawcą. - -§ 13. Pracodawca żąda od osoby, o której mowa w § 11 pkt 2 oraz w § 12, aktualnego orzeczenia lekarskiego stwierdzającego brak przeciwwskazań do pracy na danym stanowisku oraz skierowania na badania będące podstawą wydania tego orzeczenia. - -§ 2. Pracownik podlega okresowym badaniom lekarskim. W przypadku niezdolności do pracy trwającej dłużej niż 30 dni, spowodowanej chorobą, pracownik podlega ponadto kontrolnym badaniom lekarskim w celu ustalenia zdolności do wykonywania pracy na dotychczasowym stanowisku. - -§ 3. Okresowe i kontrolne badania lekarskie przeprowadza się w miarę możliwości w godzinach pracy. Za czas niewykonywania pracy w związku z przeprowadzanymi badaniami pracownik zachowuje prawo do wynagrodzenia, a w razie przejazdu na te badania do innej miejscowości przysługują mu należności na pokrycie kosztów przejazdu według zasad obowiązujących przy podróżach służbowych. - -§ 4. Pracodawca nie może dopuścić do pracy pracownika bez aktualnego orzeczenia lekarskiego stwierdzającego brak przeciwwskazań do pracy na określonym stanowisku w warunkach pracy opisanych w skierowaniu na badania lekarskie. - -§ 4a. Wstępne, okresowe i kontrolne badania lekarskie przeprowadza się na podstawie skierowania wydanego przez pracodawcę. - -§ 5. Pracodawca zatrudniający pracowników w warunkach narażenia na działanie substancji i czynników rakotwórczych lub pyłów zwłókniających jest obowiązany zapewnić tym pracownikom okresowe badania lekarskie także: - -1) po zaprzestaniu pracy w kontakcie z tymi substancjami, czynnikami lub pyłami, -2) po rozwiązaniu stosunku pracy, jeżeli zainteresowana osoba zgłosi wniosek o objęcie takimi badaniami. -§ 6. Badania, o których mowa w § 1, 2 i 5, są przeprowadzane na koszt pracodawcy, z zastrzeżeniem § 61. Pracodawca ponosi ponadto inne koszty profilaktycznej opieki zdrowotnej nad pracownikami, niezbędnej z uwagi na warunki pracy. - -§ 61. W przypadku gdy pracownik skierowany na wstępne, okresowe albo kontrolne badania lekarskie spełnia warunki objęcia programem zdrowotnym lub programem polityki zdrowotnej, lekarz przeprowadzający wstępne, okresowe albo kontrolne badania lekarskie kieruje pracownika, za jego zgodą, do udziału w programie zdrowotnym lub programie polityki zdrowotnej. Jeżeli pracownik wykona wstępne, okresowe albo kontrolne badania lekarskie zgodnie z programem zdrowotnym lub programem polityki zdrowotnej, badania te są finansowane na zasadach określonych w programie zdrowotnym lub programie polityki zdrowotnej. - -§ 62. Jeżeli zakres badań określonych w programie zdrowotnym lub programie polityki zdrowotnej nie odpowiada pełnemu zakresowi badań wymaganych w celu wydania orzeczenia lekarskiego dotyczącego przeciwwskazań do pracy na określonym stanowisku w warunkach pracy opisanych w skierowaniu, o którym mowa w § 4a, określonych w przepisach wydanych na podstawie § 8, lekarz przeprowadzający wstępne, okresowe albo kontrolne badania lekarskie wydaje pracownikowi również skierowanie na przeprowadzenie pozostałych badań wynikających z tych przepisów. - -§ 63. Lekarz wydaje orzeczenie lekarskie stwierdzające brak przeciwwskazań do pracy w warunkach pracy opisanych w skierowaniu, o którym mowa w § 4a, wyłącznie na podstawie wyników badań, których zakres odpowiada zakresowi badań określonych w przepisach wydanych na podstawie § 8. - -§ 64. Minister właściwy do spraw zdrowia ogłasza, w drodze obwieszczenia, wykaz programów zdrowotnych lub programów polityki zdrowotnej realizowanych przez ministra właściwego do spraw zdrowia lub Narodowy Fundusz Zdrowia, które uwzględnia lekarz w ramach przeprowadzania badania wstępnego, badania okresowego albo badania kontrolnego pracownika. - -§ 65. Do przeprowadzania badań w zakresie wskazanym w programie zdrowotnym lub programie polityki zdrowotnej stosuje się § 3. - -§ 7. Pracodawca przechowuje orzeczenia wydane na podstawie badań lekarskich, o których mowa w § 1, 2 i 5, orzeczenia i skierowania uzyskane na podstawie § 13 oraz skierowania, o których mowa w § 4a. - -§ 71. W przypadku stwierdzenia, że warunki określone w skierowaniu, o którym mowa w § 13, nie odpowiadają warunkom występującym na danym stanowisku pracy, pracodawca zwraca osobie przyjmowanej do pracy to skierowanie oraz orzeczenie lekarskie wydane w wyniku tego skierowania. - -§ 8. Minister właściwy do spraw zdrowia w porozumieniu z ministrem właściwym do spraw pracy określi, w drodze rozporządzenia: - -1) tryb i zakres badań lekarskich, o których mowa w § 1, 2 i 5, oraz częstotliwość badań okresowych, a także sposób dokumentowania i kontroli badań lekarskich, -2) tryb wydawania i przechowywania orzeczeń lekarskich do celów przewidzianych w niniejszej ustawie i w przepisach wydanych na jej podstawie, -3) zakres informacji objętych skierowaniem na badania lekarskie i orzeczeniem lekarskim, a także wzory tych dokumentów, -4) zakres profilaktycznej opieki zdrowotnej, o której mowa w § 6 zdanie drugie, -5) dodatkowe wymagania kwalifikacyjne, jakie powinni spełniać lekarze przeprowadzający badania, o których mowa w § 1, 2 i 5, oraz sprawujący profilaktyczną opiekę zdrowotną, o której mowa w § 6 zdanie drugie -- uwzględniając konieczność zapewnienia prawidłowego przebiegu i kompleksowości badań lekarskich, o których mowa w § 1, 2 i 5, profilaktycznej opieki zdrowotnej, o której mowa w § 6 zdanie drugie, a także informacji umożliwiających porównanie warunków pracy u pracodawcy oraz ochrony danych osobowych osób poddanych badaniom. -Art. 230. § 1. W razie stwierdzenia u pracownika objawów wskazujących na powstawanie choroby zawodowej, pracodawca jest obowiązany, na podstawie orzeczenia lekarskiego, w terminie i na czas określony w tym orzeczeniu, przenieść pracownika do innej pracy nie narażającej go na działanie czynnika, który wywołał te objawy. - -§ 2. Jeżeli przeniesienie do innej pracy powoduje obniżenie wynagrodzenia, pracownikowi przysługuje dodatek wyrównawczy przez okres nie przekraczający 6 miesięcy. - -Art. 231. Pracodawca, na podstawie orzeczenia lekarskiego, przenosi do odpowiedniej pracy pracownika, który stał się niezdolny do wykonywania dotychczasowej pracy wskutek wypadku przy pracy lub choroby zawodowej i nie został uznany za niezdolnego do pracy w rozumieniu przepisów o emeryturach i rentach z Funduszu Ubezpieczeń Społecznych. Przepis art. 230 § 2 stosuje się odpowiednio. - -Art. 232. Pracodawca jest obowiązany zapewnić pracownikom zatrudnionym w warunkach szczególnie uciążliwych, nieodpłatnie, odpowiednie posiłki i napoje, jeżeli jest to niezbędne ze względów profilaktycznych. Rada Ministrów określi, w drodze rozporządzenia, rodzaje tych posiłków i napojów oraz wymagania, jakie powinny spełniać, a także przypadki i warunki ich wydawania. - -Art. 233. Pracodawca jest obowiązany zapewnić pracownikom odpowiednie urządzenia higieniczno-sanitarne oraz dostarczyć niezbędne środki higieny osobistej. - -Rozdział VII -Wypadki przy pracy i choroby zawodowe - -Art. 234. § 1. W razie wypadku przy pracy pracodawca jest obowiązany podjąć niezbędne działania eliminujące lub ograniczające zagrożenie, zapewnić udzielenie pierwszej pomocy osobom poszkodowanym i ustalenie w przewidzianym trybie okoliczności i przyczyn wypadku oraz zastosować odpowiednie środki zapobiegające podobnym wypadkom. - -§ 2. Pracodawca jest obowiązany niezwłocznie zawiadomić właściwego okręgowego inspektora pracy i prokuratora o śmiertelnym, ciężkim lub zbiorowym wypadku przy pracy oraz o każdym innym wypadku, który wywołał wymienione skutki, mającym związek z pracą, jeżeli może być uznany za wypadek przy pracy. - -§ 3. Pracodawca jest obowiązany prowadzić rejestr wypadków przy pracy. - -§ 31. Pracodawca jest obowiązany przechowywać protokół ustalenia okoliczności i przyczyn wypadku przy pracy wraz z pozostałą dokumentacją powypadkową przez 10 lat. - -§ 4. Koszty związane z ustalaniem okoliczności i przyczyn wypadków przy pracy ponosi pracodawca. - -Art. 235. § 1. Pracodawca jest obowiązany niezwłocznie zgłosić właściwemu państwowemu inspektorowi sanitarnemu i właściwemu okręgowemu inspektorowi pracy każdy przypadek podejrzenia choroby zawodowej. - -§ 2. Obowiązek, o którym mowa w § 1, dotyczy także lekarza podmiotu właściwego do rozpoznania choroby zawodowej, o którym mowa w przepisach wydanych na podstawie art. 237 § 1 pkt 6. - -§ 21. W każdym przypadku podejrzenia choroby zawodowej: - -1) lekarz, -2) lekarz dentysta, który podczas wykonywania zawodu powziął takie podejrzenie u pacjenta -- kieruje na badania w celu wydania orzeczenia o rozpoznaniu choroby zawodowej albo o braku podstaw do jej rozpoznania. -§ 22. Zgłoszenia podejrzenia choroby zawodowej może również dokonać pracownik lub były pracownik, który podejrzewa, że występujące u niego objawy mogą wskazywać na taką chorobę, przy czym pracownik aktualnie zatrudniony zgłasza podejrzenie za pośrednictwem lekarza sprawującego nad nim profilaktyczną opiekę zdrowotną. - -§ 3. W razie rozpoznania u pracownika choroby zawodowej, pracodawca jest obowiązany: - -1) ustalić przyczyny powstania choroby zawodowej oraz charakter i rozmiar zagrożenia tą chorobą, działając w porozumieniu z właściwym państwowym inspektorem sanitarnym, -2) przystąpić niezwłocznie do usunięcia czynników powodujących powstanie choroby zawodowej i zastosować inne niezbędne środki zapobiegawcze, -3) zapewnić realizację zaleceń lekarskich. -§ 4. Pracodawca jest obowiązany prowadzić rejestr obejmujący przypadki stwierdzonych chorób zawodowych i podejrzeń o takie choroby. - -§ 5. Pracodawca przesyła zawiadomienie o skutkach choroby zawodowej do instytutu medycyny pracy wskazanego w przepisach wydanych na podstawie art. 237 § 11 oraz do właściwego państwowego inspektora sanitarnego. - - -Art. 2351. Za chorobę zawodową uważa się chorobę, wymienioną w wykazie chorób zawodowych, jeżeli w wyniku oceny warunków pracy można stwierdzić bezspornie lub z wysokim prawdopodobieństwem, że została ona spowodowana działaniem czynników szkodliwych dla zdrowia występujących w środowisku pracy albo w związku ze sposobem wykonywania pracy, zwanych "narażeniem zawodowym". - - -Art. 2352. Rozpoznanie choroby zawodowej u pracownika lub byłego pracownika może nastąpić w okresie jego zatrudnienia w narażeniu zawodowym albo po zakończeniu pracy w takim narażeniu, pod warunkiem wystąpienia udokumentowanych objawów chorobowych w okresie ustalonym w wykazie chorób zawodowych. - -Art. 236. Pracodawca jest obowiązany systematycznie analizować przyczyny wypadków przy pracy, chorób zawodowych i innych chorób związanych z warunkami środowiska pracy i na podstawie wyników tych analiz stosować właściwe środki zapobiegawcze. - -Art. 237. § 1. Rada Ministrów określi w drodze rozporządzenia: - -1) sposób i tryb postępowania przy ustalaniu okoliczności i przyczyn wypadków przy pracy oraz sposób ich dokumentowania, a także zakres informacji zamieszczanych w rejestrze wypadków przy pracy, -2) skład zespołu powypadkowego, -3) wykaz chorób zawodowych, -4) okres, w którym wystąpienie udokumentowanych objawów chorobowych upoważnia do rozpoznania choroby zawodowej pomimo wcześniejszego zakończenia pracy w narażeniu zawodowym, -5) sposób i tryb postępowania dotyczący zgłaszania podejrzenia, rozpoznawania i stwierdzania chorób zawodowych, -6) podmioty właściwe w sprawie rozpoznawania chorób zawodowych -- uwzględniając aktualną wiedzę w zakresie patogenezy i epidemiologii chorób powodowanych przez czynniki szkodliwe dla człowieka występujące w środowisku pracy oraz kierując się koniecznością zapobiegania występowaniu wypadków przy pracy i chorób zawodowych. -§ 11. Rada Ministrów wskaże w drodze rozporządzenia instytut medycyny pracy, do którego pracodawca przesyła zawiadomienie o skutkach choroby zawodowej oraz termin, w którym ma ono być przesłane, mając na uwadze specjalizację instytutu oraz rodzaj prowadzonych w nim badań. - -§ 2. Minister właściwy do spraw pracy określi, w drodze rozporządzenia, wzór protokołu ustalenia okoliczności i przyczyn wypadku przy pracy zawierający dane dotyczące poszkodowanego, składu zespołu powypadkowego, wypadku i jego skutków, stwierdzenie, że wypadek jest lub nie jest wypadkiem przy pracy, oraz wnioski i zalecane środki profilaktyczne, a także pouczenie dla stron postępowania powypadkowego. - -§ 3. Minister właściwy do spraw pracy określi, w drodze rozporządzenia, wzór statystycznej karty wypadku przy pracy, uwzględniając dane dotyczące pracodawcy, poszkodowanego, wypadku przy pracy, a także jego skutków oraz sposób i terminy jej sporządzania i przekazywania do właściwego urzędu statystycznego. - -§ 4. Minister właściwy do spraw zdrowia określi, w drodze rozporządzenia: - -1) sposób dokumentowania chorób zawodowych i skutków tych chorób, a także prowadzenia rejestrów chorób zawodowych, uwzględniając w szczególności wzory dokumentów stosowanych w postępowaniu dotyczącym tych chorób oraz dane objęte rejestrem. -2) (uchylony) -Art. 2371. § 1. Pracownikowi, który uległ wypadkowi przy pracy lub zachorował na chorobę zawodową określoną w wykazie, o którym mowa w art. 237 § 1 pkt 3, przysługują świadczenia z ubezpieczenia społecznego, określone w odrębnych przepisach. - -§ 2. Pracownikowi, który uległ wypadkowi przy pracy, przysługuje od pracodawcy odszkodowanie za utratę lub uszkodzenie w związku z wypadkiem przedmiotów osobistego użytku oraz przedmiotów niezbędnych do wykonywania pracy, z wyjątkiem utraty lub uszkodzenia pojazdów samochodowych oraz wartości pieniężnych. - -Rozdział VIII -Szkolenie - -Art. 2372. Minister Edukacji Narodowej jest obowiązany zapewnić uwzględnianie problematyki bezpieczeństwa i higieny pracy oraz ergonomii w programach nauczania w szkołach, po uzgodnieniu zakresu tej problematyki z Ministrem Pracy i Polityki Socjalnej. - -Art. 2373. § 1. Nie wolno dopuścić pracownika do pracy, do której wykonywania nie posiada on wymaganych kwalifikacji lub potrzebnych umiejętności, a także dostatecznej znajomości przepisów oraz zasad bezpieczeństwa i higieny pracy. - -§ 2. Pracodawca jest obowiązany zapewnić przeszkolenie pracownika w zakresie bezpieczeństwa i higieny pracy przed dopuszczeniem go do pracy oraz prowadzenie okresowych szkoleń w tym zakresie. Szkolenie pracownika przed dopuszczeniem do pracy nie jest wymagane w przypadku podjęcia przez niego pracy na tym samym stanowisku pracy, które zajmował u danego pracodawcy bezpośrednio przed nawiązaniem z tym pracodawcą kolejnej umowy o pracę. - -§ 21. Pracodawca jest obowiązany odbyć szkolenie w dziedzinie bezpieczeństwa i higieny pracy w zakresie niezbędnym do wykonywania ciążących na nim obowiązków. Szkolenie to powinno być okresowo powtarzane. - -§ 22. Szkolenie okresowe pracownika, o którym mowa w § 2, nie jest wymagane w przypadku pracownika na stanowisku administracyjno-biurowym, gdy rodzaj przeważającej działalności pracodawcy w rozumieniu przepisów o statystyce publicznej znajduje się w grupie działalności, dla której ustalono nie wyższą niż trzecia kategorię ryzyka w rozumieniu przepisów o ubezpieczeniu społecznym z tytułu wypadków przy pracy i chorób zawodowych, chyba że z oceny ryzyka, o której mowa w art. 226 pkt 1, wynika, że jest to konieczne. - -§ 23. W przypadku gdy rodzaj przeważającej działalności pracodawcy w rozumieniu przepisów o statystyce publicznej znajdzie się w grupie działalności, dla której zostanie ustalona wyższa niż trzecia kategoria ryzyka w rozumieniu przepisów o ubezpieczeniu społecznym z tytułu wypadków przy pracy i chorób zawodowych, pracodawca jest obowiązany przeprowadzić szkolenie okresowe pracownika, o którym mowa w § 22, w zakresie bezpieczeństwa i higieny pracy, w terminie nie dłuższym niż 6 miesięcy, licząc od dnia ustalenia wyższej kategorii ryzyka. - -§ 24. Przepis § 23 stosuje się odpowiednio, gdy z dokonanej oceny ryzyka, o której mowa w art. 226 pkt 1, wynika, że przeprowadzenie szkolenia okresowego pracownika, o którym mowa w § 22, stało się konieczne. Szkolenie okresowe przeprowadza się w terminie nie dłuższym niż 6 miesięcy, licząc od dnia dokonania oceny ryzyka. - -§ 3. Szkolenia, o których mowa w § 2, odbywają się w czasie pracy i na koszt pracodawcy. - -Art. 2374. § 1. Pracodawca jest obowiązany zaznajamiać pracowników z przepisami i zasadami bezpieczeństwa i higieny pracy dotyczącymi wykonywanych przez nich prac. - -§ 2. Pracodawca jest obowiązany wydawać szczegółowe instrukcje i wskazówki dotyczące bezpieczeństwa i higieny pracy na stanowiskach pracy. - -§ 3. Pracownik jest obowiązany potwierdzić na piśmie zapoznanie się z przepisami oraz zasadami bezpieczeństwa i higieny pracy. - -Art. 2375. Minister właściwy do spraw pracy określi, w drodze rozporządzenia, szczegółowe zasady szkolenia w dziedzinie bezpieczeństwa i higieny pracy, zakres tego szkolenia, wymagania dotyczące treści i realizacji programów szkolenia, sposób dokumentowania szkolenia oraz przypadki, w których pracodawcy lub pracownicy mogą być zwolnieni z określonych rodzajów szkolenia. - -Rozdział IX -Środki ochrony indywidualnej oraz odzież i obuwie robocze - -Art. 2376. § 1. Pracodawca jest obowiązany dostarczyć pracownikowi nieodpłatnie środki ochrony indywidualnej zabezpieczające przed działaniem niebezpiecznych i szkodliwych dla zdrowia czynników występujących w środowisku pracy oraz informować go o sposobach posługiwania się tymi środkami. - -§ 2. (skreślony). - -§ 3. Pracodawca jest obowiązany dostarczać pracownikowi środki ochrony indywidualnej, które spełniają wymagania dotyczące oceny zgodności określone w odrębnych przepisach. - -Art. 2377. § 1. Pracodawca jest obowiązany dostarczyć pracownikowi nieodpłatnie odzież i obuwie robocze, spełniające wymagania określone w Polskich Normach: - -1) jeżeli odzież własna pracownika może ulec zniszczeniu lub znacznemu zabrudzeniu, -2) ze względu na wymagania technologiczne, sanitarne lub bezpieczeństwa i higieny pracy. -§ 2. Pracodawca może ustalić stanowiska, na których dopuszcza się używanie przez pracowników, za ich zgodą, własnej odzieży i obuwia roboczego, spełniających wymagania bezpieczeństwa i higieny pracy. - -§ 3. Przepis § 2 nie dotyczy stanowisk, na których są wykonywane prace związane z bezpośrednią obsługą maszyn i innych urządzeń technicznych albo prace powodujące intensywne brudzenie lub skażenie odzieży i obuwia roboczego środkami chemicznymi lub promieniotwórczymi albo materiałami biologicznie zakaźnymi. - -§ 4. Pracownikowi używającemu własnej odzieży i obuwia roboczego, zgodnie z § 2, pracodawca wypłaca ekwiwalent pieniężny w wysokości uwzględniającej ich aktualne ceny. - -Art. 2378. § 1. Pracodawca ustala rodzaje środków ochrony indywidualnej oraz odzieży i obuwia roboczego, których stosowanie na określonych stanowiskach jest niezbędne w związku z art. 2376 § 1 i art. 2377 § 1, oraz przewidywane okresy użytkowania odzieży i obuwia roboczego. - -§ 2. Środki ochrony indywidualnej oraz odzież i obuwie robocze, o których mowa w art. 2376 § 1 i art. 2377 § 1, stanowią własność pracodawcy. - -Art. 2379. § 1. Pracodawca nie może dopuścić pracownika do pracy bez środków ochrony indywidualnej oraz odzieży i obuwia roboczego, przewidzianych do stosowania na danym stanowisku pracy. - -§ 2. Pracodawca jest obowiązany zapewnić, aby stosowane środki ochrony indywidualnej oraz odzież i obuwie robocze posiadały właściwości ochronne i użytkowe, oraz zapewnić odpowiednio ich pranie, konserwację, naprawę, odpylanie i odkażanie. - -§ 3. Jeżeli pracodawca nie może zapewnić prania odzieży roboczej, czynności te mogą być wykonywane przez pracownika, pod warunkiem wypłacania przez pracodawcę ekwiwalentu pieniężnego w wysokości kosztów poniesionych przez pracownika. - -Art. 23710. § 1. Pracodawca jest obowiązany zapewnić, aby środki ochrony indywidualnej oraz odzież i obuwie robocze, które w wyniku stosowania w procesie pracy uległy skażeniu środkami chemicznymi lub promieniotwórczymi albo materiałami biologicznie zakaźnymi, były przechowywane wyłącznie w miejscu przez niego wyznaczonym. - -§ 2. Powierzanie pracownikowi prania, konserwacji, odpylania i odkażania przedmiotów, o których mowa w § 1, jest niedopuszczalne. - -Rozdział X -Służba bezpieczeństwa i higieny pracy - -Art. 23711. § 1. Pracodawca zatrudniający więcej niż 100 pracowników tworzy służbę bezpieczeństwa i higieny pracy, zwaną dalej „służbą bhp”, pełniącą funkcje doradcze i kontrolne w zakresie bezpieczeństwa i higieny pracy, zaś pracodawca zatrudniający do 100 pracowników powierza wykonywanie zadań służby bhp pracownikowi zatrudnionemu przy innej pracy. Pracodawca posiadający ukończone szkolenie niezbędne do wykonywania zadań służby bhp może sam wykonywać zadania tej służby, jeżeli: - -1) zatrudnia do 10 pracowników albo -2) zatrudnia do 50 pracowników i jest zakwalifikowany do grupy działalności, dla której ustalono nie wyższą niż trzecia kategorię ryzyka w rozumieniu przepisów o ubezpieczeniu społecznym z tytułu wypadków przy pracy i chorób zawodowych. -§ 2. Pracodawca - w przypadku braku kompetentnych pracowników - może powierzyć wykonywanie zadań służby bhp specjalistom spoza zakładu pracy. Pracownik służby bhp oraz pracownik zatrudniony przy innej pracy, któremu powierzono wykonywanie zadań służby bhp, o którym mowa w § 1, a także specjalista spoza zakładu pracy powinni spełniać wymagania kwalifikacyjne niezbędne do wykonywania zadań służby bhp oraz ukończyć szkolenie w dziedzinie bezpieczeństwa i higieny pracy dla pracowników tej służby. - -§ 3. Pracownik służby bhp oraz pracownik zatrudniony przy innej pracy, któremu powierzono wykonywanie zadań tej służby, nie mogą ponosić jakichkolwiek niekorzystnych dla nich następstw z powodu wykonywania zadań i uprawnień służby bhp. - -§ 4. Właściwy inspektor pracy może nakazać utworzenie służby bhp, albo zwiększenie liczby pracowników tej służby, jeżeli jest to uzasadnione stwierdzonymi zagrożeniami zawodowymi. - -§ 5. Rada Ministrów określi, w drodze rozporządzenia: - -1) szczegółowy zakres działania, uprawnienia, organizację, liczebność i podporządkowanie służby bhp, -2) kwalifikacje wymagane do wykonywania zadań służby bhp. -Rozdział XI -Konsultacje w zakresie bezpieczeństwa i higieny pracy oraz komisja bezpieczeństwa i higieny pracy - - -Art. 23711a. § 1. Pracodawca konsultuje z pracownikami lub ich przedstawicielami wszystkie działania związane z bezpieczeństwem i higieną pracy, w szczególności dotyczące: - -1) zmian w organizacji pracy i wyposażeniu stanowisk pracy, wprowadzania nowych procesów technologicznych oraz substancji chemicznych i ich mieszanin, jeżeli mogą one stwarzać zagrożenie dla zdrowia lub życia pracowników, -2) oceny ryzyka zawodowego występującego przy wykonywaniu określonych prac oraz informowania pracowników o tym ryzyku, -3) tworzenia służby bhp lub powierzania wykonywania zadań tej służby innym osobom oraz wyznaczania pracowników do udzielania pierwszej pomocy, a także wykonywania działań w zakresie zwalczania pożarów i ewakuacji pracowników, -4) przydzielania pracownikom środków ochrony indywidualnej oraz odzieży i obuwia roboczego, -5) szkolenia pracowników w dziedzinie bezpieczeństwa i higieny pracy. -§ 2. Pracownicy lub ich przedstawiciele mogą przedstawiać pracodawcy wnioski w sprawie eliminacji lub ograniczenia zagrożeń zawodowych. - -§ 3. Pracodawca zapewnia odpowiednie warunki do przeprowadzania konsultacji, a zwłaszcza zapewnia, aby odbywały się w godzinach pracy. Za czas nieprzepracowany w związku z udziałem w konsultacjach pracownicy lub ich przedstawiciele zachowują prawo do wynagrodzenia. - -§ 4. Na umotywowany wniosek pracowników lub ich przedstawicieli dotyczący spraw zagrożenia zdrowia i życia pracowników inspektorzy pracy Państwowej Inspekcji Pracy przeprowadzają kontrole oraz stosują środki prawne przewidziane w przepisach o Państwowej Inspekcji Pracy. - -§ 5. U pracodawcy, u którego została powołana komisja bezpieczeństwa i higieny pracy - konsultacje, o których mowa w § 1, mogą być prowadzone w ramach tej komisji, natomiast uprawnienia, o których mowa w § 2 i 4, przysługują pracownikom lub ich przedstawicielom wchodzącym w skład komisji. - -§ 6. Pracownicy lub ich przedstawiciele nie mogą ponosić jakichkolwiek niekorzystnych dla nich konsekwencji z tytułu działalności, o której mowa w § 1, 2 i 4. Dotyczy to również pracowników lub ich przedstawicieli, o których mowa w § 5. - -Art. 23712. - -§ 1. Pracodawca zatrudniający więcej niż 250 pracowników powołuje komisję bezpieczeństwa i higieny pracy, zwaną dalej „komisją bhp”, jako swój organ doradczy i opiniodawczy. W skład komisji bhp wchodzą w równej liczbie przedstawiciele pracodawcy, w tym pracownicy służby bhp i lekarz sprawujący profilaktyczną opiekę zdrowotną nad pracownikami, oraz przedstawiciele pracowników, w tym społeczny inspektor pracy. - -§ 2. Przewodniczącym komisji bhp jest pracodawca lub osoba przez niego upoważniona, a wiceprzewodniczącym - społeczny inspektor pracy lub przedstawiciel pracowników. - -Art. 23713. - -§ 1. Zadaniem komisji bhp jest dokonywanie przeglądu warunków pracy, okresowej oceny stanu bezpieczeństwa i higieny pracy, opiniowanie podejmowanych przez pracodawcę środków zapobiegających wypadkom przy pracy i chorobom zawodowym, formułowanie wniosków dotyczących poprawy warunków pracy oraz współdziałanie z pracodawcą w realizacji jego obowiązków w zakresie bezpieczeństwa i higieny pracy. - -§ 2. Posiedzenia komisji bhp odbywają się w godzinach pracy, nie rzadziej niż raz na kwartał. Za czas nieprzepracowany w związku z udziałem w posiedzeniach komisji bhp pracownik zachowuje prawo do wynagrodzenia. - -§ 3. Komisja bhp w związku z wykonywaniem zadań wymienionych w § 1 korzysta z ekspertyz lub opinii specjalistów spoza zakładu pracy w przypadkach uzgodnionych z pracodawcą i na jego koszt. - - -Art. 23713a. Przedstawiciele pracowników, o których mowa w art. 23711a i art. 23712, są wybierani przez zakładowe organizacje związkowe, a jeżeli u pracodawcy takie organizacje nie działają - przez pracowników, w trybie przyjętym w zakładzie pracy. - -Rozdział XII -Obowiązki organów sprawujących nadzór nad przedsiębiorstwami lub innymi jednostkami organizacyjnymi państwowymi albo samorządowymi - -Art. 23714. Organy sprawujące nadzór nad przedsiębiorstwami lub innymi jednostkami organizacyjnymi państwowymi albo samorządowymi są obowiązane podejmować działania na rzecz kształtowania bezpiecznych i higienicznych warunków pracy, w szczególności: - -1) udzielać przedsiębiorstwom i jednostkom organizacyjnym pomocy przy wykonywaniu zadań z zakresu bezpieczeństwa i higieny pracy, -2) dokonywać, co najmniej raz w roku, oceny stanu bezpieczeństwa i higieny pracy w przedsiębiorstwach i jednostkach organizacyjnych oraz określać kierunki poprawy tego stanu, -3) w miarę potrzeb i możliwości - inicjować i prowadzić badania naukowe dotyczące bezpieczeństwa i higieny pracy. -Rozdział XIII -Przepisy bezpieczeństwa i higieny pracy dotyczące wykonywania prac w różnych gałęziach pracy - -Art. 23715. § 1. Minister Pracy i Polityki Socjalnej w porozumieniu z Ministrem Zdrowia i Opieki Społecznej określi, w drodze rozporządzenia, ogólnie obowiązujące przepisy bezpieczeństwa i higieny pracy dotyczące prac wykonywanych w różnych gałęziach pracy. - -§ 2. Ministrowie właściwi dla określonych gałęzi pracy lub rodzajów prac w porozumieniu z Ministrem Pracy i Polityki Socjalnej oraz Ministrem Zdrowia i Opieki Społecznej określą, w drodze rozporządzenia, przepisy bezpieczeństwa i higieny pracy dotyczące tych gałęzi lub prac. - -DZIAŁ JEDENASTY -Układy zbiorowe pracy - -Rozdział I -Przepisy ogólne - -Art. 238. § 1. Ilekroć w przepisach działu jest mowa o: - -1) ponadzakładowej organizacji związkowej - należy przez to rozumieć organizację związkową będącą ogólnokrajowym związkiem zawodowym, zrzeszeniem (federacją) związków zawodowych lub ogólnokrajową organizacją międzyzwiązkową (konfederacją), -2) organizacji związkowej reprezentującej pracowników - należy przez to rozumieć organizację związkową zrzeszającą pracowników, dla których układ jest zawierany. Dotyczy to również zrzeszenia (federacji) związków zawodowych, w skład którego wchodzą te organizacje związkowe, a także ogólnokrajowej organizacji międzyzwiązkowej (konfederacji) zrzeszającej takie organizacje związkowe lub zrzeszenia (federacje) związków zawodowych. -§ 2. Przepisy rozdziału odnoszące się do: - -1) układu - stosuje się odpowiednio do układu ponadzakładowego i układu zakładowego, -2) pracodawców - stosuje się odpowiednio do pracodawcy. -Art. 239. § 1. Układ zawiera się dla wszystkich pracowników zatrudnionych przez pracodawców objętych jego postanowieniami, chyba że strony w układzie postanowią inaczej. - -§ 2. Układem mogą być objęci emeryci i renciści. - -§ 3. Układu nie zawiera się dla: - -1) członków korpusu służby cywilnej, -2) pracowników urzędów państwowych zatrudnionych na podstawie mianowania i powołania, -3) pracowników samorządowych zatrudnionych na podstawie wyboru, mianowania i powołania w: -a) urzędach marszałkowskich, -b) starostwach powiatowych, -c) urzędach gminy, -d) biurach (ich odpowiednikach) związków jednostek samorządu terytorialnego, -e) biurach (ich odpowiednikach) jednostek administracyjnych jednostek samorządu terytorialnego, -4) sędziów, asesorów sądowych i prokuratorów. -Art. 240. § 1. Układ określa: - -1) warunki, jakim powinna odpowiadać treść stosunku pracy, z zastrzeżeniem § 3, -2) wzajemne zobowiązania stron układu, w tym dotyczące stosowania układu i przestrzegania jego postanowień. -§ 2. Układ może określać inne sprawy poza wymienionymi w § 1, nie uregulowane w przepisach prawa pracy w sposób bezwzględnie obowiązujący. - -§ 3. Układ nie może naruszać praw osób trzecich. - -§ 4. Zawarcie układu dla pracowników zatrudnionych w jednostkach budżetowych oraz samorządowych zakładach budżetowych może nastąpić wyłącznie w ramach środków finansowych będących w ich dyspozycji, w tym wynagrodzeń określonych na podstawie odrębnych przepisów. - -§ 5. Wniosek o zarejestrowanie układu zawartego dla pracowników zatrudnionych w jednostkach budżetowych oraz samorządowych zakładach budżetowych powinien zawierać oświadczenie organu, który utworzył dany podmiot lub przejął funkcje takiego organu, o spełnieniu wymogu, o którym mowa w § 4. - -Art. 241. (skreślony). - -Art. 2411. Strony, określając wzajemne zobowiązania przy stosowaniu układu, mogą w szczególności ustalić: - -1) sposób publikacji układu i rozpowszechniania jego treści, -2) tryb dokonywania okresowych ocen funkcjonowania układu, -3) tryb wyjaśniania treści postanowień układu oraz rozstrzygania sporów między stronami w tym zakresie. -4) (skreślony). -Art. 2412. § 1. Zawarcie układu następuje w drodze rokowań. - -§ 2. Podmiot występujący z inicjatywą zawarcia układu jest obowiązany powiadomić o tym każdą organizację związkową reprezentującą pracowników, dla których ma być zawarty układ, w celu wspólnego prowadzenia rokowań przez wszystkie organizacje związkowe. - -§ 3. Strona uprawniona do zawarcia układu nie może odmówić żądaniu drugiej strony podjęcia rokowań: - -1) w celu zawarcia układu dla pracowników nie objętych układem, -2) w celu zmiany układu uzasadnionej istotną zmianą sytuacji ekonomicznej bądź finansowej pracodawców lub pogorszeniem się sytuacji materialnej pracowników, -3) jeżeli żądanie zostało zgłoszone nie wcześniej niż 60 dni przed upływem okresu, na jaki układ został zawarty, albo po dniu wypowiedzenia układu. -Art. 2413. § 1. Każda ze stron jest obowiązana prowadzić rokowania w dobrej wierze i z poszanowaniem słusznych interesów drugiej strony. Oznacza to w szczególności: - -1) uwzględnianie postulatów organizacji związkowej uzasadnionych sytuacją ekonomiczną pracodawców, -2) powstrzymywanie się od wysuwania postulatów, których realizacja w sposób oczywisty przekracza możliwości finansowe pracodawców, -3) poszanowanie interesów pracowników nie objętych układem. -§ 2. Strony układu mogą określić tryb rozstrzygania kwestii spornych związanych z przedmiotem rokowań lub innych spornych zagadnień, które mogą wyłonić się w trakcie tych rokowań. W takim przypadku nie mają zastosowania przepisy o rozwiązywaniu sporów zbiorowych, chyba że strony postanowią o ich stosowaniu w określonym zakresie. - -Art. 2414. § 1. Pracodawca jest obowiązany udzielić przedstawicielom związków zawodowych prowadzącym rokowania informacji o swojej sytuacji ekonomicznej w zakresie objętym rokowaniami i niezbędnym do prowadzenia odpowiedzialnych rokowań. Obowiązek ten dotyczy w szczególności informacji objętych sprawozdawczością Głównego Urzędu Statystycznego. - -§ 2. Przedstawiciele związków zawodowych są obowiązani do nieujawniania uzyskanych od pracodawcy informacji, stanowiących tajemnicę przedsiębiorstwa w rozumieniu przepisów o zwalczaniu nieuczciwej konkurencji. - -§ 3. Na żądanie każdej ze stron może być powołany ekspert, którego zadaniem jest przedstawienie opinii w sprawach związanych z przedmiotem rokowań. Koszty ekspertyzy pokrywa strona, która żądała powołania eksperta, chyba że strony postanowią inaczej. - -§ 4. Przepisy § 1-3 nie naruszają przepisów o ochronie informacji niejawnych. - -Art. 2415. § 1. Układ zawiera się w formie pisemnej na czas nie określony lub na czas określony. - -§ 2. W układzie ustala się zakres jego obowiązywania oraz wskazuje siedziby stron układu. - -§ 3. Przed upływem terminu obowiązywania układu zawartego na czas określony strony mogą przedłużyć jego obowiązywanie na czas określony lub uznać układ za zawarty na czas nie określony. - -Art. 2416. § 1. Treść postanowień układu wyjaśniają wspólnie jego strony. - -§ 2. Wyjaśnienia treści postanowień układu, dokonane wspólnie przez strony układu, wiążą także strony, które zawarły porozumienie o stosowaniu tego układu. Wyjaśnienia udostępnia się stronom porozumienia. - -Art. 2417. § 1. Układ rozwiązuje się: - -1) na podstawie zgodnego oświadczenia stron, -2) z upływem okresu, na który został zawarty, -3) z upływem okresu wypowiedzenia dokonanego przez jedną ze stron. -§ 2. Oświadczenie stron o rozwiązaniu układu oraz wypowiedzenie układu następuje w formie pisemnej. - -§ 3. Okres wypowiedzenia układu wynosi trzy miesiące kalendarzowe, chyba że strony w układzie postanowią inaczej. - -§ 4. (utrata mocy). - -§ 5. (skreślony). - -Art. 2418. § 1. W okresie jednego roku od dnia przejścia zakładu pracy lub jego części na nowego pracodawcę do pracowników stosuje się postanowienia układu, którym byli objęci przed przejściem zakładu pracy lub jego części na nowego pracodawcę, chyba że odrębne przepisy stanowią inaczej. Postanowienia tego układu stosuje się w brzmieniu obowiązującym w dniu przejścia zakładu pracy lub jego części na nowego pracodawcę. Pracodawca może stosować do tych pracowników korzystniejsze warunki niż wynikające z dotychczasowego układu. - -§ 2. Po upływie okresu stosowania dotychczasowego układu wynikające z tego układu warunki umów o pracę lub innych aktów stanowiących podstawę nawiązania stosunku pracy stosuje się do upływu okresu wypowiedzenia tych warunków. Przepis art. 24113 § 2 zdanie drugie stosuje się. - -§ 3. Jeżeli w przypadkach, o których mowa w § 1, nowy pracodawca przejmuje również inne osoby objęte układem obowiązującym u dotychczasowego pracodawcy, stosuje postanowienia układu dotyczące tych osób przez okres jednego roku od dnia przejęcia. - -§ 4. Jeżeli pracownicy przed ich przejęciem byli objęci układem ponadzakładowym, obowiązującym u nowego pracodawcy, przepisy § 1-3 stosuje się do układu zakładowego. - -Art. 2419. § 1. Zmiany do układu wprowadza się w drodze protokołów dodatkowych. Do protokołów dodatkowych stosuje się odpowiednio przepisy dotyczące układu. - -§ 2. Jeżeli układ został zawarty przez więcej niż jedną organizację związkową, przez okres jego obowiązywania wszelkie czynności dotyczące tego układu podejmują organizacje związkowe, które go zawarły, z zastrzeżeniem § 3 i 4. - -§ 3. Strony układu mogą wyrazić zgodę, aby w prawa i obowiązki strony wstąpiła organizacja związkowa, która nie zawarła układu. - -§ 4. Organizacja związkowa, która po zawarciu układu stała się reprezentatywna na podstawie art. 252 ust. 1 lub art. 253 ust. 1 ustawy o związkach zawodowych, może wstąpić w prawa i obowiązki strony układu, składając w tym celu oświadczenie stronom tego układu. Do zakładowej organizacji związkowej stosuje się odpowiednio art. 253 ust. 3-6 ustawy o związkach zawodowych, a w celu stwierdzenia reprezentatywności - art. 251 ust. 2-12 ustawy o związkach zawodowych. - -§ 5. Informacja o wstąpieniu organizacji związkowej w prawa i obowiązki strony układu podlega zgłoszeniu do rejestru układów. - -Art. 24110. § 1. Strony uprawnione do zawarcia układu mogą zawrzeć porozumienie o stosowaniu w całości lub w części układu, którego nie są stronami. Do porozumienia stosuje się odpowiednio przepisy dotyczące układu. - -§ 2. Organ rejestrujący porozumienie, o którym mowa w § 1, powiadamia strony układu o rejestracji tego porozumienia. - -§ 3. Zmiana postanowień układu przez strony, które zawarły ten układ, nie powoduje zmian w treści porozumienia, o którym mowa w § 1. - -Art. 24111. § 1. Układ podlega wpisowi do rejestru prowadzonego dla: - -1) układów ponadzakładowych przez ministra właściwego do spraw pracy, -2) układów zakładowych przez właściwego okręgowego inspektora pracy. -§ 2. Układ zawarty zgodnie z prawem podlega rejestracji w ciągu: - -1) trzech miesięcy - w odniesieniu do układu ponadzakładowego, -2) jednego miesiąca - w odniesieniu do układu zakładowego, -- od dnia złożenia wniosku w tej sprawie przez jedną ze stron układu. -§ 3. Jeżeli postanowienia układu są niezgodne z prawem, organ uprawniony do jego rejestracji może: - -1) za zgodą stron układu wpisać układ do rejestru bez tych postanowień, -2) wezwać strony układu do dokonania w układzie odpowiednich zmian w terminie 14 dni. -§ 4. Jeżeli strony układu nie wyrażą zgody na wpisanie układu do rejestru bez postanowień niezgodnych z prawem lub nie dokonają w terminie odpowiednich zmian w układzie, organ uprawniony do rejestracji układu odmawia jego rejestracji. - -§ 5. W ciągu 30 dni od dnia zawiadomienia o odmowie rejestracji przysługuje odwołanie: - -1) stronom układu ponadzakładowego - do Sądu Okręgowego - Sądu Pracy i Ubezpieczeń Społecznych w Warszawie, -2) stronom układu zakładowego - do właściwego dla siedziby pracodawcy sądu rejonowego - sądu pracy. -Sąd rozpoznaje sprawę w trybie przepisów Kodeksu postępowania cywilnego o postępowaniu nieprocesowym. -§ 51. Osoba mająca interes prawny może, w terminie 90 dni od dnia zarejestrowania układu, wystąpić do organu, który układ zarejestrował, z zastrzeżeniem, że został on zawarty z naruszeniem przepisów o zawieraniu układów zbiorowych pracy. Zastrzeżenie powinno być złożone na piśmie i zawierać uzasadnienie. - -§ 52. Organ rejestrujący w ciągu 14 dni po otrzymaniu zastrzeżenia, o którym mowa w § 51, wzywa strony układu do przedstawienia dokumentów i złożenia wyjaśnień niezbędnych do rozpatrzenia zastrzeżenia. - -§ 53. W razie stwierdzenia, że układ został zawarty z naruszeniem przepisów o zawieraniu układów zbiorowych pracy, organ rejestrujący wzywa strony układu do usunięcia tych nieprawidłowości, chyba że ich usunięcie nie jest możliwe. - -§ 54. W razie gdy: - -1) strony układu nie przedstawią w wyznaczonym terminie, nie krótszym niż 30 dni, dokumentów i wyjaśnień, o których mowa w § 52, lub -2) strony układu w wyznaczonym terminie, nie krótszym niż 30 dni, nie usuną nieprawidłowości, o której mowa w § 53, lub usunięcie tej nieprawidłowości nie jest możliwe, -organ rejestrujący wykreśla układ z rejestru układów. Przepis § 5 stosuje się odpowiednio. -§ 55. Warunki umów o pracę lub innych aktów stanowiących podstawę nawiązania stosunku pracy, wynikające z układu wykreślonego z rejestru układów, obowiązują do upływu okresu wypowiedzenia tych warunków. Przepis art. 24113 § 2 zdanie drugie stosuje się. - -§ 6. Minister właściwy do spraw pracy w celu zapewnienia jednolitych zasad rejestracji układów zbiorowych pracy i prowadzenia rejestru tych układów określi, w drodze rozporządzenia, tryb postępowania w sprawie rejestracji układów zbiorowych pracy, w szczególności warunki składania wniosków o wpis do rejestru układów i o rejestrację układu, zakres informacji objętych tymi wnioskami oraz dokumenty dołączane do wniosków, skutki niezachowania wymogów dotyczących formy i treści wniosków, jak również tryb wykreślenia układu z rejestru, a także sposób prowadzenia rejestru układów i akt rejestrowych oraz wzory klauzul rejestracyjnych i kart rejestrowych. - -Art. 24112. § 1. Układ wchodzi w życie w terminie w nim określonym, nie wcześniej jednak niż z dniem zarejestrowania. - -§ 2. Pracodawca jest obowiązany: - -1) zawiadomić pracowników o wejściu układu w życie, o zmianach dotyczących układu oraz o wypowiedzeniu i rozwiązaniu układu, -2) dostarczyć zakładowej organizacji związkowej niezbędną liczbę egzemplarzy układu, -3) na żądanie pracownika udostępnić do wglądu tekst układu i wyjaśnić jego treść. -Art. 24113. § 1. Korzystniejsze postanowienia układu, z dniem jego wejścia w życie, zastępują z mocy prawa wynikające z dotychczasowych przepisów prawa pracy warunki umowy o pracę lub innego aktu stanowiącego podstawę nawiązania stosunku pracy. - -§ 2. Postanowienia układu mniej korzystne dla pracowników wprowadza się w drodze wypowiedzenia pracownikom dotychczasowych warunków umowy o pracę lub innego aktu stanowiącego podstawę nawiązania stosunku pracy. Przy wypowiedzeniu dotychczasowych warunków umowy o pracę lub innego aktu stanowiącego podstawę nawiązania stosunku pracy nie mają zastosowania przepisy ograniczające dopuszczalność wypowiadania warunków takiej umowy lub aktu. - -Rozdział II -Ponadzakładowy układ zbiorowy pracy - -Art. 24114. § 1. Ponadzakładowy układ zbiorowy pracy, zwany dalej „układem ponadzakładowym”, zawierają: - -1) ze strony pracowników właściwy statutowo organ ponadzakładowej organizacji związkowej, -2) ze strony pracodawców właściwy statutowo organ organizacji pracodawców - w imieniu zrzeszonych w tej organizacji pracodawców. -§ 2. (skreślony). - -§ 3. (skreślony). - - -Art. 24114a. § 1. W razie gdy ponadzakładowa organizacja związkowa reprezentująca pracowników, dla których ma być zawarty układ ponadzakładowy, wchodzi w skład zrzeszenia (federacji) związków zawodowych lub ogólnokrajowej organizacji międzyzwiązkowej (konfederacji), do zawarcia układu jest upoważniona, z zastrzeżeniem § 2, wyłącznie ta ponadzakładowa organizacja związkowa. - -§ 2. Ogólnokrajowa organizacja międzyzwiązkowa (konfederacja) uczestniczy w rokowaniach i zawiera układ ponadzakładowy w miejsce wchodzących w jej skład ponadzakładowych organizacji związkowych, reprezentujących pracowników, dla których układ ten ma być zawarty i które uzyskały reprezentatywność na podstawie art. 252 ust. 3 ustawy o związkach zawodowych, w razie skierowania do niej umotywowanego pisemnego wniosku w tej sprawie przez organizację pracodawców prowadzącą rokowania w sprawie zawarcia tego układu lub co najmniej jedną z pozostałych ponadzakładowych organizacji związkowych prowadzących rokowania w sprawie zawarcia tego układu. Organizacja, do której skierowano wniosek, nie może odmówić przystąpienia do rokowań; odmowa skutkuje pozbawieniem reprezentatywności dla potrzeb określonego układu ponadzakładowego wszystkich organizacji, w miejsce których powinna wstąpić organizacja, do której skierowany został wniosek. - -§ 3. W razie gdy organizacja pracodawców zrzeszająca pracodawców, którzy mają być objęci układem ponadzakładowym, wchodzi w skład federacji lub konfederacji, prawo do zawarcia układu przysługuje organizacji, w której pracodawcy są bezpośrednio zrzeszeni. - -Art. 24115. Prawo wystąpienia z inicjatywą zawarcia układu ponadzakładowego przysługuje: - -1) organizacji pracodawców uprawnionej do zawarcia układu ze strony pracodawców, -2) każdej ponadzakładowej organizacji związkowej reprezentującej pracowników, dla których ma być zawarty układ. -Art. 24116. - -§ 1. Jeżeli pracowników, dla których ma być zawarty układ ponadzakładowy, reprezentuje więcej niż jedna organizacja związkowa, rokowania w celu zawarcia układu prowadzi ich wspólna reprezentacja lub działające wspólnie poszczególne organizacje związkowe. - -§ 2. Jeżeli w terminie wyznaczonym przez podmiot występujący z inicjatywą zawarcia układu ponadzakładowego, nie krótszym niż 30 dni od dnia zgłoszenia inicjatywy zawarcia układu, nie wszystkie organizacje związkowe przystąpią do rokowań w trybie określonym w § 1, do prowadzenia rokowań są uprawnione organizacje związkowe, które przystąpiły do rokowań. Rokowania te są prowadzone w trybie określonym w § 1. - -§ 3. Warunkiem prowadzenia rokowań, o których mowa w § 2, jest uczestniczenie w nich co najmniej jednej reprezentatywnej ponadzakładowej organizacji związkowej w rozumieniu art. 252 ust. 1 ustawy o związkach zawodowych. - -§ 4. Jeżeli przed zawarciem układu zostanie utworzona ponadzakładowa organizacja związkowa, ma ona prawo przystąpić do rokowań. - -§ 5. Układ ponadzakładowy zawierają wszystkie organizacje związkowe, które prowadziły rokowania nad tym układem, bądź co najmniej wszystkie reprezentatywne organizacje związkowe, w rozumieniu art. 252 ust. 1 ustawy o związkach zawodowych, uczestniczące w rokowaniach. - -Art. 24117. (uchylony) - -Art. 24118. (uchylony) - -Art. 24119. § 1. W razie połączenia lub podziału organizacji związkowej lub organizacji pracodawców, która zawarła układ ponadzakładowy, jej prawa i obowiązki przechodzą na organizację powstałą w wyniku połączenia lub podziału. - -§ 2. W razie rozwiązania organizacji pracodawców lub wszystkich organizacji związkowych, będących stroną układu ponadzakładowego, pracodawca może odstąpić od stosowania układu ponadzakładowego w całości lub w części po upływie okresu co najmniej równego okresowi wypowiedzenia układu, składając stosowne oświadczenie na piśmie pozostałej stronie tego układu. Przepis art. 2418 § 2 stosuje się odpowiednio. - -§ 3. (skreślony). - -§ 4. Informacje dotyczące spraw, o których mowa w § 1 i 2, podlegają zgłoszeniu do rejestru układów. - -Art. 24120. (skreślony). - -Art. 24121. (skreślony). - -Rozdział III -Zakładowy układ zbiorowy pracy - -Art. 24122. (skreślony). - -Art. 24123. Zakładowy układ zbiorowy pracy, zwany dalej „układem zakładowym”, zawiera pracodawca i zakładowa organizacja związkowa. - -Art. 24124. Prawo wystąpienia z inicjatywą zawarcia układu zakładowego przysługuje: - -1) pracodawcy, -2) każdej zakładowej organizacji związkowej. -Art. 24125. - -§ 1. Jeżeli pracowników, dla których ma być zawarty układ zakładowy, reprezentuje więcej niż jedna organizacja związkowa, rokowania w celu zawarcia układu prowadzi ich wspólna reprezentacja lub działające wspólnie poszczególne organizacje związkowe. - -§ 2. Jeżeli w terminie wyznaczonym przez podmiot występujący z inicjatywą zawarcia układu zakładowego, nie krótszym niż 30 dni od dnia zgłoszenia inicjatywy zawarcia układu, nie wszystkie organizacje związkowe przystąpią do rokowań w trybie określonym w § 1, do prowadzenia rokowań są uprawnione organizacje związkowe, które przystąpiły do rokowań. Rokowania te są prowadzone w trybie określonym w § 1. - -§ 3. Warunkiem prowadzenia rokowań, o których mowa w § 2, jest uczestniczenie w nich co najmniej jednej reprezentatywnej zakładowej organizacji związkowej w rozumieniu art. 253 ust. 1 lub 2 ustawy o związkach zawodowych. - -§ 4. Jeżeli przed zawarciem układu zostanie utworzona zakładowa organizacja związkowa, ma ona prawo przystąpić do rokowań. - -§ 5. Układ zakładowy zawierają wszystkie organizacje związkowe, które prowadziły rokowania nad tym układem, bądź przynajmniej wszystkie reprezentatywne organizacje związkowe, w rozumieniu art. 253 ust. 1 lub 2 ustawy o związkach zawodowych, uczestniczące w rokowaniach. - - -Art. 24125a. (uchylony) - -Art. 24126. § 1. Postanowienia układu zakładowego nie mogą być mniej korzystne dla pracowników niż postanowienia obejmującego ich układu ponadzakładowego. - -§ 2. Układ zakładowy nie może określać warunków wynagradzania pracowników zarządzających w imieniu pracodawcy zakładem pracy, w rozumieniu art. 128 § 2 pkt 2, oraz osób zarządzających zakładem pracy na innej podstawie niż stosunek pracy. - -Art. 24127. § 1. Ze względu na sytuację finansową pracodawcy strony układu zakładowego mogą zawrzeć porozumienie o zawieszeniu stosowania u danego pracodawcy, w całości lub w części, tego układu oraz układu ponadzakładowego bądź jednego z nich, na okres nie dłuższy niż 3 lata. W razie gdy u pracodawcy obowiązuje jedynie układ ponadzakładowy, porozumienie o zawieszeniu stosowania tego układu lub niektórych jego postanowień mogą zawrzeć strony uprawnione do zawarcia układu zakładowego. - -§ 2. Porozumienie, o którym mowa w § 1, podlega zgłoszeniu do rejestru odpowiednio układów zakładowych lub układów ponadzakładowych. Ponadto informację o zawieszeniu stosowania układu ponadzakładowego strony porozumienia przekazują stronom tego układu. - -§ 3. W zakresie i przez czas określony w porozumieniu, o którym mowa w § 1, nie stosuje się z mocy prawa wynikających z układu ponadzakładowego oraz z układu zakładowego warunków umów o pracę i innych aktów stanowiących podstawę nawiązania stosunku pracy. - -Art. 24128. - -§ 1. Układ zakładowy może obejmować więcej niż jednego pracodawcę, jeżeli pracodawcy ci wchodzą w skład tej samej osoby prawnej. - -§ 2. Rokowania nad zawarciem układu zakładowego prowadzą: - -1) właściwy organ osoby prawnej, o której mowa w § 1, oraz -2) wszystkie zakładowe organizacje związkowe działające u pracodawców, z zastrzeżeniem § 3. -§ 3. Jeżeli zakładowe organizacje związkowe należą do tego samego związku, federacji lub konfederacji, do prowadzenia rokowań w ich imieniu jest uprawniony organ wskazany przez ten związek, federację lub konfederację. - -§ 4. Jeżeli w terminie wyznaczonym przez podmiot występujący z inicjatywą zawarcia układu zakładowego, nie krótszym niż 30 dni od dnia zgłoszenia inicjatywy zawarcia układu, nie wszystkie organizacje związkowe przystąpią do rokowań, do prowadzenia rokowań są uprawnione organizacje związkowe, które do nich przystąpiły, pod warunkiem uczestniczenia w tych rokowaniach wszystkich organów, o których mowa w § 3, wskazanych przez ponadzakładowe organizacje związkowe reprezentujące pracowników zatrudnionych u pracodawców wchodzących w skład osoby prawnej, reprezentatywne w rozumieniu art. 252 ust. 1 pkt 1 i 2 oraz ust. 3 ustawy o związkach zawodowych. - -§ 5. Układ zakładowy zawierają wszystkie organizacje związkowe, które prowadziły rokowania nad tym układem, bądź co najmniej wszystkie organy, o których mowa w § 3, wskazane przez ponadzakładowe organizacje związkowe reprezentujące pracowników zatrudnionych u pracodawców wchodzących w skład osoby prawnej, reprezentatywne w rozumieniu art. 252 ust. 1 pkt 1 i 2 oraz ust. 3 ustawy o związkach zawodowych. - -§ 6. Przepisy § 1-5 stosuje się odpowiednio do jednostki nieposiadającej osobowości prawnej, w skład której wchodzi więcej niż jeden pracodawca. - -Art. 24129. § 1. (skreślony). - -§ 2. W razie połączenia zakładowych organizacji związkowych, z których choćby jedna zawarła układ zakładowy, jej prawa i obowiązki przechodzą na organizację powstałą w wyniku połączenia. - -§ 3. W razie rozwiązania wszystkich organizacji związkowych, które zawarły układ zakładowy, pracodawca może odstąpić od stosowania tego układu w całości lub w części po upływie okresu co najmniej równego okresowi wypowiedzenia układu. Przepis art. 2418 § 2 stosuje się odpowiednio. - -§ 4. (skreślony). - -§ 5. (skreślony). - -Art. 24130. Przepisy rozdziału stosuje się odpowiednio do międzyzakładowej organizacji związkowej działającej u pracodawcy. - -DZIAŁ DWUNASTY -Rozpatrywanie sporów o roszczenia ze stosunku pracy - -Rozdział I -Przepisy ogólne - -Art. 242. § 1. Pracownik może dochodzić swych roszczeń ze stosunku pracy na drodze sądowej. - -§ 2. Przed skierowaniem sprawy na drogę sądową pracownik może żądać wszczęcia postępowania pojednawczego przed komisją pojednawczą. - -Art. 243. Pracodawca i pracownik powinni dążyć do polubownego załatwienia sporu ze stosunku pracy. - -Rozdział II -Postępowanie pojednawcze - -Art. 244. § 1. W celu polubownego załatwiania sporów o roszczenia pracowników ze stosunku pracy mogą być powoływane komisje pojednawcze. - -§ 2. (skreślony). - -§ 3. Komisję pojednawczą powołują wspólnie pracodawca i zakładowa organizacja związkowa, a jeżeli u danego pracodawcy nie działa zakładowa organizacja związkowa - pracodawca, po uzyskaniu pozytywnej opinii pracowników. - -§ 4. (skreślony). - -Art. 245. W trybie przewidzianym w art. 244 § 3 ustala się: - -1) zasady i tryb powoływania komisji, -2) czas trwania kadencji, -3) liczbę członków komisji. -Art. 246. Członkiem komisji pojednawczej nie może być: - -1) osoba zarządzająca, w imieniu pracodawcy, zakładem pracy, -2) główny księgowy, -3) radca prawny, -4) osoba prowadząca sprawy osobowe, zatrudnienia i płac. -Art. 247. Komisja pojednawcza wybiera ze swego grona przewodniczącego komisji oraz jego zastępców i ustala regulamin postępowania pojednawczego. - -Art. 248. § 1. Komisja pojednawcza wszczyna postępowanie na wniosek pracownika zgłoszony na piśmie lub ustnie do protokołu. Na wniosku stwierdza się datę jego wpływu. - -§ 2. Zgłoszenie przez pracownika wniosku do komisji pojednawczej przerywa bieg terminów, o których mowa w art. 264. - -Art. 249. Komisja pojednawcza przeprowadza postępowanie pojednawcze w zespołach składających się co najmniej z 3 członków tej komisji. - -Art. 250. (skreślony). - -Art. 251. § 1. Komisja pojednawcza powinna dążyć, aby załatwienie sprawy w drodze ugody nastąpiło w terminie 14 dni od dnia złożenia wniosku. Termin zakończenia postępowania przed komisją pojednawczą stwierdza się w protokole posiedzenia zespołu. - -§ 2. W sprawach dotyczących rozwiązania, wygaśnięcia lub nawiązania stosunku pracy, o których mowa w art. 264, wniosek do komisji pojednawczej wnosi się przed upływem terminów określonych w tym przepisie. - -§ 3. W sprawach, o których mowa w § 2, postępowanie pojednawcze kończy się z mocy prawa z upływem 14 dni od dnia złożenia wniosku przez pracownika, a w innych sprawach - z upływem 30 dni od dnia złożenia wniosku. - -Art. 252. Ugodę zawartą przed komisją pojednawczą wpisuje się do protokołu posiedzenia zespołu. Protokół podpisują strony i członkowie zespołu. - -Art. 253. Niedopuszczalne jest zawarcie ugody, która byłaby sprzeczna z prawem lub zasadami współżycia społecznego. - -Art. 254. Jeżeli postępowanie przed komisją pojednawczą nie doprowadziło do zawarcia ugody, komisja na żądanie pracownika, zgłoszone w terminie 14 dni od dnia zakończenia postępowania pojednawczego, przekazuje niezwłocznie sprawę sądowi pracy. Wniosek pracownika o polubowne załatwienie sprawy przez komisję pojednawczą zastępuje pozew. Pracownik zamiast zgłoszenia tego żądania może wnieść pozew do sądu pracy na zasadach ogólnych. - -Art. 255. § 1. W razie niewykonania ugody przez pracodawcę podlega ona wykonaniu w trybie przepisów Kodeksu postępowania cywilnego, po nadaniu jej przez sąd pracy klauzuli wykonalności. - -§ 2. Sąd pracy odmówi nadania klauzuli wykonalności, jeżeli ze złożonych akt komisji wynika, że ugoda jest sprzeczna z prawem lub zasadami współżycia społecznego. Nie wyklucza to możliwości dochodzenia ustalenia niezgodności ugody z prawem lub zasadami współżycia społecznego na zasadach ogólnych. - -Art. 256. Pracownik może wystąpić do sądu pracy w terminie 30 dni od dnia zawarcia ugody z żądaniem uznania jej za bezskuteczną, jeżeli uważa, że ugoda narusza jego słuszny interes. Jednakże w sprawach, o których mowa w art. 251 § 2, z żądaniem takim pracownik może wystąpić tylko przed upływem 14 dni od dnia zawarcia ugody. - -Art. 257. Sprawowanie obowiązków członka komisji pojednawczej jest funkcją społeczną. Jednakże członek komisji pojednawczej zachowuje prawo do wynagrodzenia za czas nie przepracowany w związku z udziałem w pracach komisji. - -Art. 258. § 1. Pracodawca jest obowiązany zapewnić komisji pojednawczej warunki lokalowe oraz środki techniczne umożliwiające właściwe jej funkcjonowanie. - -§ 2. Wydatki związane z działalnością komisji pojednawczej ponosi pracodawca. Wydatki te obejmują również równowartość utraconego wynagrodzenia za czas nie przepracowany przez pracownika w związku z udziałem w postępowaniu pojednawczym. - -Art. 259. (skreślony). - -Art. 260. (skreślony). - -Art. 261. (skreślony). - -Rozdział III -Sądy pracy - -Art. 262. § 1. Spory o roszczenia ze stosunku pracy rozstrzygają sądy powszechne, zwane „sądami pracy”. - -§ 2. Nie podlegają właściwości sądów pracy spory dotyczące: - -1) ustanawiania nowych warunków pracy i płacy; -2) stosowania norm pracy. -3) (uchylony) -§ 3. Zasady tworzenia sądów pracy, organizację i tryb postępowania przed tymi sądami regulują odrębne przepisy. - -Art. 263. (uchylony). - -Art. 264. - -§ 1. Odwołanie od wypowiedzenia umowy o pracę wnosi się do sądu pracy w ciągu 21 dni od dnia doręczenia pisma wypowiadającego umowę o pracę. - -§ 2. Żądanie przywrócenia do pracy lub odszkodowania wnosi się do sądu pracy w ciągu 21 dni od dnia doręczenia zawiadomienia o rozwiązaniu umowy o pracę bez wypowiedzenia lub od dnia wygaśnięcia umowy o pracę. - -§ 3. Żądanie nawiązania umowy o pracę wnosi się do sądu pracy w ciągu 21 dni od dnia doręczenia zawiadomienia o odmowie przyjęcia do pracy. - -Art. 265. § 1. Jeżeli pracownik nie dokonał - bez swojej winy - w terminie czynności, o których mowa w art. 97 § 21 i w art. 264, sąd pracy na jego wniosek postanowi przywrócenie uchybionego terminu. - -§ 2. Wniosek o przywrócenie terminu wnosi się do sądu pracy w ciągu 7 dni od dnia ustania przyczyny uchybienia terminu. We wniosku należy uprawdopodobnić okoliczności uzasadniające przywrócenie terminu. - -Art. 266. (skreślony). - -Art. 267. (skreślony). - -Art. 268. (skreślony). - -Art. 269. (skreślony). - -Art. 270. (skreślony). - -Art. 271. (skreślony). - -Art. 272. (skreślony). - -Art. 273. (skreślony). - -Art. 274. (skreślony). - -Art. 275. (skreślony). - -Art. 276. (skreślony). - -Art. 277. (skreślony). - -Art. 278. (skreślony). - -Art. 279. (skreślony). - -Art. 280. (skreślony). - -DZIAŁ TRZYNASTY -Odpowiedzialność za wykroczenia przeciwko prawom pracownika - -Art. 281. § 1. Kto, będąc pracodawcą lub działając w jego imieniu: - -1) zawiera umowę cywilnoprawną w warunkach, w których zgodnie z art. 22 § 1 powinna być zawarta umowa o pracę, -1a) nie zawiadamia właściwego okręgowego inspektora pracy, w formie pisemnej lub elektronicznej, o zawarciu umowy o pracę, o której mowa w art. 251 § 4 pkt 4, wraz ze wskazaniem przyczyn zawarcia takiej umowy, w terminie 5 dni roboczych od dnia jej zawarcia, -2) nie potwierdza na piśmie zawartej z pracownikiem umowy o pracę przed dopuszczeniem go do pracy, -2a) nie informuje pracownika w terminie o warunkach jego zatrudnienia, naruszając w sposób rażący przepisy art. 29 § 3, 32 i 33 oraz art. 291 § 2 i 4, -2b) nie udziela pracownikowi w terminie w postaci papierowej lub elektronicznej odpowiedzi na wniosek lub nie informuje o przyczynie odmowy uwzględnienia wniosku, o których mowa w art. 293 § 3, -3) wypowiada lub rozwiązuje z pracownikiem stosunek pracy bez wypowiedzenia, naruszając w sposób rażący przepisy prawa pracy, -4) stosuje wobec pracowników inne kary niż przewidziane w przepisach prawa pracy o odpowiedzialności porządkowej pracowników, -5) narusza przepisy o czasie pracy lub przepisy o uprawnieniach pracowników związanych z rodzicielstwem i zatrudnianiu młodocianych, -5a) narusza przepisy o elastycznej organizacji pracy, o której mowa w art. 1881, -5b) narusza przepisy o urlopie opiekuńczym, o którym mowa w art. 1731-1733, -5c) narusza przepisy dotyczące uwzględnienia wniosków, o których mowa w art. 1421 i art. 6719 § 6 i 7, -5d) narusza przepisy dotyczące pokrywania przez pracodawcę kosztów szkoleń, o którym mowa w art. 9413, -6) nie prowadzi dokumentacji pracowniczej, -6a) nie przechowuje dokumentacji pracowniczej przez okres, o którym mowa w art. 94 pkt 9b, art. 945 § 2 i art. 946 pkt 2, albo przez dłuższy okres, jeżeli wynika on z odrębnych przepisów, -7) pozostawia dokumentację pracowniczą w warunkach grożących uszkodzeniem lub zniszczeniem -- podlega karze grzywny od 1 000 zł do 30 000 zł. - -§ 2. Jeżeli pracownik, o którym mowa w § 1 pkt 2, jest osobą, o której mowa w art. 2 ust. 1 pkt 4 ustawy z dnia 6 grudnia 2018 r. o Krajowym Rejestrze Zadłużonych (Dz. U. z 2019 r. poz. 55, 912, 1214 i 1802, z 2020 r. poz. 1747 oraz z 2021 r. poz. 1080), pracodawca lub osoba działająca w jego imieniu podlega karze grzywny od 1500 zł do 45 000 zł. - -Art. 282. § 1. Kto, wbrew obowiązkowi: - -1) nie wypłaca w ustalonym terminie wynagrodzenia za pracę lub innego świadczenia przysługującego pracownikowi albo uprawnionemu do tego świadczenia członkowi rodziny pracownika, wysokość tego wynagrodzenia lub świadczenia bezpodstawnie obniża albo dokonuje bezpodstawnych potrąceń, -2) nie udziela przysługującego pracownikowi urlopu wypoczynkowego lub bezpodstawnie obniża wymiar tego urlopu, -3) nie wydaje pracownikowi w terminie świadectwa pracy, -podlega karze grzywny od 1 000 zł do 30 000 zł. - -§ 2. Tej samej karze podlega, kto wbrew obowiązkowi nie wykonuje podlegającego wykonaniu orzeczenia sądu pracy lub ugody zawartej przed komisją pojednawczą lub sądem pracy. - -§ 3. Kto wbrew obowiązkowi wypłaca wynagrodzenie wyższe niż wynikające z zawartej umowy o pracę, bez dokonania potrąceń na zaspokojenie świadczeń alimentacyjnych, pracownikowi będącemu osobą, o której mowa w art. 2 ust. 1 pkt 4 ustawy z dnia 6 grudnia 2018 r. o Krajowym Rejestrze Zadłużonych, podlega karze grzywny od 1500 zł do 45 000 zł. - -Art. 283. § 1. Kto, będąc odpowiedzialnym za stan bezpieczeństwa i higieny pracy albo kierując pracownikami lub innymi osobami fizycznymi, nie przestrzega przepisów lub zasad bezpieczeństwa i higieny pracy, podlega karze grzywny od 1 000 zł do 30 000 zł. - -§ 2. Tej samej karze podlega, kto: - -1) (uchylony), -2) wbrew obowiązkowi nie zapewnia, aby budowa lub przebudowa obiektu budowlanego albo jego części, w których przewiduje się pomieszczenia pracy, była wykonywana na podstawie projektów uwzględniających wymagania bezpieczeństwa i higieny pracy, -3) wbrew obowiązkowi wyposaża stanowiska pracy w maszyny i inne urządzenia techniczne, które nie spełniają wymagań dotyczących oceny zgodności, -4) wbrew obowiązkowi dostarcza pracownikowi środki ochrony indywidualnej, które nie spełniają wymagań dotyczących oceny zgodności, -5) wbrew obowiązkowi stosuje: -a) materiały i procesy technologiczne bez uprzedniego ustalenia stopnia ich szkodliwości dla zdrowia pracowników i bez podjęcia odpowiednich środków profilaktycznych, -b) substancje chemiczne i ich mieszaniny nieoznakowane w sposób widoczny i umożliwiający ich identyfikację, -c) substancje niebezpieczne, mieszaniny niebezpieczne, substancje stwarzające zagrożenie lub mieszaniny stwarzające zagrożenie nieposiadające kart charakterystyki, a także opakowań zabezpieczających przed ich szkodliwym działaniem, pożarem lub wybuchem, -6) wbrew obowiązkowi nie zawiadamia właściwego okręgowego inspektora pracy, prokuratora lub innego właściwego organu o śmiertelnym, ciężkim lub zbiorowym wypadku przy pracy oraz o każdym innym wypadku, który wywołał wymienione skutki, mającym związek z pracą, jeżeli może być uznany za wypadek przy pracy, nie zgłasza choroby zawodowej albo podejrzenia o taką chorobę, nie ujawnia wypadku przy pracy lub choroby zawodowej, albo przedstawia niezgodne z prawdą informacje, dowody lub dokumenty dotyczące takich wypadków i chorób, -7) nie wykonuje w wyznaczonym terminie podlegającego wykonaniu nakazu organu Państwowej Inspekcji Pracy, -8) utrudnia działalność organu Państwowej Inspekcji Pracy, w szczególności uniemożliwia prowadzenie wizytacji zakładu pracy lub nie udziela informacji niezbędnych do wykonywania jej zadań, -9) bez zezwolenia właściwego inspektora pracy dopuszcza do wykonywania pracy lub innych zajęć zarobkowych przez dziecko do ukończenia przez nie 16 roku życia. -Rozdział II -(skreślony) - -Art. 284. (skreślony). - -Art. 285. (skreślony). - -Art. 286. (skreślony). - -Art. 287. (skreślony). - -Art. 288. (skreślony). - -Art. 289. (skreślony). - -Art. 290. (skreślony). - -Art. 2901. (skreślony). - -DZIAŁ CZTERNASTY -Przedawnienie roszczeń - -Art. 291. § 1. Roszczenia ze stosunku pracy ulegają przedawnieniu z upływem 3 lat od dnia, w którym roszczenie stało się wymagalne. - -§ 2. Jednakże roszczenia pracodawcy o naprawienie szkody, wyrządzonej przez pracownika wskutek niewykonania lub nienależytego wykonania obowiązków pracowniczych, ulegają przedawnieniu z upływem 1 roku od dnia, w którym pracodawca powziął wiadomość o wyrządzeniu przez pracownika szkody, nie później jednak niż z upływem 3 lat od jej wyrządzenia. - -§ 21. Przepis § 2 stosuje się także do roszczenia pracodawcy, o którym mowa w art. 611 oraz w art. 1011 § 2. - -§ 3. Jeżeli pracownik umyślnie wyrządził szkodę, do przedawnienia roszczenia o naprawienie tej szkody stosuje się przepisy Kodeksu cywilnego. - -§ 4. Terminy przedawnienia nie mogą być skracane ani przedłużane przez czynność prawną. - -§ 5. Roszczenie stwierdzone prawomocnym orzeczeniem organu powołanego do rozstrzygania sporów, jak również roszczenie stwierdzone ugodą zawartą w trybie określonym w kodeksie przed takim organem, ulega przedawnieniu z upływem 10 lat od dnia uprawomocnienia się orzeczenia lub zawarcia ugody. - -Art. 292. Po upływie terminu przedawnienia roszczenia ze stosunku pracy ten, przeciwko komu przysługuje roszczenie, może uchylić się od jego zaspokojenia, chyba że zrzeka się korzystania z zarzutu przedawnienia. Zrzeczenie się zarzutu przedawnienia dokonane przed upływem terminu przedawnienia jest nieważne. - -Art. 293. Bieg przedawnienia nie rozpoczyna się, a rozpoczęty ulega zawieszeniu na czas trwania przeszkody, gdy z powodu siły wyższej uprawniony nie może dochodzić przysługujących mu roszczeń przed właściwym organem powołanym do rozstrzygania sporów. - - -Art. 2931. Bieg przedawnienia roszczenia o urlop wypoczynkowy nie rozpoczyna się, a rozpoczęty ulega zawieszeniu na czas korzystania z urlopu wychowawczego. - -Art. 294. Przedawnienie względem osoby, która nie ma pełnej zdolności do czynności prawnych albo co do której istnieje podstawa do jej całkowitego ubezwłasnowolnienia, nie może skończyć się wcześniej niż z upływem 2 lat od dnia ustanowienia dla niej przedstawiciela ustawowego albo od dnia ustania przyczyny jego ustanowienia. Jeżeli termin przedawnienia wynosi 1 rok, jego bieg liczy się od dnia ustanowienia przedstawiciela ustawowego albo od dnia, w którym ustała przyczyna jego ustanowienia. - -Art. 295. § 1. Bieg przedawnienia przerywa się: - -1) przez każdą czynność przed właściwym organem powołanym do rozstrzygania sporów lub egzekwowania roszczeń przedsięwziętą bezpośrednio w celu dochodzenia lub ustalenia albo zaspokojenia lub zabezpieczenia roszczenia, -2) przez uznanie roszczenia. -§ 2. Po każdym przerwaniu przedawnienia biegnie ono na nowo. Jeżeli przerwa biegu przedawnienia nastąpiła wskutek jednej z przyczyn przewidzianych w § 1 pkt 1, przedawnienie nie biegnie na nowo, dopóki postępowanie wszczęte w celu dochodzenia lub ustalenia albo zaspokojenia lub zabezpieczenia roszczenia, nie zostanie zakończone. - -DZIAŁ CZTERNASTYa -(uchylony) - -Art. 2951. (uchylony). - -Art. 2952. (uchylony). - -DZIAŁ PIĘTNASTY -Przepisy końcowe - -Art. 296. (skreślony). - -Art. 297. Minister Pracy i Polityki Socjalnej, określi w drodze rozporządzenia: - -1) sposób ustalania wynagrodzenia: -a) przysługującego w okresie niewykonywania pracy, -b) stanowiącego podstawę ustalania wysokości kar pieniężnych, potrąceń, odszkodowań, odpraw pośmiertnych lub innych należności przewidzianych w Kodeksie pracy, -2) sposób ustalania wysokości dodatków wyrównawczych do wynagrodzenia. -Art. 298. (uchylony). - -Art. 2981. Minister właściwy do spraw pracy w porozumieniu z ministrem właściwym do spraw informatyzacji określi, w drodze rozporządzenia: - -1) zakres, sposób i warunki prowadzenia, przechowywania oraz zmiany postaci dokumentacji pracowniczej, z uwzględnieniem wymagań dotyczących dokumentacji w postaci elektronicznej w zakresie organizacji jej przetwarzania i przenoszenia pomiędzy systemami teleinformatycznymi, -2) sposób i tryb doręczania informacji lub zawiadomienia o możliwości odbioru dokumentacji pracowniczej w przypadku upływu okresu jej przechowywania oraz poprzedniej postaci tej dokumentacji w przypadku zmiany postaci jej prowadzenia i przechowywania, a także sposób odbioru dokumentacji pracowniczej, -3) sposób wydawania kopii całości lub części dokumentacji pracowniczej pracownikowi, byłemu pracownikowi lub osobom, o których mowa w art. 949 § 3 -- uwzględniając konieczność rzetelnego prowadzenia dokumentacji pracowniczej, zapewnienia realizacji prawa dostępu do tej dokumentacji, potrzebę przechowywania dokumentacji pracowniczej w sposób gwarantujący zachowanie jej poufności, integralności, kompletności oraz dostępności, w warunkach niegrożących jej uszkodzeniem lub zniszczeniem. -Art. 2982. Minister Pracy i Polityki Socjalnej określi, w drodze rozporządzenia, sposób usprawiedliwiania nieobecności w pracy oraz zakres przysługujących pracownikom zwolnień od pracy, a także przypadki, w których za czas nieobecności lub zwolnienia pracownik zachowuje prawo do wynagrodzenia. - - -Art. 2983. (uchylony). - -Art. 299. (skreślony). - -Art. 300. W sprawach nie unormowanych przepisami prawa pracy do stosunku pracy stosuje się odpowiednio przepisy Kodeksu cywilnego, jeżeli nie są one sprzeczne z zasadami prawa pracy. - -Art. 301. § 1. Szczególne uprawnienia związane ze stosunkiem pracy osób powołanych do czynnej służby wojskowej i zwolnionych z tej służby normują przepisy ustawy z dnia 11 marca 2022 r. o obronie Ojczyzny. - -§ 2. Okres czynnej służby wojskowej wlicza się do okresu zatrudnienia w zakresie i na zasadach przewidzianych w przepisach, o których mowa w § 1. - -Art. 302. Do okresu zatrudnienia wlicza się okres służby w Policji, Urzędzie Ochrony Państwa, Agencji Bezpieczeństwa Wewnętrznego, Agencji Wywiadu, Służbie Kontrwywiadu Wojskowego, Służbie Wywiadu Wojskowego, Centralnym Biurze Antykorupcyjnym, Biurze Ochrony Rządu, Służbie Ochrony Państwa, Służbie Więziennej, Straży Granicznej i Państwowej Straży Pożarnej w zakresie i na zasadach przewidzianych odrębnymi przepisami. - -Art. 303. § 1. Rada Ministrów określi w drodze rozporządzenia zakres stosowania przepisów prawa pracy do osób wykonujących pracę nakładczą, ze zmianami wynikającymi z odmiennych warunków wykonywania tej pracy. - -§ 2. Rada Ministrów może określić, w drodze rozporządzenia, zakres stosowania przepisów prawa pracy do osób stale wykonujących pracę na innej podstawie niż stosunek pracy lub umowa o pracę nakładczą, ze zmianami wynikającymi z odmiennych warunków wykonywania tej pracy. - -Art. 304. § 1. Pracodawca jest obowiązany zapewnić bezpieczne i higieniczne warunki pracy, o których mowa w art. 207 § 2, osobom fizycznym wykonującym pracę na innej podstawie niż stosunek pracy w zakładzie pracy lub w miejscu wyznaczonym przez pracodawcę, a także osobom prowadzącym w zakładzie pracy lub w miejscu wyznaczonym przez pracodawcę na własny rachunek działalność gospodarczą. - -§ 2. Pracodawca jest obowiązany zapewnić bezpieczne i higieniczne warunki zajęć odbywanych na terenie zakładu pracy przez studentów i uczniów nie będących jego pracownikami. - -§ 3. Obowiązki określone w art. 207 § 2 stosuje się odpowiednio do przedsiębiorców niebędących pracodawcami, organizujących pracę wykonywaną przez osoby fizyczne: - -1) na innej podstawie niż stosunek pracy, -2) prowadzące na własny rachunek działalność gospodarczą. -§ 4. W razie prowadzenia prac w miejscu, do którego mają dostęp osoby nie biorące udziału w procesie pracy, pracodawca jest obowiązany zastosować środki niezbędne do zapewnienia ochrony życia i zdrowia tym osobom. - -§ 5. Minister Obrony Narodowej - w stosunku do żołnierzy w czynnej służbie wojskowej oraz żołnierzy pełniących służbę w aktywnej rezerwie i w pasywnej rezerwie, a Minister Sprawiedliwości - w stosunku do osób przebywających w zakładach karnych, okręgowych ośrodkach wychowawczych, zakładach poprawczych lub w schroniskach dla nieletnich, w porozumieniu z ministrem właściwym do spraw pracy, określą, w drodze rozporządzeń, zakres stosowania do tych osób przepisów działu dziesiątego w razie wykonywania określonych zadań lub prac na terenie zakładu pracy lub w miejscu wyznaczonym przez pracodawcę, mając na uwadze bezpieczeństwo wykonywania tych zadań lub prac. - -Art. 3041. Obowiązki, o których mowa w art. 211, w zakresie określonym przez pracodawcę lub inny podmiot organizujący pracę, ciążą również na osobach fizycznych wykonujących pracę na innej podstawie niż stosunek pracy w zakładzie pracy lub w miejscu wyznaczonym przez pracodawcę lub inny podmiot organizujący pracę, a także na osobach prowadzących na własny rachunek działalność gospodarczą, w zakładzie pracy lub w miejscu wyznaczonym przez pracodawcę lub inny podmiot organizujący pracę. - -Art. 3042. Do członków rolniczych spółdzielni produkcyjnych i współpracujących z nimi członków ich rodzin oraz członków spółdzielni kółek rolniczych (usług rolniczych) stosuje się odpowiednio art. 208 § 1, art. 213 § 2, art. 217 § 2, art. 218, art. 220 § 1 i art. 221 § 1-3. - -Art. 3043. Do osób fizycznych prowadzących na własny rachunek działalność gospodarczą stosuje się odpowiednio art. 208 § 1. - -Art. 3044. Pracodawca jest obowiązany przydzielać niezbędną odzież roboczą i środki ochrony indywidualnej osobom wykonującym krótkotrwałe prace albo czynności inspekcyjne, w czasie których ich własna odzież może ulec zniszczeniu lub znacznemu zabrudzeniu, a także ze względu na bezpieczeństwo wykonywania tych prac lub czynności. - - -Art. 3045. § 1. Wykonywanie pracy lub innych zajęć zarobkowych przez dziecko do ukończenia przez nie 16 roku życia jest dozwolone wyłącznie na rzecz podmiotu prowadzącego działalność kulturalną, artystyczną, sportową lub reklamową i wymaga uprzedniej zgody przedstawiciela ustawowego lub opiekuna tego dziecka, a także zezwolenia właściwego inspektora pracy. - -§ 2. Właściwy inspektor pracy wydaje zezwolenie, o którym mowa w § 1, na wniosek podmiotu określonego w tym przepisie. - -§ 3. Właściwy inspektor pracy odmawia wydania zezwolenia, jeżeli wykonywanie pracy lub innych zajęć zarobkowych w zakresie przewidzianym w § 1: - -1) powoduje zagrożenie dla życia, zdrowia i rozwoju psychofizycznego dziecka, -2) zagraża wypełnianiu obowiązku szkolnego przez dziecko. -§ 4. Podmiot, o którym mowa w § 1, dołącza do wniosku o wydanie zezwolenia: - -1) pisemną zgodę przedstawiciela ustawowego lub opiekuna dziecka na wykonywanie przez dziecko pracy lub innych zajęć zarobkowych, -2) opinię poradni psychologiczno-pedagogicznej dotyczącą braku przeciwwskazań do wykonywania przez dziecko pracy lub innych zajęć zarobkowych, -3) orzeczenie lekarza stwierdzające brak przeciwwskazań do wykonywania przez dziecko pracy lub innych zajęć zarobkowych, -4) jeżeli dziecko podlega obowiązkowi szkolnemu - opinię dyrektora szkoły, do której dziecko uczęszcza, dotyczącą możliwości wypełniania przez dziecko tego obowiązku w czasie wykonywania przez nie pracy lub innych zajęć zarobkowych. -§ 5. Zezwolenie, o którym mowa w § 1, powinno zawierać: - -1) dane osobowe dziecka i jego przedstawiciela ustawowego lub opiekuna, -2) oznaczenie podmiotu prowadzącego działalność w zakresie przewidzianym w § 1, -3) określenie rodzaju pracy lub innych zajęć zarobkowych, które może wykonywać dziecko, -4) określenie dopuszczalnego okresu wykonywania przez dziecko pracy lub innych zajęć zarobkowych, -5) określenie dopuszczalnego dobowego wymiaru czasu pracy lub innych zajęć zarobkowych, -6) inne niezbędne ustalenia, wymagane ze względu na dobro dziecka lub rodzaj, charakter albo warunki wykonywania pracy lub innych zajęć zarobkowych przez dziecko. -§ 6. Na wniosek przedstawiciela ustawowego lub opiekuna dziecka właściwy inspektor pracy cofa wydane zezwolenie. - -§ 7. Właściwy inspektor pracy cofa wydane zezwolenie z urzędu, jeżeli stwierdzi, że warunki pracy dziecka nie odpowiadają warunkom określonym w wydanym zezwoleniu. - -Art. 305. (skreślony). \ No newline at end of file diff --git a/docs/urlopproporcjonalny.txt b/docs/urlopproporcjonalny.txt deleted file mode 100644 index cb77a3d..0000000 --- a/docs/urlopproporcjonalny.txt +++ /dev/null @@ -1,11 +0,0 @@ -Podstawowe zasady naliczania urlopu proporcjonalnego - -Kalendarzowy miesiąc pracy odpowiada 1/12 wymiaru urlopu wypoczynkowego, który przysługuje pracownikowi na podstawie art. 154 § 1 i 2 k.p. To oznacza, że 1 kalendarzowy miesiąc pracy to 1/12 z 20 dni (1,66) lub 26 dni (2,16) urlopu wypoczynkowego dla pracownika na pełnym etacie. Niektórzy zaokrąglają wyniki do 1,67 dnia urlopu i 2,17 dnia urlopu. - -Niepełny kalendarzowy miesiąc pracy zaokrągla się w górę do pełnego miesiąca. Jeżeli pracownik przepracuje tylko 1 dzień w miesiącu, zyska prawo do urlopu za cały miesiąc. - -Niepełny dzień urlopu zaokrągla się w górę do pełnego dnia. Uwaga – nie musisz tak postąpić w przypadku urlopu liczonego proporcjonalnie dla osoby, która podjęła pierwszą pracę w życiu. - -Zaokrąglając niepełne dni urlopu, pamiętaj, że wymiar urlopu wypoczynkowego należny pracownikowi pełnoetatowemu w danym roku kalendarzowym nie może przekroczyć 20 lub 26 dni (w zależności od stażu pracy). - -Jeśli pracownik rozwiązuje umowę o pracę z dotychczasowym pracodawcą i zawiera nową umowę o pracę z kolejnym pracodawcą w tym samym miesiącu kalendarzowym, to tylko wcześniejszy pracodawca zaokrągla ten niepełny miesiąc pracy w górę. \ No newline at end of file diff --git a/docs/ustawaopanstwowejinspekcjipracy.pdf b/docs/ustawaopanstwowejinspekcjipracy.pdf deleted file mode 100644 index b3a7d5e..0000000 Binary files a/docs/ustawaopanstwowejinspekcjipracy.pdf and /dev/null differ diff --git a/entrypoint.sh b/entrypoint.sh deleted file mode 100644 index bc267ab..0000000 --- a/entrypoint.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash -git config --global credential.helper store -git config --global user.name ${GIT_USERNAME} -git config --global user.email ${GIT_EMAIL} -echo "https://${GIT_USERNAME}:${GIT_TOKEN}@${GIT_HOST}" > ~/.git-credentials -cd /home -git clone --single-branch --branch main/finetuning https://repo.pokash.pl/POKASH.PL/ably.do.git -python /app/${MODELNAME}.py - -# Po zakończeniu głównego procesu, przejdź w tryb czuwania -echo "Główny proces zakończony. Przechodzę w tryb czuwania..." -tail -f /dev/null diff --git a/gemma-faiss.py b/gemma-faiss.py deleted file mode 100644 index 4c46cad..0000000 --- a/gemma-faiss.py +++ /dev/null @@ -1,93 +0,0 @@ -import os -os.environ["TOKENIZERS_PARALLELISM"] = "false" - -import faiss -import numpy as np -import ollama -import gradio as gr -import os -import argparse -from sentence_transformers import SentenceTransformer - -# === KONFIGURACJA === -model_name = "hse.ably.do:latest" # Nazwa modelu Ollama -faiss_index_path = "faiss_index.idx" # Plik indeksu FAISS -kodeks_file = "/home/ably.do/docs/kodekspracy.txt" # Plik z treścią kodeksu pracy -embedding_model = SentenceTransformer("all-MiniLM-L6-v2") # Model do embedowania tekstu - -# === KROK 1: WCZYTYWANIE KODEKSU PRACY === -def load_kodeks(filepath): - with open(filepath, "r", encoding="utf-8") as file: - content = file.read() - articles = content.split("\n\n") # Dzielimy na sekcje - return [article.strip() for article in articles if article.strip().startswith("Art.")] - -# === KROK 2: TWORZENIE INDEKSU FAISS === -def create_faiss_index(sections): - embeddings = embedding_model.encode(sections, convert_to_numpy=True) # Tworzenie wektorów - index = faiss.IndexFlatL2(embeddings.shape[1]) # Indeks FAISS - index.add(embeddings) # Dodanie wektorów do FAISS - faiss.write_index(index, faiss_index_path) # Zapis indeksu - return index, sections - -# === KROK 3: WYSZUKIWANIE NAJBLIŻSZEGO FRAGMENTU === -def search_faiss(query, index, sections, top_k=3): - query_vector = embedding_model.encode([query], convert_to_numpy=True) - _, idx = index.search(query_vector, top_k) # Szukamy więcej wyników - - results = [sections[i] for i in idx[0] if i < len(sections)] - return "\n\n".join(results) # Połącz kilka najlepszych fragmentów - -# === KROK 4: GENEROWANIE ODPOWIEDZI Z OLLAMA === -def generate_response(user_query): - if not os.path.exists(faiss_index_path): - return "Błąd: Indeks FAISS nie istnieje. Uruchom aplikację z opcją --rebuild-index." - - try: - index = faiss.read_index(faiss_index_path) - except Exception as e: - return f"Błąd ładowania FAISS: {str(e)}" - - sections = load_kodeks(kodeks_file) - best_match = search_faiss(user_query, index, sections) - - # 👀 DEBUG: Sprawdź, co zwraca FAISS - print(f"🔍 Najlepsze dopasowanie FAISS dla '{user_query}':\n{best_match}") - - prompt = f""" - Odpowiedz na pytanie na podstawie następującego tekstu: - - {best_match} - - Pytanie: {user_query} - Podaj dokładny tekst artykułu, jeśli go znajdziesz w treści powyżej. - """ - - response = ollama.chat(model=model_name, messages=[{"role": "user", "content": prompt}]) - - print(f"📝 Odpowiedź modelu:\n{response}") # 👀 DEBUG: Sprawdź odpowiedź Ollama - - return response.get("message", response.get("content", "Błąd: Nie udało się wygenerować odpowiedzi.")) - -# === KROK 5: INTERFEJS WEBOWY === -iface = gr.Interface( - fn=generate_response, - inputs=gr.Textbox(label="Zadaj pytanie o kodeks pracy"), - outputs=gr.Textbox(label="Odpowiedź"), - title="Asystent Kodeksu Pracy", - description="Wpisz pytanie, a system zwróci odpowiedni fragment kodeksu pracy." -) - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("--rebuild-index", action="store_true", help="Odbudowanie indeksu FAISS") - args = parser.parse_args() - - if args.rebuild_index or not os.path.exists(faiss_index_path): - print("Tworzenie nowego indeksu FAISS...") - sections = load_kodeks(kodeks_file) - create_faiss_index(sections) - else: - print("Indeks FAISS już istnieje.") - - iface.launch(share=True) \ No newline at end of file diff --git a/gemma.py b/gemma.py deleted file mode 100644 index 11c7caf..0000000 --- a/gemma.py +++ /dev/null @@ -1,119 +0,0 @@ -import os -os.environ["TOKENIZERS_PARALLELISM"] = "false" - -import torch -import faiss -import numpy as np -from sentence_transformers import SentenceTransformer -from datasets import Dataset -from peft import LoraConfig, get_peft_model -from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments, Trainer, DataCollatorForLanguageModeling - -# 1️⃣ Inicjalizacja modelu do embeddingów -embed_model = SentenceTransformer("all-MiniLM-L6-v2") - -# 2️⃣ Dodanie dokumentów i embeddingów -def read_documents_from_file(file_path): - with open(file_path, 'r', encoding='utf-8') as file: - content = file.read() - articles = content.split('\n\n') - documents = [] - for article in articles: - if article.strip().startswith('Art.'): - documents.append(article.strip()) - return documents -#documents = [ -# "Jak założyć firmę w Polsce?", -# "Jak rozliczyć podatek VAT?", -# "Procedura składania reklamacji w e-sklepie.", -# "Jakie dokumenty są potrzebne do rejestracji działalności?" -#] -file_path = './docs/kodekspracy.txt' # Zmień na właściwą ścieżkę -documents = read_documents_from_file(file_path) -embeddings = embed_model.encode(documents) - -# 3️⃣ Inicjalizacja FAISS i dodanie wektorów -dim = embeddings.shape[1] -index = faiss.IndexFlatL2(dim) -index.add(np.array(embeddings, dtype=np.float32)) - -# 4️⃣ Przygotowanie danych treningowych -def create_training_data(): - data = { - "text": documents, - "embedding": embeddings.tolist() - } - return Dataset.from_dict(data) - -dataset = create_training_data() - -# Podział danych na treningowe i ewaluacyjne -split_dataset = dataset.train_test_split(test_size=0.25) -train_dataset = split_dataset["train"] -eval_dataset = split_dataset["test"] - -# 5️⃣ Ładowanie modelu Gemma 2B -device = "cuda" if torch.cuda.is_available() else "cpu" -model_name = "google/gemma-2-2b" -model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype=torch.float16).to(device) -tokenizer = AutoTokenizer.from_pretrained(model_name) - -# 6️⃣ Konfiguracja LoRA -lora_config = LoraConfig( - r=8, lora_alpha=32, lora_dropout=0.1, bias="none", task_type="CAUSAL_LM" -) -model = get_peft_model(model, lora_config) - -# 7️⃣ Tokenizacja danych -max_length = 384 - -def tokenize_function(examples): - return tokenizer( - examples["text"], - padding="max_length", - truncation=True, - max_length=max_length - ) - -tokenized_train = train_dataset.map(tokenize_function, batched=True) -tokenized_eval = eval_dataset.map(tokenize_function, batched=True) - -# 8️⃣ Parametry treningu -training_args = TrainingArguments( - output_dir="./results", - eval_strategy="steps", # Ewaluacja co określoną liczbę kroków - eval_steps=500, # Ewaluacja co 500 kroków - save_strategy="steps", # Zapis modelu co określoną liczbę kroków - save_steps=500, # Zapis modelu co 500 kroków - learning_rate=1e-5, - per_device_train_batch_size=2, - per_device_eval_batch_size=2, - num_train_epochs=16, - weight_decay=0.01, - load_best_model_at_end=True, # Wczytaj najlepszy model na końcu - metric_for_best_model="loss", # Kryterium wyboru najlepszego modelu - greater_is_better=False, # Niższy loss = lepszy model -) - -# 9️⃣ Data Collator -data_collator = DataCollatorForLanguageModeling( - tokenizer=tokenizer, - mlm=False -) - -# 🔟 Trening modelu -trainer = Trainer( - model=model, - args=training_args, - train_dataset=tokenized_train, - eval_dataset=tokenized_eval, # Dodany zestaw ewaluacyjny - data_collator=data_collator, -) - -trainer.train() - -# 1️⃣1️⃣ Zapis modelu -model.save_pretrained("./trained_model/gemma") -tokenizer.save_pretrained("./trained_model/gemma") - -print("✅ Model został wytrenowany i zapisany!") \ No newline at end of file diff --git a/gpt.py b/gpt.py deleted file mode 100644 index dfa57e9..0000000 --- a/gpt.py +++ /dev/null @@ -1,118 +0,0 @@ -import os -import re -import torch -from transformers import AutoTokenizer, AutoModelForCausalLM, TrainingArguments, Trainer, DataCollatorForLanguageModeling -from datasets import Dataset - -# Konfiguracja -os.environ["TOKENIZERS_PARALLELISM"] = "false" -MODEL_NAME = "gpt2-medium" -SPECIAL_TOKENS = ["[CITATION_START]", "[CITATION_END]"] -TEXT_FILE_PATH = "./docs/kodekspracy.txt" # Zmień na właściwą ścieżkę - -def prepare_dataset_from_file(file_path): - with open(file_path, 'r', encoding='utf-8') as f: - text = f.read() - - # Wydziel artykuły za pomocą wyrażenia regularnego - articles = re.findall(r'Art\.\s*\d+[a-z]*\..*?(?=\s*Art\.\s*\d+[a-z]*\.|\Z)', text, flags=re.DOTALL) - - formatted_articles = [] - for article in articles: - # Usuń zbędne białe znaki - article = ' '.join(article.strip().split()) - - # Wydziel numer artykułu i treść - art_match = re.match(r'Art\.\s*(\d+[a-z]*)\.?\s*(.*)', article, re.DOTALL) - if art_match: - art_number = art_match.group(1) - art_text = art_match.group(2) - - # Podziel na paragrafy, jeśli istnieją - paragraphs = re.split(r'(§\s*\d+\.)', art_text) - if len(paragraphs) > 1: - formatted_paragraphs = [] - for i in range(1, len(paragraphs), 2): - para_num = paragraphs[i].strip() - para_text = paragraphs[i+1].strip() - formatted_paragraphs.append(f"{para_num} {para_text}") - formatted = f"[CITATION_START] Kodeks Pracy, Art. {art_number} [CITATION_END]\n" + "\n".join(formatted_paragraphs) - else: - formatted = f"[CITATION_START] Kodeks Pracy, Art. {art_number} [CITATION_END] {art_text}" - - formatted_articles.append({"text": formatted}) - - # Dodaj przykłady pytań i odpowiedzi - questions = [ - f"Zacytuj artykuł {art_number} Kodeksu pracy.", - f"Co mówi artykuł {art_number} Kodeksu pracy?", - f"Podaj treść artykułu {art_number} Kodeksu pracy." - ] - for question in questions: - formatted_articles.append({"text": f"{question}\n{formatted}"}) - - return formatted_articles - - -def main(): - # Inicjalizacja tokenizera - tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME) - tokenizer.add_special_tokens({"additional_special_tokens": SPECIAL_TOKENS}) - tokenizer.pad_token = tokenizer.eos_token - - # Przygotowanie danych - data = prepare_dataset_from_file(TEXT_FILE_PATH) - dataset = Dataset.from_dict({"text": [d["text"] for d in data]}) - - # Tokenizacja - def tokenize_function(examples): - tokenized = tokenizer( - examples["text"], - truncation=True, - padding="max_length", - max_length=1024, # Zwiększono dla dłuższych artykułów - return_tensors="pt" - ) - tokenized["labels"] = tokenized["input_ids"].clone() - return tokenized - - tokenized_dataset = dataset.map(tokenize_function, batched=True) - - # Model i data collator - model = AutoModelForCausalLM.from_pretrained(MODEL_NAME) - model.resize_token_embeddings(len(tokenizer), mean_resizing=False) - - data_collator = DataCollatorForLanguageModeling( - tokenizer=tokenizer, - mlm=False - ) - - # Konfiguracja treningu - training_args = TrainingArguments( - output_dir="./results", - num_train_epochs=32, # Zwiększono liczbę epok - per_device_train_batch_size=2, - learning_rate=1e-5, #precyzja uczenia - logging_steps=10, - weight_decay=0.01, - report_to="none", - save_strategy="no", - load_best_model_at_end=True, # Ładowanie najlepszego modelu na końcu - ) - - - # Trainer - trainer = Trainer( - model=model, - args=training_args, - train_dataset=tokenized_dataset, - data_collator=data_collator - ) - - print("Rozpoczęcie treningu...") - trainer.train() - trainer.save_model("./trained_model/gpt") - tokenizer.save_pretrained("./trained_model/gpt") - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/hatch_build.py b/hatch_build.py new file mode 100644 index 0000000..8ddaf07 --- /dev/null +++ b/hatch_build.py @@ -0,0 +1,23 @@ +# noqa: INP001 +import os +import shutil +import subprocess +from sys import stderr + +from hatchling.builders.hooks.plugin.interface import BuildHookInterface + + +class CustomBuildHook(BuildHookInterface): + def initialize(self, version, build_data): + super().initialize(version, build_data) + stderr.write(">>> Building Open Webui frontend\n") + npm = shutil.which("npm") + if npm is None: + raise RuntimeError( + "NodeJS `npm` is required for building Open Webui but it was not found" + ) + stderr.write("### npm install\n") + subprocess.run([npm, "install"], check=True) # noqa: S603 + stderr.write("\n### npm run build\n") + os.environ["APP_BUILD_HASH"] = version + subprocess.run([npm, "run", "build"], check=True) # noqa: S603 diff --git a/hft.py b/hft.py deleted file mode 100644 index 1f2a4e7..0000000 --- a/hft.py +++ /dev/null @@ -1,261 +0,0 @@ -import os -import torch -import torch.nn as nn -from transformers import AutoTokenizer, AutoModelForCausalLM, TrainingArguments, Trainer, DataCollatorForLanguageModeling -from datasets import Dataset -import re -import json -import PyPDF2 -import docx2txt -import pytesseract -from PIL import Image -from collections import defaultdict -from huggingface_hub import login - -# Konfiguracja -os.environ['TORCH_USE_CUDA_DSA'] = '1' -os.environ["TOKENIZERS_PARALLELISM"] = "false" -login(token="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") - -class SourceMapper: - def __init__(self): - self.source_to_idx = defaultdict(lambda: len(self.source_to_idx)) - self.idx_to_source = {} - - def add_source(self, source): - if source and source not in self.source_to_idx: - idx = self.source_to_idx[source] - self.idx_to_source[idx] = source - - def get_idx(self, source): - return self.source_to_idx[source] if source else -1 - - def get_source(self, idx): - return self.idx_to_source.get(idx, "Unknown") - -def load_file_catalog(catalog_path): - try: - with open(catalog_path, 'r', encoding='utf-8') as file: - return json.load(file) - except Exception as e: - print(f"Błąd wczytywania katalogu plików: {str(e)}") - return {} - -def identify_legal_document(filename, file_catalog): - base_name = os.path.splitext(filename)[0].lower() - return file_catalog.get(base_name, "Opracowanie własne") - -def extract_text_from_file(file_path): - try: - _, ext = os.path.splitext(file_path) - ext = ext.lower() - - if ext in ['.txt', '.md']: - with open(file_path, 'r', encoding='utf-8') as file: - return file.read() - elif ext == '.pdf': - text = "" - try: - with open(file_path, 'rb') as file: - reader = PyPDF2.PdfReader(file) - for page in reader.pages: - text += page.extract_text() or "" - except Exception as e: - print(f"Błąd PDF: {str(e)}") - return text - elif ext in ['.doc', '.docx']: - return docx2txt.process(file_path) - elif ext in ['.jpg', '.jpeg', '.png', '.bmp', '.tiff']: - return pytesseract.image_to_string(Image.open(file_path)) - else: - print(f"Nieobsługiwany format pliku: {ext}") - return "" - except Exception as e: - print(f"Błąd ekstrakcji tekstu: {str(e)}") - return "" - -def prepare_dataset(directory, catalog_path, source_mapper): - file_catalog = load_file_catalog(catalog_path) - data = [] - - print(f"\n{'='*50}\nDIAGNOSTYKA DANYCH\n{'='*50}") - - for root, _, files in os.walk(directory): - for file in files: - file_path = os.path.join(root, file) - print(f"\nPrzetwarzanie pliku: {file_path}") - - try: - text = extract_text_from_file(file_path) - if not text.strip(): - print("Pominięto - brak tekstu") - continue - - print(f"Długość tekstu: {len(text)} znaków") - - doc_type = identify_legal_document(file, file_catalog) - print(f"Rozpoznany typ dokumentu: {doc_type}") - - if doc_type != "Opracowanie własne": - articles = re.split(r'(?i)(Art[\.\s]+\d+[\.\s]?)', text) - articles = [a.strip() for a in articles if a.strip()] - - print(f"Znaleziono {len(articles)} fragmentów") - - for i in range(0, len(articles)-1, 2): - article_number = articles[i] - article_content = articles[i+1] - - if len(article_content) < 50: - continue - - source = f"{doc_type}, {article_number}" - source_mapper.add_source(source) - data.append({ - "text": f"{article_number} {article_content}", - "source_idx": source_mapper.get_idx(source) - }) - else: - clean_text = re.sub(r'\s+', ' ', text).strip() - chunks = [clean_text[i:i+512] for i in range(0, len(clean_text), 512)] - chunks = [c for c in chunks if c.strip()] - - for chunk in chunks: - data.append({ - "text": chunk, - "source_idx": -1 - }) - print(f"Dodano {len(chunks)} chunków") - - except Exception as e: - print(f"Błąd podczas przetwarzania pliku: {str(e)}") - continue - - print(f"\nPodsumowanie przygotowania danych:") - print(f"Łączna liczba przykładów: {len(data)}") - if data: - print("Przykładowy wpis:") - print(json.dumps(data[0], indent=2, ensure_ascii=False)) - else: - print("BRAK DANYCH - sprawdź diagnostykę powyżej") - - return data - -class CustomModel(nn.Module): - def __init__(self, model_name, config): - super().__init__() - self.base_model = AutoModelForCausalLM.from_pretrained(model_name, config=config) - self.source_embedding = nn.Embedding(10000, config.hidden_size, padding_idx=-1) - - for param in self.base_model.parameters(): - param.requires_grad = False - for param in self.base_model.get_output_embeddings().parameters(): - param.requires_grad = True - - def forward(self, input_ids=None, attention_mask=None, labels=None, source_idx=None, **kwargs): - if source_idx is not None: - valid_indices = torch.clamp(source_idx, 0, self.source_embedding.num_embeddings-1) - source_embeds = self.source_embedding(valid_indices).unsqueeze(1) - inputs_embeds = self.base_model.get_input_embeddings()(input_ids) + source_embeds - return self.base_model( - inputs_embeds=inputs_embeds, - attention_mask=attention_mask, - labels=labels, - **kwargs - ) - return self.base_model( - input_ids=input_ids, - attention_mask=attention_mask, - labels=labels, - **kwargs - ) - - def generate(self, *args, **kwargs): - return self.base_model.generate(*args, **kwargs) - -class CustomDataCollator(DataCollatorForLanguageModeling): - def torch_call(self, examples): - # Przetwórz podstawowe pola - input_ids = torch.stack([torch.tensor(ex["input_ids"]) for ex in examples]) - attention_mask = torch.stack([torch.tensor(ex["attention_mask"]) for ex in examples]) - labels = torch.stack([torch.tensor(ex["labels"]) for ex in examples]) - - batch = { - "input_ids": input_ids, - "attention_mask": attention_mask, - "labels": labels - } - - # Dodaj source_idx jeśli istnieje - if "source_idx" in examples[0]: - source_idx = torch.stack([torch.tensor(ex["source_idx"]) for ex in examples]) - batch["source_idx"] = source_idx - - return batch - -def main(): - source_mapper = SourceMapper() - model_name = "crumb/nano-mistral" - tokenizer = AutoTokenizer.from_pretrained(model_name) - tokenizer.pad_token = tokenizer.eos_token - - # Przygotowanie danych - catalog_path = "catalog.json" - data = prepare_dataset("docs", catalog_path, source_mapper) - - if not data: - print("\nBrak danych do treningu!") - return - - #dataset = Dataset.from_list(data) - dataset = Dataset.from_dict({k: [d[k] for d in data] for k in data[0]}) - - - def tokenize_function(examples): - tokenized = tokenizer( - examples["text"], - truncation=True, - padding="max_length", - max_length=512, - return_tensors="pt" - ) - return { - "input_ids": tokenized["input_ids"].squeeze(), - "attention_mask": tokenized["attention_mask"].squeeze(), - "labels": tokenized["input_ids"].squeeze().clone(), - "source_idx": examples["source_idx"] # Dodano bez konwersji do tensora - } - - tokenized_dataset = dataset.map(tokenize_function, batched=True, batch_size=16) - - model = CustomModel(model_name, AutoModelForCausalLM.from_pretrained(model_name).config) - model.source_mapper = source_mapper - device = torch.device("cuda" if torch.cuda.is_available() else "cpu") - model.to(device) - - training_args = TrainingArguments( - output_dir="./results", - num_train_epochs=3, - per_device_train_batch_size=2, - gradient_accumulation_steps=4, - learning_rate=2e-5, - fp16=torch.cuda.is_available(), - logging_steps=10, - save_strategy="steps", - save_steps=1000, - report_to="none", - remove_unused_columns=False - ) - - trainer = Trainer( - model=model, - args=training_args, - train_dataset=tokenized_dataset, - data_collator=CustomDataCollator(tokenizer=tokenizer, mlm=False) - ) - - print("\nRozpoczęcie treningu...") - trainer.train() - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/i18next-parser.config.ts b/i18next-parser.config.ts new file mode 100644 index 0000000..37ce57e --- /dev/null +++ b/i18next-parser.config.ts @@ -0,0 +1,38 @@ +// i18next-parser.config.ts +import { getLanguages } from './src/lib/i18n/index.ts'; + +const getLangCodes = async () => { + const languages = await getLanguages(); + return languages.map((l) => l.code); +}; + +export default { + contextSeparator: '_', + createOldCatalogs: false, + defaultNamespace: 'translation', + defaultValue: '', + indentation: 2, + keepRemoved: false, + keySeparator: false, + lexers: { + svelte: ['JavascriptLexer'], + js: ['JavascriptLexer'], + ts: ['JavascriptLexer'], + + default: ['JavascriptLexer'] + }, + lineEnding: 'auto', + locales: await getLangCodes(), + namespaceSeparator: false, + output: 'src/lib/i18n/locales/$LOCALE/$NAMESPACE.json', + pluralSeparator: '_', + input: 'src/**/*.{js,svelte}', + sort: true, + verbose: true, + failOnWarnings: false, + failOnUpdate: false, + customValueTemplate: null, + resetDefaultValueLocale: null, + i18nextOptions: null, + yamlOptions: null +}; diff --git a/kubernetes/helm/README.md b/kubernetes/helm/README.md new file mode 100644 index 0000000..5737007 --- /dev/null +++ b/kubernetes/helm/README.md @@ -0,0 +1,4 @@ +# Helm Charts +Open WebUI Helm Charts are now hosted in a separate repo, which can be found here: https://github.com/open-webui/helm-charts + +The charts are released at https://helm.openwebui.com. \ No newline at end of file diff --git a/kubernetes/manifest/base/kustomization.yaml b/kubernetes/manifest/base/kustomization.yaml new file mode 100644 index 0000000..61500f8 --- /dev/null +++ b/kubernetes/manifest/base/kustomization.yaml @@ -0,0 +1,8 @@ +resources: + - open-webui.yaml + - ollama-service.yaml + - ollama-statefulset.yaml + - webui-deployment.yaml + - webui-service.yaml + - webui-ingress.yaml + - webui-pvc.yaml diff --git a/kubernetes/manifest/base/ollama-service.yaml b/kubernetes/manifest/base/ollama-service.yaml new file mode 100644 index 0000000..8bab65b --- /dev/null +++ b/kubernetes/manifest/base/ollama-service.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + name: ollama-service + namespace: open-webui +spec: + selector: + app: ollama + ports: + - protocol: TCP + port: 11434 + targetPort: 11434 \ No newline at end of file diff --git a/kubernetes/manifest/base/ollama-statefulset.yaml b/kubernetes/manifest/base/ollama-statefulset.yaml new file mode 100644 index 0000000..cd1144c --- /dev/null +++ b/kubernetes/manifest/base/ollama-statefulset.yaml @@ -0,0 +1,41 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: ollama + namespace: open-webui +spec: + serviceName: "ollama" + replicas: 1 + selector: + matchLabels: + app: ollama + template: + metadata: + labels: + app: ollama + spec: + containers: + - name: ollama + image: ollama/ollama:latest + ports: + - containerPort: 11434 + resources: + requests: + cpu: "2000m" + memory: "2Gi" + limits: + cpu: "4000m" + memory: "4Gi" + nvidia.com/gpu: "0" + volumeMounts: + - name: ollama-volume + mountPath: /root/.ollama + tty: true + volumeClaimTemplates: + - metadata: + name: ollama-volume + spec: + accessModes: [ "ReadWriteOnce" ] + resources: + requests: + storage: 30Gi \ No newline at end of file diff --git a/kubernetes/manifest/base/open-webui.yaml b/kubernetes/manifest/base/open-webui.yaml new file mode 100644 index 0000000..9c1a599 --- /dev/null +++ b/kubernetes/manifest/base/open-webui.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: open-webui \ No newline at end of file diff --git a/kubernetes/manifest/base/webui-deployment.yaml b/kubernetes/manifest/base/webui-deployment.yaml new file mode 100644 index 0000000..79a0a9a --- /dev/null +++ b/kubernetes/manifest/base/webui-deployment.yaml @@ -0,0 +1,38 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: open-webui-deployment + namespace: open-webui +spec: + replicas: 1 + selector: + matchLabels: + app: open-webui + template: + metadata: + labels: + app: open-webui + spec: + containers: + - name: open-webui + image: ghcr.io/open-webui/open-webui:main + ports: + - containerPort: 8080 + resources: + requests: + cpu: "500m" + memory: "500Mi" + limits: + cpu: "1000m" + memory: "1Gi" + env: + - name: OLLAMA_BASE_URL + value: "http://ollama-service.open-webui.svc.cluster.local:11434" + tty: true + volumeMounts: + - name: webui-volume + mountPath: /app/backend/data + volumes: + - name: webui-volume + persistentVolumeClaim: + claimName: open-webui-pvc \ No newline at end of file diff --git a/kubernetes/manifest/base/webui-ingress.yaml b/kubernetes/manifest/base/webui-ingress.yaml new file mode 100644 index 0000000..dc0b53c --- /dev/null +++ b/kubernetes/manifest/base/webui-ingress.yaml @@ -0,0 +1,20 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: open-webui-ingress + namespace: open-webui + #annotations: + # Use appropriate annotations for your Ingress controller, e.g., for NGINX: + # nginx.ingress.kubernetes.io/rewrite-target: / +spec: + rules: + - host: open-webui.minikube.local + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: open-webui-service + port: + number: 8080 diff --git a/kubernetes/manifest/base/webui-pvc.yaml b/kubernetes/manifest/base/webui-pvc.yaml new file mode 100644 index 0000000..97fb761 --- /dev/null +++ b/kubernetes/manifest/base/webui-pvc.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + labels: + app: open-webui + name: open-webui-pvc + namespace: open-webui +spec: + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 2Gi \ No newline at end of file diff --git a/kubernetes/manifest/base/webui-service.yaml b/kubernetes/manifest/base/webui-service.yaml new file mode 100644 index 0000000..d73845f --- /dev/null +++ b/kubernetes/manifest/base/webui-service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: open-webui-service + namespace: open-webui +spec: + type: NodePort # Use LoadBalancer if you're on a cloud that supports it + selector: + app: open-webui + ports: + - protocol: TCP + port: 8080 + targetPort: 8080 + # If using NodePort, you can optionally specify the nodePort: + # nodePort: 30000 \ No newline at end of file diff --git a/kubernetes/manifest/gpu/kustomization.yaml b/kubernetes/manifest/gpu/kustomization.yaml new file mode 100644 index 0000000..c0d39fb --- /dev/null +++ b/kubernetes/manifest/gpu/kustomization.yaml @@ -0,0 +1,8 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - ../base + +patches: +- path: ollama-statefulset-gpu.yaml diff --git a/kubernetes/manifest/gpu/ollama-statefulset-gpu.yaml b/kubernetes/manifest/gpu/ollama-statefulset-gpu.yaml new file mode 100644 index 0000000..3e42443 --- /dev/null +++ b/kubernetes/manifest/gpu/ollama-statefulset-gpu.yaml @@ -0,0 +1,17 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: ollama + namespace: open-webui +spec: + selector: + matchLabels: + app: ollama + serviceName: "ollama" + template: + spec: + containers: + - name: ollama + resources: + limits: + nvidia.com/gpu: "1" diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..e48c793 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,12878 @@ +{ + "name": "open-webui", + "version": "0.5.18", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "open-webui", + "version": "0.5.18", + "dependencies": { + "@codemirror/lang-javascript": "^6.2.2", + "@codemirror/lang-python": "^6.1.6", + "@codemirror/language-data": "^6.5.1", + "@codemirror/theme-one-dark": "^6.1.2", + "@huggingface/transformers": "^3.0.0", + "@mediapipe/tasks-vision": "^0.10.17", + "@pyscript/core": "^0.4.32", + "@sveltejs/adapter-node": "^2.0.0", + "@sveltejs/svelte-virtual-list": "^3.0.1", + "@tiptap/core": "^2.10.0", + "@tiptap/extension-code-block-lowlight": "^2.10.0", + "@tiptap/extension-highlight": "^2.10.0", + "@tiptap/extension-placeholder": "^2.10.0", + "@tiptap/extension-typography": "^2.10.0", + "@tiptap/pm": "^2.10.0", + "@tiptap/starter-kit": "^2.10.0", + "@xyflow/svelte": "^0.1.19", + "async": "^3.2.5", + "bits-ui": "^0.19.7", + "codemirror": "^6.0.1", + "codemirror-lang-hcl": "^0.0.0-beta.2", + "crc-32": "^1.2.2", + "dayjs": "^1.11.10", + "dompurify": "^3.1.6", + "eventsource-parser": "^1.1.2", + "file-saver": "^2.0.5", + "fuse.js": "^7.0.0", + "highlight.js": "^11.9.0", + "i18next": "^23.10.0", + "i18next-browser-languagedetector": "^7.2.0", + "i18next-resources-to-backend": "^1.2.0", + "idb": "^7.1.1", + "js-sha256": "^0.10.1", + "jspdf": "^3.0.0", + "katex": "^0.16.21", + "kokoro-js": "^1.1.1", + "marked": "^9.1.0", + "mermaid": "^10.9.3", + "paneforge": "^0.0.6", + "panzoom": "^9.4.3", + "prosemirror-commands": "^1.6.0", + "prosemirror-example-setup": "^1.2.3", + "prosemirror-history": "^1.4.1", + "prosemirror-keymap": "^1.2.2", + "prosemirror-markdown": "^1.13.1", + "prosemirror-model": "^1.23.0", + "prosemirror-schema-basic": "^1.2.3", + "prosemirror-schema-list": "^1.4.1", + "prosemirror-state": "^1.4.3", + "prosemirror-view": "^1.34.3", + "pyodide": "^0.27.2", + "socket.io-client": "^4.2.0", + "sortablejs": "^1.15.2", + "svelte-sonner": "^0.3.19", + "tippy.js": "^6.3.7", + "turndown": "^7.2.0", + "undici": "^7.3.0", + "uuid": "^9.0.1", + "vite-plugin-static-copy": "^2.2.0" + }, + "devDependencies": { + "@sveltejs/adapter-auto": "3.2.2", + "@sveltejs/adapter-static": "^3.0.2", + "@sveltejs/kit": "^2.5.20", + "@sveltejs/vite-plugin-svelte": "^3.1.1", + "@tailwindcss/container-queries": "^0.1.1", + "@tailwindcss/postcss": "^4.0.0", + "@tailwindcss/typography": "^0.5.13", + "@typescript-eslint/eslint-plugin": "^6.17.0", + "@typescript-eslint/parser": "^6.17.0", + "cypress": "^13.15.0", + "eslint": "^8.56.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-cypress": "^3.4.0", + "eslint-plugin-svelte": "^2.43.0", + "i18next-parser": "^9.0.1", + "postcss": "^8.4.31", + "prettier": "^3.3.3", + "prettier-plugin-svelte": "^3.2.6", + "sass-embedded": "^1.81.0", + "svelte": "^4.2.18", + "svelte-check": "^3.8.5", + "svelte-confetti": "^1.3.2", + "tailwindcss": "^4.0.0", + "tslib": "^2.4.1", + "typescript": "^5.5.4", + "vite": "^5.4.14", + "vitest": "^1.6.1" + }, + "engines": { + "node": ">=18.13.0 <=22.x.x", + "npm": ">=6.0.0" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.9.tgz", + "integrity": "sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg==", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@braintree/sanitize-url": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz", + "integrity": "sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==" + }, + "node_modules/@bufbuild/protobuf": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.2.2.tgz", + "integrity": "sha512-UNtPCbrwrenpmrXuRwn9jYpPoweNXj8X5sMvYgsqYyaH8jQ6LfUJSk3dJLnBK+6sfYPrF4iAIo5sd5HQ+tg75A==", + "devOptional": true, + "license": "(Apache-2.0 AND BSD-3-Clause)" + }, + "node_modules/@codemirror/autocomplete": { + "version": "6.16.2", + "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.16.2.tgz", + "integrity": "sha512-MjfDrHy0gHKlPWsvSsikhO1+BOh+eBHNgfH1OXs1+DAf30IonQldgMM3kxLDTG9ktE7kDLaA1j/l7KMPA4KNfw==", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0" + }, + "peerDependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@codemirror/commands": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.6.0.tgz", + "integrity": "sha512-qnY+b7j1UNcTS31Eenuc/5YJB6gQOzkUoNmJQc0rznwqSRpeaWWpjkWy2C/MPTcePpsKJEM26hXrOXl1+nceXg==", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.4.0", + "@codemirror/view": "^6.27.0", + "@lezer/common": "^1.1.0" + } + }, + "node_modules/@codemirror/lang-angular": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@codemirror/lang-angular/-/lang-angular-0.1.3.tgz", + "integrity": "sha512-xgeWGJQQl1LyStvndWtruUvb4SnBZDAu/gvFH/ZU+c0W25tQR8e5hq7WTwiIY2dNxnf+49mRiGI/9yxIwB6f5w==", + "dependencies": { + "@codemirror/lang-html": "^6.0.0", + "@codemirror/lang-javascript": "^6.1.2", + "@codemirror/language": "^6.0.0", + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.3.3" + } + }, + "node_modules/@codemirror/lang-cpp": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-cpp/-/lang-cpp-6.0.2.tgz", + "integrity": "sha512-6oYEYUKHvrnacXxWxYa6t4puTlbN3dgV662BDfSH8+MfjQjVmP697/KYTDOqpxgerkvoNm7q5wlFMBeX8ZMocg==", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@lezer/cpp": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-css": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.3.0.tgz", + "integrity": "sha512-CyR4rUNG9OYcXDZwMPvJdtb6PHbBDKUc/6Na2BIwZ6dKab1JQqKa4di+RNRY9Myn7JB81vayKwJeQ7jEdmNVDA==", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.0.2", + "@lezer/css": "^1.1.7" + } + }, + "node_modules/@codemirror/lang-go": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-go/-/lang-go-6.0.1.tgz", + "integrity": "sha512-7fNvbyNylvqCphW9HD6WFnRpcDjr+KXX/FgqXy5H5ZS0eC5edDljukm/yNgYkwTsgp2busdod50AOTIy6Jikfg==", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.6.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/go": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-html": { + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/@codemirror/lang-html/-/lang-html-6.4.9.tgz", + "integrity": "sha512-aQv37pIMSlueybId/2PVSP6NPnmurFDVmZwzc7jszd2KAF8qd4VBbvNYPXWQq90WIARjsdVkPbw29pszmHws3Q==", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/lang-css": "^6.0.0", + "@codemirror/lang-javascript": "^6.0.0", + "@codemirror/language": "^6.4.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0", + "@lezer/css": "^1.1.0", + "@lezer/html": "^1.3.0" + } + }, + "node_modules/@codemirror/lang-java": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-java/-/lang-java-6.0.1.tgz", + "integrity": "sha512-OOnmhH67h97jHzCuFaIEspbmsT98fNdhVhmA3zCxW0cn7l8rChDhZtwiwJ/JOKXgfm4J+ELxQihxaI7bj7mJRg==", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@lezer/java": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-javascript": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.2.tgz", + "integrity": "sha512-VGQfY+FCc285AhWuwjYxQyUQcYurWlxdKYT4bqwr3Twnd5wP5WSeu52t4tvvuWmljT4EmgEgZCqSieokhtY8hg==", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.6.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0", + "@lezer/javascript": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-json": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.1.tgz", + "integrity": "sha512-+T1flHdgpqDDlJZ2Lkil/rLiRy684WMLc74xUnjJH48GQdfJo/pudlTRreZmKwzP8/tGdKf83wlbAdOCzlJOGQ==", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@lezer/json": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-less": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-less/-/lang-less-6.0.2.tgz", + "integrity": "sha512-EYdQTG22V+KUUk8Qq582g7FMnCZeEHsyuOJisHRft/mQ+ZSZ2w51NupvDUHiqtsOy7It5cHLPGfHQLpMh9bqpQ==", + "dependencies": { + "@codemirror/lang-css": "^6.2.0", + "@codemirror/language": "^6.0.0", + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-liquid": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-liquid/-/lang-liquid-6.2.1.tgz", + "integrity": "sha512-J1Mratcm6JLNEiX+U2OlCDTysGuwbHD76XwuL5o5bo9soJtSbz2g6RU3vGHFyS5DC8rgVmFSzi7i6oBftm7tnA==", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/lang-html": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.3.1" + } + }, + "node_modules/@codemirror/lang-markdown": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@codemirror/lang-markdown/-/lang-markdown-6.3.0.tgz", + "integrity": "sha512-lYrI8SdL/vhd0w0aHIEvIRLRecLF7MiiRfzXFZY94dFwHqC9HtgxgagJ8fyYNBldijGatf9wkms60d8SrAj6Nw==", + "dependencies": { + "@codemirror/autocomplete": "^6.7.1", + "@codemirror/lang-html": "^6.0.0", + "@codemirror/language": "^6.3.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.2.1", + "@lezer/markdown": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-php": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-php/-/lang-php-6.0.1.tgz", + "integrity": "sha512-ublojMdw/PNWa7qdN5TMsjmqkNuTBD3k6ndZ4Z0S25SBAiweFGyY68AS3xNcIOlb6DDFDvKlinLQ40vSLqf8xA==", + "dependencies": { + "@codemirror/lang-html": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/php": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-python": { + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/@codemirror/lang-python/-/lang-python-6.1.6.tgz", + "integrity": "sha512-ai+01WfZhWqM92UqjnvorkxosZ2aq2u28kHvr+N3gu012XqY2CThD67JPMHnGceRfXPDBmn1HnyqowdpF57bNg==", + "dependencies": { + "@codemirror/autocomplete": "^6.3.2", + "@codemirror/language": "^6.8.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.2.1", + "@lezer/python": "^1.1.4" + } + }, + "node_modules/@codemirror/lang-rust": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-rust/-/lang-rust-6.0.1.tgz", + "integrity": "sha512-344EMWFBzWArHWdZn/NcgkwMvZIWUR1GEBdwG8FEp++6o6vT6KL9V7vGs2ONsKxxFUPXKI0SPcWhyYyl2zPYxQ==", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@lezer/rust": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-sass": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-sass/-/lang-sass-6.0.2.tgz", + "integrity": "sha512-l/bdzIABvnTo1nzdY6U+kPAC51czYQcOErfzQ9zSm9D8GmNPD0WTW8st/CJwBTPLO8jlrbyvlSEcN20dc4iL0Q==", + "dependencies": { + "@codemirror/lang-css": "^6.2.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.0.2", + "@lezer/sass": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-sql": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@codemirror/lang-sql/-/lang-sql-6.8.0.tgz", + "integrity": "sha512-aGLmY4OwGqN3TdSx3h6QeA1NrvaYtF7kkoWR/+W7/JzB0gQtJ+VJxewlnE3+VImhA4WVlhmkJr109PefOOhjLg==", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-vue": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@codemirror/lang-vue/-/lang-vue-0.1.3.tgz", + "integrity": "sha512-QSKdtYTDRhEHCfo5zOShzxCmqKJvgGrZwDQSdbvCRJ5pRLWBS7pD/8e/tH44aVQT6FKm0t6RVNoSUWHOI5vNug==", + "dependencies": { + "@codemirror/lang-html": "^6.0.0", + "@codemirror/lang-javascript": "^6.1.2", + "@codemirror/language": "^6.0.0", + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.3.1" + } + }, + "node_modules/@codemirror/lang-wast": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-wast/-/lang-wast-6.0.2.tgz", + "integrity": "sha512-Imi2KTpVGm7TKuUkqyJ5NRmeFWF7aMpNiwHnLQe0x9kmrxElndyH0K6H/gXtWwY6UshMRAhpENsgfpSwsgmC6Q==", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-xml": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@codemirror/lang-xml/-/lang-xml-6.1.0.tgz", + "integrity": "sha512-3z0blhicHLfwi2UgkZYRPioSgVTo9PV5GP5ducFH6FaHy0IAJRg+ixj5gTR1gnT/glAIC8xv4w2VL1LoZfs+Jg==", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.4.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/xml": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-yaml": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-yaml/-/lang-yaml-6.1.1.tgz", + "integrity": "sha512-HV2NzbK9bbVnjWxwObuZh5FuPCowx51mEfoFT9y3y+M37fA3+pbxx4I7uePuygFzDsAmCTwQSc/kXh/flab4uw==", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.2.0", + "@lezer/yaml": "^1.0.0" + } + }, + "node_modules/@codemirror/language": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.2.tgz", + "integrity": "sha512-kgbTYTo0Au6dCSc/TFy7fK3fpJmgHDv1sG1KNQKJXVi+xBTEeBPY/M30YXiU6mMXeH+YIDLsbrT4ZwNRdtF+SA==", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.23.0", + "@lezer/common": "^1.1.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0", + "style-mod": "^4.0.0" + } + }, + "node_modules/@codemirror/language-data": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@codemirror/language-data/-/language-data-6.5.1.tgz", + "integrity": "sha512-0sWxeUSNlBr6OmkqybUTImADFUP0M3P0IiSde4nc24bz/6jIYzqYSgkOSLS+CBIoW1vU8Q9KUWXscBXeoMVC9w==", + "dependencies": { + "@codemirror/lang-angular": "^0.1.0", + "@codemirror/lang-cpp": "^6.0.0", + "@codemirror/lang-css": "^6.0.0", + "@codemirror/lang-go": "^6.0.0", + "@codemirror/lang-html": "^6.0.0", + "@codemirror/lang-java": "^6.0.0", + "@codemirror/lang-javascript": "^6.0.0", + "@codemirror/lang-json": "^6.0.0", + "@codemirror/lang-less": "^6.0.0", + "@codemirror/lang-liquid": "^6.0.0", + "@codemirror/lang-markdown": "^6.0.0", + "@codemirror/lang-php": "^6.0.0", + "@codemirror/lang-python": "^6.0.0", + "@codemirror/lang-rust": "^6.0.0", + "@codemirror/lang-sass": "^6.0.0", + "@codemirror/lang-sql": "^6.0.0", + "@codemirror/lang-vue": "^0.1.1", + "@codemirror/lang-wast": "^6.0.0", + "@codemirror/lang-xml": "^6.0.0", + "@codemirror/lang-yaml": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/legacy-modes": "^6.4.0" + } + }, + "node_modules/@codemirror/legacy-modes": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@codemirror/legacy-modes/-/legacy-modes-6.4.1.tgz", + "integrity": "sha512-vdg3XY7OAs5uLDx2Iw+cGfnwtd7kM+Et/eMsqAGTfT/JKiVBQZXosTzjEbWAi/FrY6DcQIz8mQjBozFHZEUWQA==", + "dependencies": { + "@codemirror/language": "^6.0.0" + } + }, + "node_modules/@codemirror/lint": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.8.0.tgz", + "integrity": "sha512-lsFofvaw0lnPRJlQylNsC4IRt/1lI4OD/yYslrSGVndOJfStc58v+8p9dgGiD90ktOfL7OhBWns1ZETYgz0EJA==", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "crelt": "^1.0.5" + } + }, + "node_modules/@codemirror/search": { + "version": "6.5.6", + "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.6.tgz", + "integrity": "sha512-rpMgcsh7o0GuCDUXKPvww+muLA1pDJaFrpq/CCHtpQJYz8xopu4D1hPcKRoDD0YlF8gZaqTNIRa4VRBWyhyy7Q==", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "crelt": "^1.0.5" + } + }, + "node_modules/@codemirror/state": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.1.tgz", + "integrity": "sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A==" + }, + "node_modules/@codemirror/theme-one-dark": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@codemirror/theme-one-dark/-/theme-one-dark-6.1.2.tgz", + "integrity": "sha512-F+sH0X16j/qFLMAfbciKTxVOwkdAS336b7AXTKOZhy8BR3eH/RelsnLgLFINrpST63mmN2OuwUt0W2ndUgYwUA==", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/highlight": "^1.0.0" + } + }, + "node_modules/@codemirror/view": { + "version": "6.28.0", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.28.0.tgz", + "integrity": "sha512-fo7CelaUDKWIyemw4b+J57cWuRkOu4SWCCPfNDkPvfWkGjM9D5racHQXr4EQeYCD6zEBIBxGCeaKkQo+ysl0gA==", + "dependencies": { + "@codemirror/state": "^6.4.0", + "style-mod": "^4.1.0", + "w3c-keyname": "^2.2.4" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@cypress/request": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.5.tgz", + "integrity": "sha512-v+XHd9XmWbufxF1/bTaVm2yhbxY+TB4YtWRqF2zaXBlDNMkls34KiATz0AVDLavL3iB6bQk9/7n3oY1EoLSWGA==", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~4.0.0", + "http-signature": "~1.4.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "performance-now": "^2.1.0", + "qs": "6.13.0", + "safe-buffer": "^5.1.2", + "tough-cookie": "^4.1.3", + "tunnel-agent": "^0.6.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@cypress/request/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@cypress/xvfb": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", + "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", + "dev": true, + "dependencies": { + "debug": "^3.1.0", + "lodash.once": "^4.1.1" + } + }, + "node_modules/@cypress/xvfb/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.1.tgz", + "integrity": "sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", + "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", + "dependencies": { + "@floating-ui/utils": "^0.2.1" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.3.tgz", + "integrity": "sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==", + "dependencies": { + "@floating-ui/core": "^1.0.0", + "@floating-ui/utils": "^0.2.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", + "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" + }, + "node_modules/@gulpjs/to-absolute-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@gulpjs/to-absolute-glob/-/to-absolute-glob-4.0.0.tgz", + "integrity": "sha512-kjotm7XJrJ6v+7knhPaRgaT6q8F8K2jiafwYdNHLzmV0uGLuZY43FK6smNSHUPrhq5kX2slCUy+RGG/xGqmIKA==", + "dev": true, + "dependencies": { + "is-negated-glob": "^1.0.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@huggingface/jinja": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@huggingface/jinja/-/jinja-0.3.3.tgz", + "integrity": "sha512-vQQr2JyWvVFba3Lj9es4q9vCl1sAc74fdgnEMoX8qHrXtswap9ge9uO3ONDzQB0cQ0PUyaKY2N6HaVbTBvSXvw==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@huggingface/transformers": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@huggingface/transformers/-/transformers-3.3.3.tgz", + "integrity": "sha512-OcMubhBjW6u1xnp0zSt5SvCxdGHuhP2k+w2Vlm3i0vNcTJhJTZWxxYQmPBfcb7PX+Q6c43lGSzWD6tsJFwka4Q==", + "license": "Apache-2.0", + "dependencies": { + "@huggingface/jinja": "^0.3.3", + "onnxruntime-node": "1.20.1", + "onnxruntime-web": "1.21.0-dev.20250206-d981b153d3", + "sharp": "^0.33.5" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", + "dev": true + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", + "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", + "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", + "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz", + "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz", + "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz", + "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz", + "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz", + "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz", + "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz", + "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", + "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.5" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz", + "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz", + "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz", + "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz", + "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz", + "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz", + "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==", + "cpu": [ + "wasm32" + ], + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.2.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz", + "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", + "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@internationalized/date": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.5.2.tgz", + "integrity": "sha512-vo1yOMUt2hzp63IutEaTUxROdvQg1qlMRsbCvbay2AK2Gai7wIgCyK5weEX3nHkiLgo4qCXHijFNC/ILhlRpOQ==", + "dependencies": { + "@swc/helpers": "^0.5.0" + } + }, + "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/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/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@lezer/common": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.1.tgz", + "integrity": "sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ==" + }, + "node_modules/@lezer/cpp": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@lezer/cpp/-/cpp-1.1.2.tgz", + "integrity": "sha512-macwKtyeUO0EW86r3xWQCzOV9/CF8imJLpJlPv3sDY57cPGeUZ8gXWOWNlJr52TVByMV3PayFQCA5SHEERDmVQ==", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/css": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.1.9.tgz", + "integrity": "sha512-TYwgljcDv+YrV0MZFFvYFQHCfGgbPMR6nuqLabBdmZoFH3EP1gvw8t0vae326Ne3PszQkbXfVBjCnf3ZVCr0bA==", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/go": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@lezer/go/-/go-1.0.0.tgz", + "integrity": "sha512-co9JfT3QqX1YkrMmourYw2Z8meGC50Ko4d54QEcQbEYpvdUvN4yb0NBZdn/9ertgvjsySxHsKzH3lbm3vqJ4Jw==", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/highlight": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.0.tgz", + "integrity": "sha512-WrS5Mw51sGrpqjlh3d4/fOwpEV2Hd3YOkp9DBt4k8XZQcoTHZFB7sx030A6OcahF4J1nDQAa3jXlTVVYH50IFA==", + "dependencies": { + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@lezer/html": { + "version": "1.3.10", + "resolved": "https://registry.npmjs.org/@lezer/html/-/html-1.3.10.tgz", + "integrity": "sha512-dqpT8nISx/p9Do3AchvYGV3qYc4/rKr3IBZxlHmpIKam56P47RSHkSF5f13Vu9hebS1jM0HmtJIwLbWz1VIY6w==", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/java": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@lezer/java/-/java-1.1.2.tgz", + "integrity": "sha512-3j8X70JvYf0BZt8iSRLXLkt0Ry1hVUgH6wT32yBxH/Xi55nW2VMhc1Az4SKwu4YGSmxCm1fsqDDcHTuFjC8pmg==", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/javascript": { + "version": "1.4.16", + "resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.4.16.tgz", + "integrity": "sha512-84UXR3N7s11MPQHWgMnjb9571fr19MmXnr5zTv2XX0gHXXUvW3uPJ8GCjKrfTXmSdfktjRK0ayKklw+A13rk4g==", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.1.3", + "@lezer/lr": "^1.3.0" + } + }, + "node_modules/@lezer/json": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.2.tgz", + "integrity": "sha512-xHT2P4S5eeCYECyKNPhr4cbEL9tc8w83SPwRC373o9uEdrvGKTZoJVAGxpOsZckMlEh9W23Pc72ew918RWQOBQ==", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/lr": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.1.tgz", + "integrity": "sha512-CHsKq8DMKBf9b3yXPDIU4DbH+ZJd/sJdYOW2llbW/HudP5u0VS6Bfq1hLYfgU7uAYGFIyGGQIsSOXGPEErZiJw==", + "dependencies": { + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@lezer/markdown": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@lezer/markdown/-/markdown-1.3.1.tgz", + "integrity": "sha512-DGlzU/i8DC8k0uz1F+jeePrkATl0jWakauTzftMQOcbaMkHbNSRki/4E2tOzJWsVpoKYhe7iTJ03aepdwVUXUA==", + "dependencies": { + "@lezer/common": "^1.0.0", + "@lezer/highlight": "^1.0.0" + } + }, + "node_modules/@lezer/php": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@lezer/php/-/php-1.0.2.tgz", + "integrity": "sha512-GN7BnqtGRpFyeoKSEqxvGvhJQiI4zkgmYnDk/JIyc7H7Ifc1tkPnUn/R2R8meH3h/aBf5rzjvU8ZQoyiNDtDrA==", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.1.0" + } + }, + "node_modules/@lezer/python": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/@lezer/python/-/python-1.1.14.tgz", + "integrity": "sha512-ykDOb2Ti24n76PJsSa4ZoDF0zH12BSw1LGfQXCYJhJyOGiFTfGaX0Du66Ze72R+u/P35U+O6I9m8TFXov1JzsA==", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/rust": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@lezer/rust/-/rust-1.0.2.tgz", + "integrity": "sha512-Lz5sIPBdF2FUXcWeCu1//ojFAZqzTQNRga0aYv6dYXqJqPfMdCAI0NzajWUd4Xijj1IKJLtjoXRPMvTKWBcqKg==", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/sass": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@lezer/sass/-/sass-1.0.7.tgz", + "integrity": "sha512-8HLlOkuX/SMHOggI2DAsXUw38TuURe+3eQ5hiuk9QmYOUyC55B1dYEIMkav5A4IELVaW4e1T4P9WRiI5ka4mdw==", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/xml": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@lezer/xml/-/xml-1.0.5.tgz", + "integrity": "sha512-VFouqOzmUWfIg+tfmpcdV33ewtK+NSwd4ngSe1aG7HFb4BN0ExyY1b8msp+ndFrnlG4V4iC8yXacjFtrwERnaw==", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/yaml": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@lezer/yaml/-/yaml-1.0.3.tgz", + "integrity": "sha512-GuBLekbw9jDBDhGur82nuwkxKQ+a3W5H0GfaAthDXcAu+XdpS43VlnxA9E9hllkpSP5ellRDKjLLj7Lu9Wr6xA==", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.4.0" + } + }, + "node_modules/@mediapipe/tasks-vision": { + "version": "0.10.17", + "resolved": "https://registry.npmjs.org/@mediapipe/tasks-vision/-/tasks-vision-0.10.17.tgz", + "integrity": "sha512-CZWV/q6TTe8ta61cZXjfnnHsfWIdFhms03M9T7Cnd5y2mdpylJM0rF1qRq+wsQVRMLz1OYPVEBU9ph2Bx8cxrg==" + }, + "node_modules/@melt-ui/svelte": { + "version": "0.76.0", + "resolved": "https://registry.npmjs.org/@melt-ui/svelte/-/svelte-0.76.0.tgz", + "integrity": "sha512-X1ktxKujjLjOBt8LBvfckHGDMrkHWceRt1jdsUTf0EH76ikNPP1ofSoiV0IhlduDoCBV+2YchJ8kXCDfDXfC9Q==", + "dependencies": { + "@floating-ui/core": "^1.3.1", + "@floating-ui/dom": "^1.4.5", + "@internationalized/date": "^3.5.0", + "dequal": "^2.0.3", + "focus-trap": "^7.5.2", + "nanoid": "^5.0.4" + }, + "peerDependencies": { + "svelte": ">=3 <5" + } + }, + "node_modules/@mixmark-io/domino": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@mixmark-io/domino/-/domino-2.2.0.tgz", + "integrity": "sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==" + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "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/@polka/url": { + "version": "1.0.0-next.28", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz", + "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==", + "license": "MIT" + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, + "node_modules/@pyscript/core": { + "version": "0.4.32", + "resolved": "https://registry.npmjs.org/@pyscript/core/-/core-0.4.32.tgz", + "integrity": "sha512-WQATzPp1ggf871+PukCmTypzScXkEB1EWD/vg5GNxpM96N6rDPqQ13msuA5XvwU01ZVhL8HHSFDLk4IfaXNGWg==", + "dependencies": { + "@ungap/with-resolvers": "^0.1.0", + "basic-devtools": "^0.1.6", + "polyscript": "^0.12.8", + "sticky-module": "^0.1.1", + "to-json-callback": "^0.1.1", + "type-checked-collections": "^0.1.7" + } + }, + "node_modules/@remirror/core-constants": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@remirror/core-constants/-/core-constants-3.0.0.tgz", + "integrity": "sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==", + "license": "MIT" + }, + "node_modules/@rollup/plugin-commonjs": { + "version": "25.0.7", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.7.tgz", + "integrity": "sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ==", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "commondir": "^1.0.1", + "estree-walker": "^2.0.2", + "glob": "^8.0.3", + "is-reference": "1.2.1", + "magic-string": "^0.30.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.68.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-json": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.1.0.tgz", + "integrity": "sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==", + "dependencies": { + "@rollup/pluginutils": "^5.1.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "15.2.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", + "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-builtin-module": "^3.2.1", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.78.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", + "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz", + "integrity": "sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz", + "integrity": "sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz", + "integrity": "sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz", + "integrity": "sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz", + "integrity": "sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz", + "integrity": "sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz", + "integrity": "sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz", + "integrity": "sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz", + "integrity": "sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz", + "integrity": "sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz", + "integrity": "sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz", + "integrity": "sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz", + "integrity": "sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz", + "integrity": "sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz", + "integrity": "sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz", + "integrity": "sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==" + }, + "node_modules/@svelte-put/shortcut": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@svelte-put/shortcut/-/shortcut-3.1.1.tgz", + "integrity": "sha512-2L5EYTZXiaKvbEelVkg5znxqvfZGZai3m97+cAiUBhLZwXnGtviTDpHxOoZBsqz41szlfRMcamW/8o0+fbW3ZQ==", + "peerDependencies": { + "svelte": "^3.55.0 || ^4.0.0 || ^5.0.0" + } + }, + "node_modules/@sveltejs/adapter-auto": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-3.2.2.tgz", + "integrity": "sha512-Mso5xPCA8zgcKrv+QioVlqMZkyUQ5MjDJiEPuG/Z7cV/5tmwV7LmcVWk5tZ+H0NCOV1x12AsoSpt/CwFwuVXMA==", + "dev": true, + "dependencies": { + "import-meta-resolve": "^4.1.0" + }, + "peerDependencies": { + "@sveltejs/kit": "^2.0.0" + } + }, + "node_modules/@sveltejs/adapter-node": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-node/-/adapter-node-2.1.2.tgz", + "integrity": "sha512-ZfVY5buBclWHoBT+RbkMUViJGEIZ3IfT/0Hvhlgp+qC3LRZwp+wS1Zsw5dgkB2sFDZXctbLNXJtwlkjSp1mw0g==", + "dependencies": { + "@rollup/plugin-commonjs": "^25.0.7", + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^15.2.3", + "rollup": "^4.8.0" + }, + "peerDependencies": { + "@sveltejs/kit": "^2.0.0" + } + }, + "node_modules/@sveltejs/adapter-static": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.6.tgz", + "integrity": "sha512-MGJcesnJWj7FxDcB/GbrdYD3q24Uk0PIL4QIX149ku+hlJuj//nxUbb0HxUTpjkecWfHjVveSUnUaQWnPRXlpg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@sveltejs/kit": "^2.0.0" + } + }, + "node_modules/@sveltejs/kit": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.12.1.tgz", + "integrity": "sha512-M3rPijGImeOkI0DBJSwjqz+YFX2DyOf6NzWgHVk3mqpT06dlYCpcv5xh1q4rYEqB58yQlk4QA1Y35PUqnUiFKw==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@types/cookie": "^0.6.0", + "cookie": "^0.6.0", + "devalue": "^5.1.0", + "esm-env": "^1.2.1", + "import-meta-resolve": "^4.1.0", + "kleur": "^4.1.5", + "magic-string": "^0.30.5", + "mrmime": "^2.0.0", + "sade": "^1.8.1", + "set-cookie-parser": "^2.6.0", + "sirv": "^3.0.0", + "tiny-glob": "^0.2.9" + }, + "bin": { + "svelte-kit": "svelte-kit.js" + }, + "engines": { + "node": ">=18.13" + }, + "peerDependencies": { + "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0", + "svelte": "^4.0.0 || ^5.0.0-next.0", + "vite": "^5.0.3 || ^6.0.0" + } + }, + "node_modules/@sveltejs/svelte-virtual-list": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sveltejs/svelte-virtual-list/-/svelte-virtual-list-3.0.1.tgz", + "integrity": "sha512-aF9TptS7NKKS7/TqpsxQBSDJ9Q0XBYzBehCeIC5DzdMEgrJZpIYao9LRLnyyo6SVodpapm2B7FE/Lj+FSA5/SQ==", + "license": "LIL" + }, + "node_modules/@sveltejs/vite-plugin-svelte": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-3.1.1.tgz", + "integrity": "sha512-rimpFEAboBBHIlzISibg94iP09k/KYdHgVhJlcsTfn7KMBhc70jFX/GRWkRdFCc2fdnk+4+Bdfej23cMDnJS6A==", + "dependencies": { + "@sveltejs/vite-plugin-svelte-inspector": "^2.1.0", + "debug": "^4.3.4", + "deepmerge": "^4.3.1", + "kleur": "^4.1.5", + "magic-string": "^0.30.10", + "svelte-hmr": "^0.16.0", + "vitefu": "^0.2.5" + }, + "engines": { + "node": "^18.0.0 || >=20" + }, + "peerDependencies": { + "svelte": "^4.0.0 || ^5.0.0-next.0", + "vite": "^5.0.0" + } + }, + "node_modules/@sveltejs/vite-plugin-svelte-inspector": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-2.1.0.tgz", + "integrity": "sha512-9QX28IymvBlSCqsCll5t0kQVxipsfhFFL+L2t3nTWfXnddYwxBuAEtTtlaVQpRz9c37BhJjltSeY4AJSC03SSg==", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.0.0 || >=20" + }, + "peerDependencies": { + "@sveltejs/vite-plugin-svelte": "^3.0.0", + "svelte": "^4.0.0 || ^5.0.0-next.0", + "vite": "^5.0.0" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.7.tgz", + "integrity": "sha512-BVvNZhx362+l2tSwSuyEUV4h7+jk9raNdoTSdLfwTshXJSaGmYKluGRJznziCI3KX02Z19DdsQrdfrpXAU3Hfg==", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/container-queries": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/container-queries/-/container-queries-0.1.1.tgz", + "integrity": "sha512-p18dswChx6WnTSaJCSGx6lTmrGzNNvm2FtXmiO6AuA1V4U5REyoqwmT6kgAsIMdjo07QdAfYXHJ4hnMtfHzWgA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "tailwindcss": ">=3.2.0" + } + }, + "node_modules/@tailwindcss/node": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.0.6.tgz", + "integrity": "sha512-jb6E0WeSq7OQbVYcIJ6LxnZTeC4HjMvbzFBMCrQff4R50HBlo/obmYNk6V2GCUXDeqiXtvtrQgcIbT+/boB03Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "enhanced-resolve": "^5.18.0", + "jiti": "^2.4.2", + "tailwindcss": "4.0.6" + } + }, + "node_modules/@tailwindcss/node/node_modules/jiti": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/@tailwindcss/node/node_modules/tailwindcss": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.0.6.tgz", + "integrity": "sha512-mysewHYJKaXgNOW6pp5xon/emCsfAMnO8WMaGKZZ35fomnR/T5gYnRg2/yRTTrtXiEl1tiVkeRt0eMO6HxEZqw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.0.6.tgz", + "integrity": "sha512-lVyKV2y58UE9CeKVcYykULe9QaE1dtKdxDEdrTPIdbzRgBk6bdxHNAoDqvcqXbIGXubn3VOl1O/CFF77v/EqSA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.0.6", + "@tailwindcss/oxide-darwin-arm64": "4.0.6", + "@tailwindcss/oxide-darwin-x64": "4.0.6", + "@tailwindcss/oxide-freebsd-x64": "4.0.6", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.0.6", + "@tailwindcss/oxide-linux-arm64-gnu": "4.0.6", + "@tailwindcss/oxide-linux-arm64-musl": "4.0.6", + "@tailwindcss/oxide-linux-x64-gnu": "4.0.6", + "@tailwindcss/oxide-linux-x64-musl": "4.0.6", + "@tailwindcss/oxide-win32-arm64-msvc": "4.0.6", + "@tailwindcss/oxide-win32-x64-msvc": "4.0.6" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.0.6.tgz", + "integrity": "sha512-xDbym6bDPW3D2XqQqX3PjqW3CKGe1KXH7Fdkc60sX5ZLVUbzPkFeunQaoP+BuYlLc2cC1FoClrIRYnRzof9Sow==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.0.6.tgz", + "integrity": "sha512-1f71/ju/tvyGl5c2bDkchZHy8p8EK/tDHCxlpYJ1hGNvsYihZNurxVpZ0DefpN7cNc9RTT8DjrRoV8xXZKKRjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.0.6.tgz", + "integrity": "sha512-s/hg/ZPgxFIrGMb0kqyeaqZt505P891buUkSezmrDY6lxv2ixIELAlOcUVTkVh245SeaeEiUVUPiUN37cwoL2g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.0.6.tgz", + "integrity": "sha512-Z3Wo8FWZnmio8+xlcbb7JUo/hqRMSmhQw8IGIRoRJ7GmLR0C+25Wq+bEX/135xe/yEle2lFkhu9JBHd4wZYiig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.0.6.tgz", + "integrity": "sha512-SNSwkkim1myAgmnbHs4EjXsPL7rQbVGtjcok5EaIzkHkCAVK9QBQsWeP2Jm2/JJhq4wdx8tZB9Y7psMzHYWCkA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.0.6.tgz", + "integrity": "sha512-tJ+mevtSDMQhKlwCCuhsFEFg058kBiSy4TkoeBG921EfrHKmexOaCyFKYhVXy4JtkaeeOcjJnCLasEeqml4i+Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.0.6.tgz", + "integrity": "sha512-IoArz1vfuTR4rALXMUXI/GWWfx2EaO4gFNtBNkDNOYhlTD4NVEwE45nbBoojYiTulajI4c2XH8UmVEVJTOJKxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.0.6.tgz", + "integrity": "sha512-QtsUfLkEAeWAC3Owx9Kg+7JdzE+k9drPhwTAXbXugYB9RZUnEWWx5x3q/au6TvUYcL+n0RBqDEO2gucZRvRFgQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.0.6.tgz", + "integrity": "sha512-QthvJqIji2KlGNwLcK/PPYo7w1Wsi/8NK0wAtRGbv4eOPdZHkQ9KUk+oCoP20oPO7i2a6X1aBAFQEL7i08nNMA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.0.6.tgz", + "integrity": "sha512-+oka+dYX8jy9iP00DJ9Y100XsqvbqR5s0yfMZJuPR1H/lDVtDfsZiSix1UFBQ3X1HWxoEEl6iXNJHWd56TocVw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.0.6.tgz", + "integrity": "sha512-+o+juAkik4p8Ue/0LiflQXPmVatl6Av3LEZXpBTfg4qkMIbZdhCGWFzHdt2NjoMiLOJCFDddoV6GYaimvK1Olw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/postcss": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.0.0.tgz", + "integrity": "sha512-lI2bPk4TvwavHdehjr5WiC6HnZ59hacM6ySEo4RM/H7tsjWd8JpqiNW9ThH7rO/yKtrn4mGBoXshpvn8clXjPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "@tailwindcss/node": "^4.0.0", + "@tailwindcss/oxide": "^4.0.0", + "lightningcss": "^1.29.1", + "postcss": "^8.4.41", + "tailwindcss": "4.0.0" + } + }, + "node_modules/@tailwindcss/typography": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.13.tgz", + "integrity": "sha512-ADGcJ8dX21dVVHIwTRgzrcunY6YY9uSlAHHGVKvkA+vLc5qLwEszvKts40lx7z0qc4clpjclwLeK5rVCV2P/uw==", + "dev": true, + "dependencies": { + "lodash.castarray": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.merge": "^4.6.2", + "postcss-selector-parser": "6.0.10" + }, + "peerDependencies": { + "tailwindcss": ">=3.0.0 || insiders" + } + }, + "node_modules/@tiptap/core": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.10.0.tgz", + "integrity": "sha512-58nAjPxLRFcXepdDqQRC1mhrw6E8Sanqr6bbO4Tz0+FWgDJMZvHG+dOK5wHaDVNSgK2iJDz08ETvQayfOOgDvg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-blockquote": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-2.10.0.tgz", + "integrity": "sha512-6Xmfo2lpfIRcbfkLD/NGX4YgQqfgAbu6XaZQZf5oGtHLPTrz4D7Mw20GgNBHzae2XwUCwLMt6zXOkBgU/LnlZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-bold": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.10.0.tgz", + "integrity": "sha512-1wL8UI1Aii0u2cbDEvwyqsZb2pgBt8HLJdsIax/ELoF2tKCD5821nElqTGLBBg4pUGPa0ru9ZemuL8GdXZp3Qg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-bullet-list": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.10.0.tgz", + "integrity": "sha512-Cl+DGu6D3SgF/hlKUDNet3gaZFy6cPEonOOkHwzXoybDXXdddFbaTvt9MLkBRUR3ldksXuVRP2/LwZsK5WyxJQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-code": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.10.0.tgz", + "integrity": "sha512-8JznKG1Jmv8gJezZGPoka8oRmfrcAAnMEOeMpKXjwMrIbQ6QynTZpqMGGVL1kfkZlLV84PYm+CGjGgjSsT4iZw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-code-block": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.10.0.tgz", + "integrity": "sha512-QH+LP7L1s1EJlrDFnfgOP0q+Siqt0Zbkx4ICMcUGvEsycl53Ti8P0DRW7fAjRISdTCItuWJYvtmiYY7O3rYb+Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-code-block-lowlight": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block-lowlight/-/extension-code-block-lowlight-2.10.0.tgz", + "integrity": "sha512-dAv03XIHT5h+sdFmJzvx2FfpfFOOK9SBKHflRUdqTa8eA+0VZNAcPRjvJWVEWqts1fKZDJj774mO28NlhFzk9Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/extension-code-block": "^2.7.0", + "@tiptap/pm": "^2.7.0", + "highlight.js": "^11", + "lowlight": "^2 || ^3" + } + }, + "node_modules/@tiptap/extension-document": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.10.0.tgz", + "integrity": "sha512-vseMW3EKiQAPgdbN48Y8F0nRqWhhrAo9DLacAfP7tu0x3uv44uotNjDBtAgp5QmJmqQVyrEdkLSZaU5vFzduhQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-dropcursor": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-2.10.0.tgz", + "integrity": "sha512-tifxp/a3NxTjLAuYBx9XAwVo4MSDoY/mQ8E18QtuXj0vuieCFxd8Bkyre0otubIAAQePXLTVGQoxPrKmMAa+Jg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-gapcursor": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-2.10.0.tgz", + "integrity": "sha512-GViEnSnEBE74k7SYdXrQ4aXlKmWkrd9awdj/TgDSORgpZ4Dfyqtn+ENIWWby4NhL+BPM9P5hGCjkQXZsi6JKOw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-hard-break": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.10.0.tgz", + "integrity": "sha512-NL/xPYUhhvQyCnOO5Yn+BlBOMLC1ru32nw7ox12TShGmaeKBrnV0DhzBRkyJU0MqCS26oWjieNPxfu0lR3oMSA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-heading": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-2.10.0.tgz", + "integrity": "sha512-x2Uj5wrAHFaUdlChwLoQVmWtzZCuNyJpBRA19kA4idWL5z+6cIrUWepvwVBxA8ou6ictbzWW15o+blKtW7DlqA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-highlight": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-highlight/-/extension-highlight-2.10.0.tgz", + "integrity": "sha512-HU8UuKU7ljlzNn7jg29pM8QtIX7QvePcBjcWAt6K3qVwF1cbBNguIjKRY2rmoonU2nu8I6GknQNgV847kZifCQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-history": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.10.0.tgz", + "integrity": "sha512-5aYOmxqaCnw7e7wmWqFZmkpYCxxDjEzFbgVI6WknqNwqeOizR4+YJf3aAt/lTbksLJe47XF+NBX51gOm/ZBCiw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-horizontal-rule": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.10.0.tgz", + "integrity": "sha512-el1SzI/x/h4HW8UltxJlyMSrRsO55ypKPLQHJC9h7F6kTTR31fJUzQa3AeTFrZvXS0kNHIFRpAMstw+N0L5TYg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-italic": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.10.0.tgz", + "integrity": "sha512-MqPYbHAEeO8QBvZRIkF4J2OTf/uiUPzUiXGLJ50w1ozfMBIw1txMvfR3g2cpwfvZlcOgYTgy7M0Oq00nQz5eXg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-list-item": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.10.0.tgz", + "integrity": "sha512-BxC6NNHd2xcC+mk5hpYWURUdj/mRz6TGFwH5CsyrUXPxApx0+V+EPHaAgdpu8dr+jtTEzjXF62V6e2JmOAPimg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-ordered-list": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-2.10.0.tgz", + "integrity": "sha512-jsK+mvzs7HmxQuQOU3HgIga+v7zUbQlmSP4/danusqUihJ+lc1n0frDCIkVvJrnSB3FChvNgT6ZEA14HOhdJzg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-paragraph": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.10.0.tgz", + "integrity": "sha512-4LUkVaJYjNdNZ7QOX6TRcA+m7oCtyrLGk49G22wl7XcPBkQPILP1mCUCU4f41bhjfhCgK5PPWP63kMtD+cEACg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-placeholder": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-placeholder/-/extension-placeholder-2.10.0.tgz", + "integrity": "sha512-1o6azk2plgYAFgMrV3prnBb1NZjl2V1T3wwnH4n3/h9z9lJ0v5BBAk9r+TRYSrcdXknwwHAWFYnQe6dc9buG2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-strike": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.10.0.tgz", + "integrity": "sha512-SxApLJMQkxnmPGR3lwaskvLK61yI+Bu9hGZGdwMZqNh6o3LoDOxDaXjHD5joeMYQiqQrBE9zg46506MsXtrU7Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-text": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.10.0.tgz", + "integrity": "sha512-SSnNncADS1KucdEcJlF6WGCs5+1pAhPrD68vlw34oj3NDT3Zh05KiyXsCV3Nw4wpHOnbWahV+z3uT2SnR+xgoQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-text-style": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text-style/-/extension-text-style-2.10.0.tgz", + "integrity": "sha512-VZtH1dp64wg1UcFtUPpRQK+kOm4JHBIv+WXuKX7EnpIEKjHKnyfV94BBVmaqY5UE4n3kbkkmIRB2Cmix/10AMg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-typography": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-typography/-/extension-typography-2.10.0.tgz", + "integrity": "sha512-03IOfJm4bk2hZ4SsSfxgBOVzcDxMRBlFD7ZY12H2EGNf1TKxj/0ANWhAH54FtquuOMoY5aWg5LZf0lk++8UDAw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/pm": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.10.0.tgz", + "integrity": "sha512-ohshlWf4MlW6D3rQkNQnhmiQ2w4pwRoQcJmTPt8UJoIDGkeKmZh494fQp4Aeh80XuGd81SsCv//1HJeyaeHJYQ==", + "license": "MIT", + "dependencies": { + "prosemirror-changeset": "^2.2.1", + "prosemirror-collab": "^1.3.1", + "prosemirror-commands": "^1.6.2", + "prosemirror-dropcursor": "^1.8.1", + "prosemirror-gapcursor": "^1.3.2", + "prosemirror-history": "^1.4.1", + "prosemirror-inputrules": "^1.4.0", + "prosemirror-keymap": "^1.2.2", + "prosemirror-markdown": "^1.13.1", + "prosemirror-menu": "^1.2.4", + "prosemirror-model": "^1.23.0", + "prosemirror-schema-basic": "^1.2.3", + "prosemirror-schema-list": "^1.4.1", + "prosemirror-state": "^1.4.3", + "prosemirror-tables": "^1.6.1", + "prosemirror-trailing-node": "^3.0.0", + "prosemirror-transform": "^1.10.2", + "prosemirror-view": "^1.36.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + } + }, + "node_modules/@tiptap/starter-kit": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-2.10.0.tgz", + "integrity": "sha512-hMIM9a6HjYZo25EzhZHlKEIR7CFi0grRSOltEyggiyBuQqKFkI7iwCpZVVtviDV1FwV0EPANpIAxPS7aBRgFdg==", + "license": "MIT", + "dependencies": { + "@tiptap/core": "^2.10.0", + "@tiptap/extension-blockquote": "^2.10.0", + "@tiptap/extension-bold": "^2.10.0", + "@tiptap/extension-bullet-list": "^2.10.0", + "@tiptap/extension-code": "^2.10.0", + "@tiptap/extension-code-block": "^2.10.0", + "@tiptap/extension-document": "^2.10.0", + "@tiptap/extension-dropcursor": "^2.10.0", + "@tiptap/extension-gapcursor": "^2.10.0", + "@tiptap/extension-hard-break": "^2.10.0", + "@tiptap/extension-heading": "^2.10.0", + "@tiptap/extension-history": "^2.10.0", + "@tiptap/extension-horizontal-rule": "^2.10.0", + "@tiptap/extension-italic": "^2.10.0", + "@tiptap/extension-list-item": "^2.10.0", + "@tiptap/extension-ordered-list": "^2.10.0", + "@tiptap/extension-paragraph": "^2.10.0", + "@tiptap/extension-strike": "^2.10.0", + "@tiptap/extension-text": "^2.10.0", + "@tiptap/extension-text-style": "^2.10.0", + "@tiptap/pm": "^2.10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + } + }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==" + }, + "node_modules/@types/d3-drag": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", + "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-scale": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", + "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-scale-chromatic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.3.tgz", + "integrity": "sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==" + }, + "node_modules/@types/d3-selection": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.10.tgz", + "integrity": "sha512-cuHoUgS/V3hLdjJOLTT691+G2QoqAjCVLmr4kJXR4ha56w1Zdu8UUQ5TxLRqudgNjwXeQxKMq4j+lyf9sWuslg==" + }, + "node_modules/@types/d3-time": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", + "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==" + }, + "node_modules/@types/d3-transition": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.8.tgz", + "integrity": "sha512-ew63aJfQ/ms7QQ4X7pk5NxQ9fZH/z+i24ZfJ6tJSfqxJMrYLiK01EAs2/Rtw/JreGUsS3pLPNV644qXFGnoZNQ==", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-zoom": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", + "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", + "dependencies": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==" + }, + "node_modules/@types/markdown-it": { + "version": "14.1.2", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", + "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", + "dependencies": { + "@types/linkify-it": "^5", + "@types/mdurl": "^2" + } + }, + "node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/@types/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==" + }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "node_modules/@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" + }, + "node_modules/@types/node": { + "version": "20.11.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.30.tgz", + "integrity": "sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/pug": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz", + "integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==", + "dev": true + }, + "node_modules/@types/raf": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/@types/raf/-/raf-3.4.3.tgz", + "integrity": "sha512-c4YAvMedbPZ5tEyxzQdMoOhhJ4RD3rngZIdwC2/qDN3d7JpEhB6fiBRKVY1lg5B7Wk+uPBjn5f39j1/2MY1oOw==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==" + }, + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true + }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", + "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==", + "dev": true + }, + "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/@types/symlink-or-copy": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/symlink-or-copy/-/symlink-or-copy-1.2.2.tgz", + "integrity": "sha512-MQ1AnmTLOncwEf9IVU+B2e4Hchrku5N67NkgcAHW0p3sdzPe0FNMANxEm6OJUzPniEQGkeT3OROLlCwZJLWFZA==", + "dev": true + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/unist": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", + "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/type-utils": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", + "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", + "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" + }, + "node_modules/@ungap/with-resolvers": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@ungap/with-resolvers/-/with-resolvers-0.1.0.tgz", + "integrity": "sha512-g7f0IkJdPW2xhY7H4iE72DAsIyfuwEFc6JWc2tYFwKDMWWAF699vGjrM348cwQuOXgHpe1gWFe+Eiyjx/ewvvw==" + }, + "node_modules/@vitest/expect": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.1.tgz", + "integrity": "sha512-jXL+9+ZNIJKruofqXuuTClf44eSpcHlgj3CiuNihUF3Ioujtmc0zIa3UJOW5RjDK1YLBJZnWBlPuqhYycLioog==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "1.6.1", + "@vitest/utils": "1.6.1", + "chai": "^4.3.10" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.1.tgz", + "integrity": "sha512-3nSnYXkVkf3mXFfE7vVyPmi3Sazhb/2cfZGGs0JRzFsPFvAMBEcrweV1V1GsrstdXeKCTXlJbvnQwGWgEIHmOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "1.6.1", + "p-limit": "^5.0.0", + "pathe": "^1.1.1" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner/node_modules/p-limit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", + "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@vitest/runner/node_modules/yocto-queue": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@vitest/snapshot": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.1.tgz", + "integrity": "sha512-WvidQuWAzU2p95u8GAKlRMqMyN1yOJkGHnx3M1PL9Raf7AQ1kwLKg04ADlCa3+OXUZE7BceOhVZiuWAbzCKcUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.1.tgz", + "integrity": "sha512-MGcMmpGkZebsMZhbQKkAf9CX5zGvjkBTqf8Zx3ApYWXr3wG+QvEu2eXWfnIIWYSJExIp4V9FCKDEeygzkYrXMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^2.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.1.tgz", + "integrity": "sha512-jOrrUvXM4Av9ZWiG1EajNto0u96kWAhJ1LmPmJhXXQx/32MecEKd10pOLYgS2BQx1TgkGhloPU1ArDW2vvaY6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/@webreflection/fetch": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@webreflection/fetch/-/fetch-0.1.5.tgz", + "integrity": "sha512-zCcqCJoNLvdeF41asAK71XPlwSPieeRDsE09albBunJEksuYPYNillKNQjf8p5BqSoTKTuKrW3lUm3MNodUC4g==" + }, + "node_modules/@xyflow/svelte": { + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/@xyflow/svelte/-/svelte-0.1.19.tgz", + "integrity": "sha512-yW5w5aI+Yqkob4kLQpVDo/ZmX+E9Pw7459kqwLfv4YG4N1NYXrsDRh9cyph/rapbuDnPi6zqK5E8LKrgaCQC0w==", + "dependencies": { + "@svelte-put/shortcut": "^3.1.0", + "@xyflow/system": "0.0.42", + "classcat": "^5.0.4" + }, + "peerDependencies": { + "svelte": "^3.0.0 || ^4.0.0" + } + }, + "node_modules/@xyflow/system": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@xyflow/system/-/system-0.0.42.tgz", + "integrity": "sha512-kWYj+Y0GOct0jKYTdyRMNOLPxGNbb2TYvPg2gTmJnZ31DOOMkL5uRBLX825DR2gOACDu+i5FHLxPJUPf/eGOJw==", + "dependencies": { + "@types/d3-drag": "^3.0.7", + "@types/d3-selection": "^3.0.10", + "@types/d3-transition": "^3.0.8", + "@types/d3-zoom": "^3.0.8", + "d3-drag": "^3.0.0", + "d3-selection": "^3.0.0", + "d3-zoom": "^3.0.0" + } + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/amator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/amator/-/amator-1.1.0.tgz", + "integrity": "sha512-V5+aH8pe+Z3u/UG3L3pG3BaFQGXAyXHVQDroRwjPHdh08bcUEchAVsU1MCuJSCaU5o60wTK6KaE6te5memzgYw==", + "dependencies": { + "bezier-easing": "^2.0.3" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "dev": true, + "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/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "license": "(MIT OR Apache-2.0)", + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", + "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", + "dev": true + }, + "node_modules/axobject-query": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz", + "integrity": "sha512-+60uv1hiVFhHZeO+Lz0RYzsVHy5Wr1ayX0mwda9KPDVLNJgZ1T9Ny7VmFbLDzxsH0D87I86vgj3gFrjTJUYznw==", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "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==", + "dev": true, + "optional": true + }, + "node_modules/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "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/basic-devtools": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/basic-devtools/-/basic-devtools-0.1.6.tgz", + "integrity": "sha512-g9zJ63GmdUesS3/Fwv0B5SYX6nR56TQXmGr+wE5PRTNCnGQMYWhUx/nZB/mMWnQJVLPPAp89oxDNlasdtNkW5Q==" + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/bezier-easing": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/bezier-easing/-/bezier-easing-2.1.0.tgz", + "integrity": "sha512-gbIqZ/eslnUFC1tjEvtz0sgx+xTK20wDnYMIA27VA04R7w6xxXQPZDbibjA9DTWZRA2CXtwHykkVzlCaAJAZig==" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bits-ui": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/bits-ui/-/bits-ui-0.19.7.tgz", + "integrity": "sha512-GHUpKvN7QyazhnZNkUy0lxg6W1M6KJHWSZ4a/UGCjPE6nQgk6vKbGysY67PkDtQMknZTZAzVoMj1Eic4IKeCRQ==", + "dependencies": { + "@internationalized/date": "^3.5.1", + "@melt-ui/svelte": "0.76.0", + "nanoid": "^5.0.5" + }, + "peerDependencies": { + "svelte": "^4.0.0" + } + }, + "node_modules/bl": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", + "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", + "dev": true, + "dependencies": { + "buffer": "^6.0.3", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/blob-util": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", + "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==", + "dev": true + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true + }, + "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/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/broccoli-node-api": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/broccoli-node-api/-/broccoli-node-api-1.7.0.tgz", + "integrity": "sha512-QIqLSVJWJUVOhclmkmypJJH9u9s/aWH4+FH6Q6Ju5l+Io4dtwqdPUNmDfw40o6sxhbZHhqGujDJuHTML1wG8Yw==", + "dev": true + }, + "node_modules/broccoli-node-info": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/broccoli-node-info/-/broccoli-node-info-2.2.0.tgz", + "integrity": "sha512-VabSGRpKIzpmC+r+tJueCE5h8k6vON7EIMMWu6d/FyPdtijwLQ7QvzShEw+m3mHoDzUaj/kiZsDYrS8X2adsBg==", + "dev": true, + "engines": { + "node": "8.* || >= 10.*" + } + }, + "node_modules/broccoli-output-wrapper": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/broccoli-output-wrapper/-/broccoli-output-wrapper-3.2.5.tgz", + "integrity": "sha512-bQAtwjSrF4Nu0CK0JOy5OZqw9t5U0zzv2555EA/cF8/a8SLDTIetk9UgrtMVw7qKLKdSpOZ2liZNeZZDaKgayw==", + "dev": true, + "dependencies": { + "fs-extra": "^8.1.0", + "heimdalljs-logger": "^0.1.10", + "symlink-or-copy": "^1.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + } + }, + "node_modules/broccoli-output-wrapper/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/broccoli-output-wrapper/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/broccoli-output-wrapper/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/broccoli-plugin": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/broccoli-plugin/-/broccoli-plugin-4.0.7.tgz", + "integrity": "sha512-a4zUsWtA1uns1K7p9rExYVYG99rdKeGRymW0qOCNkvDPHQxVi3yVyJHhQbM3EZwdt2E0mnhr5e0c/bPpJ7p3Wg==", + "dev": true, + "dependencies": { + "broccoli-node-api": "^1.7.0", + "broccoli-output-wrapper": "^3.2.5", + "fs-merger": "^3.2.1", + "promise-map-series": "^0.3.0", + "quick-temp": "^0.1.8", + "rimraf": "^3.0.2", + "symlink-or-copy": "^1.3.1" + }, + "engines": { + "node": "10.* || >= 12.*" + } + }, + "node_modules/btoa": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz", + "integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==", + "license": "(MIT OR Apache-2.0)", + "bin": { + "btoa": "bin/btoa.js" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "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/buffer-builder": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/buffer-builder/-/buffer-builder-0.2.0.tgz", + "integrity": "sha512-7VPMEPuYznPSoR21NE1zvd2Xna6c/CloiZCfcMXR1Jny6PjX0N4Nsa38zcBFo/FMK+BlA+FLKbJCQ0i2yxp+Xg==", + "devOptional": true, + "license": "MIT/X11" + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cachedir": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", + "integrity": "sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/canvg": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/canvg/-/canvg-3.0.10.tgz", + "integrity": "sha512-qwR2FRNO9NlzTeKIPIKpnTY6fqwuYSequ8Ru8c0YkYU7U0oW+hLUvWadLvAu1Rl72OMNiFhoLu4f8eUjQ7l/+Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "@babel/runtime": "^7.12.5", + "@types/raf": "^3.4.0", + "core-js": "^3.8.3", + "raf": "^3.4.1", + "regenerator-runtime": "^0.13.7", + "rgbcolor": "^1.0.1", + "stackblur-canvas": "^2.0.0", + "svg-pathdata": "^6.0.3" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/canvg/node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "license": "MIT", + "optional": true + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true + }, + "node_modules/chai": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/check-more-types": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", + "integrity": "sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/cheerio": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "dev": true, + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/classcat": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/classcat/-/classcat-5.0.5.tgz", + "integrity": "sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w==" + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-table3": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.4.tgz", + "integrity": "sha512-Lm3L0p+/npIQWNIiyF/nAn7T5dnOwR3xNTHXYEBFBFVPXzCVNZ5lqEC/1eo/EVfpDsQ1I+TX4ORPQgp+UI0CRw==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-table3/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/cli-table3/node_modules/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==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/cli-truncate/node_modules/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==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==", + "dev": true + }, + "node_modules/code-red": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", + "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15", + "@types/estree": "^1.0.1", + "acorn": "^8.10.0", + "estree-walker": "^3.0.3", + "periscopic": "^3.1.0" + } + }, + "node_modules/code-red/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/codedent": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/codedent/-/codedent-0.1.2.tgz", + "integrity": "sha512-qEqzcy5viM3UoCN0jYHZeXZoyd4NZQzYFg0kOBj8O1CgoGG9WYYTF+VeQRsN0OSKFjF3G1u4WDUOtOsWEx6N2w==", + "dependencies": { + "plain-tag": "^0.1.3" + } + }, + "node_modules/codemirror": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz", + "integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/commands": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/search": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0" + } + }, + "node_modules/codemirror-lang-hcl": { + "version": "0.0.0-beta.2", + "resolved": "https://registry.npmjs.org/codemirror-lang-hcl/-/codemirror-lang-hcl-0.0.0-beta.2.tgz", + "integrity": "sha512-R3ew7Z2EYTdHTMXsWKBW9zxnLoLPYO+CrAa3dPZjXLrIR96Q3GR4cwJKF7zkSsujsnWgwRQZonyWpXYXfhQYuQ==", + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/coincident": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/coincident/-/coincident-1.2.3.tgz", + "integrity": "sha512-Uxz3BMTWIslzeWjuQnizGWVg0j6khbvHUQ8+5BdM7WuJEm4ALXwq3wluYoB+uF68uPBz/oUOeJnYURKyfjexlA==", + "dependencies": { + "@ungap/structured-clone": "^1.2.0", + "@ungap/with-resolvers": "^0.1.0", + "gc-hook": "^0.3.1", + "proxy-target": "^3.0.2" + }, + "optionalDependencies": { + "ws": "^8.16.0" + } + }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/colorjs.io": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/colorjs.io/-/colorjs.io-0.5.2.tgz", + "integrity": "sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/confbox": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.7.tgz", + "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/core-js": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.40.0.tgz", + "integrity": "sha512-7vsMc/Lty6AGnn7uFpYT56QesI5D2Y/UkgKounk87OP9Z2H9Z8kj6jzcSGAxFmUtDOS0ntK6lbQz+Nsa0Jj6mQ==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/cose-base": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz", + "integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==", + "dependencies": { + "layout-base": "^1.0.0" + } + }, + "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/crelt": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", + "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-line-break": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz", + "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==", + "license": "MIT", + "optional": true, + "dependencies": { + "utrie": "^1.0.2" + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cypress": { + "version": "13.15.0", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.15.0.tgz", + "integrity": "sha512-53aO7PwOfi604qzOkCSzNlWquCynLlKE/rmmpSPcziRH6LNfaDUAklQT6WJIsD8ywxlIy+uVZsnTMCCQVd2kTw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@cypress/request": "^3.0.4", + "@cypress/xvfb": "^1.2.4", + "@types/sinonjs__fake-timers": "8.1.1", + "@types/sizzle": "^2.3.2", + "arch": "^2.2.0", + "blob-util": "^2.0.2", + "bluebird": "^3.7.2", + "buffer": "^5.7.1", + "cachedir": "^2.3.0", + "chalk": "^4.1.0", + "check-more-types": "^2.24.0", + "cli-cursor": "^3.1.0", + "cli-table3": "~0.6.1", + "commander": "^6.2.1", + "common-tags": "^1.8.0", + "dayjs": "^1.10.4", + "debug": "^4.3.4", + "enquirer": "^2.3.6", + "eventemitter2": "6.4.7", + "execa": "4.1.0", + "executable": "^4.1.1", + "extract-zip": "2.0.1", + "figures": "^3.2.0", + "fs-extra": "^9.1.0", + "getos": "^3.2.1", + "is-ci": "^3.0.1", + "is-installed-globally": "~0.4.0", + "lazy-ass": "^1.6.0", + "listr2": "^3.8.3", + "lodash": "^4.17.21", + "log-symbols": "^4.0.0", + "minimist": "^1.2.8", + "ospath": "^1.2.2", + "pretty-bytes": "^5.6.0", + "process": "^0.11.10", + "proxy-from-env": "1.0.0", + "request-progress": "^3.0.0", + "semver": "^7.5.3", + "supports-color": "^8.1.1", + "tmp": "~0.2.3", + "untildify": "^4.0.0", + "yauzl": "^2.10.0" + }, + "bin": { + "cypress": "bin/cypress" + }, + "engines": { + "node": "^16.0.0 || ^18.0.0 || >=20.0.0" + } + }, + "node_modules/cypress/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "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.1.13" + } + }, + "node_modules/cypress/node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/cypress/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cypress/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/cytoscape": { + "version": "3.29.2", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.29.2.tgz", + "integrity": "sha512-2G1ycU28Nh7OHT9rkXRLpCDP30MKH1dXJORZuBhtEhEW7pKwgPi77ImqlCWinouyE1PNepIOGZBOrE84DG7LyQ==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/cytoscape-cose-bilkent": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz", + "integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==", + "dependencies": { + "cose-base": "^1.0.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/d3": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", + "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", + "dependencies": { + "d3-array": "3", + "d3-axis": "3", + "d3-brush": "3", + "d3-chord": "3", + "d3-color": "3", + "d3-contour": "4", + "d3-delaunay": "6", + "d3-dispatch": "3", + "d3-drag": "3", + "d3-dsv": "3", + "d3-ease": "3", + "d3-fetch": "3", + "d3-force": "3", + "d3-format": "3", + "d3-geo": "3", + "d3-hierarchy": "3", + "d3-interpolate": "3", + "d3-path": "3", + "d3-polygon": "3", + "d3-quadtree": "3", + "d3-random": "3", + "d3-scale": "4", + "d3-scale-chromatic": "3", + "d3-selection": "3", + "d3-shape": "3", + "d3-time": "3", + "d3-time-format": "4", + "d3-timer": "3", + "d3-transition": "3", + "d3-zoom": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-axis": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-brush": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "3", + "d3-transition": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "dependencies": { + "d3-path": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-contour": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "dependencies": { + "d3-array": "^3.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "dependencies": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "dependencies": { + "d3-dsv": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-force": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-geo": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", + "dependencies": { + "d3-array": "2.5.0 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-polygon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-sankey": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz", + "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==", + "dependencies": { + "d3-array": "1 - 2", + "d3-shape": "^1.2.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-array": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "dependencies": { + "internmap": "^1.0.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-path": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", + "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==" + }, + "node_modules/d3-sankey/node_modules/d3-shape": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", + "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", + "dependencies": { + "d3-path": "1" + } + }, + "node_modules/d3-sankey/node_modules/internmap": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", + "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==" + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } + }, + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/dagre-d3-es": { + "version": "7.0.10", + "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.10.tgz", + "integrity": "sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A==", + "dependencies": { + "d3": "^7.8.2", + "lodash-es": "^4.17.21" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/dayjs": { + "version": "1.11.10", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", + "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delaunator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", + "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", + "dependencies": { + "robust-predicates": "^3.0.2" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/devalue": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.1.1.tgz", + "integrity": "sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==" + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "peer": true, + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/dompurify": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.6.tgz", + "integrity": "sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==" + }, + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dev": true, + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "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/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/elkjs": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/elkjs/-/elkjs-0.9.3.tgz", + "integrity": "sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ==" + }, + "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/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/engine.io-client": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.4.tgz", + "integrity": "sha512-GeZeeRjpD2qf49cZQ0Wvh/8NJNfeXkXXcoGh+F77oEAgo9gUHwT1fCRxSNU+YEEaysOJTnsFHmM5oAcPy4ntvQ==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.17.1", + "xmlhttprequest-ssl": "~2.0.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz", + "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", + "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/ensure-posix-path": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ensure-posix-path/-/ensure-posix-path-1.1.1.tgz", + "integrity": "sha512-VWU0/zXzVbeJNXvME/5EmLuEj2TauvoaTz6aFYK1Z92JCBlDlZ3Gu0tuGR42kpW1754ywTs+QB0g5TP0oj9Zaw==", + "dev": true + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/eol": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/eol/-/eol-0.9.1.tgz", + "integrity": "sha512-Ds/TEoZjwggRoz/Q2O7SE3i4Jm66mqTDfmdHdq/7DKVk3bro9Q8h6WdXKdPqFLMoqxrDK5SVRzHVPOS6uuGtrg==", + "dev": true + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es6-promise": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", + "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", + "dev": true + }, + "node_modules/esbuild": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-compat-utils": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", + "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", + "dev": true, + "dependencies": { + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-cypress": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-cypress/-/eslint-plugin-cypress-3.4.0.tgz", + "integrity": "sha512-Rrrr3Ri6wHqzrRr+TyUV7bDS4UnMMrFY1R1PP2F7XdGfe9txDC6lQEshyoNOWqGoPkbbeDm1x1XPc/adxemsnA==", + "dev": true, + "dependencies": { + "globals": "^13.20.0" + }, + "peerDependencies": { + "eslint": ">=7" + } + }, + "node_modules/eslint-plugin-svelte": { + "version": "2.43.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-2.43.0.tgz", + "integrity": "sha512-REkxQWvg2pp7QVLxQNa+dJ97xUqRe7Y2JJbSWkHSuszu0VcblZtXkPBPckkivk99y5CdLw4slqfPylL2d/X4jQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@jridgewell/sourcemap-codec": "^1.4.15", + "eslint-compat-utils": "^0.5.1", + "esutils": "^2.0.3", + "known-css-properties": "^0.34.0", + "postcss": "^8.4.38", + "postcss-load-config": "^3.1.4", + "postcss-safe-parser": "^6.0.0", + "postcss-selector-parser": "^6.1.0", + "semver": "^7.6.2", + "svelte-eslint-parser": "^0.41.0" + }, + "engines": { + "node": "^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0-0 || ^9.0.0-0", + "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0-next.191" + }, + "peerDependenciesMeta": { + "svelte": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-svelte/node_modules/postcss-selector-parser": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz", + "integrity": "sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/esm-env": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.1.tgz", + "integrity": "sha512-U9JedYYjCnadUlXk7e1Kr+aENQhtUaoaV9+gZm1T8LC/YBAPJx3NSPIAurFOC0U5vrdSevnUJS2/wUVxGwPhng==", + "license": "MIT" + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter2": { + "version": "6.4.7", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz", + "integrity": "sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==", + "dev": true + }, + "node_modules/eventsource-parser": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-1.1.2.tgz", + "integrity": "sha512-v0eOBUbiaFojBu2s2NPBfYUoRR9GjcDNvCXVaqEf5vVfpIAh9f8RCo4vXTP8c63QRKCFwoLpMpTdPwwhEKVgzA==", + "engines": { + "node": ">=14.18" + } + }, + "node_modules/execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/executable": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", + "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "dev": true, + "dependencies": { + "pify": "^2.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "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==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "license": "MIT" + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/file-saver": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz", + "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==" + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatbuffers": { + "version": "25.1.24", + "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-25.1.24.tgz", + "integrity": "sha512-Ni+KCqYquU30UEgGkrrwpbYtUcUmNuLFcQ5Xdy9DK7WUaji+AAov+Bf12FEYmu0eI15y31oD38utnBexe0cAYA==", + "license": "Apache-2.0" + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, + "node_modules/focus-trap": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.5.4.tgz", + "integrity": "sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==", + "dependencies": { + "tabbable": "^6.2.0" + } + }, + "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/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs-merger": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/fs-merger/-/fs-merger-3.2.1.tgz", + "integrity": "sha512-AN6sX12liy0JE7C2evclwoo0aCG3PFulLjrTLsJpWh/2mM+DinhpSGqYLbHBBbIW1PLRNcFhJG8Axtz8mQW3ug==", + "dev": true, + "dependencies": { + "broccoli-node-api": "^1.7.0", + "broccoli-node-info": "^2.1.0", + "fs-extra": "^8.0.1", + "fs-tree-diff": "^2.0.1", + "walk-sync": "^2.2.0" + } + }, + "node_modules/fs-merger/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-merger/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/fs-merger/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/fs-mkdirp-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-2.0.1.tgz", + "integrity": "sha512-UTOY+59K6IA94tec8Wjqm0FSh5OVudGNB0NL/P6fB3HiE3bYOY3VYBGijsnOHNkQSwC1FKkU77pmq7xp9CskLw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.8", + "streamx": "^2.12.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/fs-tree-diff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fs-tree-diff/-/fs-tree-diff-2.0.1.tgz", + "integrity": "sha512-x+CfAZ/lJHQqwlD64pYM5QxWjzWhSjroaVsr8PW831zOApL55qPibed0c+xebaLWVr2BnHFoHdrwOv8pzt8R5A==", + "dev": true, + "dependencies": { + "@types/symlink-or-copy": "^1.2.0", + "heimdalljs-logger": "^0.1.7", + "object-assign": "^4.1.0", + "path-posix": "^1.0.0", + "symlink-or-copy": "^1.1.8" + }, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/fuse.js": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-7.0.0.tgz", + "integrity": "sha512-14F4hBIxqKvD4Zz/XjDc3y94mNZN6pRv3U13Udo0lNLCWRBUsrMv2xwcF/y/Z5sV6+FQW+/ow68cHpm4sunt8Q==", + "engines": { + "node": ">=10" + } + }, + "node_modules/gc-hook": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/gc-hook/-/gc-hook-0.3.1.tgz", + "integrity": "sha512-E5M+O/h2o7eZzGhzRZGex6hbB3k4NWqO0eA+OzLRLXxhdbYPajZnynPwAtphnh+cRHPwsj5Z80dqZlfI4eK55A==" + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/getos": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz", + "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==", + "dev": true, + "dependencies": { + "async": "^3.2.0" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-stream": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-8.0.0.tgz", + "integrity": "sha512-CdIUuwOkYNv9ZadR3jJvap8CMooKziQZ/QCSPhEb7zqfsEI5YnPmvca7IvbaVE3z58ZdUYD2JsU6AUWjL8WZJA==", + "dev": true, + "dependencies": { + "@gulpjs/to-absolute-glob": "^4.0.0", + "anymatch": "^3.1.3", + "fastq": "^1.13.0", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "is-negated-glob": "^1.0.0", + "normalize-path": "^3.0.0", + "streamx": "^2.12.5" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/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/global-dirs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", + "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", + "dev": true, + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalyzer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", + "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==" + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==" + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/guid-typescript": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/guid-typescript/-/guid-typescript-1.0.9.tgz", + "integrity": "sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ==", + "license": "ISC" + }, + "node_modules/gulp-sort": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/gulp-sort/-/gulp-sort-2.0.0.tgz", + "integrity": "sha512-MyTel3FXOdh1qhw1yKhpimQrAmur9q1X0ZigLmCOxouQD+BD3za9/89O+HfbgBQvvh4igEbp0/PUWO+VqGYG1g==", + "dev": true, + "dependencies": { + "through2": "^2.0.1" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "devOptional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/heimdalljs": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/heimdalljs/-/heimdalljs-0.2.6.tgz", + "integrity": "sha512-o9bd30+5vLBvBtzCPwwGqpry2+n0Hi6H1+qwt6y+0kwRHGGF8TFIhJPmnuM0xO97zaKrDZMwO/V56fAnn8m/tA==", + "dev": true, + "dependencies": { + "rsvp": "~3.2.1" + } + }, + "node_modules/heimdalljs-logger": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/heimdalljs-logger/-/heimdalljs-logger-0.1.10.tgz", + "integrity": "sha512-pO++cJbhIufVI/fmB/u2Yty3KJD0TqNPecehFae0/eps0hkZ3b4Zc/PezUMOpYuHFQbA7FxHZxa305EhmjLj4g==", + "dev": true, + "dependencies": { + "debug": "^2.2.0", + "heimdalljs": "^0.2.6" + } + }, + "node_modules/heimdalljs-logger/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/heimdalljs-logger/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/heimdalljs/node_modules/rsvp": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-3.2.1.tgz", + "integrity": "sha512-Rf4YVNYpKjZ6ASAmibcwTNciQ5Co5Ztq6iZPEykHpkoflnD/K5ryE/rHehFsTm4NJj8nKDhbi3eKBWGogmNnkg==", + "dev": true + }, + "node_modules/highlight.js": { + "version": "11.9.0", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.9.0.tgz", + "integrity": "sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/html-escaper": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", + "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==" + }, + "node_modules/html2canvas": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz", + "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==", + "license": "MIT", + "optional": true, + "dependencies": { + "css-line-break": "^2.1.0", + "text-segmentation": "^1.0.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, + "node_modules/http-signature": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.4.0.tgz", + "integrity": "sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^2.0.2", + "sshpk": "^1.18.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true, + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/i18next": { + "version": "23.10.1", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.10.1.tgz", + "integrity": "sha512-NDiIzFbcs3O9PXpfhkjyf7WdqFn5Vq6mhzhtkXzj51aOcNuPNcTwuYNuXCpHsanZGHlHKL35G7huoFeVic1hng==", + "funding": [ + { + "type": "individual", + "url": "https://locize.com" + }, + { + "type": "individual", + "url": "https://locize.com/i18next.html" + }, + { + "type": "individual", + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + } + ], + "dependencies": { + "@babel/runtime": "^7.23.2" + } + }, + "node_modules/i18next-browser-languagedetector": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-7.2.0.tgz", + "integrity": "sha512-U00DbDtFIYD3wkWsr2aVGfXGAj2TgnELzOX9qv8bT0aJtvPV9CRO77h+vgmHFBMe7LAxdwvT/7VkCWGya6L3tA==", + "dependencies": { + "@babel/runtime": "^7.23.2" + } + }, + "node_modules/i18next-parser": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/i18next-parser/-/i18next-parser-9.0.1.tgz", + "integrity": "sha512-/Pr93/yEBdwsMKRsk4Zn63K368ALhzh8BRVrM6JNGOHy86ZKpiNJI6m8l1S/4T4Ofy1J4dlwkD7N98M70GP4aA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.23.2", + "broccoli-plugin": "^4.0.7", + "cheerio": "^1.0.0-rc.2", + "colors": "1.4.0", + "commander": "~12.1.0", + "eol": "^0.9.1", + "esbuild": "^0.20.1", + "fs-extra": "^11.1.0", + "gulp-sort": "^2.0.0", + "i18next": "^23.5.1", + "js-yaml": "4.1.0", + "lilconfig": "^3.0.0", + "rsvp": "^4.8.2", + "sort-keys": "^5.0.0", + "typescript": "^5.0.4", + "vinyl": "~3.0.0", + "vinyl-fs": "^4.0.0" + }, + "bin": { + "i18next": "bin/cli.js" + }, + "engines": { + "node": ">=18.0.0 || >=20.0.0 || >=22.0.0", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/i18next-resources-to-backend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/i18next-resources-to-backend/-/i18next-resources-to-backend-1.2.0.tgz", + "integrity": "sha512-8f1l03s+QxDmCfpSXCh9V+AFcxAwIp0UaroWuyOx+hmmv8484GcELHs+lnu54FrNij8cDBEXvEwhzZoXsKcVpg==", + "dependencies": { + "@babel/runtime": "^7.23.2" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==" + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "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/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/immutable": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.3.tgz", + "integrity": "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-meta-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "dev": true, + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dev": true, + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==" + }, + "node_modules/is-negated-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", + "integrity": "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "dependencies": { + "@types/estree": "*" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-valid-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", + "integrity": "sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true + }, + "node_modules/js-sha256": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.10.1.tgz", + "integrity": "sha512-5obBtsz9301ULlsgggLg542s/jqtddfOpV5KJc4hajc9JV8GeY2gZHSVpYBn4nWqAUTJ9v+xwtbJ1mIBgIH5Vw==" + }, + "node_modules/js-tokens": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.0.tgz", + "integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jspdf": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/jspdf/-/jspdf-3.0.0.tgz", + "integrity": "sha512-QvuQZvOI8CjfjVgtajdL0ihrDYif1cN5gXiF9lb9Pd9JOpmocvnNyFO9sdiJ/8RA5Bu8zyGOUjJLj5kiku16ug==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "atob": "^2.1.2", + "btoa": "^1.2.1", + "fflate": "^0.8.1" + }, + "optionalDependencies": { + "canvg": "^3.0.6", + "core-js": "^3.6.0", + "dompurify": "^3.2.4", + "html2canvas": "^1.0.0-rc.5" + } + }, + "node_modules/jspdf/node_modules/dompurify": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.4.tgz", + "integrity": "sha512-ysFSFEDVduQpyhzAob/kkuJjf5zWkZD8/A9ywSp1byueyuCfHamrCBa14/Oc2iiB0e51B+NpxSl5gmzn+Ms/mg==", + "license": "(MPL-2.0 OR Apache-2.0)", + "optional": true, + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, + "node_modules/jsprim": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", + "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, + "node_modules/katex": { + "version": "0.16.21", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.21.tgz", + "integrity": "sha512-XvqR7FgOHtWupfMiigNzmh+MgUVmDGU2kXZm899ZkPfcuoPuFxyHmXsgATDpFZDAXCI8tvinaVcDo8PIIJSo4A==", + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "license": "MIT", + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/katex/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/khroma": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", + "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==" + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/known-css-properties": { + "version": "0.34.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.34.0.tgz", + "integrity": "sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==", + "dev": true + }, + "node_modules/kokoro-js": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/kokoro-js/-/kokoro-js-1.1.1.tgz", + "integrity": "sha512-cyLO34iI8nBJXPnd3fI4fGeQGS+a6Uatg7eXNL6QS8TLSxaa30WD6Fj7/XoIZYaHg8q6d+TCrui/f74MTY2g1g==", + "license": "Apache-2.0", + "dependencies": { + "@huggingface/transformers": "^3.3.3", + "phonemizer": "^1.2.1" + } + }, + "node_modules/layout-base": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz", + "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==" + }, + "node_modules/lazy-ass": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", + "integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==", + "dev": true, + "engines": { + "node": "> 0.8" + } + }, + "node_modules/lead": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/lead/-/lead-4.0.0.tgz", + "integrity": "sha512-DpMa59o5uGUWWjruMp71e6knmwKU3jRBBn1kjuLWN9EeIOxNeSAwvHf03WIl8g/ZMR2oSQC9ej3yeLBwdDc/pg==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lightningcss": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.29.1.tgz", + "integrity": "sha512-FmGoeD4S05ewj+AkhTY+D+myDvXI6eL27FjHIjoyUkO/uw7WZD1fBVs0QxeYWa7E17CUHJaYX/RUGISCtcrG4Q==", + "devOptional": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^1.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-darwin-arm64": "1.29.1", + "lightningcss-darwin-x64": "1.29.1", + "lightningcss-freebsd-x64": "1.29.1", + "lightningcss-linux-arm-gnueabihf": "1.29.1", + "lightningcss-linux-arm64-gnu": "1.29.1", + "lightningcss-linux-arm64-musl": "1.29.1", + "lightningcss-linux-x64-gnu": "1.29.1", + "lightningcss-linux-x64-musl": "1.29.1", + "lightningcss-win32-arm64-msvc": "1.29.1", + "lightningcss-win32-x64-msvc": "1.29.1" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.29.1.tgz", + "integrity": "sha512-HtR5XJ5A0lvCqYAoSv2QdZZyoHNttBpa5EP9aNuzBQeKGfbyH5+UipLWvVzpP4Uml5ej4BYs5I9Lco9u1fECqw==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.29.1.tgz", + "integrity": "sha512-k33G9IzKUpHy/J/3+9MCO4e+PzaFblsgBjSGlpAaFikeBFm8B/CkO3cKU9oI4g+fjS2KlkLM/Bza9K/aw8wsNA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.29.1.tgz", + "integrity": "sha512-0SUW22fv/8kln2LnIdOCmSuXnxgxVC276W5KLTwoehiO0hxkacBxjHOL5EtHD8BAXg2BvuhsJPmVMasvby3LiQ==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.29.1.tgz", + "integrity": "sha512-sD32pFvlR0kDlqsOZmYqH/68SqUMPNj+0pucGxToXZi4XZgZmqeX/NkxNKCPsswAXU3UeYgDSpGhu05eAufjDg==", + "cpu": [ + "arm" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.29.1.tgz", + "integrity": "sha512-0+vClRIZ6mmJl/dxGuRsE197o1HDEeeRk6nzycSy2GofC2JsY4ifCRnvUWf/CUBQmlrvMzt6SMQNMSEu22csWQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.29.1.tgz", + "integrity": "sha512-UKMFrG4rL/uHNgelBsDwJcBqVpzNJbzsKkbI3Ja5fg00sgQnHw/VrzUTEc4jhZ+AN2BvQYz/tkHu4vt1kLuJyw==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.29.1.tgz", + "integrity": "sha512-u1S+xdODy/eEtjADqirA774y3jLcm8RPtYztwReEXoZKdzgsHYPl0s5V52Tst+GKzqjebkULT86XMSxejzfISw==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.29.1.tgz", + "integrity": "sha512-L0Tx0DtaNUTzXv0lbGCLB/c/qEADanHbu4QdcNOXLIe1i8i22rZRpbT3gpWYsCh9aSL9zFujY/WmEXIatWvXbw==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.29.1.tgz", + "integrity": "sha512-QoOVnkIEFfbW4xPi+dpdft/zAKmgLgsRHfJalEPYuJDOWf7cLQzYg0DEh8/sn737FaeMJxHZRc1oBreiwZCjog==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.29.1.tgz", + "integrity": "sha512-NygcbThNBe4JElP+olyTI/doBNGJvLs3bFCRPdvuCcxZCcCZ71B858IHpdm7L1btZex0FvCmM17FK98Y9MRy1Q==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss/node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "devOptional": true, + "license": "Apache-2.0", + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/lilconfig": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz", + "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, + "node_modules/listr2": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", + "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", + "dev": true, + "dependencies": { + "cli-truncate": "^2.1.0", + "colorette": "^2.0.16", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.5.1", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "enquirer": ">= 2.3.0 < 3" + }, + "peerDependenciesMeta": { + "enquirer": { + "optional": true + } + } + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/listr2/node_modules/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==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/listr2/node_modules/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==", + "dev": true, + "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/local-pkg": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", + "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", + "dev": true, + "dependencies": { + "mlly": "^1.4.2", + "pkg-types": "^1.0.3" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/locate-character": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, + "node_modules/lodash.castarray": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz", + "integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==", + "dev": true + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/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==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/long": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.4.tgz", + "integrity": "sha512-qtzLbJE8hq7VabR3mISmVGtoXP8KGc2Z/AT8OuqlYD7JTR3oqrgwdjnk07wpj1twXxYmgDXgoKVWUG/fReSzHg==", + "license": "Apache-2.0" + }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/lowlight": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-3.1.0.tgz", + "integrity": "sha512-CEbNVoSikAxwDMDPjXlqlFYiZLkDJHwyGu/MfOsJnF3d7f3tds5J3z8s/l9TMXhzfsJCCJEAsD78842mwmg0PQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.0.0", + "highlight.js": "~11.9.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/magic-string": { + "version": "0.30.11", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", + "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/markdown-it": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/marked": { + "version": "9.1.6", + "resolved": "https://registry.npmjs.org/marked/-/marked-9.1.6.tgz", + "integrity": "sha512-jcByLnIFkd5gSXZmjNvS1TlmRhCXZjIzHYlaGkPlLIekG55JDR2Z4va9tZwCiP+/RDERiNhMOFu01xd6O5ct1Q==", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 16" + } + }, + "node_modules/matcher-collection": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/matcher-collection/-/matcher-collection-2.0.1.tgz", + "integrity": "sha512-daE62nS2ZQsDg9raM0IlZzLmI2u+7ZapXBwdoeBUKAYERPDDIc0qNqA8E0Rp2D+gspKR7BgIFP52GeujaGXWeQ==", + "dev": true, + "dependencies": { + "@types/minimatch": "^3.0.3", + "minimatch": "^3.0.2" + }, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/matcher-collection/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/matcher-collection/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", + "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", + "dependencies": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "mdast-util-to-string": "^3.1.0", + "micromark": "^3.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-decode-string": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "unist-util-stringify-position": "^3.0.0", + "uvu": "^0.5.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", + "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", + "dependencies": { + "@types/mdast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" + }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/mermaid": { + "version": "10.9.3", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.9.3.tgz", + "integrity": "sha512-V80X1isSEvAewIL3xhmz/rVmc27CVljcsbWxkxlWJWY/1kQa4XOABqpDl2qQLGKzpKm6WbTfUEKImBlUfFYArw==", + "dependencies": { + "@braintree/sanitize-url": "^6.0.1", + "@types/d3-scale": "^4.0.3", + "@types/d3-scale-chromatic": "^3.0.0", + "cytoscape": "^3.28.1", + "cytoscape-cose-bilkent": "^4.1.0", + "d3": "^7.4.0", + "d3-sankey": "^0.12.3", + "dagre-d3-es": "7.0.10", + "dayjs": "^1.11.7", + "dompurify": "^3.0.5 <3.1.7", + "elkjs": "^0.9.0", + "katex": "^0.16.9", + "khroma": "^2.0.0", + "lodash-es": "^4.17.21", + "mdast-util-from-markdown": "^1.3.0", + "non-layered-tidy-tree-layout": "^2.0.2", + "stylis": "^4.1.3", + "ts-dedent": "^2.2.0", + "uuid": "^9.0.0", + "web-worker": "^1.2.0" + } + }, + "node_modules/micromark": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", + "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "micromark-core-commonmark": "^1.0.1", + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-combine-extensions": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-sanitize-uri": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", + "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-factory-destination": "^1.0.0", + "micromark-factory-label": "^1.0.0", + "micromark-factory-space": "^1.0.0", + "micromark-factory-title": "^1.0.0", + "micromark-factory-whitespace": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-classify-character": "^1.0.0", + "micromark-util-html-tag-name": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-factory-destination": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", + "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", + "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", + "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", + "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", + "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", + "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", + "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", + "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", + "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", + "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", + "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-html-tag-name": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", + "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", + "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", + "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", + "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", + "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.1.tgz", + "integrity": "sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==", + "license": "MIT", + "dependencies": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/minizlib/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minizlib/node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/minizlib/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minizlib/node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "license": "ISC", + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mktemp": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/mktemp/-/mktemp-0.4.0.tgz", + "integrity": "sha512-IXnMcJ6ZyTuhRmJSjzvHSRhlVPiN9Jwc6e59V0bEJ0ba6OBeX2L0E+mRN1QseeOF4mM+F1Rit6Nh7o+rl2Yn/A==", + "dev": true, + "engines": { + "node": ">0.9" + } + }, + "node_modules/mlly": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.0.tgz", + "integrity": "sha512-U9SDaXGEREBYQgfejV97coK0UL1r+qnF2SyO9A3qcI8MzKnsIFKHNVEkrDyNncQTKQQumsasmeq84eNMdBfsNQ==", + "dev": true, + "dependencies": { + "acorn": "^8.11.3", + "pathe": "^1.1.2", + "pkg-types": "^1.1.0", + "ufo": "^1.5.3" + } + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/mrmime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/nanoid": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.9.tgz", + "integrity": "sha512-Aooyr6MXU6HpvvWXKoVoXwKMs/KyVakWwg7xQfv5/S/RIgJMy0Ifa45H9qqYy7pTCszrHzP21Uk4PZq2HpEM8Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^18 || >=20" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/ngraph.events": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/ngraph.events/-/ngraph.events-1.2.2.tgz", + "integrity": "sha512-JsUbEOzANskax+WSYiAPETemLWYXmixuPAlmZmhIbIj6FH/WDgEGCGnRwUQBK0GjOnVm8Ui+e5IJ+5VZ4e32eQ==" + }, + "node_modules/non-layered-tidy-tree-layout": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/non-layered-tidy-tree-layout/-/non-layered-tidy-tree-layout-2.0.2.tgz", + "integrity": "sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==" + }, + "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/now-and-later": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-3.0.0.tgz", + "integrity": "sha512-pGO4pzSdaxhWTGkfSfHx3hVzJVslFPwBp2Myq9MYN/ChfJZF87ochMAXnvz6/58RJSf5ik2q9tXprBBrk2cpcg==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/onnxruntime-common": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.20.1.tgz", + "integrity": "sha512-YiU0s0IzYYC+gWvqD1HzLc46Du1sXpSiwzKb63PACIJr6LfL27VsXSXQvt68EzD3V0D5Bc0vyJTjmMxp0ylQiw==", + "license": "MIT" + }, + "node_modules/onnxruntime-node": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/onnxruntime-node/-/onnxruntime-node-1.20.1.tgz", + "integrity": "sha512-di/I4HDXRw+FLgq+TyHmQEDd3cEp9iFFZm0r4uJ1Wd7b/WE1VXtKWo8yemex347c6GNF/3Pv86ZfPhIWxORr0w==", + "hasInstallScript": true, + "license": "MIT", + "os": [ + "win32", + "darwin", + "linux" + ], + "dependencies": { + "onnxruntime-common": "1.20.1", + "tar": "^7.0.1" + } + }, + "node_modules/onnxruntime-web": { + "version": "1.21.0-dev.20250206-d981b153d3", + "resolved": "https://registry.npmjs.org/onnxruntime-web/-/onnxruntime-web-1.21.0-dev.20250206-d981b153d3.tgz", + "integrity": "sha512-esDVQdRic6J44VBMFLumYvcGfioMh80ceLmzF1yheJyuLKq/Th8VT2aj42XWQst+2bcWnAhw4IKmRQaqzU8ugg==", + "license": "MIT", + "dependencies": { + "flatbuffers": "^25.1.24", + "guid-typescript": "^1.0.9", + "long": "^5.2.3", + "onnxruntime-common": "1.21.0-dev.20250206-d981b153d3", + "platform": "^1.3.6", + "protobufjs": "^7.2.4" + } + }, + "node_modules/onnxruntime-web/node_modules/onnxruntime-common": { + "version": "1.21.0-dev.20250206-d981b153d3", + "resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.21.0-dev.20250206-d981b153d3.tgz", + "integrity": "sha512-TwaE51xV9q2y8pM61q73rbywJnusw9ivTEHAJ39GVWNZqxCoDBpe/tQkh/w9S+o/g+zS7YeeL0I/2mEWd+dgyA==", + "license": "MIT" + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/orderedmap": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz", + "integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==" + }, + "node_modules/ospath": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", + "integrity": "sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==", + "dev": true + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "license": "BlueOak-1.0.0" + }, + "node_modules/paneforge": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/paneforge/-/paneforge-0.0.6.tgz", + "integrity": "sha512-jYeN/wdREihja5c6nK3S5jritDQ+EbCqC5NrDo97qCZzZ9GkmEcN5C0ZCjF4nmhBwkDKr6tLIgz4QUKWxLXjAw==", + "dependencies": { + "nanoid": "^5.0.4" + }, + "peerDependencies": { + "svelte": "^4.0.0 || ^5.0.0-next.1" + } + }, + "node_modules/panzoom": { + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/panzoom/-/panzoom-9.4.3.tgz", + "integrity": "sha512-xaxCpElcRbQsUtIdwlrZA90P90+BHip4Vda2BC8MEb4tkI05PmR6cKECdqUCZ85ZvBHjpI9htJrZBxV5Gp/q/w==", + "dependencies": { + "amator": "^1.1.0", + "ngraph.events": "^1.2.2", + "wheel": "^1.0.0" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dev": true, + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", + "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "dev": true, + "dependencies": { + "domhandler": "^5.0.2", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-posix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/path-posix/-/path-posix-1.0.0.tgz", + "integrity": "sha512-1gJ0WpNIiYcQydgg3Ed8KzvIqTsDpNwq+cjBCssvBtuTWjEqY1AW+i+OepiEMqDCzyro9B2sLAe4RBPajMYFiA==", + "dev": true + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/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/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "devOptional": true + }, + "node_modules/periscopic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", + "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^3.0.0", + "is-reference": "^3.0.0" + } + }, + "node_modules/periscopic/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/periscopic/node_modules/is-reference": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", + "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/phonemizer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/phonemizer/-/phonemizer-1.2.1.tgz", + "integrity": "sha512-v0KJ4mi2T4Q7eJQ0W15Xd4G9k4kICSXE8bpDeJ8jisL4RyJhNWsweKTOi88QXFc4r4LZlz5jVL5lCHhkpdT71A==", + "license": "Apache-2.0" + }, + "node_modules/picocolors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkg-types": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.1.1.tgz", + "integrity": "sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==", + "dev": true, + "dependencies": { + "confbox": "^0.1.7", + "mlly": "^1.7.0", + "pathe": "^1.1.2" + } + }, + "node_modules/plain-tag": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/plain-tag/-/plain-tag-0.1.3.tgz", + "integrity": "sha512-yyVAOFKTAElc7KdLt2+UKGExNYwYb/Y/WE9i+1ezCQsJE8gbKSjewfpRqK2nQgZ4d4hhAAGgDCOcIZVilqE5UA==" + }, + "node_modules/platform": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", + "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==", + "license": "MIT" + }, + "node_modules/polyscript": { + "version": "0.12.8", + "resolved": "https://registry.npmjs.org/polyscript/-/polyscript-0.12.8.tgz", + "integrity": "sha512-kcG3W9jU/s1sYjWOTAa2jAh5D2jm3zJRi+glSTsC+lA3D1b/Sd67pEIGpyL9bWNKYSimqAx4se6jAhQjJZ7+jQ==", + "dependencies": { + "@ungap/structured-clone": "^1.2.0", + "@ungap/with-resolvers": "^0.1.0", + "@webreflection/fetch": "^0.1.5", + "basic-devtools": "^0.1.6", + "codedent": "^0.1.2", + "coincident": "^1.2.3", + "gc-hook": "^0.3.1", + "html-escaper": "^3.0.3", + "proxy-target": "^3.0.2", + "sticky-module": "^0.1.1", + "to-json-callback": "^0.1.1" + } + }, + "node_modules/postcss": { + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-load-config": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", + "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", + "dev": true, + "dependencies": { + "lilconfig": "^2.0.5", + "yaml": "^1.10.2" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/postcss-safe-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", + "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", + "dev": true, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.3.3" + } + }, + "node_modules/postcss-scss": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.9.tgz", + "integrity": "sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss-scss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.4.29" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss/node_modules/nanoid": { + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-plugin-svelte": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/prettier-plugin-svelte/-/prettier-plugin-svelte-3.2.6.tgz", + "integrity": "sha512-Y1XWLw7vXUQQZmgv1JAEiLcErqUniAF2wO7QJsw8BVMvpLET2dI5WpEIEJx1r11iHVdSMzQxivyfrH9On9t2IQ==", + "dev": true, + "peerDependencies": { + "prettier": "^3.0.0", + "svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0" + } + }, + "node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/promise-map-series": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/promise-map-series/-/promise-map-series-0.3.0.tgz", + "integrity": "sha512-3npG2NGhTc8BWBolLLf8l/92OxMGaRLbqvIh9wjCHhDXNvk4zsxaTaCpiCunW09qWPrN2zeNSNwRLVBrQQtutA==", + "dev": true, + "engines": { + "node": "10.* || >= 12.*" + } + }, + "node_modules/prosemirror-changeset": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.2.1.tgz", + "integrity": "sha512-J7msc6wbxB4ekDFj+n9gTW/jav/p53kdlivvuppHsrZXCaQdVgRghoZbSS3kwrRyAstRVQ4/+u5k7YfLgkkQvQ==", + "license": "MIT", + "dependencies": { + "prosemirror-transform": "^1.0.0" + } + }, + "node_modules/prosemirror-collab": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/prosemirror-collab/-/prosemirror-collab-1.3.1.tgz", + "integrity": "sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==", + "license": "MIT", + "dependencies": { + "prosemirror-state": "^1.0.0" + } + }, + "node_modules/prosemirror-commands": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.6.2.tgz", + "integrity": "sha512-0nDHH++qcf/BuPLYvmqZTUUsPJUCPBUXt0J1ErTcDIS369CTp773itzLGIgIXG4LJXOlwYCr44+Mh4ii6MP1QA==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.10.2" + } + }, + "node_modules/prosemirror-dropcursor": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.1.tgz", + "integrity": "sha512-M30WJdJZLyXHi3N8vxN6Zh5O8ZBbQCz0gURTfPmTIBNQ5pxrdU7A58QkNqfa98YEjSAL1HUyyU34f6Pm5xBSGw==", + "dependencies": { + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.1.0", + "prosemirror-view": "^1.1.0" + } + }, + "node_modules/prosemirror-example-setup": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/prosemirror-example-setup/-/prosemirror-example-setup-1.2.3.tgz", + "integrity": "sha512-+hXZi8+xbFvYM465zZH3rdZ9w7EguVKmUYwYLZjIJIjPK+I0nPTwn8j0ByW2avchVczRwZmOJGNvehblyIerSQ==", + "dependencies": { + "prosemirror-commands": "^1.0.0", + "prosemirror-dropcursor": "^1.0.0", + "prosemirror-gapcursor": "^1.0.0", + "prosemirror-history": "^1.0.0", + "prosemirror-inputrules": "^1.0.0", + "prosemirror-keymap": "^1.0.0", + "prosemirror-menu": "^1.0.0", + "prosemirror-schema-list": "^1.0.0", + "prosemirror-state": "^1.0.0" + } + }, + "node_modules/prosemirror-gapcursor": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.3.2.tgz", + "integrity": "sha512-wtjswVBd2vaQRrnYZaBCbyDqr232Ed4p2QPtRIUK5FuqHYKGWkEwl08oQM4Tw7DOR0FsasARV5uJFvMZWxdNxQ==", + "dependencies": { + "prosemirror-keymap": "^1.0.0", + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-view": "^1.0.0" + } + }, + "node_modules/prosemirror-history": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.4.1.tgz", + "integrity": "sha512-2JZD8z2JviJrboD9cPuX/Sv/1ChFng+xh2tChQ2X4bB2HeK+rra/bmJ3xGntCcjhOqIzSDG6Id7e8RJ9QPXLEQ==", + "dependencies": { + "prosemirror-state": "^1.2.2", + "prosemirror-transform": "^1.0.0", + "prosemirror-view": "^1.31.0", + "rope-sequence": "^1.3.0" + } + }, + "node_modules/prosemirror-inputrules": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.4.0.tgz", + "integrity": "sha512-6ygpPRuTJ2lcOXs9JkefieMst63wVJBgHZGl5QOytN7oSZs3Co/BYbc3Yx9zm9H37Bxw8kVzCnDsihsVsL4yEg==", + "dependencies": { + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.0.0" + } + }, + "node_modules/prosemirror-keymap": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.2.tgz", + "integrity": "sha512-EAlXoksqC6Vbocqc0GtzCruZEzYgrn+iiGnNjsJsH4mrnIGex4qbLdWWNza3AW5W36ZRrlBID0eM6bdKH4OStQ==", + "dependencies": { + "prosemirror-state": "^1.0.0", + "w3c-keyname": "^2.2.0" + } + }, + "node_modules/prosemirror-markdown": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.13.1.tgz", + "integrity": "sha512-Sl+oMfMtAjWtlcZoj/5L/Q39MpEnVZ840Xo330WJWUvgyhNmLBLN7MsHn07s53nG/KImevWHSE6fEj4q/GihHw==", + "dependencies": { + "@types/markdown-it": "^14.0.0", + "markdown-it": "^14.0.0", + "prosemirror-model": "^1.20.0" + } + }, + "node_modules/prosemirror-menu": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.2.4.tgz", + "integrity": "sha512-S/bXlc0ODQup6aiBbWVsX/eM+xJgCTAfMq/nLqaO5ID/am4wS0tTCIkzwytmao7ypEtjj39i7YbJjAgO20mIqA==", + "dependencies": { + "crelt": "^1.0.0", + "prosemirror-commands": "^1.0.0", + "prosemirror-history": "^1.0.0", + "prosemirror-state": "^1.0.0" + } + }, + "node_modules/prosemirror-model": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.23.0.tgz", + "integrity": "sha512-Q/fgsgl/dlOAW9ILu4OOhYWQbc7TQd4BwKH/RwmUjyVf8682Be4zj3rOYdLnYEcGzyg8LL9Q5IWYKD8tdToreQ==", + "dependencies": { + "orderedmap": "^2.0.0" + } + }, + "node_modules/prosemirror-schema-basic": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.3.tgz", + "integrity": "sha512-h+H0OQwZVqMon1PNn0AG9cTfx513zgIG2DY00eJ00Yvgb3UD+GQ/VlWW5rcaxacpCGT1Yx8nuhwXk4+QbXUfJA==", + "dependencies": { + "prosemirror-model": "^1.19.0" + } + }, + "node_modules/prosemirror-schema-list": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.4.1.tgz", + "integrity": "sha512-jbDyaP/6AFfDfu70VzySsD75Om2t3sXTOdl5+31Wlxlg62td1haUpty/ybajSfJ1pkGadlOfwQq9kgW5IMo1Rg==", + "dependencies": { + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.7.3" + } + }, + "node_modules/prosemirror-state": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.3.tgz", + "integrity": "sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==", + "dependencies": { + "prosemirror-model": "^1.0.0", + "prosemirror-transform": "^1.0.0", + "prosemirror-view": "^1.27.0" + } + }, + "node_modules/prosemirror-tables": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.6.1.tgz", + "integrity": "sha512-p8WRJNA96jaNQjhJolmbxTzd6M4huRE5xQ8OxjvMhQUP0Nzpo4zz6TztEiwk6aoqGBhz9lxRWR1yRZLlpQN98w==", + "license": "MIT", + "dependencies": { + "prosemirror-keymap": "^1.1.2", + "prosemirror-model": "^1.8.1", + "prosemirror-state": "^1.3.1", + "prosemirror-transform": "^1.2.1", + "prosemirror-view": "^1.13.3" + } + }, + "node_modules/prosemirror-trailing-node": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/prosemirror-trailing-node/-/prosemirror-trailing-node-3.0.0.tgz", + "integrity": "sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==", + "license": "MIT", + "dependencies": { + "@remirror/core-constants": "3.0.0", + "escape-string-regexp": "^4.0.0" + }, + "peerDependencies": { + "prosemirror-model": "^1.22.1", + "prosemirror-state": "^1.4.2", + "prosemirror-view": "^1.33.8" + } + }, + "node_modules/prosemirror-transform": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.10.2.tgz", + "integrity": "sha512-2iUq0wv2iRoJO/zj5mv8uDUriOHWzXRnOTVgCzSXnktS/2iQRa3UUQwVlkBlYZFtygw6Nh1+X4mGqoYBINn5KQ==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.21.0" + } + }, + "node_modules/prosemirror-view": { + "version": "1.36.0", + "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.36.0.tgz", + "integrity": "sha512-U0GQd5yFvV5qUtT41X1zCQfbw14vkbbKwLlQXhdylEmgpYVHkefXYcC4HHwWOfZa3x6Y8wxDLUBv7dxN5XQ3nA==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.20.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.1.0" + } + }, + "node_modules/protobufjs": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", + "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/proxy-from-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", + "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==", + "dev": true + }, + "node_modules/proxy-target": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/proxy-target/-/proxy-target-3.0.2.tgz", + "integrity": "sha512-FFE1XNwXX/FNC3/P8HiKaJSy/Qk68RitG/QEcLy/bVnTAPlgTAWPZKh0pARLAnpfXQPKyalBhk009NRTgsk8vQ==" + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/pyodide": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/pyodide/-/pyodide-0.27.2.tgz", + "integrity": "sha512-sfA2kiUuQVRpWI4BYnU3sX5PaTTt/xrcVEmRzRcId8DzZXGGtPgCBC0gCqjUTUYSa8ofPaSjXmzESc86yvvCHg==", + "license": "Apache-2.0", + "dependencies": { + "ws": "^8.5.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "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/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", + "dev": true + }, + "node_modules/quick-temp": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/quick-temp/-/quick-temp-0.1.8.tgz", + "integrity": "sha512-YsmIFfD9j2zaFwJkzI6eMG7y0lQP7YeWzgtFgNl38pGWZBSXJooZbOWwkcRot7Vt0Fg9L23pX0tqWU3VvLDsiA==", + "dev": true, + "dependencies": { + "mktemp": "~0.4.0", + "rimraf": "^2.5.4", + "underscore.string": "~3.3.4" + } + }, + "node_modules/quick-temp/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/quick-temp/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/quick-temp/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/quick-temp/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/raf": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", + "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", + "license": "MIT", + "optional": true, + "dependencies": { + "performance-now": "^2.1.0" + } + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", + "dev": true + }, + "node_modules/replace-ext": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", + "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/request-progress": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", + "integrity": "sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==", + "dev": true, + "dependencies": { + "throttleit": "^1.0.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-options": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-2.0.0.tgz", + "integrity": "sha512-/FopbmmFOQCfsCx77BRFdKOniglTiHumLgwvd6IDPihy1GKkadZbgQJBcTb2lMzSR1pndzd96b1nZrreZ7+9/A==", + "dev": true, + "dependencies": { + "value-or-function": "^4.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz", + "integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==", + "dev": true + }, + "node_modules/rgbcolor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rgbcolor/-/rgbcolor-1.0.1.tgz", + "integrity": "sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw==", + "license": "MIT OR SEE LICENSE IN FEEL-FREE.md", + "optional": true, + "engines": { + "node": ">= 0.8.15" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" + }, + "node_modules/rollup": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.4.tgz", + "integrity": "sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==", + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.22.4", + "@rollup/rollup-android-arm64": "4.22.4", + "@rollup/rollup-darwin-arm64": "4.22.4", + "@rollup/rollup-darwin-x64": "4.22.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.22.4", + "@rollup/rollup-linux-arm-musleabihf": "4.22.4", + "@rollup/rollup-linux-arm64-gnu": "4.22.4", + "@rollup/rollup-linux-arm64-musl": "4.22.4", + "@rollup/rollup-linux-powerpc64le-gnu": "4.22.4", + "@rollup/rollup-linux-riscv64-gnu": "4.22.4", + "@rollup/rollup-linux-s390x-gnu": "4.22.4", + "@rollup/rollup-linux-x64-gnu": "4.22.4", + "@rollup/rollup-linux-x64-musl": "4.22.4", + "@rollup/rollup-win32-arm64-msvc": "4.22.4", + "@rollup/rollup-win32-ia32-msvc": "4.22.4", + "@rollup/rollup-win32-x64-msvc": "4.22.4", + "fsevents": "~2.3.2" + } + }, + "node_modules/rope-sequence": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz", + "integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==" + }, + "node_modules/rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", + "dev": true, + "engines": { + "node": "6.* || >= 7.*" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "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": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" + }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "devOptional": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/sander": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz", + "integrity": "sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==", + "dev": true, + "dependencies": { + "es6-promise": "^3.1.2", + "graceful-fs": "^4.1.3", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.2" + } + }, + "node_modules/sander/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/sander/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sander/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/sander/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/sass-embedded": { + "version": "1.81.0", + "resolved": "https://registry.npmjs.org/sass-embedded/-/sass-embedded-1.81.0.tgz", + "integrity": "sha512-uZQ2Faxb1oWBHpeSSzjxnhClbMb3QadN0ql0ZFNuqWOLUxwaVhrMlMhPq6TDPbbfDUjihuwrMCuy695Bgna5RA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@bufbuild/protobuf": "^2.0.0", + "buffer-builder": "^0.2.0", + "colorjs.io": "^0.5.0", + "immutable": "^5.0.2", + "rxjs": "^7.4.0", + "supports-color": "^8.1.1", + "sync-child-process": "^1.0.2", + "varint": "^6.0.0" + }, + "bin": { + "sass": "dist/bin/sass.js" + }, + "engines": { + "node": ">=16.0.0" + }, + "optionalDependencies": { + "sass-embedded-android-arm": "1.81.0", + "sass-embedded-android-arm64": "1.81.0", + "sass-embedded-android-ia32": "1.81.0", + "sass-embedded-android-riscv64": "1.81.0", + "sass-embedded-android-x64": "1.81.0", + "sass-embedded-darwin-arm64": "1.81.0", + "sass-embedded-darwin-x64": "1.81.0", + "sass-embedded-linux-arm": "1.81.0", + "sass-embedded-linux-arm64": "1.81.0", + "sass-embedded-linux-ia32": "1.81.0", + "sass-embedded-linux-musl-arm": "1.81.0", + "sass-embedded-linux-musl-arm64": "1.81.0", + "sass-embedded-linux-musl-ia32": "1.81.0", + "sass-embedded-linux-musl-riscv64": "1.81.0", + "sass-embedded-linux-musl-x64": "1.81.0", + "sass-embedded-linux-riscv64": "1.81.0", + "sass-embedded-linux-x64": "1.81.0", + "sass-embedded-win32-arm64": "1.81.0", + "sass-embedded-win32-ia32": "1.81.0", + "sass-embedded-win32-x64": "1.81.0" + } + }, + "node_modules/sass-embedded-android-arm": { + "version": "1.81.0", + "resolved": "https://registry.npmjs.org/sass-embedded-android-arm/-/sass-embedded-android-arm-1.81.0.tgz", + "integrity": "sha512-NWEmIuaIEsGFNsIRa+5JpIpPJyZ32H15E85CNZqEIhhwWlk9UNw7vlOCmTH8MtabtnACwC/2NG8VyNa3nxKzUQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-android-arm64": { + "version": "1.81.0", + "resolved": "https://registry.npmjs.org/sass-embedded-android-arm64/-/sass-embedded-android-arm64-1.81.0.tgz", + "integrity": "sha512-I36P77/PKAHx6sqOmexO2iEY5kpsmQ1VxcgITZSOxPMQhdB6m4t3bTabfDuWQQmCrqqiNFtLQHeytB65bUqwiw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-android-ia32": { + "version": "1.81.0", + "resolved": "https://registry.npmjs.org/sass-embedded-android-ia32/-/sass-embedded-android-ia32-1.81.0.tgz", + "integrity": "sha512-k8V1usXw30w1GVxvrteG1RzgYJzYQ9PfL2aeOqGdroBN7zYTD9VGJXTGcxA4IeeRxmRd7szVW2mKXXS472fh8g==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-android-riscv64": { + "version": "1.81.0", + "resolved": "https://registry.npmjs.org/sass-embedded-android-riscv64/-/sass-embedded-android-riscv64-1.81.0.tgz", + "integrity": "sha512-RXlanyLXEpN/DEehXgLuKPsqT//GYlsGFxKXgRiCc8hIPAueFLQXKJmLWlL3BEtHgmFdbsStIu4aZCcb1hOFlQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-android-x64": { + "version": "1.81.0", + "resolved": "https://registry.npmjs.org/sass-embedded-android-x64/-/sass-embedded-android-x64-1.81.0.tgz", + "integrity": "sha512-RQG0FxGQ1DERNyUDED8+BDVaLIjI+BNg8lVcyqlLZUrWY6NhzjwYEeiN/DNZmMmHtqDucAPNDcsdVUNQqsBy2A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-darwin-arm64": { + "version": "1.81.0", + "resolved": "https://registry.npmjs.org/sass-embedded-darwin-arm64/-/sass-embedded-darwin-arm64-1.81.0.tgz", + "integrity": "sha512-gLKbsfII9Ppua76N41ODFnKGutla9qv0OGAas8gxe0jYBeAQFi/1iKQYdNtQtKi4mA9n5TQTqz+HHCKszZCoyA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-darwin-x64": { + "version": "1.81.0", + "resolved": "https://registry.npmjs.org/sass-embedded-darwin-x64/-/sass-embedded-darwin-x64-1.81.0.tgz", + "integrity": "sha512-7uMOlT9hD2KUJCbTN2XcfghDxt/rc50ujjfSjSHjX1SYj7mGplkINUXvVbbvvaV2wt6t9vkGkCo5qNbeBhfwBg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-arm": { + "version": "1.81.0", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm/-/sass-embedded-linux-arm-1.81.0.tgz", + "integrity": "sha512-REqR9qM4RchCE3cKqzRy9Q4zigIV82SbSpCi/O4O3oK3pg2I1z7vkb3TiJsivusG/li7aqKZGmYOtAXjruGQDA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-arm64": { + "version": "1.81.0", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm64/-/sass-embedded-linux-arm64-1.81.0.tgz", + "integrity": "sha512-jy4bvhdUmqbyw1jv1f3Uxl+MF8EU/Y/GDx4w6XPJm4Ds+mwH/TwnyAwsxxoBhWfnBnW8q2ADy039DlS5p+9csQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-ia32": { + "version": "1.81.0", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-ia32/-/sass-embedded-linux-ia32-1.81.0.tgz", + "integrity": "sha512-ga/Jk4q5Bn1aC+iHJteDZuLSKnmBUiS3dEg1fnl/Z7GaHIChceKDJOw0zNaILRXI0qT2E1at9MwzoRaRA5Nn/g==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-arm": { + "version": "1.81.0", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm/-/sass-embedded-linux-musl-arm-1.81.0.tgz", + "integrity": "sha512-oWVUvQ4d5Kx1Md75YXZl5z1WBjc+uOhfRRqzkJ3nWc8tjszxJN+y/5EOJavhsNI3/2yoTt6eMXRTqDD9b0tWSQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-arm64": { + "version": "1.81.0", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm64/-/sass-embedded-linux-musl-arm64-1.81.0.tgz", + "integrity": "sha512-hpntWf5kjkoxncA1Vh8vhsUOquZ8AROZKx0rQh7ZjSRs4JrYZASz1cfevPKaEM3wIim/nYa6TJqm0VqWsrERlA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-ia32": { + "version": "1.81.0", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-ia32/-/sass-embedded-linux-musl-ia32-1.81.0.tgz", + "integrity": "sha512-UEXUYkBuqTSwg5JNWiNlfMZ1Jx6SJkaEdx+fsL3Tk099L8cKSoJWH2EPz4ZJjNbyIMymrSdVfymheTeZ8u24xA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-riscv64": { + "version": "1.81.0", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-riscv64/-/sass-embedded-linux-musl-riscv64-1.81.0.tgz", + "integrity": "sha512-1D7OznytbIhx2XDHWi1nuQ8d/uCVR7FGGzELgaU//T8A9DapVTUgPKvB70AF1k4GzChR9IXU/WvFZs2hDTbaJg==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-x64": { + "version": "1.81.0", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-x64/-/sass-embedded-linux-musl-x64-1.81.0.tgz", + "integrity": "sha512-ia6VCTeVDQtBSMktXRFza1AZCt8/6aUoujot6Ugf4KmdytQqPJIHxkHaGftm5xwi9WdrMGYS7zgolToPijR11A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-riscv64": { + "version": "1.81.0", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-riscv64/-/sass-embedded-linux-riscv64-1.81.0.tgz", + "integrity": "sha512-KbxSsqu4tT1XbhZfJV/5NfW0VtJIGlD58RjqJqJBi8Rnjrx29/upBsuwoDWtsPV/LhoGwwU1XkSa9Q1ifCz4fQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-x64": { + "version": "1.81.0", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-x64/-/sass-embedded-linux-x64-1.81.0.tgz", + "integrity": "sha512-AMDeVY2T9WAnSFkuQcsOn5c29GRs/TuqnCiblKeXfxCSKym5uKdBl/N7GnTV6OjzoxiJBbkYKdVIaS5By7Gj4g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-win32-arm64": { + "version": "1.81.0", + "resolved": "https://registry.npmjs.org/sass-embedded-win32-arm64/-/sass-embedded-win32-arm64-1.81.0.tgz", + "integrity": "sha512-YOmBRYnygwWUmCoH14QbMRHjcvCJufeJBAp0m61tOJXIQh64ziwV4mjdqjS/Rx3zhTT4T+nulDUw4d3kLiMncA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-win32-ia32": { + "version": "1.81.0", + "resolved": "https://registry.npmjs.org/sass-embedded-win32-ia32/-/sass-embedded-win32-ia32-1.81.0.tgz", + "integrity": "sha512-HFfr/C+uLJGGTENdnssuNTmXI/xnIasUuEHEKqI+2J0FHCWT5cpz3PGAOHymPyJcZVYGUG/7gIxIx/d7t0LFYw==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-win32-x64": { + "version": "1.81.0", + "resolved": "https://registry.npmjs.org/sass-embedded-win32-x64/-/sass-embedded-win32-x64-1.81.0.tgz", + "integrity": "sha512-wxj52jDcIAwWcXb7ShZ7vQYKcVUkJ+04YM9l46jDY+qwHzliGuorAUyujLyKTE9heGD3gShJ3wPPC1lXzq6v9A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz", + "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==" + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/sharp": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", + "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==", + "hasInstallScript": true, + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.3", + "semver": "^7.6.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.5", + "@img/sharp-darwin-x64": "0.33.5", + "@img/sharp-libvips-darwin-arm64": "1.0.4", + "@img/sharp-libvips-darwin-x64": "1.0.4", + "@img/sharp-libvips-linux-arm": "1.0.5", + "@img/sharp-libvips-linux-arm64": "1.0.4", + "@img/sharp-libvips-linux-s390x": "1.0.4", + "@img/sharp-libvips-linux-x64": "1.0.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", + "@img/sharp-libvips-linuxmusl-x64": "1.0.4", + "@img/sharp-linux-arm": "0.33.5", + "@img/sharp-linux-arm64": "0.33.5", + "@img/sharp-linux-s390x": "0.33.5", + "@img/sharp-linux-x64": "0.33.5", + "@img/sharp-linuxmusl-arm64": "0.33.5", + "@img/sharp-linuxmusl-x64": "0.33.5", + "@img/sharp-wasm32": "0.33.5", + "@img/sharp-win32-ia32": "0.33.5", + "@img/sharp-win32-x64": "0.33.5" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/sirv": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.0.tgz", + "integrity": "sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==", + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/socket.io-client": { + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.5.tgz", + "integrity": "sha512-sJ/tqHOCe7Z50JCBCXrsY3I2k03iOiUe+tj1OmKeD2lXPiGH/RUCdTZFoqVyN7l1MnpIzPrGtLcijffmeouNlQ==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/sorcery": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.11.0.tgz", + "integrity": "sha512-J69LQ22xrQB1cIFJhPfgtLuI6BpWRiWu1Y3vSsIwK/eAScqJxd/+CJlUuHQRdX2C9NGFamq+KqNywGgaThwfHw==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.14", + "buffer-crc32": "^0.2.5", + "minimist": "^1.2.0", + "sander": "^0.5.0" + }, + "bin": { + "sorcery": "bin/sorcery" + } + }, + "node_modules/sort-keys": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-5.0.0.tgz", + "integrity": "sha512-Pdz01AvCAottHTPQGzndktFNdbRA75BgOfeT1hH+AMnJFv8lynkPi42rfeEhpx1saTEI3YNMWxfqu0sFD1G8pw==", + "dev": true, + "dependencies": { + "is-plain-obj": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/sortablejs": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.2.tgz", + "integrity": "sha512-FJF5jgdfvoKn1MAKSdGs33bIqLi3LmsgVTliuX6iITj834F+JRQZN90Z93yql8h0K2t0RwDPBmxwlbZfDcxNZA==" + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true + }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true + }, + "node_modules/stackblur-canvas": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-2.7.0.tgz", + "integrity": "sha512-yf7OENo23AGJhBriGx0QivY5JP6Y1HbrrDI6WLt6C5auYZXlQrheoY8hD4ibekFKz1HOfE48Ww8kMWMnJD/zcQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.14" + } + }, + "node_modules/std-env": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", + "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", + "dev": true + }, + "node_modules/sticky-module": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/sticky-module/-/sticky-module-0.1.1.tgz", + "integrity": "sha512-IuYgnyIMUx/m6rtu14l/LR2MaqOLtpXcWkxPmtPsiScRHEo+S4Tojk+DWFHOncSdFX/OsoLOM4+T92yOmI1AMw==" + }, + "node_modules/stream-composer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stream-composer/-/stream-composer-1.0.2.tgz", + "integrity": "sha512-bnBselmwfX5K10AH6L4c8+S5lgZMWI7ZYrz2rvYjCPB2DIMC4Ig8OpxGpNJSxRZ58oti7y1IcNvjBAz9vW5m4w==", + "dev": true, + "dependencies": { + "streamx": "^2.13.2" + } + }, + "node_modules/streamx": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.16.1.tgz", + "integrity": "sha512-m9QYj6WygWyWa3H1YY69amr4nVgy61xfjys7xO7kviL5rfIEc2naf+ewFiOA+aEJD7y0JO3h2GoiUv4TDwEGzQ==", + "dev": true, + "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", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "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/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/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/string-width/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/string-width/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/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/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/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.0.tgz", + "integrity": "sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==", + "dev": true, + "dependencies": { + "js-tokens": "^9.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/style-mod": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz", + "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==" + }, + "node_modules/stylis": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", + "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==" + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svelte": { + "version": "4.2.19", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.19.tgz", + "integrity": "sha512-IY1rnGr6izd10B0A8LqsBfmlT5OILVuZ7XsI0vdGPEvuonFV7NYEUK4dAkm9Zg2q0Um92kYjTpS1CAP3Nh/KWw==", + "dependencies": { + "@ampproject/remapping": "^2.2.1", + "@jridgewell/sourcemap-codec": "^1.4.15", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/estree": "^1.0.1", + "acorn": "^8.9.0", + "aria-query": "^5.3.0", + "axobject-query": "^4.0.0", + "code-red": "^1.0.3", + "css-tree": "^2.3.1", + "estree-walker": "^3.0.3", + "is-reference": "^3.0.1", + "locate-character": "^3.0.0", + "magic-string": "^0.30.4", + "periscopic": "^3.1.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/svelte-check": { + "version": "3.8.5", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.8.5.tgz", + "integrity": "sha512-3OGGgr9+bJ/+1nbPgsvulkLC48xBsqsgtc8Wam281H4G9F5v3mYGa2bHRsPuwHC5brKl4AxJH95QF73kmfihGQ==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.17", + "chokidar": "^3.4.1", + "picocolors": "^1.0.0", + "sade": "^1.7.4", + "svelte-preprocess": "^5.1.3", + "typescript": "^5.0.3" + }, + "bin": { + "svelte-check": "bin/svelte-check" + }, + "peerDependencies": { + "svelte": "^3.55.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0" + } + }, + "node_modules/svelte-confetti": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svelte-confetti/-/svelte-confetti-1.3.2.tgz", + "integrity": "sha512-R+JwFTC7hIgWVA/OuXrkj384B7CMoceb0t9VacyW6dORTQg0pWojVBB8Bo3tM30cLEQE48Fekzqgx+XSzHESMA==", + "dev": true, + "peerDependencies": { + "svelte": "^4.0.0" + } + }, + "node_modules/svelte-eslint-parser": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.41.0.tgz", + "integrity": "sha512-L6f4hOL+AbgfBIB52Z310pg1d2QjRqm7wy3kI1W6hhdhX5bvu7+f0R6w4ykp5HoDdzq+vGhIJmsisaiJDGmVfA==", + "dev": true, + "dependencies": { + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "postcss": "^8.4.39", + "postcss-scss": "^4.0.9" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0-next.191" + }, + "peerDependenciesMeta": { + "svelte": { + "optional": true + } + } + }, + "node_modules/svelte-hmr": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.16.0.tgz", + "integrity": "sha512-Gyc7cOS3VJzLlfj7wKS0ZnzDVdv3Pn2IuVeJPk9m2skfhcu5bq3wtIZyQGggr7/Iim5rH5cncyQft/kRLupcnA==", + "engines": { + "node": "^12.20 || ^14.13.1 || >= 16" + }, + "peerDependencies": { + "svelte": "^3.19.0 || ^4.0.0" + } + }, + "node_modules/svelte-preprocess": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.1.3.tgz", + "integrity": "sha512-xxAkmxGHT+J/GourS5mVJeOXZzne1FR5ljeOUAMXUkfEhkLEllRreXpbl3dIYJlcJRfL1LO1uIAPpBpBfiqGPw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@types/pug": "^2.0.6", + "detect-indent": "^6.1.0", + "magic-string": "^0.30.5", + "sorcery": "^0.11.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">= 16.0.0", + "pnpm": "^8.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.10.2", + "coffeescript": "^2.5.1", + "less": "^3.11.3 || ^4.0.0", + "postcss": "^7 || ^8", + "postcss-load-config": "^2.1.0 || ^3.0.0 || ^4.0.0 || ^5.0.0", + "pug": "^3.0.0", + "sass": "^1.26.8", + "stylus": "^0.55.0", + "sugarss": "^2.0.0 || ^3.0.0 || ^4.0.0", + "svelte": "^3.23.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0", + "typescript": ">=3.9.5 || ^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "coffeescript": { + "optional": true + }, + "less": { + "optional": true + }, + "postcss": { + "optional": true + }, + "postcss-load-config": { + "optional": true + }, + "pug": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/svelte-sonner": { + "version": "0.3.28", + "resolved": "https://registry.npmjs.org/svelte-sonner/-/svelte-sonner-0.3.28.tgz", + "integrity": "sha512-K3AmlySeFifF/cKgsYNv5uXqMVNln0NBAacOYgmkQStLa/UoU0LhfAACU6Gr+YYC8bOCHdVmFNoKuDbMEsppJg==", + "peerDependencies": { + "svelte": "^3.0.0 || ^4.0.0 || ^5.0.0-next.1" + } + }, + "node_modules/svelte/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/svelte/node_modules/is-reference": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", + "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/svg-pathdata": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/svg-pathdata/-/svg-pathdata-6.0.3.tgz", + "integrity": "sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/symlink-or-copy": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/symlink-or-copy/-/symlink-or-copy-1.3.1.tgz", + "integrity": "sha512-0K91MEXFpBUaywiwSSkmKjnGcasG/rVBXFLJz5DrgGabpYD6N+3yZrfD6uUIfpuTu65DZLHi7N8CizHc07BPZA==", + "dev": true + }, + "node_modules/sync-child-process": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/sync-child-process/-/sync-child-process-1.0.2.tgz", + "integrity": "sha512-8lD+t2KrrScJ/7KXCSyfhT3/hRq78rC0wBFqNJXv3mZyn6hW2ypM05JmlSvtqRbeq6jqA94oHbxAr2vYsJ8vDA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "sync-message-port": "^1.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/sync-message-port": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sync-message-port/-/sync-message-port-1.1.3.tgz", + "integrity": "sha512-GTt8rSKje5FilG+wEdfCkOcLL7LWqpMlr2c3LRuKt/YXxcJ52aGSbGBAdI4L3aaqfrBt6y711El53ItyH1NWzg==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==" + }, + "node_modules/tailwindcss": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.0.0.tgz", + "integrity": "sha512-ULRPI3A+e39T7pSaf1xoi58AqqJxVCLg8F/uM5A3FadUbnyDTgltVnXJvdkTjwCOGA6NazqHVcwPJC5h2vRYVQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/teex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", + "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", + "dev": true, + "dependencies": { + "streamx": "^2.12.5" + } + }, + "node_modules/text-segmentation": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", + "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==", + "license": "MIT", + "optional": true, + "dependencies": { + "utrie": "^1.0.2" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/throttleit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.1.tgz", + "integrity": "sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/tiny-glob": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", + "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", + "dependencies": { + "globalyzer": "0.1.0", + "globrex": "^0.1.2" + } + }, + "node_modules/tinybench": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz", + "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==", + "dev": true + }, + "node_modules/tinypool": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.4.tgz", + "integrity": "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", + "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tippy.js": { + "version": "6.3.7", + "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz", + "integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==", + "dependencies": { + "@popperjs/core": "^2.9.0" + } + }, + "node_modules/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "dev": true, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/to-json-callback": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/to-json-callback/-/to-json-callback-0.1.1.tgz", + "integrity": "sha512-BzOeinTT3NjE+FJ2iCvWB8HvyuyBzoH3WlSnJ+AYVC4tlePyZWSYdkQIFOARWiq0t35/XhmI0uQsFiUsRksRqg==" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/to-through": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/to-through/-/to-through-3.0.0.tgz", + "integrity": "sha512-y8MN937s/HVhEoBU1SxfHC+wxCHkV1a9gW8eAdTadYh/bGyesZIVcbjI+mSpFbSVwQici/XjBjuUyri1dnXwBw==", + "dev": true, + "dependencies": { + "streamx": "^2.12.5" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "dev": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/ts-dedent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", + "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", + "engines": { + "node": ">=6.10" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/turndown": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/turndown/-/turndown-7.2.0.tgz", + "integrity": "sha512-eCZGBN4nNNqM9Owkv9HAtWRYfLA4h909E/WGAWWBpmB275ehNhZyk87/Tpvjbp0jjNl9XwCsbe6bm6CqFsgD+A==", + "license": "MIT", + "dependencies": { + "@mixmark-io/domino": "^2.2.0" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-checked-collections": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/type-checked-collections/-/type-checked-collections-0.1.7.tgz", + "integrity": "sha512-fLIydlJy7IG9XL4wjRwEcKhxx/ekLXiWiMvcGo01cOMF+TN+5ZqajM1mRNRz2bNNi1bzou2yofhjZEQi7kgl9A==" + }, + "node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==" + }, + "node_modules/ufo": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", + "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==", + "dev": true + }, + "node_modules/underscore.string": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.6.tgz", + "integrity": "sha512-VoC83HWXmCrF6rgkyxS9GHv8W9Q5nhMKho+OadDJGzL2oDYbYEppBaCMH6pFlwLeqj2QS+hhkw2kpXkSdD1JxQ==", + "dev": true, + "dependencies": { + "sprintf-js": "^1.1.1", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/undici": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.3.0.tgz", + "integrity": "sha512-Qy96NND4Dou5jKoSJ2gm8ax8AJM/Ey9o9mz7KN1bb9GP+G0l20Zw8afxTnY2f4b7hmhn/z8aC2kfArVQlAhFBw==", + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/unist-util-stringify-position": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", + "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/utrie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz", + "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==", + "license": "MIT", + "optional": true, + "dependencies": { + "base64-arraybuffer": "^1.0.2" + } + }, + "node_modules/uuid": { + "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" + } + }, + "node_modules/uvu": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz", + "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==", + "dependencies": { + "dequal": "^2.0.0", + "diff": "^5.0.0", + "kleur": "^4.0.3", + "sade": "^1.7.3" + }, + "bin": { + "uvu": "bin.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/value-or-function": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-4.0.0.tgz", + "integrity": "sha512-aeVK81SIuT6aMJfNo9Vte8Dw0/FZINGBV8BfCraGtqVxIeLAEhJyoWs8SmvRVmXfGss2PmmOwZCuBPbZR+IYWg==", + "dev": true, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/varint": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz", + "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true + }, + "node_modules/vinyl": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz", + "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==", + "dev": true, + "dependencies": { + "clone": "^2.1.2", + "clone-stats": "^1.0.0", + "remove-trailing-separator": "^1.1.0", + "replace-ext": "^2.0.0", + "teex": "^1.0.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/vinyl-contents": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/vinyl-contents/-/vinyl-contents-2.0.0.tgz", + "integrity": "sha512-cHq6NnGyi2pZ7xwdHSW1v4Jfnho4TEGtxZHw01cmnc8+i7jgR6bRnED/LbrKan/Q7CvVLbnvA5OepnhbpjBZ5Q==", + "dev": true, + "dependencies": { + "bl": "^5.0.0", + "vinyl": "^3.0.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/vinyl-fs": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-4.0.0.tgz", + "integrity": "sha512-7GbgBnYfaquMk3Qu9g22x000vbYkOex32930rBnc3qByw6HfMEAoELjCjoJv4HuEQxHAurT+nvMHm6MnJllFLw==", + "dev": true, + "dependencies": { + "fs-mkdirp-stream": "^2.0.1", + "glob-stream": "^8.0.0", + "graceful-fs": "^4.2.11", + "iconv-lite": "^0.6.3", + "is-valid-glob": "^1.0.0", + "lead": "^4.0.0", + "normalize-path": "3.0.0", + "resolve-options": "^2.0.0", + "stream-composer": "^1.0.2", + "streamx": "^2.14.0", + "to-through": "^3.0.0", + "value-or-function": "^4.0.0", + "vinyl": "^3.0.0", + "vinyl-sourcemap": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/vinyl-sourcemap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-2.0.0.tgz", + "integrity": "sha512-BAEvWxbBUXvlNoFQVFVHpybBbjW1r03WhohJzJDSfgrrK5xVYIDTan6xN14DlyImShgDRv2gl9qhM6irVMsV0Q==", + "dev": true, + "dependencies": { + "convert-source-map": "^2.0.0", + "graceful-fs": "^4.2.10", + "now-and-later": "^3.0.0", + "streamx": "^2.12.5", + "vinyl": "^3.0.0", + "vinyl-contents": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/vite": { + "version": "5.4.14", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.14.tgz", + "integrity": "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==", + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.1.tgz", + "integrity": "sha512-YAXkfvGtuTzwWbDSACdJSg4A4DZiAqckWe90Zapc/sEX3XvHcw1NdurM/6od8J207tSDqNbSsgdCacBgvJKFuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.4", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite-plugin-static-copy": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-2.2.0.tgz", + "integrity": "sha512-ytMrKdR9iWEYHbUxs6x53m+MRl4SJsOSoMu1U1+Pfg0DjPeMlsRVx3RR5jvoonineDquIue83Oq69JvNsFSU5w==", + "license": "MIT", + "dependencies": { + "chokidar": "^3.5.3", + "fast-glob": "^3.2.11", + "fs-extra": "^11.1.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "vite": "^5.0.0 || ^6.0.0" + } + }, + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/vitefu": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz", + "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==", + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/vitest": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.6.1.tgz", + "integrity": "sha512-Ljb1cnSJSivGN0LqXd/zmDbWEM0RNNg2t1QW/XUhYl/qPqyu7CsqeWtqQXHVaJsecLPuDoak2oJcZN2QoRIOag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "1.6.1", + "@vitest/runner": "1.6.1", + "@vitest/snapshot": "1.6.1", + "@vitest/spy": "1.6.1", + "@vitest/utils": "1.6.1", + "acorn-walk": "^8.3.2", + "chai": "^4.3.10", + "debug": "^4.3.4", + "execa": "^8.0.1", + "local-pkg": "^0.5.0", + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "std-env": "^3.5.0", + "strip-literal": "^2.0.0", + "tinybench": "^2.5.1", + "tinypool": "^0.8.3", + "vite": "^5.0.0", + "vite-node": "1.6.1", + "why-is-node-running": "^2.2.2" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "1.6.1", + "@vitest/ui": "1.6.1", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/vitest/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vitest/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/vitest/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vitest/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vitest/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vitest/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vitest/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vitest/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/w3c-keyname": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", + "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==" + }, + "node_modules/walk-sync": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/walk-sync/-/walk-sync-2.2.0.tgz", + "integrity": "sha512-IC8sL7aB4/ZgFcGI2T1LczZeFWZ06b3zoHH7jBPyHxOtIIz1jppWHjjEXkOFvFojBVAK9pV7g47xOZ4LW3QLfg==", + "dev": true, + "dependencies": { + "@types/minimatch": "^3.0.3", + "ensure-posix-path": "^1.1.0", + "matcher-collection": "^2.0.0", + "minimatch": "^3.0.4" + }, + "engines": { + "node": "8.* || >= 10.*" + } + }, + "node_modules/walk-sync/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/walk-sync/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/web-worker": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.3.0.tgz", + "integrity": "sha512-BSR9wyRsy/KOValMgd5kMyr3JzpdeoR9KVId8u5GVlTTAtNChlsE4yTxeY7zMdNSyOmoKBv8NH2qeRY9Tg+IaA==" + }, + "node_modules/wheel": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wheel/-/wheel-1.0.0.tgz", + "integrity": "sha512-XiCMHibOiqalCQ+BaNSwRoZ9FDTAvOsXxGHXChBugewDj7HC8VBIER71dEOiRH1fSdLbRCQzngKTSiZ06ZQzeA==" + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/why-is-node-running": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz", + "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==", + "dev": true, + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "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/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/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/wrap-ansi-cjs/node_modules/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/wrap-ansi/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/wrap-ansi/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/wrap-ansi/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/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", + "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..1d2e867 --- /dev/null +++ b/package.json @@ -0,0 +1,118 @@ +{ + "name": "open-webui", + "version": "0.5.18", + "private": true, + "scripts": { + "dev": "npm run pyodide:fetch && vite dev --host", + "dev:5050": "npm run pyodide:fetch && vite dev --port 5050", + "build": "npm run pyodide:fetch && vite build", + "preview": "vite preview", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", + "lint": "npm run lint:frontend ; npm run lint:types ; npm run lint:backend", + "lint:frontend": "eslint . --fix", + "lint:types": "npm run check", + "lint:backend": "pylint backend/", + "format": "prettier --plugin-search-dir --write \"**/*.{js,ts,svelte,css,md,html,json}\"", + "format:backend": "black . --exclude \".venv/|/venv/\"", + "i18n:parse": "i18next --config i18next-parser.config.ts && prettier --write \"src/lib/i18n/**/*.{js,json}\"", + "cy:open": "cypress open", + "test:frontend": "vitest --passWithNoTests", + "pyodide:fetch": "node scripts/prepare-pyodide.js" + }, + "devDependencies": { + "@sveltejs/adapter-auto": "3.2.2", + "@sveltejs/adapter-static": "^3.0.2", + "@sveltejs/kit": "^2.5.20", + "@sveltejs/vite-plugin-svelte": "^3.1.1", + "@tailwindcss/container-queries": "^0.1.1", + "@tailwindcss/postcss": "^4.0.0", + "@tailwindcss/typography": "^0.5.13", + "@typescript-eslint/eslint-plugin": "^6.17.0", + "@typescript-eslint/parser": "^6.17.0", + "cypress": "^13.15.0", + "eslint": "^8.56.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-cypress": "^3.4.0", + "eslint-plugin-svelte": "^2.43.0", + "i18next-parser": "^9.0.1", + "postcss": "^8.4.31", + "prettier": "^3.3.3", + "prettier-plugin-svelte": "^3.2.6", + "sass-embedded": "^1.81.0", + "svelte": "^4.2.18", + "svelte-check": "^3.8.5", + "svelte-confetti": "^1.3.2", + "tailwindcss": "^4.0.0", + "tslib": "^2.4.1", + "typescript": "^5.5.4", + "vite": "^5.4.14", + "vitest": "^1.6.1" + }, + "type": "module", + "dependencies": { + "@codemirror/lang-javascript": "^6.2.2", + "@codemirror/lang-python": "^6.1.6", + "@codemirror/language-data": "^6.5.1", + "@codemirror/theme-one-dark": "^6.1.2", + "@huggingface/transformers": "^3.0.0", + "@mediapipe/tasks-vision": "^0.10.17", + "@pyscript/core": "^0.4.32", + "@sveltejs/adapter-node": "^2.0.0", + "@sveltejs/svelte-virtual-list": "^3.0.1", + "@tiptap/core": "^2.10.0", + "@tiptap/extension-code-block-lowlight": "^2.10.0", + "@tiptap/extension-highlight": "^2.10.0", + "@tiptap/extension-placeholder": "^2.10.0", + "@tiptap/extension-typography": "^2.10.0", + "@tiptap/pm": "^2.10.0", + "@tiptap/starter-kit": "^2.10.0", + "@xyflow/svelte": "^0.1.19", + "async": "^3.2.5", + "bits-ui": "^0.19.7", + "codemirror": "^6.0.1", + "codemirror-lang-hcl": "^0.0.0-beta.2", + "crc-32": "^1.2.2", + "dayjs": "^1.11.10", + "dompurify": "^3.1.6", + "eventsource-parser": "^1.1.2", + "file-saver": "^2.0.5", + "fuse.js": "^7.0.0", + "highlight.js": "^11.9.0", + "i18next": "^23.10.0", + "i18next-browser-languagedetector": "^7.2.0", + "i18next-resources-to-backend": "^1.2.0", + "idb": "^7.1.1", + "js-sha256": "^0.10.1", + "jspdf": "^3.0.0", + "katex": "^0.16.21", + "kokoro-js": "^1.1.1", + "marked": "^9.1.0", + "mermaid": "^10.9.3", + "paneforge": "^0.0.6", + "panzoom": "^9.4.3", + "prosemirror-commands": "^1.6.0", + "prosemirror-example-setup": "^1.2.3", + "prosemirror-history": "^1.4.1", + "prosemirror-keymap": "^1.2.2", + "prosemirror-markdown": "^1.13.1", + "prosemirror-model": "^1.23.0", + "prosemirror-schema-basic": "^1.2.3", + "prosemirror-schema-list": "^1.4.1", + "prosemirror-state": "^1.4.3", + "prosemirror-view": "^1.34.3", + "pyodide": "^0.27.2", + "socket.io-client": "^4.2.0", + "sortablejs": "^1.15.2", + "svelte-sonner": "^0.3.19", + "tippy.js": "^6.3.7", + "turndown": "^7.2.0", + "undici": "^7.3.0", + "uuid": "^9.0.1", + "vite-plugin-static-copy": "^2.2.0" + }, + "engines": { + "node": ">=18.13.0 <=22.x.x", + "npm": ">=6.0.0" + } +} diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..85b958c --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,5 @@ +export default { + plugins: { + '@tailwindcss/postcss': {} + } +}; diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..ccf4863 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,178 @@ +[project] +name = "open-webui" +description = "Open WebUI" +authors = [ + { name = "Timothy Jaeryang Baek", email = "tim@openwebui.com" } +] +license = { file = "LICENSE" } +dependencies = [ + "fastapi==0.115.7", + "uvicorn[standard]==0.30.6", + "pydantic==2.10.6", + "python-multipart==0.0.18", + + "python-socketio==5.11.3", + "python-jose==3.4.0", + "passlib[bcrypt]==1.7.4", + + "requests==2.32.3", + "aiohttp==3.11.11", + "async-timeout", + "aiocache", + "aiofiles", + + "sqlalchemy==2.0.32", + "alembic==1.14.0", + "peewee==3.17.8", + "peewee-migrate==1.12.2", + "psycopg2-binary==2.9.9", + "pgvector==0.3.5", + "PyMySQL==1.1.1", + "bcrypt==4.2.0", + + "pymongo", + "redis", + "boto3==1.35.53", + + "argon2-cffi==23.1.0", + "APScheduler==3.10.4", + + + "RestrictedPython==8.0", + + "loguru==0.7.2", + "asgiref==3.8.1", + + "openai", + "anthropic", + "google-generativeai==0.7.2", + "tiktoken", + + "langchain==0.3.7", + "langchain-community==0.3.7", + + "fake-useragent==1.5.1", + "chromadb==0.6.2", + "pymilvus==2.5.0", + "qdrant-client~=1.12.0", + "opensearch-py==2.8.0", + "playwright==1.49.1", + + "transformers", + "sentence-transformers==3.3.1", + "colbert-ai==0.2.21", + "einops==0.8.0", + + "ftfy==6.2.3", + "pypdf==4.3.1", + "fpdf2==2.8.2", + "pymdown-extensions==10.14.2", + "docx2txt==0.8", + "python-pptx==1.0.0", + "unstructured==0.16.17", + "nltk==3.9.1", + "Markdown==3.7", + "pypandoc==1.13", + "pandas==2.2.3", + "openpyxl==3.1.5", + "pyxlsb==1.0.10", + "xlrd==2.0.1", + "validators==0.34.0", + "psutil", + "sentencepiece", + "soundfile==0.13.1", + "azure-ai-documentintelligence==1.0.0", + + "opencv-python-headless==4.11.0.86", + "rapidocr-onnxruntime==1.3.24", + "rank-bm25==0.2.2", + + "faster-whisper==1.1.1", + + "PyJWT[crypto]==2.10.1", + "authlib==1.4.1", + + "black==24.8.0", + "langfuse==2.44.0", + "youtube-transcript-api==0.6.3", + "pytube==15.0.0", + + "extract_msg", + "pydub", + "duckduckgo-search~=7.3.2", + + "google-api-python-client", + "google-auth-httplib2", + "google-auth-oauthlib", + + "docker~=7.1.0", + "pytest~=8.3.2", + "pytest-docker~=3.1.1", + "moto[s3]>=5.0.26", + + "googleapis-common-protos==1.63.2", + "google-cloud-storage==2.19.0", + + "azure-identity==1.20.0", + "azure-storage-blob==12.24.1", + + "ldap3==2.9.1", + + "firecrawl-py==1.12.0", + + "gcp-storage-emulator>=2024.8.3", +] +readme = "README.md" +requires-python = ">= 3.11, < 3.13.0a1" +dynamic = ["version"] +classifiers = [ + "Development Status :: 4 - Beta", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Topic :: Communications :: Chat", + "Topic :: Multimedia", +] + +[project.scripts] +open-webui = "open_webui:app" + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.rye] +managed = true +dev-dependencies = [] + +[tool.hatch.metadata] +allow-direct-references = true + +[tool.hatch.version] +path = "package.json" +pattern = '"version":\s*"(?P[^"]+)"' + +[tool.hatch.build.hooks.custom] # keep this for reading hooks from `hatch_build.py` + +[tool.hatch.build.targets.wheel] +sources = ["backend"] +exclude = [ + ".dockerignore", + ".gitignore", + ".webui_secret_key", + "dev.sh", + "requirements.txt", + "start.sh", + "start_windows.bat", + "webui.db", + "chroma.sqlite3", +] +force-include = { "CHANGELOG.md" = "open_webui/CHANGELOG.md", build = "open_webui/frontend" } + +[tool.codespell] +# Ref: https://github.com/codespell-project/codespell#using-a-config-file +skip = '.git*,*.svg,package-lock.json,i18n,*.lock,*.css,*-bundle.js,locales,example-doc.txt,emoji-shortcodes.json' +check-hidden = true +# ignore-regex = '' +ignore-words-list = 'ans' diff --git a/readme.md b/readme.md index 9508705..54ad415 100644 --- a/readme.md +++ b/readme.md @@ -1,35 +1,228 @@ +# Open WebUI 👋 - # Przeczytaj uważnie przed uruchomieniem tego repo 📝 - To jest biblia szkolenia modeli obsługiwanych przez Ably.do +![GitHub stars](https://img.shields.io/github/stars/open-webui/open-webui?style=social) +![GitHub forks](https://img.shields.io/github/forks/open-webui/open-webui?style=social) +![GitHub watchers](https://img.shields.io/github/watchers/open-webui/open-webui?style=social) +![GitHub repo size](https://img.shields.io/github/repo-size/open-webui/open-webui) +![GitHub language count](https://img.shields.io/github/languages/count/open-webui/open-webui) +![GitHub top language](https://img.shields.io/github/languages/top/open-webui/open-webui) +![GitHub last commit](https://img.shields.io/github/last-commit/open-webui/open-webui?color=red) +![Hits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2Follama-webui%2Follama-wbui&count_bg=%2379C83D&title_bg=%23555555&icon=&icon_color=%23E7E7E7&title=hits&edge_flat=false) +[![Discord](https://img.shields.io/badge/Discord-Open_WebUI-blue?logo=discord&logoColor=white)](https://discord.gg/5rJgQTnV4s) +[![](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&color=%23fe8e86)](https://github.com/sponsors/tjbck) - ## Konfiguracja Git 🔥 - **git config --global credential.helper store** \ - Przejdź do folderu, w którym będziesz przechowywał lokalne repo. (np. **cd /home**) \ - Pobierz repo: \ - **git clone https://repo.pokash.pl/POKASH.PL/ably.do.git** \ - pierwszym razem zostaniesz poproszony o zalogowanie się. - - ## Konfiguracja Hugging Face Transpormers 🚀 - **huggingface-cli login** \ - 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 +**Open WebUI is an [extensible](https://docs.openwebui.com/features/plugin/), feature-rich, and user-friendly self-hosted AI platform designed to operate entirely offline.** It supports various LLM runners like **Ollama** and **OpenAI-compatible APIs**, with **built-in inference engine** for RAG, making it a **powerful AI deployment solution**. - **W przypadku niektórych obrazów modeli musisz przejść przez akceptację licencji** - - ## Trenowanie modelu 🔥 - Przejdź do folderu, w którym będziesz pobierał wiedzę z repo. (np. /home). \ - Pobierz najnowsze zmiany (**git pull**) \ - Uruchom skrypt Python, który rozpocznie trenowanie modelu: \ - **python3 hft.py** - - ## Wdrażanie modelu ✨ - Po wytrenowaniu modelu, - musisz przekonwertować go do formatu GGUF, który obsługuje Ollama. \ - Konwersja do GGUF - 1. Skorzystaj z narzędzia dostarczonego przez Ollama do konwersji: \ - **ollama convert your_model.bin --output your_model.gguf** \ - 2. Umieść przekonwertowany model w katalogu Ollama: \ - **mv your_model.gguf ~/.ollama/models/** +![Open WebUI Demo](./demo.gif) - Uruchomienie dostrojonego modelu \ - Użyj nazwy swojego modelu w poleceniu: \ - **ollama run your_model** *"Jakie są wymagania dotyczące ochrony słuchu?"* \ No newline at end of file +> [!TIP] +> **Looking for an [Enterprise Plan](https://docs.openwebui.com/enterprise)?** – **[Speak with Our Sales Team Today!](mailto:sales@openwebui.com)** +> +> Get **enhanced capabilities**, including **custom theming and branding**, **Service Level Agreement (SLA) support**, **Long-Term Support (LTS) versions**, and **more!** + +For more information, be sure to check out our [Open WebUI Documentation](https://docs.openwebui.com/). + +## Key Features of Open WebUI ⭐ + +- 🚀 **Effortless Setup**: Install seamlessly using Docker or Kubernetes (kubectl, kustomize or helm) for a hassle-free experience with support for both `:ollama` and `:cuda` tagged images. + +- 🤝 **Ollama/OpenAI API Integration**: Effortlessly integrate OpenAI-compatible APIs for versatile conversations alongside Ollama models. Customize the OpenAI API URL to link with **LMStudio, GroqCloud, Mistral, OpenRouter, and more**. + +- 🛡️ **Granular Permissions and User Groups**: By allowing administrators to create detailed user roles and permissions, we ensure a secure user environment. This granularity not only enhances security but also allows for customized user experiences, fostering a sense of ownership and responsibility amongst users. + +- 📱 **Responsive Design**: Enjoy a seamless experience across Desktop PC, Laptop, and Mobile devices. + +- 📱 **Progressive Web App (PWA) for Mobile**: Enjoy a native app-like experience on your mobile device with our PWA, providing offline access on localhost and a seamless user interface. + +- ✒️🔢 **Full Markdown and LaTeX Support**: Elevate your LLM experience with comprehensive Markdown and LaTeX capabilities for enriched interaction. + +- 🎤📹 **Hands-Free Voice/Video Call**: Experience seamless communication with integrated hands-free voice and video call features, allowing for a more dynamic and interactive chat environment. + +- 🛠️ **Model Builder**: Easily create Ollama models via the Web UI. Create and add custom characters/agents, customize chat elements, and import models effortlessly through [Open WebUI Community](https://openwebui.com/) integration. + +- 🐍 **Native Python Function Calling Tool**: Enhance your LLMs with built-in code editor support in the tools workspace. Bring Your Own Function (BYOF) by simply adding your pure Python functions, enabling seamless integration with LLMs. + +- 📚 **Local RAG Integration**: Dive into the future of chat interactions with groundbreaking Retrieval Augmented Generation (RAG) support. This feature seamlessly integrates document interactions into your chat experience. You can load documents directly into the chat or add files to your document library, effortlessly accessing them using the `#` command before a query. + +- 🔍 **Web Search for RAG**: Perform web searches using providers like `SearXNG`, `Google PSE`, `Brave Search`, `serpstack`, `serper`, `Serply`, `DuckDuckGo`, `TavilySearch`, `SearchApi` and `Bing` and inject the results directly into your chat experience. + +- 🌐 **Web Browsing Capability**: Seamlessly integrate websites into your chat experience using the `#` command followed by a URL. This feature allows you to incorporate web content directly into your conversations, enhancing the richness and depth of your interactions. + +- 🎨 **Image Generation Integration**: Seamlessly incorporate image generation capabilities using options such as AUTOMATIC1111 API or ComfyUI (local), and OpenAI's DALL-E (external), enriching your chat experience with dynamic visual content. + +- ⚙️ **Many Models Conversations**: Effortlessly engage with various models simultaneously, harnessing their unique strengths for optimal responses. Enhance your experience by leveraging a diverse set of models in parallel. + +- 🔐 **Role-Based Access Control (RBAC)**: Ensure secure access with restricted permissions; only authorized individuals can access your Ollama, and exclusive model creation/pulling rights are reserved for administrators. + +- 🌐🌍 **Multilingual Support**: Experience Open WebUI in your preferred language with our internationalization (i18n) support. Join us in expanding our supported languages! We're actively seeking contributors! + +- 🧩 **Pipelines, Open WebUI Plugin Support**: Seamlessly integrate custom logic and Python libraries into Open WebUI using [Pipelines Plugin Framework](https://github.com/open-webui/pipelines). Launch your Pipelines instance, set the OpenAI URL to the Pipelines URL, and explore endless possibilities. [Examples](https://github.com/open-webui/pipelines/tree/main/examples) include **Function Calling**, User **Rate Limiting** to control access, **Usage Monitoring** with tools like Langfuse, **Live Translation with LibreTranslate** for multilingual support, **Toxic Message Filtering** and much more. + +- 🌟 **Continuous Updates**: We are committed to improving Open WebUI with regular updates, fixes, and new features. + +Want to learn more about Open WebUI's features? Check out our [Open WebUI documentation](https://docs.openwebui.com/features) for a comprehensive overview! + +## 🔗 Also Check Out Open WebUI Community! + +Don't forget to explore our sibling project, [Open WebUI Community](https://openwebui.com/), where you can discover, download, and explore customized Modelfiles. Open WebUI Community offers a wide range of exciting possibilities for enhancing your chat interactions with Open WebUI! 🚀 + +## How to Install 🚀 + +### Installation via Python pip 🐍 + +Open WebUI can be installed using pip, the Python package installer. Before proceeding, ensure you're using **Python 3.11** to avoid compatibility issues. + +1. **Install Open WebUI**: + Open your terminal and run the following command to install Open WebUI: + + ```bash + pip install open-webui + ``` + +2. **Running Open WebUI**: + After installation, you can start Open WebUI by executing: + + ```bash + open-webui serve + ``` + +This will start the Open WebUI server, which you can access at [http://localhost:8080](http://localhost:8080) + +### Quick Start with Docker 🐳 + +> [!NOTE] +> Please note that for certain Docker environments, additional configurations might be needed. If you encounter any connection issues, our detailed guide on [Open WebUI Documentation](https://docs.openwebui.com/) is ready to assist you. + +> [!WARNING] +> When using Docker to install Open WebUI, make sure to include the `-v open-webui:/app/backend/data` in your Docker command. This step is crucial as it ensures your database is properly mounted and prevents any loss of data. + +> [!TIP] +> If you wish to utilize Open WebUI with Ollama included or CUDA acceleration, we recommend utilizing our official images tagged with either `:cuda` or `:ollama`. To enable CUDA, you must install the [Nvidia CUDA container toolkit](https://docs.nvidia.com/dgx/nvidia-container-runtime-upgrade/) on your Linux/WSL system. + +### Installation with Default Configuration + +- **If Ollama is on your computer**, use this command: + + ```bash + docker run -d -p 3000:8080 --add-host=host.docker.internal:host-gateway -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:main + ``` + +- **If Ollama is on a Different Server**, use this command: + + To connect to Ollama on another server, change the `OLLAMA_BASE_URL` to the server's URL: + + ```bash + docker run -d -p 3000:8080 -e OLLAMA_BASE_URL=https://example.com -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:main + ``` + +- **To run Open WebUI with Nvidia GPU support**, use this command: + + ```bash + docker run -d -p 3000:8080 --gpus all --add-host=host.docker.internal:host-gateway -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:cuda + ``` + +### Installation for OpenAI API Usage Only + +- **If you're only using OpenAI API**, use this command: + + ```bash + docker run -d -p 3000:8080 -e OPENAI_API_KEY=your_secret_key -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:main + ``` + +### Installing Open WebUI with Bundled Ollama Support + +This installation method uses a single container image that bundles Open WebUI with Ollama, allowing for a streamlined setup via a single command. Choose the appropriate command based on your hardware setup: + +- **With GPU Support**: + Utilize GPU resources by running the following command: + + ```bash + docker run -d -p 3000:8080 --gpus=all -v ollama:/root/.ollama -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:ollama + ``` + +- **For CPU Only**: + If you're not using a GPU, use this command instead: + + ```bash + docker run -d -p 3000:8080 -v ollama:/root/.ollama -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:ollama + ``` + +Both commands facilitate a built-in, hassle-free installation of both Open WebUI and Ollama, ensuring that you can get everything up and running swiftly. + +After installation, you can access Open WebUI at [http://localhost:3000](http://localhost:3000). Enjoy! 😄 + +### Other Installation Methods + +We offer various installation alternatives, including non-Docker native installation methods, Docker Compose, Kustomize, and Helm. Visit our [Open WebUI Documentation](https://docs.openwebui.com/getting-started/) or join our [Discord community](https://discord.gg/5rJgQTnV4s) for comprehensive guidance. + +### Troubleshooting + +Encountering connection issues? Our [Open WebUI Documentation](https://docs.openwebui.com/troubleshooting/) has got you covered. For further assistance and to join our vibrant community, visit the [Open WebUI Discord](https://discord.gg/5rJgQTnV4s). + +#### Open WebUI: Server Connection Error + +If you're experiencing connection issues, it’s often due to the WebUI docker container not being able to reach the Ollama server at 127.0.0.1:11434 (host.docker.internal:11434) inside the container . Use the `--network=host` flag in your docker command to resolve this. Note that the port changes from 3000 to 8080, resulting in the link: `http://localhost:8080`. + +**Example Docker Command**: + +```bash +docker run -d --network=host -v open-webui:/app/backend/data -e OLLAMA_BASE_URL=http://127.0.0.1:11434 --name open-webui --restart always ghcr.io/open-webui/open-webui:main +``` + +### Keeping Your Docker Installation Up-to-Date + +In case you want to update your local Docker installation to the latest version, you can do it with [Watchtower](https://containrrr.dev/watchtower/): + +```bash +docker run --rm --volume /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower --run-once open-webui +``` + +In the last part of the command, replace `open-webui` with your container name if it is different. + +Check our Updating Guide available in our [Open WebUI Documentation](https://docs.openwebui.com/getting-started/updating). + +### Using the Dev Branch 🌙 + +> [!WARNING] +> The `:dev` branch contains the latest unstable features and changes. Use it at your own risk as it may have bugs or incomplete features. + +If you want to try out the latest bleeding-edge features and are okay with occasional instability, you can use the `:dev` tag like this: + +```bash +docker run -d -p 3000:8080 -v open-webui:/app/backend/data --name open-webui --add-host=host.docker.internal:host-gateway --restart always ghcr.io/open-webui/open-webui:dev +``` + +### Offline Mode + +If you are running Open WebUI in an offline environment, you can set the `HF_HUB_OFFLINE` environment variable to `1` to prevent attempts to download models from the internet. + +```bash +export HF_HUB_OFFLINE=1 +``` + +## What's Next? 🌟 + +Discover upcoming features on our roadmap in the [Open WebUI Documentation](https://docs.openwebui.com/roadmap/). + +## License 📜 + +This project is licensed under the [BSD-3-Clause License](LICENSE) - see the [LICENSE](LICENSE) file for details. 📄 + +## Support 💬 + +If you have any questions, suggestions, or need assistance, please open an issue or join our +[Open WebUI Discord community](https://discord.gg/5rJgQTnV4s) to connect with us! 🤝 + +## Star History + + + + + + Star History Chart + + + +--- + +Created by [Timothy Jaeryang Baek](https://github.com/tjbck) - Let's make Open WebUI even more amazing together! 💪 diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index ae350df..0000000 --- a/requirements.txt +++ /dev/null @@ -1,11 +0,0 @@ -torch>=2.0.1 -transformers>=4.30.2 -datasets>=2.13.1 -Pillow>=9.4.0 -pytesseract>=0.3.10 -python-docx>=0.8.11 -PyPDF2>=3.0.1 -huggingface-hub>=0.16.4 -numpy -peft -weaviate-client \ No newline at end of file diff --git a/run-compose.sh b/run-compose.sh new file mode 100755 index 0000000..4fafedc --- /dev/null +++ b/run-compose.sh @@ -0,0 +1,250 @@ +#!/bin/bash + +# Define color and formatting codes +BOLD='\033[1m' +GREEN='\033[1;32m' +WHITE='\033[1;37m' +RED='\033[0;31m' +NC='\033[0m' # No Color +# Unicode character for tick mark +TICK='\u2713' + +# Detect GPU driver +get_gpu_driver() { + # Detect NVIDIA GPUs using lspci or nvidia-smi + if lspci | grep -i nvidia >/dev/null || nvidia-smi >/dev/null 2>&1; then + echo "nvidia" + return + fi + + # Detect AMD GPUs (including GCN architecture check for amdgpu vs radeon) + if lspci | grep -i amd >/dev/null; then + # List of known GCN and later architecture cards + # This is a simplified list, and in a real-world scenario, you'd want a more comprehensive one + local gcn_and_later=("Radeon HD 7000" "Radeon HD 8000" "Radeon R5" "Radeon R7" "Radeon R9" "Radeon RX") + + # Get GPU information + local gpu_info=$(lspci | grep -i 'vga.*amd') + + for model in "${gcn_and_later[@]}"; do + if echo "$gpu_info" | grep -iq "$model"; then + echo "amdgpu" + return + fi + done + + # Default to radeon if no GCN or later architecture is detected + echo "radeon" + return + fi + + # Detect Intel GPUs + if lspci | grep -i intel >/dev/null; then + echo "i915" + return + fi + + # If no known GPU is detected + echo "Unknown or unsupported GPU driver" + exit 1 +} + +# Function for rolling animation +show_loading() { + local spin='-\|/' + local i=0 + + printf " " + + while kill -0 $1 2>/dev/null; do + i=$(( (i+1) %4 )) + printf "\b${spin:$i:1}" + sleep .1 + done + + # Replace the spinner with a tick + printf "\b${GREEN}${TICK}${NC}" +} + +# Usage information +usage() { + echo "Usage: $0 [OPTIONS]" + echo "Options:" + echo " --enable-gpu[count=COUNT] Enable GPU support with the specified count." + echo " --enable-api[port=PORT] Enable API and expose it on the specified port." + echo " --webui[port=PORT] Set the port for the web user interface." + echo " --data[folder=PATH] Bind mount for ollama data folder (by default will create the 'ollama' volume)." + echo " --playwright Enable Playwright support for web scraping." + echo " --build Build the docker image before running the compose project." + echo " --drop Drop the compose project." + echo " -q, --quiet Run script in headless mode." + echo " -h, --help Show this help message." + echo "" + echo "Examples:" + echo " $0 --drop" + echo " $0 --enable-gpu[count=1]" + echo " $0 --enable-gpu[count=all]" + echo " $0 --enable-api[port=11435]" + echo " $0 --enable-gpu[count=1] --enable-api[port=12345] --webui[port=3000]" + echo " $0 --enable-gpu[count=1] --enable-api[port=12345] --webui[port=3000] --data[folder=./ollama-data]" + echo " $0 --enable-gpu[count=1] --enable-api[port=12345] --webui[port=3000] --data[folder=./ollama-data] --build" + echo "" + echo "This script configures and runs a docker-compose setup with optional GPU support, API exposure, and web UI configuration." + echo "About the gpu to use, the script automatically detects it using the "lspci" command." + echo "In this case the gpu detected is: $(get_gpu_driver)" +} + +# Default values +gpu_count=1 +api_port=11435 +webui_port=3000 +headless=false +build_image=false +kill_compose=false +enable_playwright=false + +# Function to extract value from the parameter +extract_value() { + echo "$1" | sed -E 's/.*\[.*=(.*)\].*/\1/; t; s/.*//' +} + +# Parse arguments +while [[ $# -gt 0 ]]; do + key="$1" + + case $key in + --enable-gpu*) + enable_gpu=true + value=$(extract_value "$key") + gpu_count=${value:-1} + ;; + --enable-api*) + enable_api=true + value=$(extract_value "$key") + api_port=${value:-11435} + ;; + --webui*) + value=$(extract_value "$key") + webui_port=${value:-3000} + ;; + --data*) + value=$(extract_value "$key") + data_dir=${value:-"./ollama-data"} + ;; + --playwright) + enable_playwright=true + ;; + --drop) + kill_compose=true + ;; + --build) + build_image=true + ;; + -q|--quiet) + headless=true + ;; + -h|--help) + usage + exit + ;; + *) + # Unknown option + echo "Unknown option: $key" + usage + exit 1 + ;; + esac + shift # past argument or value +done + +if [[ $kill_compose == true ]]; then + docker compose down --remove-orphans + echo -e "${GREEN}${BOLD}Compose project dropped successfully.${NC}" + exit +else + DEFAULT_COMPOSE_COMMAND="docker compose -f docker-compose.yaml" + if [[ $enable_gpu == true ]]; then + # Validate and process command-line arguments + if [[ -n $gpu_count ]]; then + if ! [[ $gpu_count =~ ^([0-9]+|all)$ ]]; then + echo "Invalid GPU count: $gpu_count" + exit 1 + fi + echo "Enabling GPU with $gpu_count GPUs" + # Add your GPU allocation logic here + export OLLAMA_GPU_DRIVER=$(get_gpu_driver) + export OLLAMA_GPU_COUNT=$gpu_count # Set OLLAMA_GPU_COUNT environment variable + fi + DEFAULT_COMPOSE_COMMAND+=" -f docker-compose.gpu.yaml" + fi + if [[ $enable_api == true ]]; then + DEFAULT_COMPOSE_COMMAND+=" -f docker-compose.api.yaml" + if [[ -n $api_port ]]; then + export OLLAMA_WEBAPI_PORT=$api_port # Set OLLAMA_WEBAPI_PORT environment variable + fi + fi + if [[ -n $data_dir ]]; then + DEFAULT_COMPOSE_COMMAND+=" -f docker-compose.data.yaml" + export OLLAMA_DATA_DIR=$data_dir # Set OLLAMA_DATA_DIR environment variable + fi + if [[ $enable_playwright == true ]]; then + DEFAULT_COMPOSE_COMMAND+=" -f docker-compose.playwright.yaml" + fi + if [[ -n $webui_port ]]; then + export OPEN_WEBUI_PORT=$webui_port # Set OPEN_WEBUI_PORT environment variable + fi + DEFAULT_COMPOSE_COMMAND+=" up -d" + DEFAULT_COMPOSE_COMMAND+=" --remove-orphans" + DEFAULT_COMPOSE_COMMAND+=" --force-recreate" + if [[ $build_image == true ]]; then + DEFAULT_COMPOSE_COMMAND+=" --build" + fi +fi + +# Recap of environment variables +echo +echo -e "${WHITE}${BOLD}Current Setup:${NC}" +echo -e " ${GREEN}${BOLD}GPU Driver:${NC} ${OLLAMA_GPU_DRIVER:-Not Enabled}" +echo -e " ${GREEN}${BOLD}GPU Count:${NC} ${OLLAMA_GPU_COUNT:-Not Enabled}" +echo -e " ${GREEN}${BOLD}WebAPI Port:${NC} ${OLLAMA_WEBAPI_PORT:-Not Enabled}" +echo -e " ${GREEN}${BOLD}Data Folder:${NC} ${data_dir:-Using ollama volume}" +echo -e " ${GREEN}${BOLD}WebUI Port:${NC} $webui_port" +echo -e " ${GREEN}${BOLD}Playwright:${NC} ${enable_playwright:-false}" +echo + +if [[ $headless == true ]]; then + echo -ne "${WHITE}${BOLD}Running in headless mode... ${NC}" + choice="y" +else + # Ask for user acceptance + echo -ne "${WHITE}${BOLD}Do you want to proceed with current setup? (Y/n): ${NC}" + read -n1 -s choice +fi + +echo + +if [[ $choice == "" || $choice == "y" ]]; then + # Execute the command with the current user + eval "$DEFAULT_COMPOSE_COMMAND" & + + # Capture the background process PID + PID=$! + + # Display the loading animation + #show_loading $PID + + # Wait for the command to finish + wait $PID + + echo + # Check exit status + if [ $? -eq 0 ]; then + echo -e "${GREEN}${BOLD}Compose project started successfully.${NC}" + else + echo -e "${RED}${BOLD}There was an error starting the compose project.${NC}" + fi +else + echo "Aborted." +fi + +echo diff --git a/run-ollama-docker.sh b/run-ollama-docker.sh new file mode 100644 index 0000000..c2a025b --- /dev/null +++ b/run-ollama-docker.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +host_port=11434 +container_port=11434 + +read -r -p "Do you want ollama in Docker with GPU support? (y/n): " use_gpu + +docker rm -f ollama || true +docker pull ollama/ollama:latest + +docker_args="-d -v ollama:/root/.ollama -p $host_port:$container_port --name ollama ollama/ollama" + +if [ "$use_gpu" = "y" ]; then + docker_args="--gpus=all $docker_args" +fi + +docker run $docker_args + +docker image prune -f \ No newline at end of file diff --git a/run.sh b/run.sh new file mode 100644 index 0000000..6793fe1 --- /dev/null +++ b/run.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +image_name="open-webui" +container_name="open-webui" +host_port=3000 +container_port=8080 + +docker build -t "$image_name" . +docker stop "$container_name" &>/dev/null || true +docker rm "$container_name" &>/dev/null || true + +docker run -d -p "$host_port":"$container_port" \ + --add-host=host.docker.internal:host-gateway \ + -v "${image_name}:/app/backend/data" \ + --name "$container_name" \ + --restart always \ + "$image_name" + +docker image prune -f diff --git a/scripts/prepare-pyodide.js b/scripts/prepare-pyodide.js new file mode 100644 index 0000000..70f3cf5 --- /dev/null +++ b/scripts/prepare-pyodide.js @@ -0,0 +1,120 @@ +const packages = [ + 'micropip', + 'packaging', + 'requests', + 'beautifulsoup4', + 'numpy', + 'pandas', + 'matplotlib', + 'scikit-learn', + 'scipy', + 'regex', + 'sympy', + 'tiktoken', + 'seaborn', + 'pytz' +]; + +import { loadPyodide } from 'pyodide'; +import { setGlobalDispatcher, ProxyAgent } from 'undici'; +import { writeFile, readFile, copyFile, readdir, rmdir } from 'fs/promises'; + +/** + * Loading network proxy configurations from the environment variables. + * And the proxy config with lowercase name has the highest priority to use. + */ +function initNetworkProxyFromEnv() { + // we assume all subsequent requests in this script are HTTPS: + // https://cdn.jsdelivr.net + // https://pypi.org + // https://files.pythonhosted.org + const allProxy = process.env.all_proxy || process.env.ALL_PROXY; + const httpsProxy = process.env.https_proxy || process.env.HTTPS_PROXY; + const httpProxy = process.env.http_proxy || process.env.HTTP_PROXY; + const preferedProxy = httpsProxy || allProxy || httpProxy; + /** + * use only http(s) proxy because socks5 proxy is not supported currently: + * @see https://github.com/nodejs/undici/issues/2224 + */ + if (!preferedProxy || !preferedProxy.startsWith('http')) return; + let preferedProxyURL; + try { + preferedProxyURL = new URL(preferedProxy).toString(); + } catch { + console.warn(`Invalid network proxy URL: "${preferedProxy}"`); + return; + } + const dispatcher = new ProxyAgent({ uri: preferedProxyURL }); + setGlobalDispatcher(dispatcher); + console.log(`Initialized network proxy "${preferedProxy}" from env`); +} + +async function downloadPackages() { + console.log('Setting up pyodide + micropip'); + + let pyodide; + try { + pyodide = await loadPyodide({ + packageCacheDir: 'static/pyodide' + }); + } catch (err) { + console.error('Failed to load Pyodide:', err); + return; + } + + const packageJson = JSON.parse(await readFile('package.json')); + const pyodideVersion = packageJson.dependencies.pyodide.replace('^', ''); + + try { + const pyodidePackageJson = JSON.parse(await readFile('static/pyodide/package.json')); + const pyodidePackageVersion = pyodidePackageJson.version.replace('^', ''); + + if (pyodideVersion !== pyodidePackageVersion) { + console.log('Pyodide version mismatch, removing static/pyodide directory'); + await rmdir('static/pyodide', { recursive: true }); + } + } catch (e) { + console.log('Pyodide package not found, proceeding with download.'); + } + + try { + console.log('Loading micropip package'); + await pyodide.loadPackage('micropip'); + + const micropip = pyodide.pyimport('micropip'); + console.log('Downloading Pyodide packages:', packages); + + try { + for (const pkg of packages) { + console.log(`Installing package: ${pkg}`); + await micropip.install(pkg); + } + } catch (err) { + console.error('Package installation failed:', err); + return; + } + + console.log('Pyodide packages downloaded, freezing into lock file'); + + try { + const lockFile = await micropip.freeze(); + await writeFile('static/pyodide/pyodide-lock.json', lockFile); + } catch (err) { + console.error('Failed to write lock file:', err); + } + } catch (err) { + console.error('Failed to load or install micropip:', err); + } +} + +async function copyPyodide() { + console.log('Copying Pyodide files into static directory'); + // Copy all files from node_modules/pyodide to static/pyodide + for await (const entry of await readdir('node_modules/pyodide')) { + await copyFile(`node_modules/pyodide/${entry}`, `static/pyodide/${entry}`); + } +} + +initNetworkProxyFromEnv(); +await downloadPackages(); +await copyPyodide(); diff --git a/src/app.css b/src/app.css new file mode 100644 index 0000000..8bdc6f1 --- /dev/null +++ b/src/app.css @@ -0,0 +1,374 @@ +@reference "./tailwind.css"; + +@font-face { + font-family: 'Inter'; + src: url('/assets/fonts/Inter-Variable.ttf'); + font-display: swap; +} + +@font-face { + font-family: 'Archivo'; + src: url('/assets/fonts/Archivo-Variable.ttf'); + font-display: swap; +} + +@font-face { + font-family: 'Mona Sans'; + src: url('/assets/fonts/Mona-Sans.woff2'); + font-display: swap; +} + +@font-face { + font-family: 'InstrumentSerif'; + src: url('/assets/fonts/InstrumentSerif-Regular.ttf'); + font-display: swap; +} + +html { + word-break: break-word; +} + +code { + /* white-space-collapse: preserve !important; */ + overflow-x: auto; + width: auto; +} + +.font-secondary { + font-family: 'InstrumentSerif', sans-serif; +} + +math { + margin-top: 1rem; +} + +.hljs { + @apply rounded-lg; +} + +.input-prose { + @apply prose dark:prose-invert prose-headings:font-semibold prose-hr:my-4 prose-hr:border-gray-100 prose-hr:dark:border-gray-800 prose-p:my-0 prose-img:my-1 prose-headings:my-1 prose-pre:my-0 prose-table:my-0 prose-blockquote:my-0 prose-ul:-my-0 prose-ol:-my-0 prose-li:-my-0 whitespace-pre-line; +} + +.input-prose-sm { + @apply prose dark:prose-invert prose-headings:font-semibold prose-hr:my-4 prose-hr:border-gray-100 prose-hr:dark:border-gray-800 prose-p:my-0 prose-img:my-1 prose-headings:my-1 prose-pre:my-0 prose-table:my-0 prose-blockquote:my-0 prose-ul:-my-0 prose-ol:-my-0 prose-li:-my-0 whitespace-pre-line text-sm; +} + +.markdown-prose { + @apply prose dark:prose-invert prose-blockquote:border-s-gray-100 prose-blockquote:dark:border-gray-800 prose-blockquote:border-s-2 prose-blockquote:not-italic prose-blockquote:font-normal prose-headings:font-semibold prose-hr:my-4 prose-hr:border-gray-100 prose-hr:dark:border-gray-800 prose-p:my-0 prose-img:my-1 prose-headings:my-1 prose-pre:my-0 prose-table:my-0 prose-blockquote:my-0 prose-ul:-my-0 prose-ol:-my-0 prose-li:-my-0 whitespace-pre-line; +} + +.markdown-prose-xs { + @apply text-xs prose dark:prose-invert prose-blockquote:border-s-gray-100 prose-blockquote:dark:border-gray-800 prose-blockquote:border-s-2 prose-blockquote:not-italic prose-blockquote:font-normal prose-headings:font-semibold prose-hr:my-0 prose-hr:border-gray-100 prose-hr:dark:border-gray-800 prose-p:my-0 prose-img:my-1 prose-headings:my-1 prose-pre:my-0 prose-table:my-0 prose-blockquote:my-0 prose-ul:-my-0 prose-ol:-my-0 prose-li:-my-0 whitespace-pre-line; +} + +.markdown a { + @apply underline; +} + +.font-primary { + font-family: 'Archivo', sans-serif; +} + +.drag-region { + -webkit-app-region: drag; +} + +.drag-region a, +.drag-region button { + -webkit-app-region: no-drag; +} + +.no-drag-region { + -webkit-app-region: no-drag; +} + +iframe { + @apply rounded-lg; +} + +li p { + display: inline; +} + +::-webkit-scrollbar-thumb { + --tw-border-opacity: 1; + background-color: rgba(236, 236, 236, 0.8); + border-color: rgba(255, 255, 255, var(--tw-border-opacity)); + border-radius: 9999px; + border-width: 1px; +} + +/* Dark theme scrollbar styles */ +.dark ::-webkit-scrollbar-thumb { + background-color: rgba(42, 42, 42, 0.8); /* Darker color for dark theme */ + border-color: rgba(0, 0, 0, var(--tw-border-opacity)); +} + +::-webkit-scrollbar { + height: 0.4rem; + width: 0.4rem; +} + +::-webkit-scrollbar-track { + background-color: transparent; + border-radius: 9999px; +} + +select { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3E%3Cpath stroke='%236B7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m6 8 4 4 4-4'/%3E%3C/svg%3E"); + background-position: right 0rem center; + background-repeat: no-repeat; + background-size: 1.5em 1.5em; + -webkit-print-color-adjust: exact; + print-color-adjust: exact; + /* padding-right: 2.5rem; */ + /* for Firefox */ + -moz-appearance: none; + /* for Chrome */ + -webkit-appearance: none; +} + +@keyframes shimmer { + 0% { + background-position: 200% 0; + } + 100% { + background-position: -200% 0; + } +} + +.shimmer { + background: linear-gradient(90deg, #9a9b9e 25%, #2a2929 50%, #9a9b9e 75%); + background-size: 200% 100%; + background-clip: text; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + animation: shimmer 4s linear infinite; + color: #818286; /* Fallback color */ +} + +:global(.dark) .shimmer { + background: linear-gradient(90deg, #818286 25%, #eae5e5 50%, #818286 75%); + background-size: 200% 100%; + background-clip: text; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + animation: shimmer 4s linear infinite; + color: #a1a3a7; /* Darker fallback color for dark mode */ +} + +@keyframes smoothFadeIn { + 0% { + opacity: 0; + transform: translateY(-10px); + } + 100% { + opacity: 1; + transform: translateY(0); + } +} + +.status-description { + animation: smoothFadeIn 0.2s forwards; +} + +.katex-mathml { + display: none; +} + +.scrollbar-hidden:active::-webkit-scrollbar-thumb, +.scrollbar-hidden:focus::-webkit-scrollbar-thumb, +.scrollbar-hidden:hover::-webkit-scrollbar-thumb { + visibility: visible; +} +.scrollbar-hidden::-webkit-scrollbar-thumb { + visibility: hidden; +} + +.scrollbar-hidden::-webkit-scrollbar-corner { + display: none; +} + +.scrollbar-none::-webkit-scrollbar { + display: none; /* for Chrome, Safari and Opera */ +} + +.scrollbar-none::-webkit-scrollbar-corner { + display: none; +} + +.scrollbar-none { + -ms-overflow-style: none; /* IE and Edge */ + scrollbar-width: none; /* Firefox */ +} + +input::-webkit-outer-spin-button, +input::-webkit-inner-spin-button { + /* display: none; <- Crashes Chrome on hover */ + -webkit-appearance: none; + margin: 0; /* <-- Apparently some margin are still there even though it's hidden */ +} + +input[type='number'] { + -moz-appearance: textfield; /* Firefox */ +} + +.cm-editor { + height: 100%; + width: 100%; +} + +.cm-scroller:active::-webkit-scrollbar-thumb, +.cm-scroller:focus::-webkit-scrollbar-thumb, +.cm-scroller:hover::-webkit-scrollbar-thumb { + visibility: visible; +} + +.cm-scroller::-webkit-scrollbar-thumb { + visibility: hidden; +} + +.cm-scroller::-webkit-scrollbar-corner { + display: none; +} + +.cm-editor.cm-focused { + outline: none; +} + +.tippy-box[data-theme~='dark'] { + @apply rounded-lg bg-gray-950 text-xs border border-gray-900 shadow-xl; +} + +.password { + -webkit-text-security: disc; +} + +.codespan { + color: #eb5757; + border-width: 0px; + padding: 3px 8px; + font-size: 0.8em; + font-weight: 600; + @apply rounded-md dark:bg-gray-800 bg-gray-100 mx-0.5; +} + +.svelte-flow { + background-color: transparent !important; +} + +.svelte-flow__edge > path { + stroke-width: 0.5; +} + +.svelte-flow__edge.animated > path { + stroke-width: 2; + @apply stroke-gray-600 dark:stroke-gray-500; +} + +.bg-gray-950-90 { + background-color: rgba(var(--color-gray-950, #0d0d0d), 0.9); +} + +.ProseMirror { + @apply h-full min-h-fit max-h-full whitespace-pre-wrap; +} + +.ProseMirror:focus { + outline: none; +} + +.ProseMirror p.is-editor-empty:first-child::before { + content: attr(data-placeholder); + float: left; + color: #adb5bd; + pointer-events: none; + + @apply line-clamp-1 absolute; +} + +.ai-autocompletion::after { + color: #a0a0a0; + + content: attr(data-suggestion); + pointer-events: none; +} + +.tiptap > pre > code { + border-radius: 0.4rem; + font-size: 0.85rem; + padding: 0.25em 0.3em; + + @apply dark:bg-gray-800 bg-gray-100; +} + +.tiptap > pre { + border-radius: 0.5rem; + font-family: 'JetBrainsMono', monospace; + margin: 1.5rem 0; + padding: 0.75rem 1rem; + + @apply dark:bg-gray-800 bg-gray-100; +} + +.tiptap p code { + color: #eb5757; + border-width: 0px; + padding: 3px 8px; + font-size: 0.8em; + font-weight: 600; + @apply rounded-md dark:bg-gray-800 bg-gray-100 mx-0.5; +} + +/* Code styling */ +.hljs-comment, +.hljs-quote { + color: #616161; +} + +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-tag, +.hljs-regexp, +.hljs-link, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #f98181; +} + +.hljs-number, +.hljs-meta, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params { + color: #fbbc88; +} + +.hljs-string, +.hljs-symbol, +.hljs-bullet { + color: #b9f18d; +} + +.hljs-title, +.hljs-section { + color: #faf594; +} + +.hljs-keyword, +.hljs-selector-tag { + color: #70cff8; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: 700; +} diff --git a/src/app.d.ts b/src/app.d.ts new file mode 100644 index 0000000..f59b884 --- /dev/null +++ b/src/app.d.ts @@ -0,0 +1,12 @@ +// See https://kit.svelte.dev/docs/types#app +// for information about these interfaces +declare global { + namespace App { + // interface Error {} + // interface Locals {} + // interface PageData {} + // interface Platform {} + } +} + +export {}; diff --git a/src/app.html b/src/app.html new file mode 100644 index 0000000..c8fbfca --- /dev/null +++ b/src/app.html @@ -0,0 +1,235 @@ + + + + + + + + + + + + + + + + + + + + + + Open WebUI + + %sveltekit.head% + + + +
        %sveltekit.body%
        + +
        + + + + +
        + + +
        +
        + +
        +
        +
        + + +
        + + + + diff --git a/src/lib/apis/audio/index.ts b/src/lib/apis/audio/index.ts new file mode 100644 index 0000000..5cd6ab9 --- /dev/null +++ b/src/lib/apis/audio/index.ts @@ -0,0 +1,193 @@ +import { AUDIO_API_BASE_URL } from '$lib/constants'; + +export const getAudioConfig = async (token: string) => { + let error = null; + + const res = await fetch(`${AUDIO_API_BASE_URL}/config`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +type OpenAIConfigForm = { + url: string; + key: string; + model: string; + speaker: string; +}; + +export const updateAudioConfig = async (token: string, payload: OpenAIConfigForm) => { + let error = null; + + const res = await fetch(`${AUDIO_API_BASE_URL}/config/update`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + ...payload + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const transcribeAudio = async (token: string, file: File) => { + const data = new FormData(); + data.append('file', file); + + let error = null; + const res = await fetch(`${AUDIO_API_BASE_URL}/transcriptions`, { + method: 'POST', + headers: { + Accept: 'application/json', + authorization: `Bearer ${token}` + }, + body: data + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const synthesizeOpenAISpeech = async ( + token: string = '', + speaker: string = 'alloy', + text: string = '', + model?: string +) => { + let error = null; + + const res = await fetch(`${AUDIO_API_BASE_URL}/speech`, { + method: 'POST', + headers: { + Authorization: `Bearer ${token}`, + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + input: text, + voice: speaker, + ...(model && { model }) + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res; + }) + .catch((err) => { + error = err.detail; + console.log(err); + + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +interface AvailableModelsResponse { + models: { name: string; id: string }[] | { id: string }[]; +} + +export const getModels = async (token: string = ''): Promise => { + let error = null; + + const res = await fetch(`${AUDIO_API_BASE_URL}/models`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + console.log(err); + + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getVoices = async (token: string = '') => { + let error = null; + + const res = await fetch(`${AUDIO_API_BASE_URL}/voices`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + console.log(err); + + return null; + }); + + if (error) { + throw error; + } + + return res; +}; diff --git a/src/lib/apis/auths/index.ts b/src/lib/apis/auths/index.ts new file mode 100644 index 0000000..40caebf --- /dev/null +++ b/src/lib/apis/auths/index.ts @@ -0,0 +1,694 @@ +import { WEBUI_API_BASE_URL } from '$lib/constants'; + +export const getAdminDetails = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/auths/admin/details`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getAdminConfig = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/auths/admin/config`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateAdminConfig = async (token: string, body: object) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/auths/admin/config`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify(body) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getSessionUser = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/auths/`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + credentials: 'include' + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const ldapUserSignIn = async (user: string, password: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/auths/ldap`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + credentials: 'include', + body: JSON.stringify({ + user: user, + password: password + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getLdapConfig = async (token: string = '') => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/auths/admin/config/ldap`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateLdapConfig = async (token: string = '', enable_ldap: boolean) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/auths/admin/config/ldap`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + }, + body: JSON.stringify({ + enable_ldap: enable_ldap + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getLdapServer = async (token: string = '') => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/auths/admin/config/ldap/server`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateLdapServer = async (token: string = '', body: object) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/auths/admin/config/ldap/server`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + }, + body: JSON.stringify(body) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const userSignIn = async (email: string, password: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/auths/signin`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + credentials: 'include', + body: JSON.stringify({ + email: email, + password: password + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const userSignUp = async ( + name: string, + email: string, + password: string, + profile_image_url: string +) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/auths/signup`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + credentials: 'include', + body: JSON.stringify({ + name: name, + email: email, + password: password, + profile_image_url: profile_image_url + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const userSignOut = async () => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/auths/signout`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json' + }, + credentials: 'include' + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res; + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } +}; + +export const addUser = async ( + token: string, + name: string, + email: string, + password: string, + role: string = 'pending' +) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/auths/add`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + }, + body: JSON.stringify({ + name: name, + email: email, + password: password, + role: role + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateUserProfile = async (token: string, name: string, profileImageUrl: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/auths/update/profile`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + }, + body: JSON.stringify({ + name: name, + profile_image_url: profileImageUrl + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateUserPassword = async (token: string, password: string, newPassword: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/auths/update/password`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + }, + body: JSON.stringify({ + password: password, + new_password: newPassword + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getSignUpEnabledStatus = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/auths/signup/enabled`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getDefaultUserRole = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/auths/signup/user/role`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateDefaultUserRole = async (token: string, role: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/auths/signup/user/role`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + role: role + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const toggleSignUpEnabledStatus = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/auths/signup/enabled/toggle`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getJWTExpiresDuration = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/auths/token/expires`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateJWTExpiresDuration = async (token: string, duration: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/auths/token/expires/update`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + duration: duration + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const createAPIKey = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/auths/api_key`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + if (error) { + throw error; + } + return res.api_key; +}; + +export const getAPIKey = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/auths/api_key`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + if (error) { + throw error; + } + return res.api_key; +}; + +export const deleteAPIKey = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/auths/api_key`, { + method: 'DELETE', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + if (error) { + throw error; + } + return res; +}; diff --git a/src/lib/apis/channels/index.ts b/src/lib/apis/channels/index.ts new file mode 100644 index 0000000..f16b435 --- /dev/null +++ b/src/lib/apis/channels/index.ts @@ -0,0 +1,442 @@ +import { WEBUI_API_BASE_URL } from '$lib/constants'; +import { t } from 'i18next'; + +type ChannelForm = { + name: string; + data?: object; + meta?: object; + access_control?: object; +}; + +export const createNewChannel = async (token: string = '', channel: ChannelForm) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/channels/create`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ ...channel }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getChannels = async (token: string = '') => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/channels/`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getChannelById = async (token: string = '', channel_id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/channels/${channel_id}`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateChannelById = async ( + token: string = '', + channel_id: string, + channel: ChannelForm +) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/channels/${channel_id}/update`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ ...channel }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const deleteChannelById = async (token: string = '', channel_id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/channels/${channel_id}/delete`, { + method: 'DELETE', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getChannelMessages = async ( + token: string = '', + channel_id: string, + skip: number = 0, + limit: number = 50 +) => { + let error = null; + + const res = await fetch( + `${WEBUI_API_BASE_URL}/channels/${channel_id}/messages?skip=${skip}&limit=${limit}`, + { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + } + ) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getChannelThreadMessages = async ( + token: string = '', + channel_id: string, + message_id: string, + skip: number = 0, + limit: number = 50 +) => { + let error = null; + + const res = await fetch( + `${WEBUI_API_BASE_URL}/channels/${channel_id}/messages/${message_id}/thread?skip=${skip}&limit=${limit}`, + { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + } + ) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +type MessageForm = { + parent_id?: string; + content: string; + data?: object; + meta?: object; +}; + +export const sendMessage = async (token: string = '', channel_id: string, message: MessageForm) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/channels/${channel_id}/messages/post`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ ...message }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateMessage = async ( + token: string = '', + channel_id: string, + message_id: string, + message: MessageForm +) => { + let error = null; + + const res = await fetch( + `${WEBUI_API_BASE_URL}/channels/${channel_id}/messages/${message_id}/update`, + { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ ...message }) + } + ) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const addReaction = async ( + token: string = '', + channel_id: string, + message_id: string, + name: string +) => { + let error = null; + + const res = await fetch( + `${WEBUI_API_BASE_URL}/channels/${channel_id}/messages/${message_id}/reactions/add`, + { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ name }) + } + ) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const removeReaction = async ( + token: string = '', + channel_id: string, + message_id: string, + name: string +) => { + let error = null; + + const res = await fetch( + `${WEBUI_API_BASE_URL}/channels/${channel_id}/messages/${message_id}/reactions/remove`, + { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ name }) + } + ) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const deleteMessage = async (token: string = '', channel_id: string, message_id: string) => { + let error = null; + + const res = await fetch( + `${WEBUI_API_BASE_URL}/channels/${channel_id}/messages/${message_id}/delete`, + { + method: 'DELETE', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + } + ) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; diff --git a/src/lib/apis/chats/index.ts b/src/lib/apis/chats/index.ts new file mode 100644 index 0000000..02bdd4e --- /dev/null +++ b/src/lib/apis/chats/index.ts @@ -0,0 +1,1054 @@ +import { WEBUI_API_BASE_URL } from '$lib/constants'; +import { getTimeRange } from '$lib/utils'; + +export const createNewChat = async (token: string, chat: object) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/new`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + chat: chat + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const importChat = async ( + token: string, + chat: object, + meta: object | null, + pinned?: boolean, + folderId?: string | null +) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/import`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + chat: chat, + meta: meta ?? {}, + pinned: pinned, + folder_id: folderId + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getChatList = async (token: string = '', page: number | null = null) => { + let error = null; + const searchParams = new URLSearchParams(); + + if (page !== null) { + searchParams.append('page', `${page}`); + } + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/?${searchParams.toString()}`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res.map((chat) => ({ + ...chat, + time_range: getTimeRange(chat.updated_at) + })); +}; + +export const getChatListByUserId = async (token: string = '', userId: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/list/user/${userId}`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res.map((chat) => ({ + ...chat, + time_range: getTimeRange(chat.updated_at) + })); +}; + +export const getArchivedChatList = async (token: string = '') => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/archived`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getAllChats = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/all`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getChatListBySearchText = async (token: string, text: string, page: number = 1) => { + let error = null; + + const searchParams = new URLSearchParams(); + searchParams.append('text', text); + searchParams.append('page', `${page}`); + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/search?${searchParams.toString()}`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res.map((chat) => ({ + ...chat, + time_range: getTimeRange(chat.updated_at) + })); +}; + +export const getChatsByFolderId = async (token: string, folderId: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/folder/${folderId}`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getAllArchivedChats = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/all/archived`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getAllUserChats = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/all/db`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getAllTags = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/all/tags`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getPinnedChatList = async (token: string = '') => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/pinned`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res.map((chat) => ({ + ...chat, + time_range: getTimeRange(chat.updated_at) + })); +}; + +export const getChatListByTagName = async (token: string = '', tagName: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/tags`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + }, + body: JSON.stringify({ + name: tagName + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res.map((chat) => ({ + ...chat, + time_range: getTimeRange(chat.updated_at) + })); +}; + +export const getChatById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/${id}`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getChatByShareId = async (token: string, share_id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/share/${share_id}`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getChatPinnedStatusById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/${id}/pinned`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + + if ('detail' in err) { + error = err.detail; + } else { + error = err; + } + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const toggleChatPinnedStatusById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/${id}/pin`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + + if ('detail' in err) { + error = err.detail; + } else { + error = err; + } + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const cloneChatById = async (token: string, id: string, title?: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/${id}/clone`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + }, + body: JSON.stringify({ + ...(title && { title: title }) + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + + if ('detail' in err) { + error = err.detail; + } else { + error = err; + } + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const cloneSharedChatById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/${id}/clone/shared`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + + if ('detail' in err) { + error = err.detail; + } else { + error = err; + } + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const shareChatById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/${id}/share`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateChatFolderIdById = async (token: string, id: string, folderId?: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/${id}/folder`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + }, + body: JSON.stringify({ + folder_id: folderId + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const archiveChatById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/${id}/archive`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const deleteSharedChatById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/${id}/share`, { + method: 'DELETE', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateChatById = async (token: string, id: string, chat: object) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/${id}`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + }, + body: JSON.stringify({ + chat: chat + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const deleteChatById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/${id}`, { + method: 'DELETE', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getTagsById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/${id}/tags`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const addTagById = async (token: string, id: string, tagName: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/${id}/tags`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + }, + body: JSON.stringify({ + name: tagName + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const deleteTagById = async (token: string, id: string, tagName: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/${id}/tags`, { + method: 'DELETE', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + }, + body: JSON.stringify({ + name: tagName + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; +export const deleteTagsById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/${id}/tags/all`, { + method: 'DELETE', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const deleteAllChats = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/`, { + method: 'DELETE', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const archiveAllChats = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/chats/archive/all`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; diff --git a/src/lib/apis/configs/index.ts b/src/lib/apis/configs/index.ts new file mode 100644 index 0000000..f7f02c7 --- /dev/null +++ b/src/lib/apis/configs/index.ts @@ -0,0 +1,317 @@ +import { WEBUI_API_BASE_URL } from '$lib/constants'; +import type { Banner } from '$lib/types'; + +export const importConfig = async (token: string, config) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/configs/import`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + config: config + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const exportConfig = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/configs/export`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getDirectConnectionsConfig = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/configs/direct_connections`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const setDirectConnectionsConfig = async (token: string, config: object) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/configs/direct_connections`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + ...config + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getCodeExecutionConfig = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/configs/code_execution`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const setCodeExecutionConfig = async (token: string, config: object) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/configs/code_execution`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + ...config + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getModelsConfig = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/configs/models`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const setModelsConfig = async (token: string, config: object) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/configs/models`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + ...config + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const setDefaultPromptSuggestions = async (token: string, promptSuggestions: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/configs/suggestions`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + suggestions: promptSuggestions + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getBanners = async (token: string): Promise => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/configs/banners`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const setBanners = async (token: string, banners: Banner[]) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/configs/banners`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + banners: banners + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; diff --git a/src/lib/apis/evaluations/index.ts b/src/lib/apis/evaluations/index.ts new file mode 100644 index 0000000..f6f35f7 --- /dev/null +++ b/src/lib/apis/evaluations/index.ts @@ -0,0 +1,246 @@ +import { WEBUI_API_BASE_URL } from '$lib/constants'; + +export const getConfig = async (token: string = '') => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/evaluations/config`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateConfig = async (token: string, config: object) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/evaluations/config`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + ...config + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getAllFeedbacks = async (token: string = '') => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/evaluations/feedbacks/all`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const exportAllFeedbacks = async (token: string = '') => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/evaluations/feedbacks/all/export`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const createNewFeedback = async (token: string, feedback: object) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/evaluations/feedback`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + ...feedback + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getFeedbackById = async (token: string, feedbackId: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/evaluations/feedback/${feedbackId}`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateFeedbackById = async (token: string, feedbackId: string, feedback: object) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/evaluations/feedback/${feedbackId}`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + ...feedback + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const deleteFeedbackById = async (token: string, feedbackId: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/evaluations/feedback/${feedbackId}`, { + method: 'DELETE', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; diff --git a/src/lib/apis/files/index.ts b/src/lib/apis/files/index.ts new file mode 100644 index 0000000..6a42ec6 --- /dev/null +++ b/src/lib/apis/files/index.ts @@ -0,0 +1,243 @@ +import { WEBUI_API_BASE_URL } from '$lib/constants'; + +export const uploadFile = async (token: string, file: File) => { + const data = new FormData(); + data.append('file', file); + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/files/`, { + method: 'POST', + headers: { + Accept: 'application/json', + authorization: `Bearer ${token}` + }, + body: data + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const uploadDir = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/files/upload/dir`, { + method: 'POST', + headers: { + Accept: 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getFiles = async (token: string = '') => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/files/`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getFileById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/files/${id}`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateFileDataContentById = async (token: string, id: string, content: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/files/${id}/data/content/update`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + content: content + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getFileContentById = async (id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/files/${id}/content`, { + method: 'GET', + headers: { + Accept: 'application/json' + }, + credentials: 'include' + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return await res.blob(); + }) + .catch((err) => { + error = err.detail; + console.log(err); + + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const deleteFileById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/files/${id}`, { + method: 'DELETE', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const deleteAllFiles = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/files/all`, { + method: 'DELETE', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; diff --git a/src/lib/apis/folders/index.ts b/src/lib/apis/folders/index.ts new file mode 100644 index 0000000..f1a1f5b --- /dev/null +++ b/src/lib/apis/folders/index.ts @@ -0,0 +1,269 @@ +import { WEBUI_API_BASE_URL } from '$lib/constants'; + +export const createNewFolder = async (token: string, name: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/folders/`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + name: name + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getFolders = async (token: string = '') => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/folders/`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getFolderById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/folders/${id}`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateFolderNameById = async (token: string, id: string, name: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/folders/${id}/update`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + name: name + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateFolderIsExpandedById = async ( + token: string, + id: string, + isExpanded: boolean +) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/folders/${id}/update/expanded`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + is_expanded: isExpanded + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateFolderParentIdById = async (token: string, id: string, parentId?: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/folders/${id}/update/parent`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + parent_id: parentId + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +type FolderItems = { + chat_ids: string[]; + file_ids: string[]; +}; + +export const updateFolderItemsById = async (token: string, id: string, items: FolderItems) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/folders/${id}/update/items`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + items: items + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const deleteFolderById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/folders/${id}`, { + method: 'DELETE', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; diff --git a/src/lib/apis/functions/index.ts b/src/lib/apis/functions/index.ts new file mode 100644 index 0000000..ed3306b --- /dev/null +++ b/src/lib/apis/functions/index.ts @@ -0,0 +1,455 @@ +import { WEBUI_API_BASE_URL } from '$lib/constants'; + +export const createNewFunction = async (token: string, func: object) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/functions/create`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + ...func + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getFunctions = async (token: string = '') => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/functions/`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const exportFunctions = async (token: string = '') => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/functions/export`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getFunctionById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateFunctionById = async (token: string, id: string, func: object) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}/update`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + ...func + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const deleteFunctionById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}/delete`, { + method: 'DELETE', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const toggleFunctionById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}/toggle`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const toggleGlobalById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}/toggle/global`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getFunctionValvesById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}/valves`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getFunctionValvesSpecById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}/valves/spec`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateFunctionValvesById = async (token: string, id: string, valves: object) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}/valves/update`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + ...valves + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getUserValvesById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}/valves/user`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getUserValvesSpecById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}/valves/user/spec`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateUserValvesById = async (token: string, id: string, valves: object) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}/valves/user/update`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + ...valves + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; diff --git a/src/lib/apis/groups/index.ts b/src/lib/apis/groups/index.ts new file mode 100644 index 0000000..b7d4f8e --- /dev/null +++ b/src/lib/apis/groups/index.ts @@ -0,0 +1,162 @@ +import { WEBUI_API_BASE_URL } from '$lib/constants'; + +export const createNewGroup = async (token: string, group: object) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/groups/create`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + ...group + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getGroups = async (token: string = '') => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/groups/`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getGroupById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/groups/id/${id}`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateGroupById = async (token: string, id: string, group: object) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/groups/id/${id}/update`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + ...group + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const deleteGroupById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/groups/id/${id}/delete`, { + method: 'DELETE', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; diff --git a/src/lib/apis/images/index.ts b/src/lib/apis/images/index.ts new file mode 100644 index 0000000..2e65104 --- /dev/null +++ b/src/lib/apis/images/index.ts @@ -0,0 +1,232 @@ +import { IMAGES_API_BASE_URL } from '$lib/constants'; + +export const getConfig = async (token: string = '') => { + let error = null; + + const res = await fetch(`${IMAGES_API_BASE_URL}/config`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = 'Server connection failed'; + } + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateConfig = async (token: string = '', config: object) => { + let error = null; + + const res = await fetch(`${IMAGES_API_BASE_URL}/config/update`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + }, + body: JSON.stringify({ + ...config + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = 'Server connection failed'; + } + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const verifyConfigUrl = async (token: string = '') => { + let error = null; + + const res = await fetch(`${IMAGES_API_BASE_URL}/config/url/verify`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = 'Server connection failed'; + } + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getImageGenerationConfig = async (token: string = '') => { + let error = null; + + const res = await fetch(`${IMAGES_API_BASE_URL}/image/config`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = 'Server connection failed'; + } + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateImageGenerationConfig = async (token: string = '', config: object) => { + let error = null; + + const res = await fetch(`${IMAGES_API_BASE_URL}/image/config/update`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + }, + body: JSON.stringify({ ...config }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = 'Server connection failed'; + } + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getImageGenerationModels = async (token: string = '') => { + let error = null; + + const res = await fetch(`${IMAGES_API_BASE_URL}/models`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = 'Server connection failed'; + } + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const imageGenerations = async (token: string = '', prompt: string) => { + let error = null; + + const res = await fetch(`${IMAGES_API_BASE_URL}/generations`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + }, + body: JSON.stringify({ + prompt: prompt + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = 'Server connection failed'; + } + return null; + }); + + if (error) { + throw error; + } + + return res; +}; diff --git a/src/lib/apis/index.ts b/src/lib/apis/index.ts new file mode 100644 index 0000000..3fb4a5d --- /dev/null +++ b/src/lib/apis/index.ts @@ -0,0 +1,1266 @@ +import { WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants'; +import { getOpenAIModelsDirect } from './openai'; + +export const getModels = async ( + token: string = '', + connections: object | null = null, + base: boolean = false +) => { + let error = null; + const res = await fetch(`${WEBUI_BASE_URL}/api/models${base ? '/base' : ''}`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + let models = res?.data ?? []; + + if (connections && !base) { + let localModels = []; + + if (connections) { + const OPENAI_API_BASE_URLS = connections.OPENAI_API_BASE_URLS; + const OPENAI_API_KEYS = connections.OPENAI_API_KEYS; + const OPENAI_API_CONFIGS = connections.OPENAI_API_CONFIGS; + + const requests = []; + for (const idx in OPENAI_API_BASE_URLS) { + const url = OPENAI_API_BASE_URLS[idx]; + + if (idx.toString() in OPENAI_API_CONFIGS) { + const apiConfig = OPENAI_API_CONFIGS[idx.toString()] ?? {}; + + const enable = apiConfig?.enable ?? true; + const modelIds = apiConfig?.model_ids ?? []; + + if (enable) { + if (modelIds.length > 0) { + const modelList = { + object: 'list', + data: modelIds.map((modelId) => ({ + id: modelId, + name: modelId, + owned_by: 'openai', + openai: { id: modelId }, + urlIdx: idx + })) + }; + + requests.push( + (async () => { + return modelList; + })() + ); + } else { + requests.push( + (async () => { + return await getOpenAIModelsDirect(url, OPENAI_API_KEYS[idx]) + .then((res) => { + return res; + }) + .catch((err) => { + return { + object: 'list', + data: [], + urlIdx: idx + }; + }); + })() + ); + } + } else { + requests.push( + (async () => { + return { + object: 'list', + data: [], + urlIdx: idx + }; + })() + ); + } + } + } + + const responses = await Promise.all(requests); + + for (const idx in responses) { + const response = responses[idx]; + const apiConfig = OPENAI_API_CONFIGS[idx.toString()] ?? {}; + + let models = Array.isArray(response) ? response : (response?.data ?? []); + models = models.map((model) => ({ ...model, openai: { id: model.id }, urlIdx: idx })); + + const prefixId = apiConfig.prefix_id; + if (prefixId) { + for (const model of models) { + model.id = `${prefixId}.${model.id}`; + } + } + + localModels = localModels.concat(models); + } + } + + models = models.concat( + localModels.map((model) => ({ + ...model, + name: model?.name ?? model?.id, + direct: true + })) + ); + + // Remove duplicates + const modelsMap = {}; + for (const model of models) { + modelsMap[model.id] = model; + } + + models = Object.values(modelsMap); + } + + return models; +}; + +type ChatCompletedForm = { + model: string; + messages: string[]; + chat_id: string; + session_id: string; +}; + +export const chatCompleted = async (token: string, body: ChatCompletedForm) => { + let error = null; + + const res = await fetch(`${WEBUI_BASE_URL}/api/chat/completed`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + }, + body: JSON.stringify(body) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = err; + } + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +type ChatActionForm = { + model: string; + messages: string[]; + chat_id: string; +}; + +export const chatAction = async (token: string, action_id: string, body: ChatActionForm) => { + let error = null; + + const res = await fetch(`${WEBUI_BASE_URL}/api/chat/actions/${action_id}`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + }, + body: JSON.stringify(body) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = err; + } + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const stopTask = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_BASE_URL}/api/tasks/stop/${id}`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = err; + } + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getTaskConfig = async (token: string = '') => { + let error = null; + + const res = await fetch(`${WEBUI_BASE_URL}/api/v1/tasks/config`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateTaskConfig = async (token: string, config: object) => { + let error = null; + + const res = await fetch(`${WEBUI_BASE_URL}/api/v1/tasks/config/update`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + }, + body: JSON.stringify(config) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = err; + } + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const generateTitle = async ( + token: string = '', + model: string, + messages: string[], + chat_id?: string +) => { + let error = null; + + const res = await fetch(`${WEBUI_BASE_URL}/api/v1/tasks/title/completions`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + model: model, + messages: messages, + ...(chat_id && { chat_id: chat_id }) + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } + return null; + }); + + if (error) { + throw error; + } + + return res?.choices[0]?.message?.content.replace(/["']/g, '') ?? 'New Chat'; +}; + +export const generateTags = async ( + token: string = '', + model: string, + messages: string, + chat_id?: string +) => { + let error = null; + + const res = await fetch(`${WEBUI_BASE_URL}/api/v1/tasks/tags/completions`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + model: model, + messages: messages, + ...(chat_id && { chat_id: chat_id }) + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } + return null; + }); + + if (error) { + throw error; + } + + try { + // Step 1: Safely extract the response string + const response = res?.choices[0]?.message?.content ?? ''; + + // Step 2: Attempt to fix common JSON format issues like single quotes + const sanitizedResponse = response.replace(/['‘’`]/g, '"'); // Convert single quotes to double quotes for valid JSON + + // Step 3: Find the relevant JSON block within the response + const jsonStartIndex = sanitizedResponse.indexOf('{'); + const jsonEndIndex = sanitizedResponse.lastIndexOf('}'); + + // Step 4: Check if we found a valid JSON block (with both `{` and `}`) + if (jsonStartIndex !== -1 && jsonEndIndex !== -1) { + const jsonResponse = sanitizedResponse.substring(jsonStartIndex, jsonEndIndex + 1); + + // Step 5: Parse the JSON block + const parsed = JSON.parse(jsonResponse); + + // Step 6: If there's a "tags" key, return the tags array; otherwise, return an empty array + if (parsed && parsed.tags) { + return Array.isArray(parsed.tags) ? parsed.tags : []; + } else { + return []; + } + } + + // If no valid JSON block found, return an empty array + return []; + } catch (e) { + // Catch and safely return empty array on any parsing errors + console.error('Failed to parse response: ', e); + return []; + } +}; + +export const generateEmoji = async ( + token: string = '', + model: string, + prompt: string, + chat_id?: string +) => { + let error = null; + + const res = await fetch(`${WEBUI_BASE_URL}/api/v1/tasks/emoji/completions`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + model: model, + prompt: prompt, + ...(chat_id && { chat_id: chat_id }) + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } + return null; + }); + + if (error) { + throw error; + } + + const response = res?.choices[0]?.message?.content.replace(/["']/g, '') ?? null; + + if (response) { + if (/\p{Extended_Pictographic}/u.test(response)) { + return response.match(/\p{Extended_Pictographic}/gu)[0]; + } + } + + return null; +}; + +export const generateQueries = async ( + token: string = '', + model: string, + messages: object[], + prompt: string, + type?: string = 'web_search' +) => { + let error = null; + + const res = await fetch(`${WEBUI_BASE_URL}/api/v1/tasks/queries/completions`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + model: model, + messages: messages, + prompt: prompt, + type: type + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } + return null; + }); + + if (error) { + throw error; + } + + // Step 1: Safely extract the response string + const response = res?.choices[0]?.message?.content ?? ''; + + try { + const jsonStartIndex = response.indexOf('{'); + const jsonEndIndex = response.lastIndexOf('}'); + + if (jsonStartIndex !== -1 && jsonEndIndex !== -1) { + const jsonResponse = response.substring(jsonStartIndex, jsonEndIndex + 1); + + // Step 5: Parse the JSON block + const parsed = JSON.parse(jsonResponse); + + // Step 6: If there's a "queries" key, return the queries array; otherwise, return an empty array + if (parsed && parsed.queries) { + return Array.isArray(parsed.queries) ? parsed.queries : []; + } else { + return []; + } + } + + // If no valid JSON block found, return response as is + return [response]; + } catch (e) { + // Catch and safely return empty array on any parsing errors + console.error('Failed to parse response: ', e); + return [response]; + } +}; + +export const generateAutoCompletion = async ( + token: string = '', + model: string, + prompt: string, + messages?: object[], + type: string = 'search query' +) => { + const controller = new AbortController(); + let error = null; + + const res = await fetch(`${WEBUI_BASE_URL}/api/v1/tasks/auto/completions`, { + signal: controller.signal, + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + model: model, + prompt: prompt, + ...(messages && { messages: messages }), + type: type, + stream: false + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } + return null; + }); + + if (error) { + throw error; + } + + const response = res?.choices[0]?.message?.content ?? ''; + + try { + const jsonStartIndex = response.indexOf('{'); + const jsonEndIndex = response.lastIndexOf('}'); + + if (jsonStartIndex !== -1 && jsonEndIndex !== -1) { + const jsonResponse = response.substring(jsonStartIndex, jsonEndIndex + 1); + + // Step 5: Parse the JSON block + const parsed = JSON.parse(jsonResponse); + + // Step 6: If there's a "queries" key, return the queries array; otherwise, return an empty array + if (parsed && parsed.text) { + return parsed.text; + } else { + return ''; + } + } + + // If no valid JSON block found, return response as is + return response; + } catch (e) { + // Catch and safely return empty array on any parsing errors + console.error('Failed to parse response: ', e); + return response; + } +}; + +export const generateMoACompletion = async ( + token: string = '', + model: string, + prompt: string, + responses: string[] +) => { + const controller = new AbortController(); + let error = null; + + const res = await fetch(`${WEBUI_BASE_URL}/api/v1/tasks/moa/completions`, { + signal: controller.signal, + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + model: model, + prompt: prompt, + responses: responses, + stream: true + }) + }).catch((err) => { + console.log(err); + error = err; + return null; + }); + + if (error) { + throw error; + } + + return [res, controller]; +}; + +export const getPipelinesList = async (token: string = '') => { + let error = null; + + const res = await fetch(`${WEBUI_BASE_URL}/api/v1/pipelines/list`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err; + return null; + }); + + if (error) { + throw error; + } + + let pipelines = res?.data ?? []; + return pipelines; +}; + +export const uploadPipeline = async (token: string, file: File, urlIdx: string) => { + let error = null; + + // Create a new FormData object to handle the file upload + const formData = new FormData(); + formData.append('file', file); + formData.append('urlIdx', urlIdx); + + const res = await fetch(`${WEBUI_BASE_URL}/api/v1/pipelines/upload`, { + method: 'POST', + headers: { + ...(token && { authorization: `Bearer ${token}` }) + // 'Content-Type': 'multipart/form-data' is not needed as Fetch API will set it automatically + }, + body: formData + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = err; + } + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const downloadPipeline = async (token: string, url: string, urlIdx: string) => { + let error = null; + + const res = await fetch(`${WEBUI_BASE_URL}/api/v1/pipelines/add`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + }, + body: JSON.stringify({ + url: url, + urlIdx: urlIdx + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = err; + } + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const deletePipeline = async (token: string, id: string, urlIdx: string) => { + let error = null; + + const res = await fetch(`${WEBUI_BASE_URL}/api/v1/pipelines/delete`, { + method: 'DELETE', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + }, + body: JSON.stringify({ + id: id, + urlIdx: urlIdx + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = err; + } + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getPipelines = async (token: string, urlIdx?: string) => { + let error = null; + + const searchParams = new URLSearchParams(); + if (urlIdx !== undefined) { + searchParams.append('urlIdx', urlIdx); + } + + const res = await fetch(`${WEBUI_BASE_URL}/api/v1/pipelines/?${searchParams.toString()}`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err; + return null; + }); + + if (error) { + throw error; + } + + let pipelines = res?.data ?? []; + return pipelines; +}; + +export const getPipelineValves = async (token: string, pipeline_id: string, urlIdx: string) => { + let error = null; + + const searchParams = new URLSearchParams(); + if (urlIdx !== undefined) { + searchParams.append('urlIdx', urlIdx); + } + + const res = await fetch( + `${WEBUI_BASE_URL}/api/v1/pipelines/${pipeline_id}/valves?${searchParams.toString()}`, + { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + } + ) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getPipelineValvesSpec = async (token: string, pipeline_id: string, urlIdx: string) => { + let error = null; + + const searchParams = new URLSearchParams(); + if (urlIdx !== undefined) { + searchParams.append('urlIdx', urlIdx); + } + + const res = await fetch( + `${WEBUI_BASE_URL}/api/v1/pipelines/${pipeline_id}/valves/spec?${searchParams.toString()}`, + { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + } + ) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updatePipelineValves = async ( + token: string = '', + pipeline_id: string, + valves: object, + urlIdx: string +) => { + let error = null; + + const searchParams = new URLSearchParams(); + if (urlIdx !== undefined) { + searchParams.append('urlIdx', urlIdx); + } + + const res = await fetch( + `${WEBUI_BASE_URL}/api/v1/pipelines/${pipeline_id}/valves/update?${searchParams.toString()}`, + { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + }, + body: JSON.stringify(valves) + } + ) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + + if ('detail' in err) { + error = err.detail; + } else { + error = err; + } + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getBackendConfig = async () => { + let error = null; + + const res = await fetch(`${WEBUI_BASE_URL}/api/config`, { + method: 'GET', + credentials: 'include', + headers: { + 'Content-Type': 'application/json' + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getChangelog = async () => { + let error = null; + + const res = await fetch(`${WEBUI_BASE_URL}/api/changelog`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json' + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getVersionUpdates = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_BASE_URL}/api/version/updates`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getModelFilterConfig = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_BASE_URL}/api/config/model/filter`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateModelFilterConfig = async ( + token: string, + enabled: boolean, + models: string[] +) => { + let error = null; + + const res = await fetch(`${WEBUI_BASE_URL}/api/config/model/filter`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + enabled: enabled, + models: models + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getWebhookUrl = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_BASE_URL}/api/webhook`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err; + return null; + }); + + if (error) { + throw error; + } + + return res.url; +}; + +export const updateWebhookUrl = async (token: string, url: string) => { + let error = null; + + const res = await fetch(`${WEBUI_BASE_URL}/api/webhook`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + url: url + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err; + return null; + }); + + if (error) { + throw error; + } + + return res.url; +}; + +export const getCommunitySharingEnabledStatus = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_BASE_URL}/api/community_sharing`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const toggleCommunitySharingEnabledStatus = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_BASE_URL}/api/community_sharing/toggle`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getModelConfig = async (token: string): Promise => { + let error = null; + + const res = await fetch(`${WEBUI_BASE_URL}/api/config/models`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err; + return null; + }); + + if (error) { + throw error; + } + + return res.models; +}; + +export interface ModelConfig { + id: string; + name: string; + meta: ModelMeta; + base_model_id?: string; + params: ModelParams; +} + +export interface ModelMeta { + description?: string; + capabilities?: object; + profile_image_url?: string; +} + +export interface ModelParams {} + +export type GlobalModelConfig = ModelConfig[]; + +export const updateModelConfig = async (token: string, config: GlobalModelConfig) => { + let error = null; + + const res = await fetch(`${WEBUI_BASE_URL}/api/config/models`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + models: config + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; diff --git a/src/lib/apis/knowledge/index.ts b/src/lib/apis/knowledge/index.ts new file mode 100644 index 0000000..c5fad13 --- /dev/null +++ b/src/lib/apis/knowledge/index.ts @@ -0,0 +1,347 @@ +import { WEBUI_API_BASE_URL } from '$lib/constants'; + +export const createNewKnowledge = async ( + token: string, + name: string, + description: string, + accessControl: null | object +) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/knowledge/create`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + name: name, + description: description, + access_control: accessControl + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getKnowledgeBases = async (token: string = '') => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/knowledge/`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getKnowledgeBaseList = async (token: string = '') => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/knowledge/list`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getKnowledgeById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/knowledge/${id}`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +type KnowledgeUpdateForm = { + name?: string; + description?: string; + data?: object; + access_control?: null | object; +}; + +export const updateKnowledgeById = async (token: string, id: string, form: KnowledgeUpdateForm) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/knowledge/${id}/update`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + name: form?.name ? form.name : undefined, + description: form?.description ? form.description : undefined, + data: form?.data ? form.data : undefined, + access_control: form.access_control + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const addFileToKnowledgeById = async (token: string, id: string, fileId: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/knowledge/${id}/file/add`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + file_id: fileId + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateFileFromKnowledgeById = async (token: string, id: string, fileId: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/knowledge/${id}/file/update`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + file_id: fileId + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const removeFileFromKnowledgeById = async (token: string, id: string, fileId: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/knowledge/${id}/file/remove`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + file_id: fileId + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const resetKnowledgeById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/knowledge/${id}/reset`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const deleteKnowledgeById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/knowledge/${id}/delete`, { + method: 'DELETE', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; diff --git a/src/lib/apis/memories/index.ts b/src/lib/apis/memories/index.ts new file mode 100644 index 0000000..3fd83ca --- /dev/null +++ b/src/lib/apis/memories/index.ts @@ -0,0 +1,186 @@ +import { WEBUI_API_BASE_URL } from '$lib/constants'; + +export const getMemories = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/memories/`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const addNewMemory = async (token: string, content: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/memories/add`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + content: content + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateMemoryById = async (token: string, id: string, content: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/memories/${id}/update`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + content: content + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const queryMemory = async (token: string, content: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/memories/query`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + content: content + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const deleteMemoryById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/memories/${id}`, { + method: 'DELETE', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const deleteMemoriesByUserId = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/memories/delete/user`, { + method: 'DELETE', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; diff --git a/src/lib/apis/models/index.ts b/src/lib/apis/models/index.ts new file mode 100644 index 0000000..9cf625d --- /dev/null +++ b/src/lib/apis/models/index.ts @@ -0,0 +1,265 @@ +import { WEBUI_API_BASE_URL } from '$lib/constants'; + +export const getModels = async (token: string = '') => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/models/`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getBaseModels = async (token: string = '') => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/models/base`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const createNewModel = async (token: string, model: object) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/models/create`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify(model) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getModelById = async (token: string, id: string) => { + let error = null; + + const searchParams = new URLSearchParams(); + searchParams.append('id', id); + + const res = await fetch(`${WEBUI_API_BASE_URL}/models/model?${searchParams.toString()}`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const toggleModelById = async (token: string, id: string) => { + let error = null; + + const searchParams = new URLSearchParams(); + searchParams.append('id', id); + + const res = await fetch(`${WEBUI_API_BASE_URL}/models/model/toggle?${searchParams.toString()}`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateModelById = async (token: string, id: string, model: object) => { + let error = null; + + const searchParams = new URLSearchParams(); + searchParams.append('id', id); + + const res = await fetch(`${WEBUI_API_BASE_URL}/models/model/update?${searchParams.toString()}`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify(model) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const deleteModelById = async (token: string, id: string) => { + let error = null; + + const searchParams = new URLSearchParams(); + searchParams.append('id', id); + + const res = await fetch(`${WEBUI_API_BASE_URL}/models/model/delete?${searchParams.toString()}`, { + method: 'DELETE', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const deleteAllModels = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/models/delete/all`, { + method: 'DELETE', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; diff --git a/src/lib/apis/ollama/index.ts b/src/lib/apis/ollama/index.ts new file mode 100644 index 0000000..b96567e --- /dev/null +++ b/src/lib/apis/ollama/index.ts @@ -0,0 +1,541 @@ +import { OLLAMA_API_BASE_URL } from '$lib/constants'; + +export const verifyOllamaConnection = async ( + token: string = '', + url: string = '', + key: string = '' +) => { + let error = null; + + const res = await fetch(`${OLLAMA_API_BASE_URL}/verify`, { + method: 'POST', + headers: { + Accept: 'application/json', + Authorization: `Bearer ${token}`, + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + url, + key + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = `Ollama: ${err?.error?.message ?? 'Network Problem'}`; + return []; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getOllamaConfig = async (token: string = '') => { + let error = null; + + const res = await fetch(`${OLLAMA_API_BASE_URL}/config`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = 'Server connection failed'; + } + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +type OllamaConfig = { + ENABLE_OLLAMA_API: boolean; + OLLAMA_BASE_URLS: string[]; + OLLAMA_API_CONFIGS: object; +}; + +export const updateOllamaConfig = async (token: string = '', config: OllamaConfig) => { + let error = null; + + const res = await fetch(`${OLLAMA_API_BASE_URL}/config/update`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + }, + body: JSON.stringify({ + ...config + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = 'Server connection failed'; + } + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getOllamaUrls = async (token: string = '') => { + let error = null; + + const res = await fetch(`${OLLAMA_API_BASE_URL}/urls`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = 'Server connection failed'; + } + return null; + }); + + if (error) { + throw error; + } + + return res.OLLAMA_BASE_URLS; +}; + +export const updateOllamaUrls = async (token: string = '', urls: string[]) => { + let error = null; + + const res = await fetch(`${OLLAMA_API_BASE_URL}/urls/update`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + }, + body: JSON.stringify({ + urls: urls + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = 'Server connection failed'; + } + return null; + }); + + if (error) { + throw error; + } + + return res.OLLAMA_BASE_URLS; +}; + +export const getOllamaVersion = async (token: string, urlIdx?: number) => { + let error = null; + + const res = await fetch(`${OLLAMA_API_BASE_URL}/api/version${urlIdx ? `/${urlIdx}` : ''}`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = 'Server connection failed'; + } + return null; + }); + + if (error) { + throw error; + } + + return res?.version ?? false; +}; + +export const getOllamaModels = async (token: string = '', urlIdx: null | number = null) => { + let error = null; + + const res = await fetch(`${OLLAMA_API_BASE_URL}/api/tags${urlIdx !== null ? `/${urlIdx}` : ''}`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = 'Server connection failed'; + } + return null; + }); + + if (error) { + throw error; + } + + return (res?.models ?? []) + .map((model) => ({ id: model.model, name: model.name ?? model.model, ...model })) + .sort((a, b) => { + return a.name.localeCompare(b.name); + }); +}; + +export const generatePrompt = async (token: string = '', model: string, conversation: string) => { + let error = null; + + if (conversation === '') { + conversation = '[no existing conversation]'; + } + + const res = await fetch(`${OLLAMA_API_BASE_URL}/api/generate`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + model: model, + prompt: `Conversation: + ${conversation} + + As USER in the conversation above, your task is to continue the conversation. Remember, Your responses should be crafted as if you're a human conversing in a natural, realistic manner, keeping in mind the context and flow of the dialogue. Please generate a fitting response to the last message in the conversation, or if there is no existing conversation, initiate one as a normal person would. + + Response: + ` + }) + }).catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const generateEmbeddings = async (token: string = '', model: string, text: string) => { + let error = null; + + const res = await fetch(`${OLLAMA_API_BASE_URL}/api/embeddings`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + model: model, + prompt: text + }) + }).catch((err) => { + error = err; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const generateTextCompletion = async (token: string = '', model: string, text: string) => { + let error = null; + + const res = await fetch(`${OLLAMA_API_BASE_URL}/api/generate`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + model: model, + prompt: text, + stream: true + }) + }).catch((err) => { + error = err; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const generateChatCompletion = async (token: string = '', body: object) => { + let controller = new AbortController(); + let error = null; + + const res = await fetch(`${OLLAMA_API_BASE_URL}/api/chat`, { + signal: controller.signal, + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify(body) + }).catch((err) => { + error = err; + return null; + }); + + if (error) { + throw error; + } + + return [res, controller]; +}; + +export const createModel = async (token: string, payload: object, urlIdx: string | null = null) => { + let error = null; + + const res = await fetch( + `${OLLAMA_API_BASE_URL}/api/create${urlIdx !== null ? `/${urlIdx}` : ''}`, + { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify(payload) + } + ).catch((err) => { + error = err; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const deleteModel = async (token: string, tagName: string, urlIdx: string | null = null) => { + let error = null; + + const res = await fetch( + `${OLLAMA_API_BASE_URL}/api/delete${urlIdx !== null ? `/${urlIdx}` : ''}`, + { + method: 'DELETE', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + name: tagName + }) + } + ) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + console.log(json); + return true; + }) + .catch((err) => { + console.log(err); + error = err; + + if ('detail' in err) { + error = err.detail; + } + + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const pullModel = async (token: string, tagName: string, urlIdx: number | null = null) => { + let error = null; + const controller = new AbortController(); + + const res = await fetch(`${OLLAMA_API_BASE_URL}/api/pull${urlIdx !== null ? `/${urlIdx}` : ''}`, { + signal: controller.signal, + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + name: tagName + }) + }).catch((err) => { + console.log(err); + error = err; + + if ('detail' in err) { + error = err.detail; + } + + return null; + }); + if (error) { + throw error; + } + return [res, controller]; +}; + +export const downloadModel = async ( + token: string, + download_url: string, + urlIdx: string | null = null +) => { + let error = null; + + const res = await fetch( + `${OLLAMA_API_BASE_URL}/models/download${urlIdx !== null ? `/${urlIdx}` : ''}`, + { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + url: download_url + }) + } + ).catch((err) => { + console.log(err); + error = err; + + if ('detail' in err) { + error = err.detail; + } + + return null; + }); + if (error) { + throw error; + } + return res; +}; + +export const uploadModel = async (token: string, file: File, urlIdx: string | null = null) => { + let error = null; + + const formData = new FormData(); + formData.append('file', file); + + const res = await fetch( + `${OLLAMA_API_BASE_URL}/models/upload${urlIdx !== null ? `/${urlIdx}` : ''}`, + { + method: 'POST', + headers: { + Authorization: `Bearer ${token}` + }, + body: formData + } + ).catch((err) => { + console.log(err); + error = err; + + if ('detail' in err) { + error = err.detail; + } + + return null; + }); + if (error) { + throw error; + } + return res; +}; + +// export const pullModel = async (token: string, tagName: string) => { +// return await fetch(`${OLLAMA_API_BASE_URL}/pull`, { +// method: 'POST', +// headers: { +// 'Content-Type': 'text/event-stream', +// Authorization: `Bearer ${token}` +// }, +// body: JSON.stringify({ +// name: tagName +// }) +// }); +// }; diff --git a/src/lib/apis/openai/index.ts b/src/lib/apis/openai/index.ts new file mode 100644 index 0000000..bab2d6e --- /dev/null +++ b/src/lib/apis/openai/index.ts @@ -0,0 +1,422 @@ +import { OPENAI_API_BASE_URL, WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants'; + +export const getOpenAIConfig = async (token: string = '') => { + let error = null; + + const res = await fetch(`${OPENAI_API_BASE_URL}/config`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = 'Server connection failed'; + } + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +type OpenAIConfig = { + ENABLE_OPENAI_API: boolean; + OPENAI_API_BASE_URLS: string[]; + OPENAI_API_KEYS: string[]; + OPENAI_API_CONFIGS: object; +}; + +export const updateOpenAIConfig = async (token: string = '', config: OpenAIConfig) => { + let error = null; + + const res = await fetch(`${OPENAI_API_BASE_URL}/config/update`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + }, + body: JSON.stringify({ + ...config + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = 'Server connection failed'; + } + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getOpenAIUrls = async (token: string = '') => { + let error = null; + + const res = await fetch(`${OPENAI_API_BASE_URL}/urls`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = 'Server connection failed'; + } + return null; + }); + + if (error) { + throw error; + } + + return res.OPENAI_API_BASE_URLS; +}; + +export const updateOpenAIUrls = async (token: string = '', urls: string[]) => { + let error = null; + + const res = await fetch(`${OPENAI_API_BASE_URL}/urls/update`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + }, + body: JSON.stringify({ + urls: urls + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = 'Server connection failed'; + } + return null; + }); + + if (error) { + throw error; + } + + return res.OPENAI_API_BASE_URLS; +}; + +export const getOpenAIKeys = async (token: string = '') => { + let error = null; + + const res = await fetch(`${OPENAI_API_BASE_URL}/keys`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = 'Server connection failed'; + } + return null; + }); + + if (error) { + throw error; + } + + return res.OPENAI_API_KEYS; +}; + +export const updateOpenAIKeys = async (token: string = '', keys: string[]) => { + let error = null; + + const res = await fetch(`${OPENAI_API_BASE_URL}/keys/update`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + }, + body: JSON.stringify({ + keys: keys + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = 'Server connection failed'; + } + return null; + }); + + if (error) { + throw error; + } + + return res.OPENAI_API_KEYS; +}; + +export const getOpenAIModelsDirect = async (url: string, key: string) => { + let error = null; + + const res = await fetch(`${url}/models`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(key && { authorization: `Bearer ${key}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = `OpenAI: ${err?.error?.message ?? 'Network Problem'}`; + return []; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getOpenAIModels = async (token: string, urlIdx?: number) => { + let error = null; + + const res = await fetch( + `${OPENAI_API_BASE_URL}/models${typeof urlIdx === 'number' ? `/${urlIdx}` : ''}`, + { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + } + ) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = `OpenAI: ${err?.error?.message ?? 'Network Problem'}`; + return []; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const verifyOpenAIConnection = async ( + token: string = '', + url: string = 'https://api.openai.com/v1', + key: string = '', + direct: boolean = false +) => { + if (!url) { + throw 'OpenAI: URL is required'; + } + + let error = null; + let res = null; + + if (direct) { + res = await fetch(`${url}/models`, { + method: 'GET', + headers: { + Accept: 'application/json', + Authorization: `Bearer ${key}`, + 'Content-Type': 'application/json' + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = `OpenAI: ${err?.error?.message ?? 'Network Problem'}`; + return []; + }); + + if (error) { + throw error; + } + } else { + res = await fetch(`${OPENAI_API_BASE_URL}/verify`, { + method: 'POST', + headers: { + Accept: 'application/json', + Authorization: `Bearer ${token}`, + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + url, + key + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = `OpenAI: ${err?.error?.message ?? 'Network Problem'}`; + return []; + }); + + if (error) { + throw error; + } + } + + return res; +}; + +export const chatCompletion = async ( + token: string = '', + body: object, + url: string = `${WEBUI_BASE_URL}/api` +): Promise<[Response | null, AbortController]> => { + const controller = new AbortController(); + let error = null; + + const res = await fetch(`${url}/chat/completions`, { + signal: controller.signal, + method: 'POST', + headers: { + Authorization: `Bearer ${token}`, + 'Content-Type': 'application/json' + }, + body: JSON.stringify(body) + }).catch((err) => { + console.log(err); + error = err; + return null; + }); + + if (error) { + throw error; + } + + return [res, controller]; +}; + +export const generateOpenAIChatCompletion = async ( + token: string = '', + body: object, + url: string = `${WEBUI_BASE_URL}/api` +) => { + let error = null; + + const res = await fetch(`${url}/chat/completions`, { + method: 'POST', + headers: { + Authorization: `Bearer ${token}`, + 'Content-Type': 'application/json' + }, + body: JSON.stringify(body) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = `${err?.detail ?? err}`; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const synthesizeOpenAISpeech = async ( + token: string = '', + speaker: string = 'alloy', + text: string = '', + model: string = 'tts-1' +) => { + let error = null; + + const res = await fetch(`${OPENAI_API_BASE_URL}/audio/speech`, { + method: 'POST', + headers: { + Authorization: `Bearer ${token}`, + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + model: model, + input: text, + voice: speaker + }) + }).catch((err) => { + console.log(err); + error = err; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; diff --git a/src/lib/apis/prompts/index.ts b/src/lib/apis/prompts/index.ts new file mode 100644 index 0000000..f1c54b1 --- /dev/null +++ b/src/lib/apis/prompts/index.ts @@ -0,0 +1,204 @@ +import { WEBUI_API_BASE_URL } from '$lib/constants'; + +type PromptItem = { + command: string; + title: string; + content: string; + access_control?: null | object; +}; + +export const createNewPrompt = async (token: string, prompt: PromptItem) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/prompts/create`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + ...prompt, + command: `/${prompt.command}` + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getPrompts = async (token: string = '') => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/prompts/`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getPromptList = async (token: string = '') => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/prompts/list`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getPromptByCommand = async (token: string, command: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/prompts/command/${command}`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updatePromptByCommand = async (token: string, prompt: PromptItem) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/prompts/command/${prompt.command}/update`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + ...prompt, + command: `/${prompt.command}` + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const deletePromptByCommand = async (token: string, command: string) => { + let error = null; + + command = command.charAt(0) === '/' ? command.slice(1) : command; + + const res = await fetch(`${WEBUI_API_BASE_URL}/prompts/command/${command}/delete`, { + method: 'DELETE', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; diff --git a/src/lib/apis/retrieval/index.ts b/src/lib/apis/retrieval/index.ts new file mode 100644 index 0000000..31317fe --- /dev/null +++ b/src/lib/apis/retrieval/index.ts @@ -0,0 +1,576 @@ +import { RETRIEVAL_API_BASE_URL } from '$lib/constants'; + +export const getRAGConfig = async (token: string) => { + let error = null; + + const res = await fetch(`${RETRIEVAL_API_BASE_URL}/config`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +type ChunkConfigForm = { + chunk_size: number; + chunk_overlap: number; +}; + +type DocumentIntelligenceConfigForm = { + key: string; + endpoint: string; +}; + +type ContentExtractConfigForm = { + engine: string; + tika_server_url: string | null; + document_intelligence_config: DocumentIntelligenceConfigForm | null; +}; + +type YoutubeConfigForm = { + language: string[]; + translation?: string | null; + proxy_url: string; +}; + +type RAGConfigForm = { + pdf_extract_images?: boolean; + enable_google_drive_integration?: boolean; + enable_onedrive_integration?: boolean; + chunk?: ChunkConfigForm; + content_extraction?: ContentExtractConfigForm; + web_loader_ssl_verification?: boolean; + youtube?: YoutubeConfigForm; +}; + +export const updateRAGConfig = async (token: string, payload: RAGConfigForm) => { + let error = null; + + const res = await fetch(`${RETRIEVAL_API_BASE_URL}/config/update`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + ...payload + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getRAGTemplate = async (token: string) => { + let error = null; + + const res = await fetch(`${RETRIEVAL_API_BASE_URL}/template`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res?.template ?? ''; +}; + +export const getQuerySettings = async (token: string) => { + let error = null; + + const res = await fetch(`${RETRIEVAL_API_BASE_URL}/query/settings`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +type QuerySettings = { + k: number | null; + r: number | null; + template: string | null; +}; + +export const updateQuerySettings = async (token: string, settings: QuerySettings) => { + let error = null; + + const res = await fetch(`${RETRIEVAL_API_BASE_URL}/query/settings/update`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + ...settings + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getEmbeddingConfig = async (token: string) => { + let error = null; + + const res = await fetch(`${RETRIEVAL_API_BASE_URL}/embedding`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +type OpenAIConfigForm = { + key: string; + url: string; +}; + +type EmbeddingModelUpdateForm = { + openai_config?: OpenAIConfigForm; + embedding_engine: string; + embedding_model: string; + embedding_batch_size?: number; +}; + +export const updateEmbeddingConfig = async (token: string, payload: EmbeddingModelUpdateForm) => { + let error = null; + + const res = await fetch(`${RETRIEVAL_API_BASE_URL}/embedding/update`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + ...payload + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getRerankingConfig = async (token: string) => { + let error = null; + + const res = await fetch(`${RETRIEVAL_API_BASE_URL}/reranking`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +type RerankingModelUpdateForm = { + reranking_model: string; +}; + +export const updateRerankingConfig = async (token: string, payload: RerankingModelUpdateForm) => { + let error = null; + + const res = await fetch(`${RETRIEVAL_API_BASE_URL}/reranking/update`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + ...payload + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export interface SearchDocument { + status: boolean; + collection_name: string; + filenames: string[]; +} + +export const processFile = async ( + token: string, + file_id: string, + collection_name: string | null = null +) => { + let error = null; + + const res = await fetch(`${RETRIEVAL_API_BASE_URL}/process/file`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + file_id: file_id, + collection_name: collection_name ? collection_name : undefined + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const processYoutubeVideo = async (token: string, url: string) => { + let error = null; + + const res = await fetch(`${RETRIEVAL_API_BASE_URL}/process/youtube`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + url: url + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const processWeb = async (token: string, collection_name: string, url: string) => { + let error = null; + + const res = await fetch(`${RETRIEVAL_API_BASE_URL}/process/web`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + url: url, + collection_name: collection_name + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const processWebSearch = async ( + token: string, + query: string, + collection_name?: string +): Promise => { + let error = null; + + const res = await fetch(`${RETRIEVAL_API_BASE_URL}/process/web/search`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + query, + collection_name: collection_name ?? '' + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const queryDoc = async ( + token: string, + collection_name: string, + query: string, + k: number | null = null +) => { + let error = null; + + const res = await fetch(`${RETRIEVAL_API_BASE_URL}/query/doc`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + collection_name: collection_name, + query: query, + k: k + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const queryCollection = async ( + token: string, + collection_names: string, + query: string, + k: number | null = null +) => { + let error = null; + + const res = await fetch(`${RETRIEVAL_API_BASE_URL}/query/collection`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + collection_names: collection_names, + query: query, + k: k + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const resetUploadDir = async (token: string) => { + let error = null; + + const res = await fetch(`${RETRIEVAL_API_BASE_URL}/reset/uploads`, { + method: 'POST', + headers: { + Accept: 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const resetVectorDB = async (token: string) => { + let error = null; + + const res = await fetch(`${RETRIEVAL_API_BASE_URL}/reset/db`, { + method: 'POST', + headers: { + Accept: 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; diff --git a/src/lib/apis/streaming/index.ts b/src/lib/apis/streaming/index.ts new file mode 100644 index 0000000..6f3677a --- /dev/null +++ b/src/lib/apis/streaming/index.ts @@ -0,0 +1,142 @@ +import { EventSourceParserStream } from 'eventsource-parser/stream'; +import type { ParsedEvent } from 'eventsource-parser'; + +type TextStreamUpdate = { + done: boolean; + value: string; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + sources?: any; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + selectedModelId?: any; + error?: any; + usage?: ResponseUsage; +}; + +type ResponseUsage = { + /** Including images and tools if any */ + prompt_tokens: number; + /** The tokens generated */ + completion_tokens: number; + /** Sum of the above two fields */ + total_tokens: number; + /** Any other fields that aren't part of the base OpenAI spec */ + [other: string]: unknown; +}; + +// createOpenAITextStream takes a responseBody with a SSE response, +// and returns an async generator that emits delta updates with large deltas chunked into random sized chunks +export async function createOpenAITextStream( + responseBody: ReadableStream, + splitLargeDeltas: boolean +): Promise> { + const eventStream = responseBody + .pipeThrough(new TextDecoderStream()) + .pipeThrough(new EventSourceParserStream()) + .getReader(); + let iterator = openAIStreamToIterator(eventStream); + if (splitLargeDeltas) { + iterator = streamLargeDeltasAsRandomChunks(iterator); + } + return iterator; +} + +async function* openAIStreamToIterator( + reader: ReadableStreamDefaultReader +): AsyncGenerator { + while (true) { + const { value, done } = await reader.read(); + if (done) { + yield { done: true, value: '' }; + break; + } + if (!value) { + continue; + } + const data = value.data; + if (data.startsWith('[DONE]')) { + yield { done: true, value: '' }; + break; + } + + try { + const parsedData = JSON.parse(data); + console.log(parsedData); + + if (parsedData.error) { + yield { done: true, value: '', error: parsedData.error }; + break; + } + + if (parsedData.sources) { + yield { done: false, value: '', sources: parsedData.sources }; + continue; + } + + if (parsedData.selected_model_id) { + yield { done: false, value: '', selectedModelId: parsedData.selected_model_id }; + continue; + } + + if (parsedData.usage) { + yield { done: false, value: '', usage: parsedData.usage }; + continue; + } + + yield { + done: false, + value: parsedData.choices?.[0]?.delta?.content ?? '' + }; + } catch (e) { + console.error('Error extracting delta from SSE event:', e); + } + } +} + +// streamLargeDeltasAsRandomChunks will chunk large deltas (length > 5) into random sized chunks between 1-3 characters +// This is to simulate a more fluid streaming, even though some providers may send large chunks of text at once +async function* streamLargeDeltasAsRandomChunks( + iterator: AsyncGenerator +): AsyncGenerator { + for await (const textStreamUpdate of iterator) { + if (textStreamUpdate.done) { + yield textStreamUpdate; + return; + } + + if (textStreamUpdate.error) { + yield textStreamUpdate; + continue; + } + if (textStreamUpdate.sources) { + yield textStreamUpdate; + continue; + } + if (textStreamUpdate.selectedModelId) { + yield textStreamUpdate; + continue; + } + if (textStreamUpdate.usage) { + yield textStreamUpdate; + continue; + } + + let content = textStreamUpdate.value; + if (content.length < 5) { + yield { done: false, value: content }; + continue; + } + while (content != '') { + const chunkSize = Math.min(Math.floor(Math.random() * 3) + 1, content.length); + const chunk = content.slice(0, chunkSize); + yield { done: false, value: chunk }; + // Do not sleep if the tab is hidden + // Timers are throttled to 1s in hidden tabs + if (document?.visibilityState !== 'hidden') { + await sleep(5); + } + content = content.slice(chunkSize); + } + } +} + +const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); diff --git a/src/lib/apis/tools/index.ts b/src/lib/apis/tools/index.ts new file mode 100644 index 0000000..d1dc11c --- /dev/null +++ b/src/lib/apis/tools/index.ts @@ -0,0 +1,422 @@ +import { WEBUI_API_BASE_URL } from '$lib/constants'; + +export const createNewTool = async (token: string, tool: object) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/tools/create`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + ...tool + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getTools = async (token: string = '') => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/tools/`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getToolList = async (token: string = '') => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/tools/list`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const exportTools = async (token: string = '') => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/tools/export`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getToolById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateToolById = async (token: string, id: string, tool: object) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}/update`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + ...tool + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const deleteToolById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}/delete`, { + method: 'DELETE', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getToolValvesById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}/valves`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getToolValvesSpecById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}/valves/spec`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateToolValvesById = async (token: string, id: string, valves: object) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}/valves/update`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + ...valves + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getUserValvesById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}/valves/user`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getUserValvesSpecById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}/valves/user/spec`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateUserValvesById = async (token: string, id: string, valves: object) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}/valves/user/update`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + ...valves + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; diff --git a/src/lib/apis/users/index.ts b/src/lib/apis/users/index.ts new file mode 100644 index 0000000..f479b13 --- /dev/null +++ b/src/lib/apis/users/index.ts @@ -0,0 +1,365 @@ +import { WEBUI_API_BASE_URL } from '$lib/constants'; +import { getUserPosition } from '$lib/utils'; + +export const getUserGroups = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/users/groups`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getUserDefaultPermissions = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/users/default/permissions`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateUserDefaultPermissions = async (token: string, permissions: object) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/users/default/permissions`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + ...permissions + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateUserRole = async (token: string, id: string, role: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/users/update/role`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + id: id, + role: role + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getUsers = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/users/`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res ? res : []; +}; + +export const getUserSettings = async (token: string) => { + let error = null; + const res = await fetch(`${WEBUI_API_BASE_URL}/users/user/settings`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateUserSettings = async (token: string, settings: object) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/users/user/settings/update`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + ...settings + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getUserById = async (token: string, userId: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/users/${userId}`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getUserInfo = async (token: string) => { + let error = null; + const res = await fetch(`${WEBUI_API_BASE_URL}/users/user/info`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateUserInfo = async (token: string, info: object) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/users/user/info/update`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + ...info + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getAndUpdateUserLocation = async (token: string) => { + const location = await getUserPosition().catch((err) => { + console.log(err); + return null; + }); + + if (location) { + await updateUserInfo(token, { location: location }); + return location; + } else { + console.log('Failed to get user location'); + return null; + } +}; + +export const deleteUserById = async (token: string, userId: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/users/${userId}`, { + method: 'DELETE', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +type UserUpdateForm = { + profile_image_url: string; + email: string; + name: string; + password: string; +}; + +export const updateUserById = async (token: string, userId: string, user: UserUpdateForm) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/users/${userId}/update`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + profile_image_url: user.profile_image_url, + email: user.email, + name: user.name, + password: user.password !== '' ? user.password : undefined + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; diff --git a/src/lib/apis/utils/index.ts b/src/lib/apis/utils/index.ts new file mode 100644 index 0000000..64db561 --- /dev/null +++ b/src/lib/apis/utils/index.ts @@ -0,0 +1,217 @@ +import { WEBUI_API_BASE_URL } from '$lib/constants'; + +export const getGravatarUrl = async (token: string, email: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/utils/gravatar?email=${email}`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err; + return null; + }); + + return res; +}; + +export const executeCode = async (token: string, code: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/utils/code/execute`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + code: code + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + + error = err; + if (err.detail) { + error = err.detail; + } + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const formatPythonCode = async (token: string, code: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/utils/code/format`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + code: code + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + + error = err; + if (err.detail) { + error = err.detail; + } + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const downloadChatAsPDF = async (token: string, title: string, messages: object[]) => { + let error = null; + + const blob = await fetch(`${WEBUI_API_BASE_URL}/utils/pdf`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + title: title, + messages: messages + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.blob(); + }) + .catch((err) => { + console.log(err); + error = err; + return null; + }); + + return blob; +}; + +export const getHTMLFromMarkdown = async (token: string, md: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/utils/markdown`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + md: md + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err; + return null; + }); + + return res.html; +}; + +export const downloadDatabase = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/utils/db/download`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (response) => { + if (!response.ok) { + throw await response.json(); + } + return response.blob(); + }) + .then((blob) => { + const url = window.URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = 'webui.db'; + document.body.appendChild(a); + a.click(); + window.URL.revokeObjectURL(url); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } +}; + +export const downloadLiteLLMConfig = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/utils/litellm/config`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (response) => { + if (!response.ok) { + throw await response.json(); + } + return response.blob(); + }) + .then((blob) => { + const url = window.URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = 'config.yaml'; + document.body.appendChild(a); + a.click(); + window.URL.revokeObjectURL(url); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } +}; diff --git a/src/lib/components/AddConnectionModal.svelte b/src/lib/components/AddConnectionModal.svelte new file mode 100644 index 0000000..cbd90b6 --- /dev/null +++ b/src/lib/components/AddConnectionModal.svelte @@ -0,0 +1,369 @@ + + + +
        +
        +
        + {#if edit} + {$i18n.t('Edit Connection')} + {:else} + {$i18n.t('Add Connection')} + {/if} +
        + +
        + +
        +
        +
        { + e.preventDefault(); + submitHandler(); + }} + > +
        +
        +
        +
        {$i18n.t('URL')}
        + +
        + +
        +
        + + + + + +
        + + + +
        +
        + +
        +
        +
        {$i18n.t('Key')}
        + +
        + +
        +
        + +
        +
        {$i18n.t('Prefix ID')}
        + +
        + + + +
        +
        +
        + +
        + +
        +
        +
        {$i18n.t('Model IDs')}
        +
        + + {#if modelIds.length > 0} +
        + {#each modelIds as modelId, modelIdx} +
        +
        + {modelId} +
        +
        + +
        +
        + {/each} +
        + {:else} +
        + {#if ollama} + {$i18n.t('Leave empty to include all models from "{{URL}}/api/tags" endpoint', { + URL: url + })} + {:else} + {$i18n.t('Leave empty to include all models from "{{URL}}/models" endpoint', { + URL: url + })} + {/if} +
        + {/if} +
        + +
        + +
        + + +
        + +
        +
        +
        + +
        + {#if edit} + + {/if} + + +
        +
        +
        +
        +
        +
        diff --git a/src/lib/components/AddFilesPlaceholder.svelte b/src/lib/components/AddFilesPlaceholder.svelte new file mode 100644 index 0000000..d3d7007 --- /dev/null +++ b/src/lib/components/AddFilesPlaceholder.svelte @@ -0,0 +1,28 @@ + + +
        +
        📄
        +
        + {#if title} + {title} + {:else} + {$i18n.t('Add Files')} + {/if} +
        + +
        + {#if content} + {content} + {:else} + {$i18n.t('Drop any files here to add to the conversation')} + {/if} +
        +
        +
        diff --git a/src/lib/components/ChangelogModal.svelte b/src/lib/components/ChangelogModal.svelte new file mode 100644 index 0000000..fd727c2 --- /dev/null +++ b/src/lib/components/ChangelogModal.svelte @@ -0,0 +1,120 @@ + + + +
        +
        +
        + {$i18n.t('What’s New in')} + {$WEBUI_NAME} + +
        + +
        +
        +
        {$i18n.t('Release Notes')}
        +
        +
        + v{WEBUI_VERSION} +
        +
        +
        + +
        +
        +
        + {#if changelog} + {#each Object.keys(changelog) as version} +
        +
        + v{version} - {changelog[version].date} +
        + +
        + + {#each Object.keys(changelog[version]).filter((section) => section !== 'date') as section} +
        +
        + {section} +
        + +
        + {#each Object.keys(changelog[version][section]) as item} +
        +
        + {changelog[version][section][item].title} +
        +
        {changelog[version][section][item].content}
        +
        + {/each} +
        +
        + {/each} +
        + {/each} + {/if} +
        +
        +
        + +
        +
        + diff --git a/src/lib/components/NotificationToast.svelte b/src/lib/components/NotificationToast.svelte new file mode 100644 index 0000000..0d3f69a --- /dev/null +++ b/src/lib/components/NotificationToast.svelte @@ -0,0 +1,53 @@ + + + diff --git a/src/lib/components/OnBoarding.svelte b/src/lib/components/OnBoarding.svelte new file mode 100644 index 0000000..e68a7f2 --- /dev/null +++ b/src/lib/components/OnBoarding.svelte @@ -0,0 +1,78 @@ + + +{#if show} +
        +
        +
        +
        + logo +
        +
        +
        + + + +
        + +
        + +
        +
        +
        + + +
        {$i18n.t(`wherever you are`)}
        + + +
        +
        + +
        {$i18n.t(`Get started`)}
        +
        +
        + + + + + +{/if} diff --git a/src/lib/components/admin/Evaluations.svelte b/src/lib/components/admin/Evaluations.svelte new file mode 100644 index 0000000..a5532ae --- /dev/null +++ b/src/lib/components/admin/Evaluations.svelte @@ -0,0 +1,100 @@ + + +{#if loaded} +
        +
        + + + +
        + +
        + {#if selectedTab === 'leaderboard'} + + {:else if selectedTab === 'feedbacks'} + + {/if} +
        +
        +{/if} diff --git a/src/lib/components/admin/Evaluations/FeedbackMenu.svelte b/src/lib/components/admin/Evaluations/FeedbackMenu.svelte new file mode 100644 index 0000000..83defd8 --- /dev/null +++ b/src/lib/components/admin/Evaluations/FeedbackMenu.svelte @@ -0,0 +1,46 @@ + + + {}}> + + + + +
        + + { + dispatch('delete'); + show = false; + }} + > + +
        {$i18n.t('Delete')}
        +
        +
        +
        +
        diff --git a/src/lib/components/admin/Evaluations/Feedbacks.svelte b/src/lib/components/admin/Evaluations/Feedbacks.svelte new file mode 100644 index 0000000..026755b --- /dev/null +++ b/src/lib/components/admin/Evaluations/Feedbacks.svelte @@ -0,0 +1,285 @@ + + +
        +
        + {$i18n.t('Feedback History')} + +
        + + {feedbacks.length} +
        + +
        +
        + + + +
        +
        +
        + +
        + {#if (feedbacks ?? []).length === 0} +
        + {$i18n.t('No feedbacks found')} +
        + {:else} + + + + + + + + + + + + + + + + {#each paginatedFeedbacks as feedback (feedback.id)} + + + + + + + + + + + {/each} + +
        + {$i18n.t('User')} + + {$i18n.t('Models')} + + {$i18n.t('Result')} + + {$i18n.t('Updated At')} +
        +
        + +
        + {feedback?.user?.name} +
        +
        +
        +
        +
        +
        + {#if feedback.data?.sibling_model_ids} +
        + {feedback.data?.model_id} +
        + + +
        + {#if feedback.data.sibling_model_ids.length > 2} + + {feedback.data.sibling_model_ids.slice(0, 2).join(', ')}, {$i18n.t( + 'and {{COUNT}} more', + { COUNT: feedback.data.sibling_model_ids.length - 2 } + )} + {:else} + {feedback.data.sibling_model_ids.join(', ')} + {/if} +
        +
        + {:else} +
        + {feedback.data?.model_id} +
        + {/if} +
        +
        +
        +
        + {#if feedback.data.rating.toString() === '1'} + + {:else if feedback.data.rating.toString() === '0'} + + {:else if feedback.data.rating.toString() === '-1'} + + {/if} +
        +
        + {dayjs(feedback.updated_at * 1000).fromNow()} + + { + deleteFeedbackHandler(feedback.id); + }} + > + + +
        + {/if} +
        + +{#if feedbacks.length > 0} +
        +
        + {$i18n.t('Help us create the best community leaderboard by sharing your feedback history!')} +
        + +
        + + + +
        +
        +{/if} + +{#if feedbacks.length > 10} + +{/if} diff --git a/src/lib/components/admin/Evaluations/Leaderboard.svelte b/src/lib/components/admin/Evaluations/Leaderboard.svelte new file mode 100644 index 0000000..e5d8a21 --- /dev/null +++ b/src/lib/components/admin/Evaluations/Leaderboard.svelte @@ -0,0 +1,414 @@ + + +
        +
        +
        + {$i18n.t('Leaderboard')} +
        + +
        + + {rankedModels.length} +
        + +
        + +
        +
        + +
        + { + loadEmbeddingModel(); + }} + /> +
        +
        +
        +
        + +
        + {#if loadingLeaderboard} +
        +
        + +
        +
        + {/if} + {#if (rankedModels ?? []).length === 0} +
        + {$i18n.t('No models found')} +
        + {:else} + + + + + + + + + + + + {#each rankedModels as model, modelIdx (model.id)} + + + + + + + + + + {/each} + +
        + {$i18n.t('RK')} + + {$i18n.t('Model')} + + {$i18n.t('Rating')} + + {$i18n.t('Won')} + + {$i18n.t('Lost')} +
        +
        + {model?.rating !== '-' ? modelIdx + 1 : '-'} +
        +
        +
        +
        + {model.name} +
        + +
        + {model.name} +
        +
        +
        + {model.rating} + +
        + {#if model.stats.won === '-'} + - + {:else} + + {model.stats.won} + {/if} +
        +
        +
        + {#if model.stats.lost === '-'} + - + {:else} + + {model.stats.lost} + {/if} +
        +
        + {/if} +
        + +
        +
        +
        + ⓘ {$i18n.t( + 'The evaluation leaderboard is based on the Elo rating system and is updated in real-time.' + )} +
        + {$i18n.t( + 'The leaderboard is currently in beta, and we may adjust the rating calculations as we refine the algorithm.' + )} +
        +
        diff --git a/src/lib/components/admin/Functions.svelte b/src/lib/components/admin/Functions.svelte new file mode 100644 index 0000000..f5868d0 --- /dev/null +++ b/src/lib/components/admin/Functions.svelte @@ -0,0 +1,568 @@ + + + + + {$i18n.t('Functions')} | {$WEBUI_NAME} + + + +
        +
        +
        + {$i18n.t('Functions')} +
        + {filteredItems.length} +
        +
        + +
        +
        +
        + +
        + +
        + +
        + + + +
        +
        +
        + +
        + {#each filteredItems as func (func.id)} +
        + +
        +
        +
        +
        + {func.type} +
        + + {#if func?.meta?.manifest?.version} +
        + v{func?.meta?.manifest?.version ?? ''} +
        + {/if} + +
        + {func.name} +
        +
        + +
        +
        {func.id}
        + +
        + {func.meta.description} +
        +
        +
        +
        +
        +
        + {#if shiftKey} + + + + {:else} + {#if func?.meta?.manifest?.funding_url ?? false} + + + + {/if} + + + + + + { + goto(`/admin/functions/edit?id=${encodeURIComponent(func.id)}`); + }} + shareHandler={() => { + shareHandler(func); + }} + cloneHandler={() => { + cloneHandler(func); + }} + exportHandler={() => { + exportHandler(func); + }} + deleteHandler={async () => { + selectedFunction = func; + showDeleteConfirm = true; + }} + toggleGlobalHandler={() => { + if (['filter', 'action'].includes(func.type)) { + toggleGlobalHandler(func); + } + }} + onClose={() => {}} + > + + + {/if} + +
        + + { + toggleFunctionById(localStorage.token, func.id); + models.set( + await getModels( + localStorage.token, + $config?.features?.enable_direct_connections && + ($settings?.directConnections ?? null) + ) + ); + }} + /> + +
        +
        +
        + {/each} +
        + + + +
        +
        + { + console.log(importFiles); + showConfirm = true; + }} + /> + + + + +
        +
        + +{#if $config?.features.enable_community_sharing} + +{/if} + + { + deleteHandler(selectedFunction); + }} +> +
        + {$i18n.t('This will delete')} {selectedFunction.name}. +
        +
        + + + { + await tick(); + models.set( + await getModels( + localStorage.token, + $config?.features?.enable_direct_connections && ($settings?.directConnections ?? null) + ) + ); + }} +/> + + { + const reader = new FileReader(); + reader.onload = async (event) => { + const _functions = JSON.parse(event.target.result); + console.log(_functions); + + for (const func of _functions) { + const res = await createNewFunction(localStorage.token, func).catch((error) => { + toast.error(`${error}`); + return null; + }); + } + + toast.success($i18n.t('Functions imported successfully')); + functions.set(await getFunctions(localStorage.token)); + models.set( + await getModels( + localStorage.token, + $config?.features?.enable_direct_connections && ($settings?.directConnections ?? null) + ) + ); + }; + + reader.readAsText(importFiles[0]); + }} +> +
        +
        +
        Please carefully review the following warnings:
        + +
          +
        • {$i18n.t('Functions allow arbitrary code execution.')}
        • +
        • {$i18n.t('Do not install functions from sources you do not fully trust.')}
        • +
        +
        + +
        + {$i18n.t( + 'I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.' + )} +
        +
        +
        diff --git a/src/lib/components/admin/Functions/FunctionEditor.svelte b/src/lib/components/admin/Functions/FunctionEditor.svelte new file mode 100644 index 0000000..6da2a83 --- /dev/null +++ b/src/lib/components/admin/Functions/FunctionEditor.svelte @@ -0,0 +1,431 @@ + + +
        +
        +
        { + if (edit) { + submitHandler(); + } else { + showConfirm = true; + } + }} + > + +
        +
        +
        + + { + submitHandler(); + }} +> +
        +
        +
        {$i18n.t('Please carefully review the following warnings:')}
        + +
          +
        • {$i18n.t('Functions allow arbitrary code execution.')}
        • +
        • {$i18n.t('Do not install functions from sources you do not fully trust.')}
        • +
        +
        + +
        + {$i18n.t( + 'I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.' + )} +
        +
        +
        diff --git a/src/lib/components/admin/Functions/FunctionMenu.svelte b/src/lib/components/admin/Functions/FunctionMenu.svelte new file mode 100644 index 0000000..71e12d0 --- /dev/null +++ b/src/lib/components/admin/Functions/FunctionMenu.svelte @@ -0,0 +1,138 @@ + + + { + if (e.detail === false) { + onClose(); + } + }} +> + + + + +
        + + {#if ['filter', 'action'].includes(func.type)} +
        +
        + + +
        {$i18n.t('Global')}
        +
        + +
        + +
        +
        + +
        + {/if} + + { + editHandler(); + }} + > + + + + +
        {$i18n.t('Edit')}
        +
        + + { + shareHandler(); + }} + > + +
        {$i18n.t('Share')}
        +
        + + { + cloneHandler(); + }} + > + + +
        {$i18n.t('Clone')}
        +
        + + { + exportHandler(); + }} + > + + +
        {$i18n.t('Export')}
        +
        + +
        + + { + deleteHandler(); + }} + > + +
        {$i18n.t('Delete')}
        +
        +
        +
        +
        diff --git a/src/lib/components/admin/Settings.svelte b/src/lib/components/admin/Settings.svelte new file mode 100644 index 0000000..60edbd2 --- /dev/null +++ b/src/lib/components/admin/Settings.svelte @@ -0,0 +1,435 @@ + + +
        +
        + + + + + + + + + + + + + + + + + + + + + + + +
        + +
        + {#if selectedTab === 'general'} + { + toast.success($i18n.t('Settings saved successfully!')); + + await tick(); + await config.set(await getBackendConfig()); + }} + /> + {:else if selectedTab === 'connections'} + { + toast.success($i18n.t('Settings saved successfully!')); + }} + /> + {:else if selectedTab === 'models'} + + {:else if selectedTab === 'evaluations'} + + {:else if selectedTab === 'documents'} + { + toast.success($i18n.t('Settings saved successfully!')); + + await tick(); + await config.set(await getBackendConfig()); + }} + /> + {:else if selectedTab === 'web'} + { + toast.success($i18n.t('Settings saved successfully!')); + + await tick(); + await config.set(await getBackendConfig()); + }} + /> + {:else if selectedTab === 'code-execution'} + { + toast.success($i18n.t('Settings saved successfully!')); + + await tick(); + await config.set(await getBackendConfig()); + }} + /> + {:else if selectedTab === 'interface'} + { + toast.success($i18n.t('Settings saved successfully!')); + }} + /> + {:else if selectedTab === 'audio'} +
        +
        diff --git a/src/lib/components/admin/Settings/Audio.svelte b/src/lib/components/admin/Settings/Audio.svelte new file mode 100644 index 0000000..d36f4af --- /dev/null +++ b/src/lib/components/admin/Settings/Audio.svelte @@ -0,0 +1,640 @@ + + +
        { + await updateConfigHandler(); + dispatch('save'); + }} +> +
        +
        +
        +
        {$i18n.t('STT Settings')}
        + +
        +
        {$i18n.t('Speech-to-Text Engine')}
        +
        + +
        +
        + + {#if STT_ENGINE === 'openai'} +
        +
        + + + +
        +
        + +
        + +
        +
        {$i18n.t('STT Model')}
        +
        +
        + + + + +
        +
        +
        + {:else if STT_ENGINE === 'deepgram'} +
        +
        + +
        +
        + +
        + +
        +
        {$i18n.t('STT Model')}
        +
        +
        + +
        +
        +
        + {$i18n.t('Leave model field empty to use the default model.')} + + {$i18n.t('Click here to see available models.')} + +
        +
        + {:else if STT_ENGINE === ''} +
        +
        {$i18n.t('STT Model')}
        + +
        +
        + +
        + + +
        + + +
        + {/if} +
        + +
        + +
        +
        {$i18n.t('TTS Settings')}
        + +
        +
        {$i18n.t('Text-to-Speech Engine')}
        +
        + +
        +
        + + {#if TTS_ENGINE === 'openai'} +
        +
        + + + +
        +
        + {:else if TTS_ENGINE === 'elevenlabs'} +
        +
        + +
        +
        + {:else if TTS_ENGINE === 'azure'} +
        +
        + + +
        +
        + {/if} + +
        + + {#if TTS_ENGINE === ''} +
        +
        {$i18n.t('TTS Voice')}
        +
        +
        + +
        +
        +
        + {:else if TTS_ENGINE === 'transformers'} +
        +
        {$i18n.t('TTS Model')}
        +
        +
        + + + + +
        +
        +
        + {$i18n.t(`Open WebUI uses SpeechT5 and CMU Arctic speaker embeddings.`)} + + To learn more about SpeechT5, + + + {$i18n.t(`click here`, { + name: 'SpeechT5' + })}. + + To see the available CMU Arctic speaker embeddings, + + {$i18n.t(`click here`)}. + +
        +
        + {:else if TTS_ENGINE === 'openai'} +
        +
        +
        {$i18n.t('TTS Voice')}
        +
        +
        + + + + {#each voices as voice} + + {/each} + +
        +
        +
        +
        +
        {$i18n.t('TTS Model')}
        +
        +
        + + + + {#each models as model} + +
        +
        +
        +
        + {:else if TTS_ENGINE === 'elevenlabs'} +
        +
        +
        {$i18n.t('TTS Voice')}
        +
        +
        + + + + {#each voices as voice} + + {/each} + +
        +
        +
        +
        +
        {$i18n.t('TTS Model')}
        +
        +
        + + + + {#each models as model} + +
        +
        +
        +
        + {:else if TTS_ENGINE === 'azure'} +
        +
        +
        {$i18n.t('TTS Voice')}
        +
        +
        + + + + {#each voices as voice} + + {/each} + +
        +
        +
        +
        +
        + {$i18n.t('Output format')} + + {$i18n.t('Available list')} + +
        +
        +
        + +
        +
        +
        +
        + {/if} + +
        + +
        +
        {$i18n.t('Response splitting')}
        +
        + +
        +
        +
        + {$i18n.t( + "Control how message text is split for TTS requests. 'Punctuation' splits into sentences, 'paragraphs' splits into paragraphs, and 'none' keeps the message as a single string." + )} +
        +
        +
        +
        +
        + +
        +
        diff --git a/src/lib/components/admin/Settings/CodeExecution.svelte b/src/lib/components/admin/Settings/CodeExecution.svelte new file mode 100644 index 0000000..c835374 --- /dev/null +++ b/src/lib/components/admin/Settings/CodeExecution.svelte @@ -0,0 +1,317 @@ + + +
        { + await submitHandler(); + saveHandler(); + }} +> +
        + {#if config} +
        +
        +
        {$i18n.t('General')}
        + +
        + +
        +
        +
        {$i18n.t('Code Execution Engine')}
        +
        + +
        +
        + + {#if config.CODE_EXECUTION_ENGINE === 'jupyter'} +
        + {$i18n.t( + 'Warning: Jupyter execution enables arbitrary code execution, posing severe security risks—proceed with extreme caution.' + )} +
        + {/if} +
        + + {#if config.CODE_EXECUTION_ENGINE === 'jupyter'} +
        +
        + {$i18n.t('Jupyter URL')} +
        + +
        +
        + +
        +
        +
        + +
        +
        +
        + {$i18n.t('Jupyter Auth')} +
        + +
        + +
        +
        + + {#if config.CODE_EXECUTION_JUPYTER_AUTH} +
        +
        + {#if config.CODE_EXECUTION_JUPYTER_AUTH === 'password'} + + {:else} + + {/if} +
        +
        + {/if} +
        + +
        +
        + {$i18n.t('Code Execution Timeout')} +
        + +
        + + + +
        +
        + {/if} +
        + +
        +
        {$i18n.t('Code Interpreter')}
        + +
        + +
        +
        +
        + {$i18n.t('Enable Code Interpreter')} +
        + + +
        +
        + + {#if config.ENABLE_CODE_INTERPRETER} +
        +
        +
        + {$i18n.t('Code Interpreter Engine')} +
        +
        + +
        +
        + + {#if config.CODE_INTERPRETER_ENGINE === 'jupyter'} +
        + {$i18n.t( + 'Warning: Jupyter execution enables arbitrary code execution, posing severe security risks—proceed with extreme caution.' + )} +
        + {/if} +
        + + {#if config.CODE_INTERPRETER_ENGINE === 'jupyter'} +
        +
        + {$i18n.t('Jupyter URL')} +
        + +
        +
        + +
        +
        +
        + +
        +
        +
        + {$i18n.t('Jupyter Auth')} +
        + +
        + +
        +
        + + {#if config.CODE_INTERPRETER_JUPYTER_AUTH} +
        +
        + {#if config.CODE_INTERPRETER_JUPYTER_AUTH === 'password'} + + {:else} + + {/if} +
        +
        + {/if} +
        + +
        +
        + {$i18n.t('Code Execution Timeout')} +
        + +
        + + + +
        +
        + {/if} + +
        + +
        +
        +
        + {$i18n.t('Code Interpreter Prompt Template')} +
        + + +