diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..cf4d3f8ac1ee2c37659877ab3276c0666b1a0672 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ + +FROM python:3.9 + +WORKDIR /code + +COPY --link --chown=1000 . . + +RUN mkdir -p /tmp/cache/ +RUN chmod a+rwx -R /tmp/cache/ +ENV TRANSFORMERS_CACHE=/tmp/cache/ + +RUN pip install --no-cache-dir -r requirements.txt + +ENV PYTHONUNBUFFERED=1 GRADIO_ALLOW_FLAGGING=never GRADIO_NUM_PORTS=1 GRADIO_SERVER_NAME=0.0.0.0 GRADIO_SERVER_PORT=7860 SYSTEM=spaces + +CMD ["python", "space.py"] diff --git a/README.md b/README.md index 175939ae4b850b43e1217be5239c293c8e4c1122..e9c1c257c14272027bbce5618eb3f4b66f4e579a 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,17 @@ + --- -title: Gradio Logsview -emoji: 🔥 -colorFrom: red -colorTo: yellow +tags: [gradio-custom-component,gradio-template-Code,logging,subprocess,process] +title: gradio_logsview V0.0.1 +colorFrom: gray +colorTo: purple sdk: docker pinned: false +license: apache-2.0 --- -Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference + +# Name: gradio_logsview + +Description: Visualize logs in your Gradio app + +Install with: pip install gradio_logsview \ No newline at end of file diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/__pycache__/__init__.cpython-310.pyc b/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..962d69a32b9033d4db68a51eff43c701dbb3c343 Binary files /dev/null and b/__pycache__/__init__.cpython-310.pyc differ diff --git a/__pycache__/app.cpython-310.pyc b/__pycache__/app.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ba0912c7bd3cb0a87591ec1506176bcf943956e0 Binary files /dev/null and b/__pycache__/app.cpython-310.pyc differ diff --git a/app.py b/app.py new file mode 100644 index 0000000000000000000000000000000000000000..a13394452ede4c61d30a82e2031d9ae9f835c1bb --- /dev/null +++ b/app.py @@ -0,0 +1,115 @@ +import logging +import random +import time + +import gradio as gr +from gradio_logsview import LogsView + + +def random_values(failing: bool = False): + for i in range(10): + logging.log( + random.choice( + [ # Random levels + logging.INFO, + logging.DEBUG, + logging.WARNING, + logging.ERROR, + logging.CRITICAL, + ] + ), + f"Value {i+1}", # Random values + ) + time.sleep(random.uniform(0, 1)) + if failing and i == 5: + raise ValueError("Failing!!") + + +def fn_process_success(): + yield from LogsView.run_process(["python", "-u", "demo/script.py"]) + + +def fn_process_failing(): + yield from LogsView.run_process(["python", "-u", "demo/script.py", "--failing"]) + + +def fn_thread_success(): + yield from LogsView.run_thread(random_values, log_level=logging.INFO, failing=False) + + +def fn_thread_failing(): + yield from LogsView.run_thread(random_values, log_level=logging.INFO, failing=True) + + +markdown_top = """ +# LogsView Demo + +This demo shows how to use the `LogsView` component to display logs from a process or a thread in real-time. + +Click on any button to launch a process or a thread and see the logs displayed in real-time. +In the thread example, logs are generated randomly with different log levels. +In the process example, logs are generated by a Python script but any command can be executed. +""" + + +markdown_bottom = """ +## How to run in a thread? + +With `LogsView.run_thread`, you can run a function in a separate thread and capture logs in real-time. +You can configure which logs to capture (log level and logger name). + +```py +from gradio_logsview import LogsView + +def fn_thread(): + # Run `my_function` in a separate thread + # All logs above `INFO` level will be captured and displayed in real-time. + yield from LogsView.run_thread(my_function, log_level=logging.INFO, arg1="value1") + +with gr.Blocks() as demo: + logs = LogsView() + btn = gr.Button("Run thread") + btn.click(fn_thread, outputs=logs) +``` + +## How to run in a process? + +With `LogsView.run_process`, you can run a command in a separate process and capture logs from the process in real-time. + +```py +from gradio_logsview import LogsView + +def fn_process(): + # Run a process and capture all logs from the process + yield from LogsView.run_process( + cmd=[mergekit-yaml", "config.yaml", "merge", "--copy-", "--cuda", "--low-cpu-memory"] + ) + +with gr.Blocks() as demo: + logs = LogsView() + btn = gr.Button("Run process") + btn.click(fn_process, outputs=logs) +``` +""" + +with gr.Blocks() as demo: + gr.Markdown(markdown_top) + + with gr.Row(): + btn_thread_success = gr.Button("Run thread (success)") + btn_thread_failing = gr.Button("Run thread (failing)") + with gr.Row(): + btn_process_success = gr.Button("Run process (success)") + btn_process_failing = gr.Button("Run process (failing)") + logs = LogsView() + + gr.Markdown(markdown_bottom) + + btn_thread_failing.click(fn_thread_failing, outputs=logs) + btn_thread_success.click(fn_thread_success, outputs=logs) + btn_process_failing.click(fn_process_failing, outputs=logs) + btn_process_success.click(fn_process_success, outputs=logs) + + +if __name__ == "__main__": + demo.launch() diff --git a/css.css b/css.css new file mode 100644 index 0000000000000000000000000000000000000000..f7256be42f9884d89b499b0f5a6cfcbed3d54c80 --- /dev/null +++ b/css.css @@ -0,0 +1,157 @@ +html { + font-family: Inter; + font-size: 16px; + font-weight: 400; + line-height: 1.5; + -webkit-text-size-adjust: 100%; + background: #fff; + color: #323232; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-rendering: optimizeLegibility; +} + +:root { + --space: 1; + --vspace: calc(var(--space) * 1rem); + --vspace-0: calc(3 * var(--space) * 1rem); + --vspace-1: calc(2 * var(--space) * 1rem); + --vspace-2: calc(1.5 * var(--space) * 1rem); + --vspace-3: calc(0.5 * var(--space) * 1rem); +} + +.app { + max-width: 748px !important; +} + +.prose p { + margin: var(--vspace) 0; + line-height: var(--vspace * 2); + font-size: 1rem; +} + +code { + font-family: "Inconsolata", sans-serif; + font-size: 16px; +} + +h1, +h1 code { + font-weight: 400; + line-height: calc(2.5 / var(--space) * var(--vspace)); +} + +h1 code { + background: none; + border: none; + letter-spacing: 0.05em; + padding-bottom: 5px; + position: relative; + padding: 0; +} + +h2 { + margin: var(--vspace-1) 0 var(--vspace-2) 0; + line-height: 1em; +} + +h3, +h3 code { + margin: var(--vspace-1) 0 var(--vspace-2) 0; + line-height: 1em; +} + +h4, +h5, +h6 { + margin: var(--vspace-3) 0 var(--vspace-3) 0; + line-height: var(--vspace); +} + +.bigtitle, +h1, +h1 code { + font-size: calc(8px * 4.5); + word-break: break-word; +} + +.title, +h2, +h2 code { + font-size: calc(8px * 3.375); + font-weight: lighter; + word-break: break-word; + border: none; + background: none; +} + +.subheading1, +h3, +h3 code { + font-size: calc(8px * 1.8); + font-weight: 600; + border: none; + background: none; + letter-spacing: 0.1em; + text-transform: uppercase; +} + +h2 code { + padding: 0; + position: relative; + letter-spacing: 0.05em; +} + +blockquote { + font-size: calc(8px * 1.1667); + font-style: italic; + line-height: calc(1.1667 * var(--vspace)); + margin: var(--vspace-2) var(--vspace-2); +} + +.subheading2, +h4 { + font-size: calc(8px * 1.4292); + text-transform: uppercase; + font-weight: 600; +} + +.subheading3, +h5 { + font-size: calc(8px * 1.2917); + line-height: calc(1.2917 * var(--vspace)); + + font-weight: lighter; + text-transform: uppercase; + letter-spacing: 0.15em; +} + +h6 { + font-size: calc(8px * 1.1667); + font-size: 1.1667em; + font-weight: normal; + font-style: italic; + font-family: "le-monde-livre-classic-byol", serif !important; + letter-spacing: 0px !important; +} + +#start .md > *:first-child { + margin-top: 0; +} + +h2 + h3 { + margin-top: 0; +} + +.md hr { + border: none; + border-top: 1px solid var(--block-border-color); + margin: var(--vspace-2) 0 var(--vspace-2) 0; +} +.prose ul { + margin: var(--vspace-2) 0 var(--vspace-1) 0; +} + +.gap { + gap: 0; +} diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..bc5000d1de70968435a9ac054279e84597c2042b --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +gradio_logsview-0.0.1-py3-none-any.whl \ No newline at end of file diff --git a/script.py b/script.py new file mode 100644 index 0000000000000000000000000000000000000000..ac7bd6578df0da557c470fd13f554ab0ccedd216 --- /dev/null +++ b/script.py @@ -0,0 +1,21 @@ +import argparse +import random +import time + + +def random_values(failing: bool = False): + for i in range(10): + print(f"Value {i+1}") + time.sleep(random.uniform(0, 1)) + if failing and i == 5: + raise ValueError("Failing!!") + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--failing", action="store_true") + args = parser.parse_args() + random_values(args.failing) + + +main() diff --git a/space.py b/space.py new file mode 100644 index 0000000000000000000000000000000000000000..53c361eb5ec543238ea930bb7c2a1900429c65dc --- /dev/null +++ b/space.py @@ -0,0 +1,456 @@ + +import gradio as gr +from app import demo as app +import os + +_docs = {'LogsView': {'description': 'Creates a component to visualize logs from a subprocess in real-time.', 'members': {'__init__': {'value': {'type': 'str | Callable | tuple[str] | None', 'default': 'None', 'description': 'Default value to show in the code editor. If callable, the function will be called whenever the app loads to set the initial value of the component.'}, 'every': {'type': 'float | None', 'default': 'None', 'description': "If `value` is a callable, run the function 'every' number of seconds while the client connection is open. Has no effect otherwise. The event can be accessed (e.g. to cancel it) via this component's .load_event attribute."}, 'lines': {'type': 'int', 'default': '5', 'description': None}, 'label': {'type': 'str | None', 'default': 'None', 'description': 'The label for this component. Appears above the component and is also used as the header if there are a table of examples for this component. If None and used in a `gr.Interface`, the label will be the name of the parameter this component is assigned to.'}, 'show_label': {'type': 'bool | None', 'default': 'None', 'description': 'if True, will display label.'}, 'container': {'type': 'bool', 'default': 'True', 'description': 'If True, will place the component in a container - providing some extra padding around the border.'}, 'scale': {'type': 'int | None', 'default': 'None', 'description': 'relative size compared to adjacent Components. For example if Components A and B are in a Row, and A has scale=2, and B has scale=1, A will be twice as wide as B. Should be an integer. scale applies in Rows, and to top-level Components in Blocks where fill_height=True.'}, 'min_width': {'type': 'int', 'default': '160', 'description': 'minimum pixel width, will wrap if not sufficient screen space to satisfy this value. If a certain scale value results in this Component being narrower than min_width, the min_width parameter will be respected first.'}, 'visible': {'type': 'bool', 'default': 'True', 'description': 'If False, component will be hidden.'}, 'elem_id': {'type': 'str | None', 'default': 'None', 'description': 'An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles.'}, 'elem_classes': {'type': 'list[str] | str | None', 'default': 'None', 'description': 'An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.'}, 'render': {'type': 'bool', 'default': 'True', 'description': 'If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.'}}, 'postprocess': {'value': {'type': 'list[Log]', 'description': 'Expects a list of `Log` logs.'}}, 'preprocess': {'return': {'type': 'LogsView', 'description': 'Passes the code entered as a `str`.'}, 'value': None}}, 'events': {'change': {'type': None, 'default': None, 'description': 'Triggered when the value of the LogsView changes either because of user input (e.g. a user types in a textbox) OR because of a function update (e.g. an image receives a value from the output of an event trigger). See `.input()` for a listener that is only triggered by user input.'}, 'input': {'type': None, 'default': None, 'description': 'This listener is triggered when the user changes the value of the LogsView.'}, 'focus': {'type': None, 'default': None, 'description': 'This listener is triggered when the LogsView is focused.'}, 'blur': {'type': None, 'default': None, 'description': 'This listener is triggered when the LogsView is unfocused/blurred.'}}}, '__meta__': {'additional_interfaces': {'Log': {'source': '@dataclass\nclass Log:\n level: Literal[\n "INFO", "DEBUG", "WARNING", "ERROR", "CRITICAL"\n ]\n message: str\n timestamp: str'}, 'LogsView': {'source': 'class LogsView(Component):\n EVENTS = [\n Events.change,\n Events.input,\n Events.focus,\n Events.blur,\n ]\n\n def __init__(\n self,\n value: str | Callable | tuple[str] | None = None,\n *,\n every: float | None = None,\n lines: int = 5,\n label: str | None = None,\n show_label: bool | None = None,\n container: bool = True,\n scale: int | None = None,\n min_width: int = 160,\n visible: bool = True,\n elem_id: str | None = None,\n elem_classes: list[str] | str | None = None,\n render: bool = True,\n ):\n self.language = "shell"\n self.lines = lines\n self.interactive = False\n super().__init__(\n label=label,\n every=every,\n show_label=show_label,\n container=container,\n scale=scale,\n min_width=min_width,\n visible=visible,\n elem_id=elem_id,\n elem_classes=elem_classes,\n render=render,\n value=value,\n )\n\n def preprocess(self, payload: str | None) -> "LogsView":\n raise NotImplementedError(\n "LogsView cannot be used as an input component."\n )\n\n def postprocess(self, value: List[Log]) -> List[Log]:\n return value\n\n def api_info(self) -> dict[str, Any]:\n return {\n "items": {\n "level": "string",\n "message": "string",\n "timestamp": "number",\n },\n "title": "Logs",\n "type": "array",\n }\n\n def example_payload(self) -> Any:\n return [\n Log(\n "INFO",\n "Hello World",\n datetime.now().isoformat(),\n )\n ]\n\n def example_value(self) -> Any:\n return [\n Log(\n "INFO",\n "Hello World",\n datetime.now().isoformat(),\n )\n ]\n\n @classmethod\n def run_process(\n cls,\n command: List[str],\n date_format: str = "%Y-%m-%d %H:%M:%S",\n ) -> Generator[List[Log], None, None]:\n process = subprocess.Popen(\n command,\n stdout=subprocess.PIPE,\n stderr=subprocess.STDOUT,\n text=True,\n )\n\n if process.stdout is None:\n raise ValueError("stdout is None")\n\n logs = []\n\n def _log(level: str, message: str):\n log = Log(\n level=level,\n message=message,\n timestamp=datetime.now().strftime(\n date_format\n ),\n )\n logs.append(log)\n return logs\n\n _log("INFO", f"Running {\' \'.join(command)}")\n for line in process.stdout:\n yield _log("INFO", line.strip())\n\n # TODO: what if task is cancelled but process is still running?\n\n process.stdout.close()\n return_code = process.wait()\n if return_code:\n yield _log(\n "ERROR",\n f"Process exited with code {return_code}",\n )\n else:\n yield _log(\n "INFO", "Process exited successfully"\n )\n\n @classmethod\n def run_thread(\n cls,\n fn: Callable,\n log_level: int = logging.INFO,\n logger_name: str | None = None,\n date_format: str = "%Y-%m-%d %H:%M:%S",\n **kwargs,\n ) -> Generator[List[Log], None, None]:\n logs = [\n Log(\n level="INFO",\n message=f"Running {fn.__name__}({\', \'.join(f\'{k}={v}\' for k, v in kwargs.items())})",\n timestamp=datetime.now().strftime(\n date_format\n ),\n )\n ]\n yield logs\n\n thread = Thread(\n target=non_failing_fn(fn), kwargs=kwargs\n )\n\n def _log(record: logging.LogRecord) -> bool:\n if record.thread != thread.ident:\n return False # Skip if not from the thread\n if logger_name and not record.name.startswith(\n logger_name\n ):\n return False # Skip if not from the logger\n if record.levelno < log_level:\n return False # Skip if too verbose\n log = Log(\n level=record.levelname,\n message=record.getMessage(),\n timestamp=datetime.fromtimestamp(\n record.created\n ).strftime(date_format),\n )\n logs.append(log)\n return True\n\n with capture_logging(log_level) as log_queue:\n thread.start()\n\n # Loop to capture and yield logs from the thread\n while thread.is_alive():\n while True:\n try:\n if _log(log_queue.get_nowait()):\n yield logs\n except queue.Empty:\n break\n thread.join(\n timeout=0.1\n ) # adjust the timeout as needed\n\n # After the thread completes, yield any remaining logs\n while True:\n try:\n if _log(log_queue.get_nowait()):\n yield logs\n except queue.Empty:\n break\n\n logs.append(\n Log(\n level="INFO",\n message="Thread completed successfully",\n timestamp=datetime.now().strftime(\n date_format\n ),\n )\n )'}}, 'user_fn_refs': {'LogsView': ['Log', 'LogsView']}}} + +abs_path = os.path.join(os.path.dirname(__file__), "css.css") + +with gr.Blocks( + css=abs_path, + theme=gr.themes.Default( + font_mono=[ + gr.themes.GoogleFont("Inconsolata"), + "monospace", + ], + ), +) as demo: + gr.Markdown( +""" +# `gradio_logsview` + +
+Static Badge +
+ +Visualize logs in your Gradio app +""", elem_classes=["md-custom"], header_links=True) + app.render() + gr.Markdown( +""" +## Installation + +```bash +pip install gradio_logsview +``` + +## Usage + +```python +import logging +import random +import time + +import gradio as gr +from gradio_logsview import LogsView + + +def random_values(failing: bool = False): + for i in range(10): + logging.log( + random.choice( + [ # Random levels + logging.INFO, + logging.DEBUG, + logging.WARNING, + logging.ERROR, + logging.CRITICAL, + ] + ), + f"Value {i+1}", # Random values + ) + time.sleep(random.uniform(0, 1)) + if failing and i == 5: + raise ValueError("Failing!!") + + +def fn_process_success(): + yield from LogsView.run_process(["python", "-u", "demo/script.py"]) + + +def fn_process_failing(): + yield from LogsView.run_process(["python", "-u", "demo/script.py", "--failing"]) + + +def fn_thread_success(): + yield from LogsView.run_thread(random_values, log_level=logging.INFO, failing=False) + + +def fn_thread_failing(): + yield from LogsView.run_thread(random_values, log_level=logging.INFO, failing=True) + + +markdown_top = \"\"\" +# LogsView Demo + +This demo shows how to use the `LogsView` component to display logs from a process or a thread in real-time. + +Click on any button to launch a process or a thread and see the logs displayed in real-time. +In the thread example, logs are generated randomly with different log levels. +In the process example, logs are generated by a Python script but any command can be executed. +\"\"\" + + +markdown_bottom = \"\"\" +## How to run in a thread? + +With `LogsView.run_thread`, you can run a function in a separate thread and capture logs in real-time. +You can configure which logs to capture (log level and logger name). + +```py +from gradio_logsview import LogsView + +def fn_thread(): + # Run `my_function` in a separate thread + # All logs above `INFO` level will be captured and displayed in real-time. + yield from LogsView.run_thread(my_function, log_level=logging.INFO, arg1="value1") + +with gr.Blocks() as demo: + logs = LogsView() + btn = gr.Button("Run thread") + btn.click(fn_thread, outputs=logs) +``` + +## How to run in a process? + +With `LogsView.run_process`, you can run a command in a separate process and capture logs from the process in real-time. + +```py +from gradio_logsview import LogsView + +def fn_process(): + # Run a process and capture all logs from the process + yield from LogsView.run_process( + cmd=[mergekit-yaml", "config.yaml", "merge", "--copy-", "--cuda", "--low-cpu-memory"] + ) + +with gr.Blocks() as demo: + logs = LogsView() + btn = gr.Button("Run process") + btn.click(fn_process, outputs=logs) +``` +\"\"\" + +with gr.Blocks() as demo: + gr.Markdown(markdown_top) + + with gr.Row(): + btn_thread_success = gr.Button("Run thread (success)") + btn_thread_failing = gr.Button("Run thread (failing)") + with gr.Row(): + btn_process_success = gr.Button("Run process (success)") + btn_process_failing = gr.Button("Run process (failing)") + logs = LogsView() + + gr.Markdown(markdown_bottom) + + btn_thread_failing.click(fn_thread_failing, outputs=logs) + btn_thread_success.click(fn_thread_success, outputs=logs) + btn_process_failing.click(fn_process_failing, outputs=logs) + btn_process_success.click(fn_process_success, outputs=logs) + + +if __name__ == "__main__": + demo.launch() + +``` +""", elem_classes=["md-custom"], header_links=True) + + + gr.Markdown(""" +## `LogsView` + +### Initialization +""", elem_classes=["md-custom"], header_links=True) + + gr.ParamViewer(value=_docs["LogsView"]["members"]["__init__"], linkify=['Log', 'LogsView']) + + + gr.Markdown("### Events") + gr.ParamViewer(value=_docs["LogsView"]["events"], linkify=['Event']) + + + + + gr.Markdown(""" + +### User function + +The impact on the users predict function varies depending on whether the component is used as an input or output for an event (or both). + +- When used as an Input, the component only impacts the input signature of the user function. +- When used as an output, the component only impacts the return signature of the user function. + +The code snippet below is accurate in cases where the component is used as both an input and an output. + +- **As input:** Is passed, passes the code entered as a `str`. +- **As output:** Should return, expects a list of `Log` logs. + + ```python +def predict( + value: LogsView +) -> list[Log]: + return value +``` +""", elem_classes=["md-custom", "LogsView-user-fn"], header_links=True) + + + + + code_Log = gr.Markdown(""" +## `Log` +```python +@dataclass +class Log: + level: Literal[ + "INFO", "DEBUG", "WARNING", "ERROR", "CRITICAL" + ] + message: str + timestamp: str +```""", elem_classes=["md-custom", "Log"], header_links=True) + + code_LogsView = gr.Markdown(""" +## `LogsView` +```python +class LogsView(Component): + EVENTS = [ + Events.change, + Events.input, + Events.focus, + Events.blur, + ] + + def __init__( + self, + value: str | Callable | tuple[str] | None = None, + *, + every: float | None = None, + lines: int = 5, + label: str | None = None, + show_label: bool | None = None, + container: bool = True, + scale: int | None = None, + min_width: int = 160, + visible: bool = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + render: bool = True, + ): + self.language = "shell" + self.lines = lines + self.interactive = False + super().__init__( + label=label, + every=every, + show_label=show_label, + container=container, + scale=scale, + min_width=min_width, + visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + value=value, + ) + + def preprocess(self, payload: str | None) -> "LogsView": + raise NotImplementedError( + "LogsView cannot be used as an input component." + ) + + def postprocess(self, value: List[Log]) -> List[Log]: + return value + + def api_info(self) -> dict[str, Any]: + return { + "items": { + "level": "string", + "message": "string", + "timestamp": "number", + }, + "title": "Logs", + "type": "array", + } + + def example_payload(self) -> Any: + return [ + Log( + "INFO", + "Hello World", + datetime.now().isoformat(), + ) + ] + + def example_value(self) -> Any: + return [ + Log( + "INFO", + "Hello World", + datetime.now().isoformat(), + ) + ] + + @classmethod + def run_process( + cls, + command: List[str], + date_format: str = "%Y-%m-%d %H:%M:%S", + ) -> Generator[List[Log], None, None]: + process = subprocess.Popen( + command, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + ) + + if process.stdout is None: + raise ValueError("stdout is None") + + logs = [] + + def _log(level: str, message: str): + log = Log( + level=level, + message=message, + timestamp=datetime.now().strftime( + date_format + ), + ) + logs.append(log) + return logs + + _log("INFO", f"Running {' '.join(command)}") + for line in process.stdout: + yield _log("INFO", line.strip()) + + # TODO: what if task is cancelled but process is still running? + + process.stdout.close() + return_code = process.wait() + if return_code: + yield _log( + "ERROR", + f"Process exited with code {return_code}", + ) + else: + yield _log( + "INFO", "Process exited successfully" + ) + + @classmethod + def run_thread( + cls, + fn: Callable, + log_level: int = logging.INFO, + logger_name: str | None = None, + date_format: str = "%Y-%m-%d %H:%M:%S", + **kwargs, + ) -> Generator[List[Log], None, None]: + logs = [ + Log( + level="INFO", + message=f"Running {fn.__name__}({', '.join(f'{k}={v}' for k, v in kwargs.items())})", + timestamp=datetime.now().strftime( + date_format + ), + ) + ] + yield logs + + thread = Thread( + target=non_failing_fn(fn), kwargs=kwargs + ) + + def _log(record: logging.LogRecord) -> bool: + if record.thread != thread.ident: + return False # Skip if not from the thread + if logger_name and not record.name.startswith( + logger_name + ): + return False # Skip if not from the logger + if record.levelno < log_level: + return False # Skip if too verbose + log = Log( + level=record.levelname, + message=record.getMessage(), + timestamp=datetime.fromtimestamp( + record.created + ).strftime(date_format), + ) + logs.append(log) + return True + + with capture_logging(log_level) as log_queue: + thread.start() + + # Loop to capture and yield logs from the thread + while thread.is_alive(): + while True: + try: + if _log(log_queue.get_nowait()): + yield logs + except queue.Empty: + break + thread.join( + timeout=0.1 + ) # adjust the timeout as needed + + # After the thread completes, yield any remaining logs + while True: + try: + if _log(log_queue.get_nowait()): + yield logs + except queue.Empty: + break + + logs.append( + Log( + level="INFO", + message="Thread completed successfully", + timestamp=datetime.now().strftime( + date_format + ), + ) + ) +```""", elem_classes=["md-custom", "LogsView"], header_links=True) + + demo.load(None, js=r"""function() { + const refs = { + Log: [], + LogsView: [], }; + const user_fn_refs = { + LogsView: ['Log', 'LogsView'], }; + requestAnimationFrame(() => { + + Object.entries(user_fn_refs).forEach(([key, refs]) => { + if (refs.length > 0) { + const el = document.querySelector(`.${key}-user-fn`); + if (!el) return; + refs.forEach(ref => { + el.innerHTML = el.innerHTML.replace( + new RegExp("\\b"+ref+"\\b", "g"), + `${ref}` + ); + }) + } + }) + + Object.entries(refs).forEach(([key, refs]) => { + if (refs.length > 0) { + const el = document.querySelector(`.${key}`); + if (!el) return; + refs.forEach(ref => { + el.innerHTML = el.innerHTML.replace( + new RegExp("\\b"+ref+"\\b", "g"), + `${ref}` + ); + }) + } + }) + }) +} + +""") + +demo.launch() diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..60188eefb61faf29c12a14228941da079044292f --- /dev/null +++ b/src/.gitignore @@ -0,0 +1,9 @@ +.eggs/ +dist/ +*.pyc +__pycache__/ +*.py[cod] +*$py.class +__tmp/* +*.pyi +node_modules \ No newline at end of file diff --git a/src/.ruff_cache/.gitignore b/src/.ruff_cache/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..b100327770759f0efb7859fe78aca4801d69ed61 --- /dev/null +++ b/src/.ruff_cache/.gitignore @@ -0,0 +1,2 @@ +# Automatically created by ruff. +* diff --git a/src/.ruff_cache/0.3.3/4346399827795627723 b/src/.ruff_cache/0.3.3/4346399827795627723 new file mode 100644 index 0000000000000000000000000000000000000000..98355f3188b04807f89358a6bb1117a95d1f9fa2 Binary files /dev/null and b/src/.ruff_cache/0.3.3/4346399827795627723 differ diff --git a/src/.ruff_cache/0.3.3/6690235712601223868 b/src/.ruff_cache/0.3.3/6690235712601223868 new file mode 100644 index 0000000000000000000000000000000000000000..c7e3f89c74322c897e82871e6eb409d9000516f0 Binary files /dev/null and b/src/.ruff_cache/0.3.3/6690235712601223868 differ diff --git a/src/.ruff_cache/CACHEDIR.TAG b/src/.ruff_cache/CACHEDIR.TAG new file mode 100644 index 0000000000000000000000000000000000000000..bc1ecb967a482524e7736038de0df6e08f9ee452 --- /dev/null +++ b/src/.ruff_cache/CACHEDIR.TAG @@ -0,0 +1 @@ +Signature: 8a477f597d28d172789f06886806bc55 \ No newline at end of file diff --git a/src/README.md b/src/README.md new file mode 100644 index 0000000000000000000000000000000000000000..13145dacbbe57602d66e6593643b0e10ee165a3d --- /dev/null +++ b/src/README.md @@ -0,0 +1,550 @@ + +# `gradio_logsview` +Static Badge + +Visualize logs in your Gradio app + +## Installation + +```bash +pip install gradio_logsview +``` + +## Usage + +```python +import logging +import random +import time + +import gradio as gr +from gradio_logsview import LogsView + + +def random_values(failing: bool = False): + for i in range(10): + logging.log( + random.choice( + [ # Random levels + logging.INFO, + logging.DEBUG, + logging.WARNING, + logging.ERROR, + logging.CRITICAL, + ] + ), + f"Value {i+1}", # Random values + ) + time.sleep(random.uniform(0, 1)) + if failing and i == 5: + raise ValueError("Failing!!") + + +def fn_process_success(): + yield from LogsView.run_process(["python", "-u", "demo/script.py"]) + + +def fn_process_failing(): + yield from LogsView.run_process(["python", "-u", "demo/script.py", "--failing"]) + + +def fn_thread_success(): + yield from LogsView.run_thread(random_values, log_level=logging.INFO, failing=False) + + +def fn_thread_failing(): + yield from LogsView.run_thread(random_values, log_level=logging.INFO, failing=True) + + +markdown_top = """ +# LogsView Demo + +This demo shows how to use the `LogsView` component to display logs from a process or a thread in real-time. + +Click on any button to launch a process or a thread and see the logs displayed in real-time. +In the thread example, logs are generated randomly with different log levels. +In the process example, logs are generated by a Python script but any command can be executed. +""" + + +markdown_bottom = """ +## How to run in a thread? + +With `LogsView.run_thread`, you can run a function in a separate thread and capture logs in real-time. +You can configure which logs to capture (log level and logger name). + +```py +from gradio_logsview import LogsView + +def fn_thread(): + # Run `my_function` in a separate thread + # All logs above `INFO` level will be captured and displayed in real-time. + yield from LogsView.run_thread(my_function, log_level=logging.INFO, arg1="value1") + +with gr.Blocks() as demo: + logs = LogsView() + btn = gr.Button("Run thread") + btn.click(fn_thread, outputs=logs) +``` + +## How to run in a process? + +With `LogsView.run_process`, you can run a command in a separate process and capture logs from the process in real-time. + +```py +from gradio_logsview import LogsView + +def fn_process(): + # Run a process and capture all logs from the process + yield from LogsView.run_process( + cmd=[mergekit-yaml", "config.yaml", "merge", "--copy-", "--cuda", "--low-cpu-memory"] + ) + +with gr.Blocks() as demo: + logs = LogsView() + btn = gr.Button("Run process") + btn.click(fn_process, outputs=logs) +``` +""" + +with gr.Blocks() as demo: + gr.Markdown(markdown_top) + + with gr.Row(): + btn_thread_success = gr.Button("Run thread (success)") + btn_thread_failing = gr.Button("Run thread (failing)") + with gr.Row(): + btn_process_success = gr.Button("Run process (success)") + btn_process_failing = gr.Button("Run process (failing)") + logs = LogsView() + + gr.Markdown(markdown_bottom) + + btn_thread_failing.click(fn_thread_failing, outputs=logs) + btn_thread_success.click(fn_thread_success, outputs=logs) + btn_process_failing.click(fn_process_failing, outputs=logs) + btn_process_success.click(fn_process_success, outputs=logs) + + +if __name__ == "__main__": + demo.launch() + +``` + +## `LogsView` + +### Initialization + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
nametypedefaultdescription
value + +```python +str | Callable | tuple[str] | None +``` + +NoneDefault value to show in the code editor. If callable, the function will be called whenever the app loads to set the initial value of the component.
every + +```python +float | None +``` + +NoneIf `value` is a callable, run the function 'every' number of seconds while the client connection is open. Has no effect otherwise. The event can be accessed (e.g. to cancel it) via this component's .load_event attribute.
lines + +```python +int +``` + +5None
label + +```python +str | None +``` + +NoneThe label for this component. Appears above the component and is also used as the header if there are a table of examples for this component. If None and used in a `gr.Interface`, the label will be the name of the parameter this component is assigned to.
show_label + +```python +bool | None +``` + +Noneif True, will display label.
container + +```python +bool +``` + +TrueIf True, will place the component in a container - providing some extra padding around the border.
scale + +```python +int | None +``` + +Nonerelative size compared to adjacent Components. For example if Components A and B are in a Row, and A has scale=2, and B has scale=1, A will be twice as wide as B. Should be an integer. scale applies in Rows, and to top-level Components in Blocks where fill_height=True.
min_width + +```python +int +``` + +160minimum pixel width, will wrap if not sufficient screen space to satisfy this value. If a certain scale value results in this Component being narrower than min_width, the min_width parameter will be respected first.
visible + +```python +bool +``` + +TrueIf False, component will be hidden.
elem_id + +```python +str | None +``` + +NoneAn optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles.
elem_classes + +```python +list[str] | str | None +``` + +NoneAn optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
render + +```python +bool +``` + +TrueIf False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
+ + +### Events + +| name | description | +|:-----|:------------| +| `change` | Triggered when the value of the LogsView changes either because of user input (e.g. a user types in a textbox) OR because of a function update (e.g. an image receives a value from the output of an event trigger). See `.input()` for a listener that is only triggered by user input. | +| `input` | This listener is triggered when the user changes the value of the LogsView. | +| `focus` | This listener is triggered when the LogsView is focused. | +| `blur` | This listener is triggered when the LogsView is unfocused/blurred. | + + + +### User function + +The impact on the users predict function varies depending on whether the component is used as an input or output for an event (or both). + +- When used as an Input, the component only impacts the input signature of the user function. +- When used as an output, the component only impacts the return signature of the user function. + +The code snippet below is accurate in cases where the component is used as both an input and an output. + +- **As output:** Is passed, passes the code entered as a `str`. +- **As input:** Should return, expects a list of `Log` logs. + + ```python + def predict( + value: LogsView + ) -> list[Log]: + return value + ``` + + +## `Log` +```python +@dataclass +class Log: + level: Literal[ + "INFO", "DEBUG", "WARNING", "ERROR", "CRITICAL" + ] + message: str + timestamp: str +``` + +## `LogsView` +```python +class LogsView(Component): + EVENTS = [ + Events.change, + Events.input, + Events.focus, + Events.blur, + ] + + def __init__( + self, + value: str | Callable | tuple[str] | None = None, + *, + every: float | None = None, + lines: int = 5, + label: str | None = None, + show_label: bool | None = None, + container: bool = True, + scale: int | None = None, + min_width: int = 160, + visible: bool = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + render: bool = True, + ): + self.language = "shell" + self.lines = lines + self.interactive = False + super().__init__( + label=label, + every=every, + show_label=show_label, + container=container, + scale=scale, + min_width=min_width, + visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + value=value, + ) + + def preprocess(self, payload: str | None) -> "LogsView": + raise NotImplementedError( + "LogsView cannot be used as an input component." + ) + + def postprocess(self, value: List[Log]) -> List[Log]: + return value + + def api_info(self) -> dict[str, Any]: + return { + "items": { + "level": "string", + "message": "string", + "timestamp": "number", + }, + "title": "Logs", + "type": "array", + } + + def example_payload(self) -> Any: + return [ + Log( + "INFO", + "Hello World", + datetime.now().isoformat(), + ) + ] + + def example_value(self) -> Any: + return [ + Log( + "INFO", + "Hello World", + datetime.now().isoformat(), + ) + ] + + @classmethod + def run_process( + cls, + command: List[str], + date_format: str = "%Y-%m-%d %H:%M:%S", + ) -> Generator[List[Log], None, None]: + process = subprocess.Popen( + command, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + ) + + if process.stdout is None: + raise ValueError("stdout is None") + + logs = [] + + def _log(level: str, message: str): + log = Log( + level=level, + message=message, + timestamp=datetime.now().strftime( + date_format + ), + ) + logs.append(log) + return logs + + _log("INFO", f"Running {' '.join(command)}") + for line in process.stdout: + yield _log("INFO", line.strip()) + + # TODO: what if task is cancelled but process is still running? + + process.stdout.close() + return_code = process.wait() + if return_code: + yield _log( + "ERROR", + f"Process exited with code {return_code}", + ) + else: + yield _log( + "INFO", "Process exited successfully" + ) + + @classmethod + def run_thread( + cls, + fn: Callable, + log_level: int = logging.INFO, + logger_name: str | None = None, + date_format: str = "%Y-%m-%d %H:%M:%S", + **kwargs, + ) -> Generator[List[Log], None, None]: + logs = [ + Log( + level="INFO", + message=f"Running {fn.__name__}({', '.join(f'{k}={v}' for k, v in kwargs.items())})", + timestamp=datetime.now().strftime( + date_format + ), + ) + ] + yield logs + + thread = Thread( + target=non_failing_fn(fn), kwargs=kwargs + ) + + def _log(record: logging.LogRecord) -> bool: + if record.thread != thread.ident: + return False # Skip if not from the thread + if logger_name and not record.name.startswith( + logger_name + ): + return False # Skip if not from the logger + if record.levelno < log_level: + return False # Skip if too verbose + log = Log( + level=record.levelname, + message=record.getMessage(), + timestamp=datetime.fromtimestamp( + record.created + ).strftime(date_format), + ) + logs.append(log) + return True + + with capture_logging(log_level) as log_queue: + thread.start() + + # Loop to capture and yield logs from the thread + while thread.is_alive(): + while True: + try: + if _log(log_queue.get_nowait()): + yield logs + except queue.Empty: + break + thread.join( + timeout=0.1 + ) # adjust the timeout as needed + + # After the thread completes, yield any remaining logs + while True: + try: + if _log(log_queue.get_nowait()): + yield logs + except queue.Empty: + break + + logs.append( + Log( + level="INFO", + message="Thread completed successfully", + timestamp=datetime.now().strftime( + date_format + ), + ) + ) +``` diff --git a/src/backend/gradio_logsview/__init__.py b/src/backend/gradio_logsview/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a0978f0b6c9506ce349aca2e35b71c9b19010591 --- /dev/null +++ b/src/backend/gradio_logsview/__init__.py @@ -0,0 +1,3 @@ +from .logsview import LogsView + +__all__ = ["LogsView"] diff --git a/src/backend/gradio_logsview/logsview.py b/src/backend/gradio_logsview/logsview.py new file mode 100644 index 0000000000000000000000000000000000000000..da6ff53d8889534f36950890f4a1895aa23cb0b0 --- /dev/null +++ b/src/backend/gradio_logsview/logsview.py @@ -0,0 +1,250 @@ +"""LogsView() custom component""" + +from __future__ import annotations + +import logging +import queue +import subprocess +import threading +import time +from contextlib import contextmanager +from dataclasses import dataclass +from datetime import datetime +from functools import wraps +from logging.handlers import QueueHandler +from queue import Queue +from threading import Thread +from typing import Any, Callable, Generator, Iterable, List, Literal + +from gradio.components.base import Component +from gradio.events import Events + + +@dataclass +class Log: + level: Literal["INFO", "DEBUG", "WARNING", "ERROR", "CRITICAL"] + message: str + timestamp: str + + +class LogsView(Component): + """ + Creates a component to visualize logs from a subprocess in real-time. + """ + + EVENTS = [ + Events.change, + Events.input, + Events.focus, + Events.blur, + ] + + def __init__( + self, + value: str | Callable | tuple[str] | None = None, + *, + every: float | None = None, + lines: int = 5, + label: str | None = None, + show_label: bool | None = None, + container: bool = True, + scale: int | None = None, + min_width: int = 160, + visible: bool = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + render: bool = True, + ): + """ + Parameters: + value: Default value to show in the code editor. If callable, the function will be called whenever the app loads to set the initial value of the component. + every: If `value` is a callable, run the function 'every' number of seconds while the client connection is open. Has no effect otherwise. The event can be accessed (e.g. to cancel it) via this component's .load_event attribute. + label: The label for this component. Appears above the component and is also used as the header if there are a table of examples for this component. If None and used in a `gr.Interface`, the label will be the name of the parameter this component is assigned to. + show_label: if True, will display label. + container: If True, will place the component in a container - providing some extra padding around the border. + scale: relative size compared to adjacent Components. For example if Components A and B are in a Row, and A has scale=2, and B has scale=1, A will be twice as wide as B. Should be an integer. scale applies in Rows, and to top-level Components in Blocks where fill_height=True. + min_width: minimum pixel width, will wrap if not sufficient screen space to satisfy this value. If a certain scale value results in this Component being narrower than min_width, the min_width parameter will be respected first. + visible: If False, component will be hidden. + elem_id: An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles. + elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles. + render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later. + """ + self.language = "shell" + self.lines = lines + self.interactive = False + super().__init__( + label=label, + every=every, + show_label=show_label, + container=container, + scale=scale, + min_width=min_width, + visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + value=value, + ) + + def preprocess(self, payload: str | None) -> "LogsView": + """ + Parameters: + payload: string corresponding to the code + Returns: + Passes the code entered as a `str`. + """ + raise NotImplementedError("LogsView cannot be used as an input component.") + + def postprocess(self, value: List[Log]) -> List[Log]: + """ + Parameters: + value: Expects a list of `Log` logs. + Returns: + Returns the list of `Log` logs. + """ + return value + + def api_info(self) -> dict[str, Any]: + return { + "items": {"level": "string", "message": "string", "timestamp": "number"}, + "title": "Logs", + "type": "array", + } + + def example_payload(self) -> Any: + return [Log("INFO", "Hello World", datetime.now().isoformat())] + + def example_value(self) -> Any: + return [Log("INFO", "Hello World", datetime.now().isoformat())] + + @classmethod + def run_process( + cls, command: List[str], date_format: str = "%Y-%m-%d %H:%M:%S" + ) -> Generator[List[Log], None, None]: + """Run a command in a subprocess and yield logs in real-time.""" + process = subprocess.Popen( + command, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + ) + + if process.stdout is None: + raise ValueError("stdout is None") + + logs = [] + + def _log(level: str, message: str): + log = Log( + level=level, + message=message, + timestamp=datetime.now().strftime(date_format), + ) + logs.append(log) + return logs + + _log("INFO", f"Running {' '.join(command)}") + for line in process.stdout: + yield _log("INFO", line.strip()) + + # TODO: what if task is cancelled but process is still running? + + process.stdout.close() + return_code = process.wait() + if return_code: + yield _log("ERROR", f"Process exited with code {return_code}") + else: + yield _log("INFO", "Process exited successfully") + + @classmethod + def run_thread( + cls, + fn: Callable, + log_level: int = logging.INFO, + logger_name: str | None = None, + date_format: str = "%Y-%m-%d %H:%M:%S", + **kwargs, + ) -> Generator[List[Log], None, None]: + """Run a function in a thread and capture logs in real-time to yield them.""" + logs = [ + Log( + level="INFO", + message=f"Running {fn.__name__}({', '.join(f'{k}={v}' for k, v in kwargs.items())})", + timestamp=datetime.now().strftime(date_format), + ) + ] + yield logs + + thread = Thread(target=non_failing_fn(fn), kwargs=kwargs) + + def _log(record: logging.LogRecord) -> bool: + """Handle log record and return True if log should be yielded.""" + if record.thread != thread.ident: + return False # Skip if not from the thread + if logger_name and not record.name.startswith(logger_name): + return False # Skip if not from the logger + if record.levelno < log_level: + return False # Skip if too verbose + log = Log( + level=record.levelname, + message=record.getMessage(), + timestamp=datetime.fromtimestamp(record.created).strftime(date_format), + ) + logs.append(log) + return True + + with capture_logging(log_level) as log_queue: + thread.start() + + # Loop to capture and yield logs from the thread + while thread.is_alive(): + while True: + try: + if _log(log_queue.get_nowait()): + yield logs + except queue.Empty: + break + thread.join(timeout=0.1) # adjust the timeout as needed + + # After the thread completes, yield any remaining logs + while True: + try: + if _log(log_queue.get_nowait()): + yield logs + except queue.Empty: + break + + logs.append( + Log( + level="INFO", + message="Thread completed successfully", + timestamp=datetime.now().strftime(date_format), + ) + ) + + +@contextmanager +def capture_logging(log_level: int) -> Generator[Queue, None, None]: + # Create a queue to capture log messages + log_queue = queue.Queue() + logger = logging.getLogger() + logger.setLevel(log_level) + handler = QueueHandler(log_queue) + logger.addHandler(handler) + + # Yield the queue + yield log_queue + + # Clean up + logger.removeHandler(handler) + + +def non_failing_fn(fn: Callable, *args, **kwargs) -> Callable: + @wraps(fn) + def _inner(*args, **kwargs): + try: + return fn(*args, **kwargs) + except Exception as e: + logging.error(f"Error in {fn.__name__}: {e}", stack_info=True) + + return _inner diff --git a/src/backend/gradio_logsview/logsview.pyi b/src/backend/gradio_logsview/logsview.pyi new file mode 100644 index 0000000000000000000000000000000000000000..199fdf1560402a9590b610e5d7e71ec4448c7aa2 --- /dev/null +++ b/src/backend/gradio_logsview/logsview.pyi @@ -0,0 +1,375 @@ +"""gr.Code() component""" + +from __future__ import annotations + +from typing import Any, Callable, Literal + +from gradio_client.documentation import document + +from gradio.components.base import Component +from gradio.events import Events + + +class LogsView(Component): + """ + Creates a component to visualize logs from a subprocess in real-time. + """ + + EVENTS = [ + Events.change, + Events.input, + Events.focus, + Events.blur, + ] + + def __init__( + self, + value: str | Callable | tuple[str] | None = None, + *, + every: float | None = None, + lines: int = 5, + label: str | None = None, + show_label: bool | None = None, + container: bool = True, + scale: int | None = None, + min_width: int = 160, + visible: bool = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + render: bool = True, + ): + """ + Parameters: + value: Default value to show in the code editor. If callable, the function will be called whenever the app loads to set the initial value of the component. + every: If `value` is a callable, run the function 'every' number of seconds while the client connection is open. Has no effect otherwise. The event can be accessed (e.g. to cancel it) via this component's .load_event attribute. + label: The label for this component. Appears above the component and is also used as the header if there are a table of examples for this component. If None and used in a `gr.Interface`, the label will be the name of the parameter this component is assigned to. + show_label: if True, will display label. + container: If True, will place the component in a container - providing some extra padding around the border. + scale: relative size compared to adjacent Components. For example if Components A and B are in a Row, and A has scale=2, and B has scale=1, A will be twice as wide as B. Should be an integer. scale applies in Rows, and to top-level Components in Blocks where fill_height=True. + min_width: minimum pixel width, will wrap if not sufficient screen space to satisfy this value. If a certain scale value results in this Component being narrower than min_width, the min_width parameter will be respected first. + visible: If False, component will be hidden. + elem_id: An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles. + elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles. + render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later. + """ + self.language = "shell" + self.lines = lines + self.interactive = False + super().__init__( + label=label, + every=every, + show_label=show_label, + container=container, + scale=scale, + min_width=min_width, + visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + value=value, + ) + + def preprocess(self, payload: str | None) -> "LogsView": + """ + Parameters: + payload: string corresponding to the code + Returns: + Passes the code entered as a `str`. + """ + raise NotImplementedError("LogsView cannot be used as an input component.") + + def postprocess(self, value: List[Log]) -> List[Log]: + """ + Parameters: + value: Expects a list of `Log` logs. + Returns: + Returns the list of `Log` logs. + """ + return value + + def api_info(self) -> dict[str, Any]: + return { + "items": {"level": "string", "message": "string", "timestamp": "number"}, + "title": "Logs", + "type": "array", + } + + def example_payload(self) -> Any: + return [Log("INFO", "Hello World", datetime.now().isoformat())] + + def example_value(self) -> Any: + return [Log("INFO", "Hello World", datetime.now().isoformat())] + + @classmethod + def run_process( + cls, command: List[str], date_format: str = "%Y-%m-%d %H:%M:%S" + ) -> Generator[List[Log], None, None]: + """Run a command in a subprocess and yield logs in real-time.""" + process = subprocess.Popen( + command, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + ) + + if process.stdout is None: + raise ValueError("stdout is None") + + logs = [] + + def _log(level: str, message: str): + log = Log( + level=level, + message=message, + timestamp=datetime.now().strftime(date_format), + ) + logs.append(log) + return logs + + _log("INFO", f"Running {' '.join(command)}") + for line in process.stdout: + yield _log("INFO", line.strip()) + + # TODO: what if task is cancelled but process is still running? + + process.stdout.close() + return_code = process.wait() + if return_code: + yield _log("ERROR", f"Process exited with code {return_code}") + else: + yield _log("INFO", "Process exited successfully") + + @classmethod + def run_thread( + cls, + fn: Callable, + log_level: int = logging.INFO, + logger_name: str | None = None, + date_format: str = "%Y-%m-%d %H:%M:%S", + **kwargs, + ) -> Generator[List[Log], None, None]: + """Run a function in a thread and capture logs in real-time to yield them.""" + logs = [ + Log( + level="INFO", + message=f"Running {fn.__name__}({', '.join(f'{k}={v}' for k, v in kwargs.items())})", + timestamp=datetime.now().strftime(date_format), + ) + ] + yield logs + + thread = Thread(target=non_failing_fn(fn), kwargs=kwargs) + + def _log(record: logging.LogRecord) -> bool: + """Handle log record and return True if log should be yielded.""" + if record.thread != thread.ident: + return False # Skip if not from the thread + if logger_name and not record.name.startswith(logger_name): + return False # Skip if not from the logger + if record.levelno < log_level: + return False # Skip if too verbose + log = Log( + level=record.levelname, + message=record.getMessage(), + timestamp=datetime.fromtimestamp(record.created).strftime(date_format), + ) + logs.append(log) + return True + + with capture_logging(log_level) as log_queue: + thread.start() + + # Loop to capture and yield logs from the thread + while thread.is_alive(): + while True: + try: + if _log(log_queue.get_nowait()): + yield logs + except queue.Empty: + break + thread.join(timeout=0.1) # adjust the timeout as needed + + # After the thread completes, yield any remaining logs + while True: + try: + if _log(log_queue.get_nowait()): + yield logs + except queue.Empty: + break + + logs.append( + Log( + level="INFO", + message="Thread completed successfully", + timestamp=datetime.now().strftime(date_format), + ) + ) + + + def change(self, + fn: Callable | None, + inputs: Component | Sequence[Component] | set[Component] | None = None, + outputs: Component | Sequence[Component] | None = None, + api_name: str | None | Literal[False] = None, + scroll_to_output: bool = False, + show_progress: Literal["full", "minimal", "hidden"] = "full", + queue: bool | None = None, + batch: bool = False, + max_batch_size: int = 4, + preprocess: bool = True, + postprocess: bool = True, + cancels: dict[str, Any] | list[dict[str, Any]] | None = None, + every: float | None = None, + trigger_mode: Literal["once", "multiple", "always_last"] | None = None, + js: str | None = None, + concurrency_limit: int | None | Literal["default"] = "default", + concurrency_id: str | None = None, + show_api: bool = True) -> Dependency: + """ + Parameters: + fn: the function to call when this event is triggered. Often a machine learning model's prediction function. Each parameter of the function corresponds to one input component, and the function should return a single value or a tuple of values, with each element in the tuple corresponding to one output component. + inputs: List of gradio.components to use as inputs. If the function takes no inputs, this should be an empty list. + outputs: List of gradio.components to use as outputs. If the function returns no outputs, this should be an empty list. + api_name: Defines how the endpoint appears in the API docs. Can be a string, None, or False. If False, the endpoint will not be exposed in the api docs. If set to None, the endpoint will be exposed in the api docs as an unnamed endpoint, although this behavior will be changed in Gradio 4.0. If set to a string, the endpoint will be exposed in the api docs with the given name. + scroll_to_output: If True, will scroll to output component on completion + show_progress: If True, will show progress animation while pending + queue: If True, will place the request on the queue, if the queue has been enabled. If False, will not put this event on the queue, even if the queue has been enabled. If None, will use the queue setting of the gradio app. + batch: If True, then the function should process a batch of inputs, meaning that it should accept a list of input values for each parameter. The lists should be of equal length (and be up to length `max_batch_size`). The function is then *required* to return a tuple of lists (even if there is only 1 output component), with each list in the tuple corresponding to one output component. + max_batch_size: Maximum number of inputs to batch together if this is called from the queue (only relevant if batch=True) + preprocess: If False, will not run preprocessing of component data before running 'fn' (e.g. leaving it as a base64 string if this method is called with the `Image` component). + postprocess: If False, will not run postprocessing of component data before returning 'fn' output to the browser. + cancels: A list of other events to cancel when this listener is triggered. For example, setting cancels=[click_event] will cancel the click_event, where click_event is the return value of another components .click method. Functions that have not yet run (or generators that are iterating) will be cancelled, but functions that are currently running will be allowed to finish. + every: Run this event 'every' number of seconds while the client connection is open. Interpreted in seconds. + trigger_mode: If "once" (default for all events except `.change()`) would not allow any submissions while an event is pending. If set to "multiple", unlimited submissions are allowed while pending, and "always_last" (default for `.change()` and `.key_up()` events) would allow a second submission after the pending event is complete. + js: Optional frontend js method to run before running 'fn'. Input arguments for js method are values of 'inputs' and 'outputs', return should be a list of values for output components. + concurrency_limit: If set, this is the maximum number of this event that can be running simultaneously. Can be set to None to mean no concurrency_limit (any number of this event can be running simultaneously). Set to "default" to use the default concurrency limit (defined by the `default_concurrency_limit` parameter in `Blocks.queue()`, which itself is 1 by default). + concurrency_id: If set, this is the id of the concurrency group. Events with the same concurrency_id will be limited by the lowest set concurrency_limit. + show_api: whether to show this event in the "view API" page of the Gradio app, or in the ".view_api()" method of the Gradio clients. Unlike setting api_name to False, setting show_api to False will still allow downstream apps to use this event. If fn is None, show_api will automatically be set to False. + """ + ... + + def input(self, + fn: Callable | None, + inputs: Component | Sequence[Component] | set[Component] | None = None, + outputs: Component | Sequence[Component] | None = None, + api_name: str | None | Literal[False] = None, + scroll_to_output: bool = False, + show_progress: Literal["full", "minimal", "hidden"] = "full", + queue: bool | None = None, + batch: bool = False, + max_batch_size: int = 4, + preprocess: bool = True, + postprocess: bool = True, + cancels: dict[str, Any] | list[dict[str, Any]] | None = None, + every: float | None = None, + trigger_mode: Literal["once", "multiple", "always_last"] | None = None, + js: str | None = None, + concurrency_limit: int | None | Literal["default"] = "default", + concurrency_id: str | None = None, + show_api: bool = True) -> Dependency: + """ + Parameters: + fn: the function to call when this event is triggered. Often a machine learning model's prediction function. Each parameter of the function corresponds to one input component, and the function should return a single value or a tuple of values, with each element in the tuple corresponding to one output component. + inputs: List of gradio.components to use as inputs. If the function takes no inputs, this should be an empty list. + outputs: List of gradio.components to use as outputs. If the function returns no outputs, this should be an empty list. + api_name: Defines how the endpoint appears in the API docs. Can be a string, None, or False. If False, the endpoint will not be exposed in the api docs. If set to None, the endpoint will be exposed in the api docs as an unnamed endpoint, although this behavior will be changed in Gradio 4.0. If set to a string, the endpoint will be exposed in the api docs with the given name. + scroll_to_output: If True, will scroll to output component on completion + show_progress: If True, will show progress animation while pending + queue: If True, will place the request on the queue, if the queue has been enabled. If False, will not put this event on the queue, even if the queue has been enabled. If None, will use the queue setting of the gradio app. + batch: If True, then the function should process a batch of inputs, meaning that it should accept a list of input values for each parameter. The lists should be of equal length (and be up to length `max_batch_size`). The function is then *required* to return a tuple of lists (even if there is only 1 output component), with each list in the tuple corresponding to one output component. + max_batch_size: Maximum number of inputs to batch together if this is called from the queue (only relevant if batch=True) + preprocess: If False, will not run preprocessing of component data before running 'fn' (e.g. leaving it as a base64 string if this method is called with the `Image` component). + postprocess: If False, will not run postprocessing of component data before returning 'fn' output to the browser. + cancels: A list of other events to cancel when this listener is triggered. For example, setting cancels=[click_event] will cancel the click_event, where click_event is the return value of another components .click method. Functions that have not yet run (or generators that are iterating) will be cancelled, but functions that are currently running will be allowed to finish. + every: Run this event 'every' number of seconds while the client connection is open. Interpreted in seconds. + trigger_mode: If "once" (default for all events except `.change()`) would not allow any submissions while an event is pending. If set to "multiple", unlimited submissions are allowed while pending, and "always_last" (default for `.change()` and `.key_up()` events) would allow a second submission after the pending event is complete. + js: Optional frontend js method to run before running 'fn'. Input arguments for js method are values of 'inputs' and 'outputs', return should be a list of values for output components. + concurrency_limit: If set, this is the maximum number of this event that can be running simultaneously. Can be set to None to mean no concurrency_limit (any number of this event can be running simultaneously). Set to "default" to use the default concurrency limit (defined by the `default_concurrency_limit` parameter in `Blocks.queue()`, which itself is 1 by default). + concurrency_id: If set, this is the id of the concurrency group. Events with the same concurrency_id will be limited by the lowest set concurrency_limit. + show_api: whether to show this event in the "view API" page of the Gradio app, or in the ".view_api()" method of the Gradio clients. Unlike setting api_name to False, setting show_api to False will still allow downstream apps to use this event. If fn is None, show_api will automatically be set to False. + """ + ... + + def focus(self, + fn: Callable | None, + inputs: Component | Sequence[Component] | set[Component] | None = None, + outputs: Component | Sequence[Component] | None = None, + api_name: str | None | Literal[False] = None, + scroll_to_output: bool = False, + show_progress: Literal["full", "minimal", "hidden"] = "full", + queue: bool | None = None, + batch: bool = False, + max_batch_size: int = 4, + preprocess: bool = True, + postprocess: bool = True, + cancels: dict[str, Any] | list[dict[str, Any]] | None = None, + every: float | None = None, + trigger_mode: Literal["once", "multiple", "always_last"] | None = None, + js: str | None = None, + concurrency_limit: int | None | Literal["default"] = "default", + concurrency_id: str | None = None, + show_api: bool = True) -> Dependency: + """ + Parameters: + fn: the function to call when this event is triggered. Often a machine learning model's prediction function. Each parameter of the function corresponds to one input component, and the function should return a single value or a tuple of values, with each element in the tuple corresponding to one output component. + inputs: List of gradio.components to use as inputs. If the function takes no inputs, this should be an empty list. + outputs: List of gradio.components to use as outputs. If the function returns no outputs, this should be an empty list. + api_name: Defines how the endpoint appears in the API docs. Can be a string, None, or False. If False, the endpoint will not be exposed in the api docs. If set to None, the endpoint will be exposed in the api docs as an unnamed endpoint, although this behavior will be changed in Gradio 4.0. If set to a string, the endpoint will be exposed in the api docs with the given name. + scroll_to_output: If True, will scroll to output component on completion + show_progress: If True, will show progress animation while pending + queue: If True, will place the request on the queue, if the queue has been enabled. If False, will not put this event on the queue, even if the queue has been enabled. If None, will use the queue setting of the gradio app. + batch: If True, then the function should process a batch of inputs, meaning that it should accept a list of input values for each parameter. The lists should be of equal length (and be up to length `max_batch_size`). The function is then *required* to return a tuple of lists (even if there is only 1 output component), with each list in the tuple corresponding to one output component. + max_batch_size: Maximum number of inputs to batch together if this is called from the queue (only relevant if batch=True) + preprocess: If False, will not run preprocessing of component data before running 'fn' (e.g. leaving it as a base64 string if this method is called with the `Image` component). + postprocess: If False, will not run postprocessing of component data before returning 'fn' output to the browser. + cancels: A list of other events to cancel when this listener is triggered. For example, setting cancels=[click_event] will cancel the click_event, where click_event is the return value of another components .click method. Functions that have not yet run (or generators that are iterating) will be cancelled, but functions that are currently running will be allowed to finish. + every: Run this event 'every' number of seconds while the client connection is open. Interpreted in seconds. + trigger_mode: If "once" (default for all events except `.change()`) would not allow any submissions while an event is pending. If set to "multiple", unlimited submissions are allowed while pending, and "always_last" (default for `.change()` and `.key_up()` events) would allow a second submission after the pending event is complete. + js: Optional frontend js method to run before running 'fn'. Input arguments for js method are values of 'inputs' and 'outputs', return should be a list of values for output components. + concurrency_limit: If set, this is the maximum number of this event that can be running simultaneously. Can be set to None to mean no concurrency_limit (any number of this event can be running simultaneously). Set to "default" to use the default concurrency limit (defined by the `default_concurrency_limit` parameter in `Blocks.queue()`, which itself is 1 by default). + concurrency_id: If set, this is the id of the concurrency group. Events with the same concurrency_id will be limited by the lowest set concurrency_limit. + show_api: whether to show this event in the "view API" page of the Gradio app, or in the ".view_api()" method of the Gradio clients. Unlike setting api_name to False, setting show_api to False will still allow downstream apps to use this event. If fn is None, show_api will automatically be set to False. + """ + ... + + def blur(self, + fn: Callable | None, + inputs: Component | Sequence[Component] | set[Component] | None = None, + outputs: Component | Sequence[Component] | None = None, + api_name: str | None | Literal[False] = None, + scroll_to_output: bool = False, + show_progress: Literal["full", "minimal", "hidden"] = "full", + queue: bool | None = None, + batch: bool = False, + max_batch_size: int = 4, + preprocess: bool = True, + postprocess: bool = True, + cancels: dict[str, Any] | list[dict[str, Any]] | None = None, + every: float | None = None, + trigger_mode: Literal["once", "multiple", "always_last"] | None = None, + js: str | None = None, + concurrency_limit: int | None | Literal["default"] = "default", + concurrency_id: str | None = None, + show_api: bool = True) -> Dependency: + """ + Parameters: + fn: the function to call when this event is triggered. Often a machine learning model's prediction function. Each parameter of the function corresponds to one input component, and the function should return a single value or a tuple of values, with each element in the tuple corresponding to one output component. + inputs: List of gradio.components to use as inputs. If the function takes no inputs, this should be an empty list. + outputs: List of gradio.components to use as outputs. If the function returns no outputs, this should be an empty list. + api_name: Defines how the endpoint appears in the API docs. Can be a string, None, or False. If False, the endpoint will not be exposed in the api docs. If set to None, the endpoint will be exposed in the api docs as an unnamed endpoint, although this behavior will be changed in Gradio 4.0. If set to a string, the endpoint will be exposed in the api docs with the given name. + scroll_to_output: If True, will scroll to output component on completion + show_progress: If True, will show progress animation while pending + queue: If True, will place the request on the queue, if the queue has been enabled. If False, will not put this event on the queue, even if the queue has been enabled. If None, will use the queue setting of the gradio app. + batch: If True, then the function should process a batch of inputs, meaning that it should accept a list of input values for each parameter. The lists should be of equal length (and be up to length `max_batch_size`). The function is then *required* to return a tuple of lists (even if there is only 1 output component), with each list in the tuple corresponding to one output component. + max_batch_size: Maximum number of inputs to batch together if this is called from the queue (only relevant if batch=True) + preprocess: If False, will not run preprocessing of component data before running 'fn' (e.g. leaving it as a base64 string if this method is called with the `Image` component). + postprocess: If False, will not run postprocessing of component data before returning 'fn' output to the browser. + cancels: A list of other events to cancel when this listener is triggered. For example, setting cancels=[click_event] will cancel the click_event, where click_event is the return value of another components .click method. Functions that have not yet run (or generators that are iterating) will be cancelled, but functions that are currently running will be allowed to finish. + every: Run this event 'every' number of seconds while the client connection is open. Interpreted in seconds. + trigger_mode: If "once" (default for all events except `.change()`) would not allow any submissions while an event is pending. If set to "multiple", unlimited submissions are allowed while pending, and "always_last" (default for `.change()` and `.key_up()` events) would allow a second submission after the pending event is complete. + js: Optional frontend js method to run before running 'fn'. Input arguments for js method are values of 'inputs' and 'outputs', return should be a list of values for output components. + concurrency_limit: If set, this is the maximum number of this event that can be running simultaneously. Can be set to None to mean no concurrency_limit (any number of this event can be running simultaneously). Set to "default" to use the default concurrency limit (defined by the `default_concurrency_limit` parameter in `Blocks.queue()`, which itself is 1 by default). + concurrency_id: If set, this is the id of the concurrency group. Events with the same concurrency_id will be limited by the lowest set concurrency_limit. + show_api: whether to show this event in the "view API" page of the Gradio app, or in the ".view_api()" method of the Gradio clients. Unlike setting api_name to False, setting show_api to False will still allow downstream apps to use this event. If fn is None, show_api will automatically be set to False. + """ + ... diff --git a/src/backend/gradio_logsview/templates/component/.gitignore b/src/backend/gradio_logsview/templates/component/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..f59ec20aabf5842d237244ece8c81ab184faeac1 --- /dev/null +++ b/src/backend/gradio_logsview/templates/component/.gitignore @@ -0,0 +1 @@ +* \ No newline at end of file diff --git a/src/backend/gradio_logsview/templates/component/Index-d65e8fec.js b/src/backend/gradio_logsview/templates/component/Index-d65e8fec.js new file mode 100644 index 0000000000000000000000000000000000000000..abab97e25ea2ed4b4ffe334ad441970d7488ee3b --- /dev/null +++ b/src/backend/gradio_logsview/templates/component/Index-d65e8fec.js @@ -0,0 +1,19773 @@ +class Y { + /** + Get the line description around the given position. + */ + lineAt(e) { + if (e < 0 || e > this.length) + throw new RangeError(`Invalid position ${e} in document of length ${this.length}`); + return this.lineInner(e, !1, 1, 0); + } + /** + Get the description for the given (1-based) line number. + */ + line(e) { + if (e < 1 || e > this.lines) + throw new RangeError(`Invalid line number ${e} in ${this.lines}-line document`); + return this.lineInner(e, !0, 1, 0); + } + /** + Replace a range of the text with the given content. + */ + replace(e, t, i) { + [e, t] = Mi(this, e, t); + let s = []; + return this.decompose( + 0, + e, + s, + 2 + /* Open.To */ + ), i.length && i.decompose( + 0, + i.length, + s, + 3 + /* Open.To */ + ), this.decompose( + t, + this.length, + s, + 1 + /* Open.From */ + ), nt.from(s, this.length - (t - e) + i.length); + } + /** + Append another document to this one. + */ + append(e) { + return this.replace(this.length, this.length, e); + } + /** + Retrieve the text between the given points. + */ + slice(e, t = this.length) { + [e, t] = Mi(this, e, t); + let i = []; + return this.decompose(e, t, i, 0), nt.from(i, t - e); + } + /** + Test whether this text is equal to another instance. + */ + eq(e) { + if (e == this) + return !0; + if (e.length != this.length || e.lines != this.lines) + return !1; + let t = this.scanIdentical(e, 1), i = this.length - this.scanIdentical(e, -1), s = new tn(this), r = new tn(e); + for (let o = t, l = t; ; ) { + if (s.next(o), r.next(o), o = 0, s.lineBreak != r.lineBreak || s.done != r.done || s.value != r.value) + return !1; + if (l += s.value.length, s.done || l >= i) + return !0; + } + } + /** + Iterate over the text. When `dir` is `-1`, iteration happens + from end to start. This will return lines and the breaks between + them as separate strings. + */ + iter(e = 1) { + return new tn(this, e); + } + /** + Iterate over a range of the text. When `from` > `to`, the + iterator will run in reverse. + */ + iterRange(e, t = this.length) { + return new rf(this, e, t); + } + /** + Return a cursor that iterates over the given range of lines, + _without_ returning the line breaks between, and yielding empty + strings for empty lines. + + When `from` and `to` are given, they should be 1-based line numbers. + */ + iterLines(e, t) { + let i; + if (e == null) + i = this.iter(); + else { + t == null && (t = this.lines + 1); + let s = this.line(e).from; + i = this.iterRange(s, Math.max(s, t == this.lines + 1 ? this.length : t <= 1 ? 0 : this.line(t - 1).to)); + } + return new of(i); + } + /** + Return the document as a string, using newline characters to + separate lines. + */ + toString() { + return this.sliceString(0); + } + /** + Convert the document to an array of lines (which can be + deserialized again via [`Text.of`](https://codemirror.net/6/docs/ref/#state.Text^of)). + */ + toJSON() { + let e = []; + return this.flatten(e), e; + } + /** + @internal + */ + constructor() { + } + /** + Create a `Text` instance for the given array of lines. + */ + static of(e) { + if (e.length == 0) + throw new RangeError("A document must have at least one line"); + return e.length == 1 && !e[0] ? Y.empty : e.length <= 32 ? new le(e) : nt.from(le.split(e, [])); + } +} +class le extends Y { + constructor(e, t = kd(e)) { + super(), this.text = e, this.length = t; + } + get lines() { + return this.text.length; + } + get children() { + return null; + } + lineInner(e, t, i, s) { + for (let r = 0; ; r++) { + let o = this.text[r], l = s + o.length; + if ((t ? i : l) >= e) + return new vd(s, l, i, o); + s = l + 1, i++; + } + } + decompose(e, t, i, s) { + let r = e <= 0 && t >= this.length ? this : new le(kl(this.text, e, t), Math.min(t, this.length) - Math.max(0, e)); + if (s & 1) { + let o = i.pop(), l = ts(r.text, o.text.slice(), 0, r.length); + if (l.length <= 32) + i.push(new le(l, o.length + r.length)); + else { + let a = l.length >> 1; + i.push(new le(l.slice(0, a)), new le(l.slice(a))); + } + } else + i.push(r); + } + replace(e, t, i) { + if (!(i instanceof le)) + return super.replace(e, t, i); + [e, t] = Mi(this, e, t); + let s = ts(this.text, ts(i.text, kl(this.text, 0, e)), t), r = this.length + i.length - (t - e); + return s.length <= 32 ? new le(s, r) : nt.from(le.split(s, []), r); + } + sliceString(e, t = this.length, i = ` +`) { + [e, t] = Mi(this, e, t); + let s = ""; + for (let r = 0, o = 0; r <= t && o < this.text.length; o++) { + let l = this.text[o], a = r + l.length; + r > e && o && (s += i), e < a && t > r && (s += l.slice(Math.max(0, e - r), t - r)), r = a + 1; + } + return s; + } + flatten(e) { + for (let t of this.text) + e.push(t); + } + scanIdentical() { + return 0; + } + static split(e, t) { + let i = [], s = -1; + for (let r of e) + i.push(r), s += r.length + 1, i.length == 32 && (t.push(new le(i, s)), i = [], s = -1); + return s > -1 && t.push(new le(i, s)), t; + } +} +class nt extends Y { + constructor(e, t) { + super(), this.children = e, this.length = t, this.lines = 0; + for (let i of e) + this.lines += i.lines; + } + lineInner(e, t, i, s) { + for (let r = 0; ; r++) { + let o = this.children[r], l = s + o.length, a = i + o.lines - 1; + if ((t ? a : l) >= e) + return o.lineInner(e, t, i, s); + s = l + 1, i = a + 1; + } + } + decompose(e, t, i, s) { + for (let r = 0, o = 0; o <= t && r < this.children.length; r++) { + let l = this.children[r], a = o + l.length; + if (e <= a && t >= o) { + let h = s & ((o <= e ? 1 : 0) | (a >= t ? 2 : 0)); + o >= e && a <= t && !h ? i.push(l) : l.decompose(e - o, t - o, i, h); + } + o = a + 1; + } + } + replace(e, t, i) { + if ([e, t] = Mi(this, e, t), i.lines < this.lines) + for (let s = 0, r = 0; s < this.children.length; s++) { + let o = this.children[s], l = r + o.length; + if (e >= r && t <= l) { + let a = o.replace(e - r, t - r, i), h = this.lines - o.lines + a.lines; + if (a.lines < h >> 4 && a.lines > h >> 6) { + let f = this.children.slice(); + return f[s] = a, new nt(f, this.length - (t - e) + i.length); + } + return super.replace(r, l, a); + } + r = l + 1; + } + return super.replace(e, t, i); + } + sliceString(e, t = this.length, i = ` +`) { + [e, t] = Mi(this, e, t); + let s = ""; + for (let r = 0, o = 0; r < this.children.length && o <= t; r++) { + let l = this.children[r], a = o + l.length; + o > e && r && (s += i), e < a && t > o && (s += l.sliceString(e - o, t - o, i)), o = a + 1; + } + return s; + } + flatten(e) { + for (let t of this.children) + t.flatten(e); + } + scanIdentical(e, t) { + if (!(e instanceof nt)) + return 0; + let i = 0, [s, r, o, l] = t > 0 ? [0, 0, this.children.length, e.children.length] : [this.children.length - 1, e.children.length - 1, -1, -1]; + for (; ; s += t, r += t) { + if (s == o || r == l) + return i; + let a = this.children[s], h = e.children[r]; + if (a != h) + return i + a.scanIdentical(h, t); + i += a.length + 1; + } + } + static from(e, t = e.reduce((i, s) => i + s.length + 1, -1)) { + let i = 0; + for (let d of e) + i += d.lines; + if (i < 32) { + let d = []; + for (let p of e) + p.flatten(d); + return new le(d, t); + } + let s = Math.max( + 32, + i >> 5 + /* Tree.BranchShift */ + ), r = s << 1, o = s >> 1, l = [], a = 0, h = -1, f = []; + function c(d) { + let p; + if (d.lines > r && d instanceof nt) + for (let m of d.children) + c(m); + else + d.lines > o && (a > o || !a) ? (u(), l.push(d)) : d instanceof le && a && (p = f[f.length - 1]) instanceof le && d.lines + p.lines <= 32 ? (a += d.lines, h += d.length + 1, f[f.length - 1] = new le(p.text.concat(d.text), p.length + 1 + d.length)) : (a + d.lines > s && u(), a += d.lines, h += d.length + 1, f.push(d)); + } + function u() { + a != 0 && (l.push(f.length == 1 ? f[0] : nt.from(f, h)), h = -1, a = f.length = 0); + } + for (let d of e) + c(d); + return u(), l.length == 1 ? l[0] : new nt(l, t); + } +} +Y.empty = /* @__PURE__ */ new le([""], 0); +function kd(n) { + let e = -1; + for (let t of n) + e += t.length + 1; + return e; +} +function ts(n, e, t = 0, i = 1e9) { + for (let s = 0, r = 0, o = !0; r < n.length && s <= i; r++) { + let l = n[r], a = s + l.length; + a >= t && (a > i && (l = l.slice(0, i - s)), s < t && (l = l.slice(t - s)), o ? (e[e.length - 1] += l, o = !1) : e.push(l)), s = a + 1; + } + return e; +} +function kl(n, e, t) { + return ts(n, [""], e, t); +} +class tn { + constructor(e, t = 1) { + this.dir = t, this.done = !1, this.lineBreak = !1, this.value = "", this.nodes = [e], this.offsets = [t > 0 ? 1 : (e instanceof le ? e.text.length : e.children.length) << 1]; + } + nextInner(e, t) { + for (this.done = this.lineBreak = !1; ; ) { + let i = this.nodes.length - 1, s = this.nodes[i], r = this.offsets[i], o = r >> 1, l = s instanceof le ? s.text.length : s.children.length; + if (o == (t > 0 ? l : 0)) { + if (i == 0) + return this.done = !0, this.value = "", this; + t > 0 && this.offsets[i - 1]++, this.nodes.pop(), this.offsets.pop(); + } else if ((r & 1) == (t > 0 ? 0 : 1)) { + if (this.offsets[i] += t, e == 0) + return this.lineBreak = !0, this.value = ` +`, this; + e--; + } else if (s instanceof le) { + let a = s.text[o + (t < 0 ? -1 : 0)]; + if (this.offsets[i] += t, a.length > Math.max(0, e)) + return this.value = e == 0 ? a : t > 0 ? a.slice(e) : a.slice(0, a.length - e), this; + e -= a.length; + } else { + let a = s.children[o + (t < 0 ? -1 : 0)]; + e > a.length ? (e -= a.length, this.offsets[i] += t) : (t < 0 && this.offsets[i]--, this.nodes.push(a), this.offsets.push(t > 0 ? 1 : (a instanceof le ? a.text.length : a.children.length) << 1)); + } + } + } + next(e = 0) { + return e < 0 && (this.nextInner(-e, -this.dir), e = this.value.length), this.nextInner(e, this.dir); + } +} +class rf { + constructor(e, t, i) { + this.value = "", this.done = !1, this.cursor = new tn(e, t > i ? -1 : 1), this.pos = t > i ? e.length : 0, this.from = Math.min(t, i), this.to = Math.max(t, i); + } + nextInner(e, t) { + if (t < 0 ? this.pos <= this.from : this.pos >= this.to) + return this.value = "", this.done = !0, this; + e += Math.max(0, t < 0 ? this.pos - this.to : this.from - this.pos); + let i = t < 0 ? this.pos - this.from : this.to - this.pos; + e > i && (e = i), i -= e; + let { value: s } = this.cursor.next(e); + return this.pos += (s.length + e) * t, this.value = s.length <= i ? s : t < 0 ? s.slice(s.length - i) : s.slice(0, i), this.done = !this.value, this; + } + next(e = 0) { + return e < 0 ? e = Math.max(e, this.from - this.pos) : e > 0 && (e = Math.min(e, this.to - this.pos)), this.nextInner(e, this.cursor.dir); + } + get lineBreak() { + return this.cursor.lineBreak && this.value != ""; + } +} +class of { + constructor(e) { + this.inner = e, this.afterBreak = !0, this.value = "", this.done = !1; + } + next(e = 0) { + let { done: t, lineBreak: i, value: s } = this.inner.next(e); + return t && this.afterBreak ? (this.value = "", this.afterBreak = !1) : t ? (this.done = !0, this.value = "") : i ? this.afterBreak ? this.value = "" : (this.afterBreak = !0, this.next()) : (this.value = s, this.afterBreak = !1), this; + } + get lineBreak() { + return !1; + } +} +typeof Symbol < "u" && (Y.prototype[Symbol.iterator] = function() { + return this.iter(); +}, tn.prototype[Symbol.iterator] = rf.prototype[Symbol.iterator] = of.prototype[Symbol.iterator] = function() { + return this; +}); +class vd { + /** + @internal + */ + constructor(e, t, i, s) { + this.from = e, this.to = t, this.number = i, this.text = s; + } + /** + The length of the line (not including any line break after it). + */ + get length() { + return this.to - this.from; + } +} +function Mi(n, e, t) { + return e = Math.max(0, Math.min(n.length, e)), [e, Math.max(e, Math.min(n.length, t))]; +} +let vi = /* @__PURE__ */ "lc,34,7n,7,7b,19,,,,2,,2,,,20,b,1c,l,g,,2t,7,2,6,2,2,,4,z,,u,r,2j,b,1m,9,9,,o,4,,9,,3,,5,17,3,3b,f,,w,1j,,,,4,8,4,,3,7,a,2,t,,1m,,,,2,4,8,,9,,a,2,q,,2,2,1l,,4,2,4,2,2,3,3,,u,2,3,,b,2,1l,,4,5,,2,4,,k,2,m,6,,,1m,,,2,,4,8,,7,3,a,2,u,,1n,,,,c,,9,,14,,3,,1l,3,5,3,,4,7,2,b,2,t,,1m,,2,,2,,3,,5,2,7,2,b,2,s,2,1l,2,,,2,4,8,,9,,a,2,t,,20,,4,,2,3,,,8,,29,,2,7,c,8,2q,,2,9,b,6,22,2,r,,,,,,1j,e,,5,,2,5,b,,10,9,,2u,4,,6,,2,2,2,p,2,4,3,g,4,d,,2,2,6,,f,,jj,3,qa,3,t,3,t,2,u,2,1s,2,,7,8,,2,b,9,,19,3,3b,2,y,,3a,3,4,2,9,,6,3,63,2,2,,1m,,,7,,,,,2,8,6,a,2,,1c,h,1r,4,1c,7,,,5,,14,9,c,2,w,4,2,2,,3,1k,,,2,3,,,3,1m,8,2,2,48,3,,d,,7,4,,6,,3,2,5i,1m,,5,ek,,5f,x,2da,3,3x,,2o,w,fe,6,2x,2,n9w,4,,a,w,2,28,2,7k,,3,,4,,p,2,5,,47,2,q,i,d,,12,8,p,b,1a,3,1c,,2,4,2,2,13,,1v,6,2,2,2,2,c,,8,,1b,,1f,,,3,2,2,5,2,,,16,2,8,,6m,,2,,4,,fn4,,kh,g,g,g,a6,2,gt,,6a,,45,5,1ae,3,,2,5,4,14,3,4,,4l,2,fx,4,ar,2,49,b,4w,,1i,f,1k,3,1d,4,2,2,1x,3,10,5,,8,1q,,c,2,1g,9,a,4,2,,2n,3,2,,,2,6,,4g,,3,8,l,2,1l,2,,,,,m,,e,7,3,5,5f,8,2,3,,,n,,29,,2,6,,,2,,,2,,2,6j,,2,4,6,2,,2,r,2,2d,8,2,,,2,2y,,,,2,6,,,2t,3,2,4,,5,77,9,,2,6t,,a,2,,,4,,40,4,2,2,4,,w,a,14,6,2,4,8,,9,6,2,3,1a,d,,2,ba,7,,6,,,2a,m,2,7,,2,,2,3e,6,3,,,2,,7,,,20,2,3,,,,9n,2,f0b,5,1n,7,t4,,1r,4,29,,f5k,2,43q,,,3,4,5,8,8,2,7,u,4,44,3,1iz,1j,4,1e,8,,e,,m,5,,f,11s,7,,h,2,7,,2,,5,79,7,c5,4,15s,7,31,7,240,5,gx7k,2o,3k,6o".split(",").map((n) => n ? parseInt(n, 36) : 1); +for (let n = 1; n < vi.length; n++) + vi[n] += vi[n - 1]; +function xd(n) { + for (let e = 1; e < vi.length; e += 2) + if (vi[e] > n) + return vi[e - 1] <= n; + return !1; +} +function vl(n) { + return n >= 127462 && n <= 127487; +} +const xl = 8205; +function ve(n, e, t = !0, i = !0) { + return (t ? lf : Sd)(n, e, i); +} +function lf(n, e, t) { + if (e == n.length) + return e; + e && af(n.charCodeAt(e)) && hf(n.charCodeAt(e - 1)) && e--; + let i = ge(n, e); + for (e += Ue(i); e < n.length; ) { + let s = ge(n, e); + if (i == xl || s == xl || t && xd(s)) + e += Ue(s), i = s; + else if (vl(s)) { + let r = 0, o = e - 2; + for (; o >= 0 && vl(ge(n, o)); ) + r++, o -= 2; + if (r % 2 == 0) + break; + e += 2; + } else + break; + } + return e; +} +function Sd(n, e, t) { + for (; e > 0; ) { + let i = lf(n, e - 2, t); + if (i < e) + return i; + e--; + } + return 0; +} +function af(n) { + return n >= 56320 && n < 57344; +} +function hf(n) { + return n >= 55296 && n < 56320; +} +function ge(n, e) { + let t = n.charCodeAt(e); + if (!hf(t) || e + 1 == n.length) + return t; + let i = n.charCodeAt(e + 1); + return af(i) ? (t - 55296 << 10) + (i - 56320) + 65536 : t; +} +function ff(n) { + return n <= 65535 ? String.fromCharCode(n) : (n -= 65536, String.fromCharCode((n >> 10) + 55296, (n & 1023) + 56320)); +} +function Ue(n) { + return n < 65536 ? 1 : 2; +} +const Er = /\r\n?|\n/; +var pe = /* @__PURE__ */ function(n) { + return n[n.Simple = 0] = "Simple", n[n.TrackDel = 1] = "TrackDel", n[n.TrackBefore = 2] = "TrackBefore", n[n.TrackAfter = 3] = "TrackAfter", n; +}(pe || (pe = {})); +class ct { + // Sections are encoded as pairs of integers. The first is the + // length in the current document, and the second is -1 for + // unaffected sections, and the length of the replacement content + // otherwise. So an insertion would be (0, n>0), a deletion (n>0, + // 0), and a replacement two positive numbers. + /** + @internal + */ + constructor(e) { + this.sections = e; + } + /** + The length of the document before the change. + */ + get length() { + let e = 0; + for (let t = 0; t < this.sections.length; t += 2) + e += this.sections[t]; + return e; + } + /** + The length of the document after the change. + */ + get newLength() { + let e = 0; + for (let t = 0; t < this.sections.length; t += 2) { + let i = this.sections[t + 1]; + e += i < 0 ? this.sections[t] : i; + } + return e; + } + /** + False when there are actual changes in this set. + */ + get empty() { + return this.sections.length == 0 || this.sections.length == 2 && this.sections[1] < 0; + } + /** + Iterate over the unchanged parts left by these changes. `posA` + provides the position of the range in the old document, `posB` + the new position in the changed document. + */ + iterGaps(e) { + for (let t = 0, i = 0, s = 0; t < this.sections.length; ) { + let r = this.sections[t++], o = this.sections[t++]; + o < 0 ? (e(i, s, r), s += r) : s += o, i += r; + } + } + /** + Iterate over the ranges changed by these changes. (See + [`ChangeSet.iterChanges`](https://codemirror.net/6/docs/ref/#state.ChangeSet.iterChanges) for a + variant that also provides you with the inserted text.) + `fromA`/`toA` provides the extent of the change in the starting + document, `fromB`/`toB` the extent of the replacement in the + changed document. + + When `individual` is true, adjacent changes (which are kept + separate for [position mapping](https://codemirror.net/6/docs/ref/#state.ChangeDesc.mapPos)) are + reported separately. + */ + iterChangedRanges(e, t = !1) { + Rr(this, e, t); + } + /** + Get a description of the inverted form of these changes. + */ + get invertedDesc() { + let e = []; + for (let t = 0; t < this.sections.length; ) { + let i = this.sections[t++], s = this.sections[t++]; + s < 0 ? e.push(i, s) : e.push(s, i); + } + return new ct(e); + } + /** + Compute the combined effect of applying another set of changes + after this one. The length of the document after this set should + match the length before `other`. + */ + composeDesc(e) { + return this.empty ? e : e.empty ? this : cf(this, e); + } + /** + Map this description, which should start with the same document + as `other`, over another set of changes, so that it can be + applied after it. When `before` is true, map as if the changes + in `other` happened before the ones in `this`. + */ + mapDesc(e, t = !1) { + return e.empty ? this : Ir(this, e, t); + } + mapPos(e, t = -1, i = pe.Simple) { + let s = 0, r = 0; + for (let o = 0; o < this.sections.length; ) { + let l = this.sections[o++], a = this.sections[o++], h = s + l; + if (a < 0) { + if (h > e) + return r + (e - s); + r += l; + } else { + if (i != pe.Simple && h >= e && (i == pe.TrackDel && s < e && h > e || i == pe.TrackBefore && s < e || i == pe.TrackAfter && h > e)) + return null; + if (h > e || h == e && t < 0 && !l) + return e == s || t < 0 ? r : r + a; + r += a; + } + s = h; + } + if (e > s) + throw new RangeError(`Position ${e} is out of range for changeset of length ${s}`); + return r; + } + /** + Check whether these changes touch a given range. When one of the + changes entirely covers the range, the string `"cover"` is + returned. + */ + touchesRange(e, t = e) { + for (let i = 0, s = 0; i < this.sections.length && s <= t; ) { + let r = this.sections[i++], o = this.sections[i++], l = s + r; + if (o >= 0 && s <= t && l >= e) + return s < e && l > t ? "cover" : !0; + s = l; + } + return !1; + } + /** + @internal + */ + toString() { + let e = ""; + for (let t = 0; t < this.sections.length; ) { + let i = this.sections[t++], s = this.sections[t++]; + e += (e ? " " : "") + i + (s >= 0 ? ":" + s : ""); + } + return e; + } + /** + Serialize this change desc to a JSON-representable value. + */ + toJSON() { + return this.sections; + } + /** + Create a change desc from its JSON representation (as produced + by [`toJSON`](https://codemirror.net/6/docs/ref/#state.ChangeDesc.toJSON). + */ + static fromJSON(e) { + if (!Array.isArray(e) || e.length % 2 || e.some((t) => typeof t != "number")) + throw new RangeError("Invalid JSON representation of ChangeDesc"); + return new ct(e); + } + /** + @internal + */ + static create(e) { + return new ct(e); + } +} +class fe extends ct { + constructor(e, t) { + super(e), this.inserted = t; + } + /** + Apply the changes to a document, returning the modified + document. + */ + apply(e) { + if (this.length != e.length) + throw new RangeError("Applying change set to a document with the wrong length"); + return Rr(this, (t, i, s, r, o) => e = e.replace(s, s + (i - t), o), !1), e; + } + mapDesc(e, t = !1) { + return Ir(this, e, t, !0); + } + /** + Given the document as it existed _before_ the changes, return a + change set that represents the inverse of this set, which could + be used to go from the document created by the changes back to + the document as it existed before the changes. + */ + invert(e) { + let t = this.sections.slice(), i = []; + for (let s = 0, r = 0; s < t.length; s += 2) { + let o = t[s], l = t[s + 1]; + if (l >= 0) { + t[s] = l, t[s + 1] = o; + let a = s >> 1; + for (; i.length < a; ) + i.push(Y.empty); + i.push(o ? e.slice(r, r + o) : Y.empty); + } + r += o; + } + return new fe(t, i); + } + /** + Combine two subsequent change sets into a single set. `other` + must start in the document produced by `this`. If `this` goes + `docA` → `docB` and `other` represents `docB` → `docC`, the + returned value will represent the change `docA` → `docC`. + */ + compose(e) { + return this.empty ? e : e.empty ? this : cf(this, e, !0); + } + /** + Given another change set starting in the same document, maps this + change set over the other, producing a new change set that can be + applied to the document produced by applying `other`. When + `before` is `true`, order changes as if `this` comes before + `other`, otherwise (the default) treat `other` as coming first. + + Given two changes `A` and `B`, `A.compose(B.map(A))` and + `B.compose(A.map(B, true))` will produce the same document. This + provides a basic form of [operational + transformation](https://en.wikipedia.org/wiki/Operational_transformation), + and can be used for collaborative editing. + */ + map(e, t = !1) { + return e.empty ? this : Ir(this, e, t, !0); + } + /** + Iterate over the changed ranges in the document, calling `f` for + each, with the range in the original document (`fromA`-`toA`) + and the range that replaces it in the new document + (`fromB`-`toB`). + + When `individual` is true, adjacent changes are reported + separately. + */ + iterChanges(e, t = !1) { + Rr(this, e, t); + } + /** + Get a [change description](https://codemirror.net/6/docs/ref/#state.ChangeDesc) for this change + set. + */ + get desc() { + return ct.create(this.sections); + } + /** + @internal + */ + filter(e) { + let t = [], i = [], s = [], r = new fn(this); + e: + for (let o = 0, l = 0; ; ) { + let a = o == e.length ? 1e9 : e[o++]; + for (; l < a || l == a && r.len == 0; ) { + if (r.done) + break e; + let f = Math.min(r.len, a - l); + me(s, f, -1); + let c = r.ins == -1 ? -1 : r.off == 0 ? r.ins : 0; + me(t, f, c), c > 0 && Tt(i, t, r.text), r.forward(f), l += f; + } + let h = e[o++]; + for (; l < h; ) { + if (r.done) + break e; + let f = Math.min(r.len, h - l); + me(t, f, -1), me(s, f, r.ins == -1 ? -1 : r.off == 0 ? r.ins : 0), r.forward(f), l += f; + } + } + return { + changes: new fe(t, i), + filtered: ct.create(s) + }; + } + /** + Serialize this change set to a JSON-representable value. + */ + toJSON() { + let e = []; + for (let t = 0; t < this.sections.length; t += 2) { + let i = this.sections[t], s = this.sections[t + 1]; + s < 0 ? e.push(i) : s == 0 ? e.push([i]) : e.push([i].concat(this.inserted[t >> 1].toJSON())); + } + return e; + } + /** + Create a change set for the given changes, for a document of the + given length, using `lineSep` as line separator. + */ + static of(e, t, i) { + let s = [], r = [], o = 0, l = null; + function a(f = !1) { + if (!f && !s.length) + return; + o < t && me(s, t - o, -1); + let c = new fe(s, r); + l = l ? l.compose(c.map(l)) : c, s = [], r = [], o = 0; + } + function h(f) { + if (Array.isArray(f)) + for (let c of f) + h(c); + else if (f instanceof fe) { + if (f.length != t) + throw new RangeError(`Mismatched change set length (got ${f.length}, expected ${t})`); + a(), l = l ? l.compose(f.map(l)) : f; + } else { + let { from: c, to: u = c, insert: d } = f; + if (c > u || c < 0 || u > t) + throw new RangeError(`Invalid change range ${c} to ${u} (in doc of length ${t})`); + let p = d ? typeof d == "string" ? Y.of(d.split(i || Er)) : d : Y.empty, m = p.length; + if (c == u && m == 0) + return; + c < o && a(), c > o && me(s, c - o, -1), me(s, u - c, m), Tt(r, s, p), o = u; + } + } + return h(e), a(!l), l; + } + /** + Create an empty changeset of the given length. + */ + static empty(e) { + return new fe(e ? [e, -1] : [], []); + } + /** + Create a changeset from its JSON representation (as produced by + [`toJSON`](https://codemirror.net/6/docs/ref/#state.ChangeSet.toJSON). + */ + static fromJSON(e) { + if (!Array.isArray(e)) + throw new RangeError("Invalid JSON representation of ChangeSet"); + let t = [], i = []; + for (let s = 0; s < e.length; s++) { + let r = e[s]; + if (typeof r == "number") + t.push(r, -1); + else { + if (!Array.isArray(r) || typeof r[0] != "number" || r.some((o, l) => l && typeof o != "string")) + throw new RangeError("Invalid JSON representation of ChangeSet"); + if (r.length == 1) + t.push(r[0], 0); + else { + for (; i.length < s; ) + i.push(Y.empty); + i[s] = Y.of(r.slice(1)), t.push(r[0], i[s].length); + } + } + } + return new fe(t, i); + } + /** + @internal + */ + static createSet(e, t) { + return new fe(e, t); + } +} +function me(n, e, t, i = !1) { + if (e == 0 && t <= 0) + return; + let s = n.length - 2; + s >= 0 && t <= 0 && t == n[s + 1] ? n[s] += e : e == 0 && n[s] == 0 ? n[s + 1] += t : i ? (n[s] += e, n[s + 1] += t) : n.push(e, t); +} +function Tt(n, e, t) { + if (t.length == 0) + return; + let i = e.length - 2 >> 1; + if (i < n.length) + n[n.length - 1] = n[n.length - 1].append(t); + else { + for (; n.length < i; ) + n.push(Y.empty); + n.push(t); + } +} +function Rr(n, e, t) { + let i = n.inserted; + for (let s = 0, r = 0, o = 0; o < n.sections.length; ) { + let l = n.sections[o++], a = n.sections[o++]; + if (a < 0) + s += l, r += l; + else { + let h = s, f = r, c = Y.empty; + for (; h += l, f += a, a && i && (c = c.append(i[o - 2 >> 1])), !(t || o == n.sections.length || n.sections[o + 1] < 0); ) + l = n.sections[o++], a = n.sections[o++]; + e(s, h, r, f, c), s = h, r = f; + } + } +} +function Ir(n, e, t, i = !1) { + let s = [], r = i ? [] : null, o = new fn(n), l = new fn(e); + for (let a = -1; ; ) + if (o.ins == -1 && l.ins == -1) { + let h = Math.min(o.len, l.len); + me(s, h, -1), o.forward(h), l.forward(h); + } else if (l.ins >= 0 && (o.ins < 0 || a == o.i || o.off == 0 && (l.len < o.len || l.len == o.len && !t))) { + let h = l.len; + for (me(s, l.ins, -1); h; ) { + let f = Math.min(o.len, h); + o.ins >= 0 && a < o.i && o.len <= f && (me(s, 0, o.ins), r && Tt(r, s, o.text), a = o.i), o.forward(f), h -= f; + } + l.next(); + } else if (o.ins >= 0) { + let h = 0, f = o.len; + for (; f; ) + if (l.ins == -1) { + let c = Math.min(f, l.len); + h += c, f -= c, l.forward(c); + } else if (l.ins == 0 && l.len < f) + f -= l.len, l.next(); + else + break; + me(s, h, a < o.i ? o.ins : 0), r && a < o.i && Tt(r, s, o.text), a = o.i, o.forward(o.len - f); + } else { + if (o.done && l.done) + return r ? fe.createSet(s, r) : ct.create(s); + throw new Error("Mismatched change set lengths"); + } +} +function cf(n, e, t = !1) { + let i = [], s = t ? [] : null, r = new fn(n), o = new fn(e); + for (let l = !1; ; ) { + if (r.done && o.done) + return s ? fe.createSet(i, s) : ct.create(i); + if (r.ins == 0) + me(i, r.len, 0, l), r.next(); + else if (o.len == 0 && !o.done) + me(i, 0, o.ins, l), s && Tt(s, i, o.text), o.next(); + else { + if (r.done || o.done) + throw new Error("Mismatched change set lengths"); + { + let a = Math.min(r.len2, o.len), h = i.length; + if (r.ins == -1) { + let f = o.ins == -1 ? -1 : o.off ? 0 : o.ins; + me(i, a, f, l), s && f && Tt(s, i, o.text); + } else + o.ins == -1 ? (me(i, r.off ? 0 : r.len, a, l), s && Tt(s, i, r.textBit(a))) : (me(i, r.off ? 0 : r.len, o.off ? 0 : o.ins, l), s && !o.off && Tt(s, i, o.text)); + l = (r.ins > a || o.ins >= 0 && o.len > a) && (l || i.length > h), r.forward2(a), o.forward(a); + } + } + } +} +class fn { + constructor(e) { + this.set = e, this.i = 0, this.next(); + } + next() { + let { sections: e } = this.set; + this.i < e.length ? (this.len = e[this.i++], this.ins = e[this.i++]) : (this.len = 0, this.ins = -2), this.off = 0; + } + get done() { + return this.ins == -2; + } + get len2() { + return this.ins < 0 ? this.len : this.ins; + } + get text() { + let { inserted: e } = this.set, t = this.i - 2 >> 1; + return t >= e.length ? Y.empty : e[t]; + } + textBit(e) { + let { inserted: t } = this.set, i = this.i - 2 >> 1; + return i >= t.length && !e ? Y.empty : t[i].slice(this.off, e == null ? void 0 : this.off + e); + } + forward(e) { + e == this.len ? this.next() : (this.len -= e, this.off += e); + } + forward2(e) { + this.ins == -1 ? this.forward(e) : e == this.ins ? this.next() : (this.ins -= e, this.off += e); + } +} +class Kt { + constructor(e, t, i) { + this.from = e, this.to = t, this.flags = i; + } + /** + The anchor of the range—the side that doesn't move when you + extend it. + */ + get anchor() { + return this.flags & 32 ? this.to : this.from; + } + /** + The head of the range, which is moved when the range is + [extended](https://codemirror.net/6/docs/ref/#state.SelectionRange.extend). + */ + get head() { + return this.flags & 32 ? this.from : this.to; + } + /** + True when `anchor` and `head` are at the same position. + */ + get empty() { + return this.from == this.to; + } + /** + If this is a cursor that is explicitly associated with the + character on one of its sides, this returns the side. -1 means + the character before its position, 1 the character after, and 0 + means no association. + */ + get assoc() { + return this.flags & 8 ? -1 : this.flags & 16 ? 1 : 0; + } + /** + The bidirectional text level associated with this cursor, if + any. + */ + get bidiLevel() { + let e = this.flags & 7; + return e == 7 ? null : e; + } + /** + The goal column (stored vertical offset) associated with a + cursor. This is used to preserve the vertical position when + [moving](https://codemirror.net/6/docs/ref/#view.EditorView.moveVertically) across + lines of different length. + */ + get goalColumn() { + let e = this.flags >> 6; + return e == 16777215 ? void 0 : e; + } + /** + Map this range through a change, producing a valid range in the + updated document. + */ + map(e, t = -1) { + let i, s; + return this.empty ? i = s = e.mapPos(this.from, t) : (i = e.mapPos(this.from, 1), s = e.mapPos(this.to, -1)), i == this.from && s == this.to ? this : new Kt(i, s, this.flags); + } + /** + Extend this range to cover at least `from` to `to`. + */ + extend(e, t = e) { + if (e <= this.anchor && t >= this.anchor) + return C.range(e, t); + let i = Math.abs(e - this.anchor) > Math.abs(t - this.anchor) ? e : t; + return C.range(this.anchor, i); + } + /** + Compare this range to another range. + */ + eq(e, t = !1) { + return this.anchor == e.anchor && this.head == e.head && (!t || !this.empty || this.assoc == e.assoc); + } + /** + Return a JSON-serializable object representing the range. + */ + toJSON() { + return { anchor: this.anchor, head: this.head }; + } + /** + Convert a JSON representation of a range to a `SelectionRange` + instance. + */ + static fromJSON(e) { + if (!e || typeof e.anchor != "number" || typeof e.head != "number") + throw new RangeError("Invalid JSON representation for SelectionRange"); + return C.range(e.anchor, e.head); + } + /** + @internal + */ + static create(e, t, i) { + return new Kt(e, t, i); + } +} +class C { + constructor(e, t) { + this.ranges = e, this.mainIndex = t; + } + /** + Map a selection through a change. Used to adjust the selection + position for changes. + */ + map(e, t = -1) { + return e.empty ? this : C.create(this.ranges.map((i) => i.map(e, t)), this.mainIndex); + } + /** + Compare this selection to another selection. By default, ranges + are compared only by position. When `includeAssoc` is true, + cursor ranges must also have the same + [`assoc`](https://codemirror.net/6/docs/ref/#state.SelectionRange.assoc) value. + */ + eq(e, t = !1) { + if (this.ranges.length != e.ranges.length || this.mainIndex != e.mainIndex) + return !1; + for (let i = 0; i < this.ranges.length; i++) + if (!this.ranges[i].eq(e.ranges[i], t)) + return !1; + return !0; + } + /** + Get the primary selection range. Usually, you should make sure + your code applies to _all_ ranges, by using methods like + [`changeByRange`](https://codemirror.net/6/docs/ref/#state.EditorState.changeByRange). + */ + get main() { + return this.ranges[this.mainIndex]; + } + /** + Make sure the selection only has one range. Returns a selection + holding only the main range from this selection. + */ + asSingle() { + return this.ranges.length == 1 ? this : new C([this.main], 0); + } + /** + Extend this selection with an extra range. + */ + addRange(e, t = !0) { + return C.create([e].concat(this.ranges), t ? 0 : this.mainIndex + 1); + } + /** + Replace a given range with another range, and then normalize the + selection to merge and sort ranges if necessary. + */ + replaceRange(e, t = this.mainIndex) { + let i = this.ranges.slice(); + return i[t] = e, C.create(i, this.mainIndex); + } + /** + Convert this selection to an object that can be serialized to + JSON. + */ + toJSON() { + return { ranges: this.ranges.map((e) => e.toJSON()), main: this.mainIndex }; + } + /** + Create a selection from a JSON representation. + */ + static fromJSON(e) { + if (!e || !Array.isArray(e.ranges) || typeof e.main != "number" || e.main >= e.ranges.length) + throw new RangeError("Invalid JSON representation for EditorSelection"); + return new C(e.ranges.map((t) => Kt.fromJSON(t)), e.main); + } + /** + Create a selection holding a single range. + */ + static single(e, t = e) { + return new C([C.range(e, t)], 0); + } + /** + Sort and merge the given set of ranges, creating a valid + selection. + */ + static create(e, t = 0) { + if (e.length == 0) + throw new RangeError("A selection needs at least one range"); + for (let i = 0, s = 0; s < e.length; s++) { + let r = e[s]; + if (r.empty ? r.from <= i : r.from < i) + return C.normalized(e.slice(), t); + i = r.to; + } + return new C(e, t); + } + /** + Create a cursor selection range at the given position. You can + safely ignore the optional arguments in most situations. + */ + static cursor(e, t = 0, i, s) { + return Kt.create(e, e, (t == 0 ? 0 : t < 0 ? 8 : 16) | (i == null ? 7 : Math.min(6, i)) | (s ?? 16777215) << 6); + } + /** + Create a selection range. + */ + static range(e, t, i, s) { + let r = (i ?? 16777215) << 6 | (s == null ? 7 : Math.min(6, s)); + return t < e ? Kt.create(t, e, 48 | r) : Kt.create(e, t, (t > e ? 8 : 0) | r); + } + /** + @internal + */ + static normalized(e, t = 0) { + let i = e[t]; + e.sort((s, r) => s.from - r.from), t = e.indexOf(i); + for (let s = 1; s < e.length; s++) { + let r = e[s], o = e[s - 1]; + if (r.empty ? r.from <= o.to : r.from < o.to) { + let l = o.from, a = Math.max(r.to, o.to); + s <= t && t--, e.splice(--s, 2, r.anchor > r.head ? C.range(a, l) : C.range(l, a)); + } + } + return new C(e, t); + } +} +function uf(n, e) { + for (let t of n.ranges) + if (t.to > e) + throw new RangeError("Selection points outside of document"); +} +let Eo = 0; +class D { + constructor(e, t, i, s, r) { + this.combine = e, this.compareInput = t, this.compare = i, this.isStatic = s, this.id = Eo++, this.default = e([]), this.extensions = typeof r == "function" ? r(this) : r; + } + /** + Returns a facet reader for this facet, which can be used to + [read](https://codemirror.net/6/docs/ref/#state.EditorState.facet) it but not to define values for it. + */ + get reader() { + return this; + } + /** + Define a new facet. + */ + static define(e = {}) { + return new D(e.combine || ((t) => t), e.compareInput || ((t, i) => t === i), e.compare || (e.combine ? (t, i) => t === i : Ro), !!e.static, e.enables); + } + /** + Returns an extension that adds the given value to this facet. + */ + of(e) { + return new is([], this, 0, e); + } + /** + Create an extension that computes a value for the facet from a + state. You must take care to declare the parts of the state that + this value depends on, since your function is only called again + for a new state when one of those parts changed. + + In cases where your value depends only on a single field, you'll + want to use the [`from`](https://codemirror.net/6/docs/ref/#state.Facet.from) method instead. + */ + compute(e, t) { + if (this.isStatic) + throw new Error("Can't compute a static facet"); + return new is(e, this, 1, t); + } + /** + Create an extension that computes zero or more values for this + facet from a state. + */ + computeN(e, t) { + if (this.isStatic) + throw new Error("Can't compute a static facet"); + return new is(e, this, 2, t); + } + from(e, t) { + return t || (t = (i) => i), this.compute([e], (i) => t(i.field(e))); + } +} +function Ro(n, e) { + return n == e || n.length == e.length && n.every((t, i) => t === e[i]); +} +class is { + constructor(e, t, i, s) { + this.dependencies = e, this.facet = t, this.type = i, this.value = s, this.id = Eo++; + } + dynamicSlot(e) { + var t; + let i = this.value, s = this.facet.compareInput, r = this.id, o = e[r] >> 1, l = this.type == 2, a = !1, h = !1, f = []; + for (let c of this.dependencies) + c == "doc" ? a = !0 : c == "selection" ? h = !0 : ((t = e[c.id]) !== null && t !== void 0 ? t : 1) & 1 || f.push(e[c.id]); + return { + create(c) { + return c.values[o] = i(c), 1; + }, + update(c, u) { + if (a && u.docChanged || h && (u.docChanged || u.selection) || Nr(c, f)) { + let d = i(c); + if (l ? !Sl(d, c.values[o], s) : !s(d, c.values[o])) + return c.values[o] = d, 1; + } + return 0; + }, + reconfigure: (c, u) => { + let d, p = u.config.address[r]; + if (p != null) { + let m = ps(u, p); + if (this.dependencies.every((g) => g instanceof D ? u.facet(g) === c.facet(g) : g instanceof Me ? u.field(g, !1) == c.field(g, !1) : !0) || (l ? Sl(d = i(c), m, s) : s(d = i(c), m))) + return c.values[o] = m, 0; + } else + d = i(c); + return c.values[o] = d, 1; + } + }; + } +} +function Sl(n, e, t) { + if (n.length != e.length) + return !1; + for (let i = 0; i < n.length; i++) + if (!t(n[i], e[i])) + return !1; + return !0; +} +function Nr(n, e) { + let t = !1; + for (let i of e) + nn(n, i) & 1 && (t = !0); + return t; +} +function _d(n, e, t) { + let i = t.map((a) => n[a.id]), s = t.map((a) => a.type), r = i.filter((a) => !(a & 1)), o = n[e.id] >> 1; + function l(a) { + let h = []; + for (let f = 0; f < i.length; f++) { + let c = ps(a, i[f]); + if (s[f] == 2) + for (let u of c) + h.push(u); + else + h.push(c); + } + return e.combine(h); + } + return { + create(a) { + for (let h of i) + nn(a, h); + return a.values[o] = l(a), 1; + }, + update(a, h) { + if (!Nr(a, r)) + return 0; + let f = l(a); + return e.compare(f, a.values[o]) ? 0 : (a.values[o] = f, 1); + }, + reconfigure(a, h) { + let f = Nr(a, i), c = h.config.facets[e.id], u = h.facet(e); + if (c && !f && Ro(t, c)) + return a.values[o] = u, 0; + let d = l(a); + return e.compare(d, u) ? (a.values[o] = u, 0) : (a.values[o] = d, 1); + } + }; +} +const _l = /* @__PURE__ */ D.define({ static: !0 }); +class Me { + constructor(e, t, i, s, r) { + this.id = e, this.createF = t, this.updateF = i, this.compareF = s, this.spec = r, this.provides = void 0; + } + /** + Define a state field. + */ + static define(e) { + let t = new Me(Eo++, e.create, e.update, e.compare || ((i, s) => i === s), e); + return e.provide && (t.provides = e.provide(t)), t; + } + create(e) { + let t = e.facet(_l).find((i) => i.field == this); + return ((t == null ? void 0 : t.create) || this.createF)(e); + } + /** + @internal + */ + slot(e) { + let t = e[this.id] >> 1; + return { + create: (i) => (i.values[t] = this.create(i), 1), + update: (i, s) => { + let r = i.values[t], o = this.updateF(r, s); + return this.compareF(r, o) ? 0 : (i.values[t] = o, 1); + }, + reconfigure: (i, s) => s.config.address[this.id] != null ? (i.values[t] = s.field(this), 0) : (i.values[t] = this.create(i), 1) + }; + } + /** + Returns an extension that enables this field and overrides the + way it is initialized. Can be useful when you need to provide a + non-default starting value for the field. + */ + init(e) { + return [this, _l.of({ field: this, create: e })]; + } + /** + State field instances can be used as + [`Extension`](https://codemirror.net/6/docs/ref/#state.Extension) values to enable the field in a + given state. + */ + get extension() { + return this; + } +} +const qt = { lowest: 4, low: 3, default: 2, high: 1, highest: 0 }; +function Wi(n) { + return (e) => new df(e, n); +} +const vn = { + /** + The highest precedence level, for extensions that should end up + near the start of the precedence ordering. + */ + highest: /* @__PURE__ */ Wi(qt.highest), + /** + A higher-than-default precedence, for extensions that should + come before those with default precedence. + */ + high: /* @__PURE__ */ Wi(qt.high), + /** + The default precedence, which is also used for extensions + without an explicit precedence. + */ + default: /* @__PURE__ */ Wi(qt.default), + /** + A lower-than-default precedence. + */ + low: /* @__PURE__ */ Wi(qt.low), + /** + The lowest precedence level. Meant for things that should end up + near the end of the extension order. + */ + lowest: /* @__PURE__ */ Wi(qt.lowest) +}; +class df { + constructor(e, t) { + this.inner = e, this.prec = t; + } +} +class Ps { + /** + Create an instance of this compartment to add to your [state + configuration](https://codemirror.net/6/docs/ref/#state.EditorStateConfig.extensions). + */ + of(e) { + return new Vr(this, e); + } + /** + Create an [effect](https://codemirror.net/6/docs/ref/#state.TransactionSpec.effects) that + reconfigures this compartment. + */ + reconfigure(e) { + return Ps.reconfigure.of({ compartment: this, extension: e }); + } + /** + Get the current content of the compartment in the state, or + `undefined` if it isn't present. + */ + get(e) { + return e.config.compartments.get(this); + } +} +class Vr { + constructor(e, t) { + this.compartment = e, this.inner = t; + } +} +class ds { + constructor(e, t, i, s, r, o) { + for (this.base = e, this.compartments = t, this.dynamicSlots = i, this.address = s, this.staticValues = r, this.facets = o, this.statusTemplate = []; this.statusTemplate.length < i.length; ) + this.statusTemplate.push( + 0 + /* SlotStatus.Unresolved */ + ); + } + staticFacet(e) { + let t = this.address[e.id]; + return t == null ? e.default : this.staticValues[t >> 1]; + } + static resolve(e, t, i) { + let s = [], r = /* @__PURE__ */ Object.create(null), o = /* @__PURE__ */ new Map(); + for (let u of Cd(e, t, o)) + u instanceof Me ? s.push(u) : (r[u.facet.id] || (r[u.facet.id] = [])).push(u); + let l = /* @__PURE__ */ Object.create(null), a = [], h = []; + for (let u of s) + l[u.id] = h.length << 1, h.push((d) => u.slot(d)); + let f = i == null ? void 0 : i.config.facets; + for (let u in r) { + let d = r[u], p = d[0].facet, m = f && f[u] || []; + if (d.every( + (g) => g.type == 0 + /* Provider.Static */ + )) + if (l[p.id] = a.length << 1 | 1, Ro(m, d)) + a.push(i.facet(p)); + else { + let g = p.combine(d.map((y) => y.value)); + a.push(i && p.compare(g, i.facet(p)) ? i.facet(p) : g); + } + else { + for (let g of d) + g.type == 0 ? (l[g.id] = a.length << 1 | 1, a.push(g.value)) : (l[g.id] = h.length << 1, h.push((y) => g.dynamicSlot(y))); + l[p.id] = h.length << 1, h.push((g) => _d(g, p, d)); + } + } + let c = h.map((u) => u(l)); + return new ds(e, o, c, l, a, r); + } +} +function Cd(n, e, t) { + let i = [[], [], [], [], []], s = /* @__PURE__ */ new Map(); + function r(o, l) { + let a = s.get(o); + if (a != null) { + if (a <= l) + return; + let h = i[a].indexOf(o); + h > -1 && i[a].splice(h, 1), o instanceof Vr && t.delete(o.compartment); + } + if (s.set(o, l), Array.isArray(o)) + for (let h of o) + r(h, l); + else if (o instanceof Vr) { + if (t.has(o.compartment)) + throw new RangeError("Duplicate use of compartment in extensions"); + let h = e.get(o.compartment) || o.inner; + t.set(o.compartment, h), r(h, l); + } else if (o instanceof df) + r(o.inner, o.prec); + else if (o instanceof Me) + i[l].push(o), o.provides && r(o.provides, l); + else if (o instanceof is) + i[l].push(o), o.facet.extensions && r(o.facet.extensions, qt.default); + else { + let h = o.extension; + if (!h) + throw new Error(`Unrecognized extension value in extension set (${o}). This sometimes happens because multiple instances of @codemirror/state are loaded, breaking instanceof checks.`); + r(h, l); + } + } + return r(n, qt.default), i.reduce((o, l) => o.concat(l)); +} +function nn(n, e) { + if (e & 1) + return 2; + let t = e >> 1, i = n.status[t]; + if (i == 4) + throw new Error("Cyclic dependency between fields and/or facets"); + if (i & 2) + return i; + n.status[t] = 4; + let s = n.computeSlot(n, n.config.dynamicSlots[t]); + return n.status[t] = 2 | s; +} +function ps(n, e) { + return e & 1 ? n.config.staticValues[e >> 1] : n.values[e >> 1]; +} +const pf = /* @__PURE__ */ D.define(), Fr = /* @__PURE__ */ D.define({ + combine: (n) => n.some((e) => e), + static: !0 +}), mf = /* @__PURE__ */ D.define({ + combine: (n) => n.length ? n[0] : void 0, + static: !0 +}), gf = /* @__PURE__ */ D.define(), bf = /* @__PURE__ */ D.define(), yf = /* @__PURE__ */ D.define(), wf = /* @__PURE__ */ D.define({ + combine: (n) => n.length ? n[0] : !1 +}); +class kt { + /** + @internal + */ + constructor(e, t) { + this.type = e, this.value = t; + } + /** + Define a new type of annotation. + */ + static define() { + return new Ad(); + } +} +class Ad { + /** + Create an instance of this annotation. + */ + of(e) { + return new kt(this, e); + } +} +class Md { + /** + @internal + */ + constructor(e) { + this.map = e; + } + /** + Create a [state effect](https://codemirror.net/6/docs/ref/#state.StateEffect) instance of this + type. + */ + of(e) { + return new q(this, e); + } +} +class q { + /** + @internal + */ + constructor(e, t) { + this.type = e, this.value = t; + } + /** + Map this effect through a position mapping. Will return + `undefined` when that ends up deleting the effect. + */ + map(e) { + let t = this.type.map(this.value, e); + return t === void 0 ? void 0 : t == this.value ? this : new q(this.type, t); + } + /** + Tells you whether this effect object is of a given + [type](https://codemirror.net/6/docs/ref/#state.StateEffectType). + */ + is(e) { + return this.type == e; + } + /** + Define a new effect type. The type parameter indicates the type + of values that his effect holds. It should be a type that + doesn't include `undefined`, since that is used in + [mapping](https://codemirror.net/6/docs/ref/#state.StateEffect.map) to indicate that an effect is + removed. + */ + static define(e = {}) { + return new Md(e.map || ((t) => t)); + } + /** + Map an array of effects through a change set. + */ + static mapEffects(e, t) { + if (!e.length) + return e; + let i = []; + for (let s of e) { + let r = s.map(t); + r && i.push(r); + } + return i; + } +} +q.reconfigure = /* @__PURE__ */ q.define(); +q.appendConfig = /* @__PURE__ */ q.define(); +class ae { + constructor(e, t, i, s, r, o) { + this.startState = e, this.changes = t, this.selection = i, this.effects = s, this.annotations = r, this.scrollIntoView = o, this._doc = null, this._state = null, i && uf(i, t.newLength), r.some((l) => l.type == ae.time) || (this.annotations = r.concat(ae.time.of(Date.now()))); + } + /** + @internal + */ + static create(e, t, i, s, r, o) { + return new ae(e, t, i, s, r, o); + } + /** + The new document produced by the transaction. Contrary to + [`.state`](https://codemirror.net/6/docs/ref/#state.Transaction.state)`.doc`, accessing this won't + force the entire new state to be computed right away, so it is + recommended that [transaction + filters](https://codemirror.net/6/docs/ref/#state.EditorState^transactionFilter) use this getter + when they need to look at the new document. + */ + get newDoc() { + return this._doc || (this._doc = this.changes.apply(this.startState.doc)); + } + /** + The new selection produced by the transaction. If + [`this.selection`](https://codemirror.net/6/docs/ref/#state.Transaction.selection) is undefined, + this will [map](https://codemirror.net/6/docs/ref/#state.EditorSelection.map) the start state's + current selection through the changes made by the transaction. + */ + get newSelection() { + return this.selection || this.startState.selection.map(this.changes); + } + /** + The new state created by the transaction. Computed on demand + (but retained for subsequent access), so it is recommended not to + access it in [transaction + filters](https://codemirror.net/6/docs/ref/#state.EditorState^transactionFilter) when possible. + */ + get state() { + return this._state || this.startState.applyTransaction(this), this._state; + } + /** + Get the value of the given annotation type, if any. + */ + annotation(e) { + for (let t of this.annotations) + if (t.type == e) + return t.value; + } + /** + Indicates whether the transaction changed the document. + */ + get docChanged() { + return !this.changes.empty; + } + /** + Indicates whether this transaction reconfigures the state + (through a [configuration compartment](https://codemirror.net/6/docs/ref/#state.Compartment) or + with a top-level configuration + [effect](https://codemirror.net/6/docs/ref/#state.StateEffect^reconfigure). + */ + get reconfigured() { + return this.startState.config != this.state.config; + } + /** + Returns true if the transaction has a [user + event](https://codemirror.net/6/docs/ref/#state.Transaction^userEvent) annotation that is equal to + or more specific than `event`. For example, if the transaction + has `"select.pointer"` as user event, `"select"` and + `"select.pointer"` will match it. + */ + isUserEvent(e) { + let t = this.annotation(ae.userEvent); + return !!(t && (t == e || t.length > e.length && t.slice(0, e.length) == e && t[e.length] == ".")); + } +} +ae.time = /* @__PURE__ */ kt.define(); +ae.userEvent = /* @__PURE__ */ kt.define(); +ae.addToHistory = /* @__PURE__ */ kt.define(); +ae.remote = /* @__PURE__ */ kt.define(); +function Td(n, e) { + let t = []; + for (let i = 0, s = 0; ; ) { + let r, o; + if (i < n.length && (s == e.length || e[s] >= n[i])) + r = n[i++], o = n[i++]; + else if (s < e.length) + r = e[s++], o = e[s++]; + else + return t; + !t.length || t[t.length - 1] < r ? t.push(r, o) : t[t.length - 1] < o && (t[t.length - 1] = o); + } +} +function kf(n, e, t) { + var i; + let s, r, o; + return t ? (s = e.changes, r = fe.empty(e.changes.length), o = n.changes.compose(e.changes)) : (s = e.changes.map(n.changes), r = n.changes.mapDesc(e.changes, !0), o = n.changes.compose(s)), { + changes: o, + selection: e.selection ? e.selection.map(r) : (i = n.selection) === null || i === void 0 ? void 0 : i.map(s), + effects: q.mapEffects(n.effects, s).concat(q.mapEffects(e.effects, r)), + annotations: n.annotations.length ? n.annotations.concat(e.annotations) : e.annotations, + scrollIntoView: n.scrollIntoView || e.scrollIntoView + }; +} +function Hr(n, e, t) { + let i = e.selection, s = xi(e.annotations); + return e.userEvent && (s = s.concat(ae.userEvent.of(e.userEvent))), { + changes: e.changes instanceof fe ? e.changes : fe.of(e.changes || [], t, n.facet(mf)), + selection: i && (i instanceof C ? i : C.single(i.anchor, i.head)), + effects: xi(e.effects), + annotations: s, + scrollIntoView: !!e.scrollIntoView + }; +} +function vf(n, e, t) { + let i = Hr(n, e.length ? e[0] : {}, n.doc.length); + e.length && e[0].filter === !1 && (t = !1); + for (let r = 1; r < e.length; r++) { + e[r].filter === !1 && (t = !1); + let o = !!e[r].sequential; + i = kf(i, Hr(n, e[r], o ? i.changes.newLength : n.doc.length), o); + } + let s = ae.create(n, i.changes, i.selection, i.effects, i.annotations, i.scrollIntoView); + return Od(t ? Dd(s) : s); +} +function Dd(n) { + let e = n.startState, t = !0; + for (let s of e.facet(gf)) { + let r = s(n); + if (r === !1) { + t = !1; + break; + } + Array.isArray(r) && (t = t === !0 ? r : Td(t, r)); + } + if (t !== !0) { + let s, r; + if (t === !1) + r = n.changes.invertedDesc, s = fe.empty(e.doc.length); + else { + let o = n.changes.filter(t); + s = o.changes, r = o.filtered.mapDesc(o.changes).invertedDesc; + } + n = ae.create(e, s, n.selection && n.selection.map(r), q.mapEffects(n.effects, r), n.annotations, n.scrollIntoView); + } + let i = e.facet(bf); + for (let s = i.length - 1; s >= 0; s--) { + let r = i[s](n); + r instanceof ae ? n = r : Array.isArray(r) && r.length == 1 && r[0] instanceof ae ? n = r[0] : n = vf(e, xi(r), !1); + } + return n; +} +function Od(n) { + let e = n.startState, t = e.facet(yf), i = n; + for (let s = t.length - 1; s >= 0; s--) { + let r = t[s](n); + r && Object.keys(r).length && (i = kf(i, Hr(e, r, n.changes.newLength), !0)); + } + return i == n ? n : ae.create(e, n.changes, n.selection, i.effects, i.annotations, i.scrollIntoView); +} +const Bd = []; +function xi(n) { + return n == null ? Bd : Array.isArray(n) ? n : [n]; +} +var Ee = /* @__PURE__ */ function(n) { + return n[n.Word = 0] = "Word", n[n.Space = 1] = "Space", n[n.Other = 2] = "Other", n; +}(Ee || (Ee = {})); +const Ld = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/; +let Wr; +try { + Wr = /* @__PURE__ */ new RegExp("[\\p{Alphabetic}\\p{Number}_]", "u"); +} catch { +} +function Pd(n) { + if (Wr) + return Wr.test(n); + for (let e = 0; e < n.length; e++) { + let t = n[e]; + if (/\w/.test(t) || t > "€" && (t.toUpperCase() != t.toLowerCase() || Ld.test(t))) + return !0; + } + return !1; +} +function Ed(n) { + return (e) => { + if (!/\S/.test(e)) + return Ee.Space; + if (Pd(e)) + return Ee.Word; + for (let t = 0; t < n.length; t++) + if (e.indexOf(n[t]) > -1) + return Ee.Word; + return Ee.Other; + }; +} +class U { + constructor(e, t, i, s, r, o) { + this.config = e, this.doc = t, this.selection = i, this.values = s, this.status = e.statusTemplate.slice(), this.computeSlot = r, o && (o._state = this); + for (let l = 0; l < this.config.dynamicSlots.length; l++) + nn(this, l << 1); + this.computeSlot = null; + } + field(e, t = !0) { + let i = this.config.address[e.id]; + if (i == null) { + if (t) + throw new RangeError("Field is not present in this state"); + return; + } + return nn(this, i), ps(this, i); + } + /** + Create a [transaction](https://codemirror.net/6/docs/ref/#state.Transaction) that updates this + state. Any number of [transaction specs](https://codemirror.net/6/docs/ref/#state.TransactionSpec) + can be passed. Unless + [`sequential`](https://codemirror.net/6/docs/ref/#state.TransactionSpec.sequential) is set, the + [changes](https://codemirror.net/6/docs/ref/#state.TransactionSpec.changes) (if any) of each spec + are assumed to start in the _current_ document (not the document + produced by previous specs), and its + [selection](https://codemirror.net/6/docs/ref/#state.TransactionSpec.selection) and + [effects](https://codemirror.net/6/docs/ref/#state.TransactionSpec.effects) are assumed to refer + to the document created by its _own_ changes. The resulting + transaction contains the combined effect of all the different + specs. For [selection](https://codemirror.net/6/docs/ref/#state.TransactionSpec.selection), later + specs take precedence over earlier ones. + */ + update(...e) { + return vf(this, e, !0); + } + /** + @internal + */ + applyTransaction(e) { + let t = this.config, { base: i, compartments: s } = t; + for (let l of e.effects) + l.is(Ps.reconfigure) ? (t && (s = /* @__PURE__ */ new Map(), t.compartments.forEach((a, h) => s.set(h, a)), t = null), s.set(l.value.compartment, l.value.extension)) : l.is(q.reconfigure) ? (t = null, i = l.value) : l.is(q.appendConfig) && (t = null, i = xi(i).concat(l.value)); + let r; + t ? r = e.startState.values.slice() : (t = ds.resolve(i, s, this), r = new U(t, this.doc, this.selection, t.dynamicSlots.map(() => null), (a, h) => h.reconfigure(a, this), null).values); + let o = e.startState.facet(Fr) ? e.newSelection : e.newSelection.asSingle(); + new U(t, e.newDoc, o, r, (l, a) => a.update(l, e), e); + } + /** + Create a [transaction spec](https://codemirror.net/6/docs/ref/#state.TransactionSpec) that + replaces every selection range with the given content. + */ + replaceSelection(e) { + return typeof e == "string" && (e = this.toText(e)), this.changeByRange((t) => ({ + changes: { from: t.from, to: t.to, insert: e }, + range: C.cursor(t.from + e.length) + })); + } + /** + Create a set of changes and a new selection by running the given + function for each range in the active selection. The function + can return an optional set of changes (in the coordinate space + of the start document), plus an updated range (in the coordinate + space of the document produced by the call's own changes). This + method will merge all the changes and ranges into a single + changeset and selection, and return it as a [transaction + spec](https://codemirror.net/6/docs/ref/#state.TransactionSpec), which can be passed to + [`update`](https://codemirror.net/6/docs/ref/#state.EditorState.update). + */ + changeByRange(e) { + let t = this.selection, i = e(t.ranges[0]), s = this.changes(i.changes), r = [i.range], o = xi(i.effects); + for (let l = 1; l < t.ranges.length; l++) { + let a = e(t.ranges[l]), h = this.changes(a.changes), f = h.map(s); + for (let u = 0; u < l; u++) + r[u] = r[u].map(f); + let c = s.mapDesc(h, !0); + r.push(a.range.map(c)), s = s.compose(f), o = q.mapEffects(o, f).concat(q.mapEffects(xi(a.effects), c)); + } + return { + changes: s, + selection: C.create(r, t.mainIndex), + effects: o + }; + } + /** + Create a [change set](https://codemirror.net/6/docs/ref/#state.ChangeSet) from the given change + description, taking the state's document length and line + separator into account. + */ + changes(e = []) { + return e instanceof fe ? e : fe.of(e, this.doc.length, this.facet(U.lineSeparator)); + } + /** + Using the state's [line + separator](https://codemirror.net/6/docs/ref/#state.EditorState^lineSeparator), create a + [`Text`](https://codemirror.net/6/docs/ref/#state.Text) instance from the given string. + */ + toText(e) { + return Y.of(e.split(this.facet(U.lineSeparator) || Er)); + } + /** + Return the given range of the document as a string. + */ + sliceDoc(e = 0, t = this.doc.length) { + return this.doc.sliceString(e, t, this.lineBreak); + } + /** + Get the value of a state [facet](https://codemirror.net/6/docs/ref/#state.Facet). + */ + facet(e) { + let t = this.config.address[e.id]; + return t == null ? e.default : (nn(this, t), ps(this, t)); + } + /** + Convert this state to a JSON-serializable object. When custom + fields should be serialized, you can pass them in as an object + mapping property names (in the resulting object, which should + not use `doc` or `selection`) to fields. + */ + toJSON(e) { + let t = { + doc: this.sliceDoc(), + selection: this.selection.toJSON() + }; + if (e) + for (let i in e) { + let s = e[i]; + s instanceof Me && this.config.address[s.id] != null && (t[i] = s.spec.toJSON(this.field(e[i]), this)); + } + return t; + } + /** + Deserialize a state from its JSON representation. When custom + fields should be deserialized, pass the same object you passed + to [`toJSON`](https://codemirror.net/6/docs/ref/#state.EditorState.toJSON) when serializing as + third argument. + */ + static fromJSON(e, t = {}, i) { + if (!e || typeof e.doc != "string") + throw new RangeError("Invalid JSON representation for EditorState"); + let s = []; + if (i) { + for (let r in i) + if (Object.prototype.hasOwnProperty.call(e, r)) { + let o = i[r], l = e[r]; + s.push(o.init((a) => o.spec.fromJSON(l, a))); + } + } + return U.create({ + doc: e.doc, + selection: C.fromJSON(e.selection), + extensions: t.extensions ? s.concat([t.extensions]) : s + }); + } + /** + Create a new state. You'll usually only need this when + initializing an editor—updated states are created by applying + transactions. + */ + static create(e = {}) { + let t = ds.resolve(e.extensions || [], /* @__PURE__ */ new Map()), i = e.doc instanceof Y ? e.doc : Y.of((e.doc || "").split(t.staticFacet(U.lineSeparator) || Er)), s = e.selection ? e.selection instanceof C ? e.selection : C.single(e.selection.anchor, e.selection.head) : C.single(0); + return uf(s, i.length), t.staticFacet(Fr) || (s = s.asSingle()), new U(t, i, s, t.dynamicSlots.map(() => null), (r, o) => o.create(r), null); + } + /** + The size (in columns) of a tab in the document, determined by + the [`tabSize`](https://codemirror.net/6/docs/ref/#state.EditorState^tabSize) facet. + */ + get tabSize() { + return this.facet(U.tabSize); + } + /** + Get the proper [line-break](https://codemirror.net/6/docs/ref/#state.EditorState^lineSeparator) + string for this state. + */ + get lineBreak() { + return this.facet(U.lineSeparator) || ` +`; + } + /** + Returns true when the editor is + [configured](https://codemirror.net/6/docs/ref/#state.EditorState^readOnly) to be read-only. + */ + get readOnly() { + return this.facet(wf); + } + /** + Look up a translation for the given phrase (via the + [`phrases`](https://codemirror.net/6/docs/ref/#state.EditorState^phrases) facet), or return the + original string if no translation is found. + + If additional arguments are passed, they will be inserted in + place of markers like `$1` (for the first value) and `$2`, etc. + A single `$` is equivalent to `$1`, and `$$` will produce a + literal dollar sign. + */ + phrase(e, ...t) { + for (let i of this.facet(U.phrases)) + if (Object.prototype.hasOwnProperty.call(i, e)) { + e = i[e]; + break; + } + return t.length && (e = e.replace(/\$(\$|\d*)/g, (i, s) => { + if (s == "$") + return "$"; + let r = +(s || 1); + return !r || r > t.length ? i : t[r - 1]; + })), e; + } + /** + Find the values for a given language data field, provided by the + the [`languageData`](https://codemirror.net/6/docs/ref/#state.EditorState^languageData) facet. + + Examples of language data fields are... + + - [`"commentTokens"`](https://codemirror.net/6/docs/ref/#commands.CommentTokens) for specifying + comment syntax. + - [`"autocomplete"`](https://codemirror.net/6/docs/ref/#autocomplete.autocompletion^config.override) + for providing language-specific completion sources. + - [`"wordChars"`](https://codemirror.net/6/docs/ref/#state.EditorState.charCategorizer) for adding + characters that should be considered part of words in this + language. + - [`"closeBrackets"`](https://codemirror.net/6/docs/ref/#autocomplete.CloseBracketConfig) controls + bracket closing behavior. + */ + languageDataAt(e, t, i = -1) { + let s = []; + for (let r of this.facet(pf)) + for (let o of r(this, t, i)) + Object.prototype.hasOwnProperty.call(o, e) && s.push(o[e]); + return s; + } + /** + Return a function that can categorize strings (expected to + represent a single [grapheme cluster](https://codemirror.net/6/docs/ref/#state.findClusterBreak)) + into one of: + + - Word (contains an alphanumeric character or a character + explicitly listed in the local language's `"wordChars"` + language data, which should be a string) + - Space (contains only whitespace) + - Other (anything else) + */ + charCategorizer(e) { + return Ed(this.languageDataAt("wordChars", e).join("")); + } + /** + Find the word at the given position, meaning the range + containing all [word](https://codemirror.net/6/docs/ref/#state.CharCategory.Word) characters + around it. If no word characters are adjacent to the position, + this returns null. + */ + wordAt(e) { + let { text: t, from: i, length: s } = this.doc.lineAt(e), r = this.charCategorizer(e), o = e - i, l = e - i; + for (; o > 0; ) { + let a = ve(t, o, !1); + if (r(t.slice(a, o)) != Ee.Word) + break; + o = a; + } + for (; l < s; ) { + let a = ve(t, l); + if (r(t.slice(l, a)) != Ee.Word) + break; + l = a; + } + return o == l ? null : C.range(o + i, l + i); + } +} +U.allowMultipleSelections = Fr; +U.tabSize = /* @__PURE__ */ D.define({ + combine: (n) => n.length ? n[0] : 4 +}); +U.lineSeparator = mf; +U.readOnly = wf; +U.phrases = /* @__PURE__ */ D.define({ + compare(n, e) { + let t = Object.keys(n), i = Object.keys(e); + return t.length == i.length && t.every((s) => n[s] == e[s]); + } +}); +U.languageData = pf; +U.changeFilter = gf; +U.transactionFilter = bf; +U.transactionExtender = yf; +Ps.reconfigure = /* @__PURE__ */ q.define(); +function hi(n, e, t = {}) { + let i = {}; + for (let s of n) + for (let r of Object.keys(s)) { + let o = s[r], l = i[r]; + if (l === void 0) + i[r] = o; + else if (!(l === o || o === void 0)) + if (Object.hasOwnProperty.call(t, r)) + i[r] = t[r](l, o); + else + throw new Error("Config merge conflict for field " + r); + } + for (let s in e) + i[s] === void 0 && (i[s] = e[s]); + return i; +} +class Xt { + /** + Compare this value with another value. Used when comparing + rangesets. The default implementation compares by identity. + Unless you are only creating a fixed number of unique instances + of your value type, it is a good idea to implement this + properly. + */ + eq(e) { + return this == e; + } + /** + Create a [range](https://codemirror.net/6/docs/ref/#state.Range) with this value. + */ + range(e, t = e) { + return zr.create(e, t, this); + } +} +Xt.prototype.startSide = Xt.prototype.endSide = 0; +Xt.prototype.point = !1; +Xt.prototype.mapMode = pe.TrackDel; +let zr = class xf { + constructor(e, t, i) { + this.from = e, this.to = t, this.value = i; + } + /** + @internal + */ + static create(e, t, i) { + return new xf(e, t, i); + } +}; +function qr(n, e) { + return n.from - e.from || n.value.startSide - e.value.startSide; +} +class Io { + constructor(e, t, i, s) { + this.from = e, this.to = t, this.value = i, this.maxPoint = s; + } + get length() { + return this.to[this.to.length - 1]; + } + // Find the index of the given position and side. Use the ranges' + // `from` pos when `end == false`, `to` when `end == true`. + findIndex(e, t, i, s = 0) { + let r = i ? this.to : this.from; + for (let o = s, l = r.length; ; ) { + if (o == l) + return o; + let a = o + l >> 1, h = r[a] - e || (i ? this.value[a].endSide : this.value[a].startSide) - t; + if (a == o) + return h >= 0 ? o : l; + h >= 0 ? l = a : o = a + 1; + } + } + between(e, t, i, s) { + for (let r = this.findIndex(t, -1e9, !0), o = this.findIndex(i, 1e9, !1, r); r < o; r++) + if (s(this.from[r] + e, this.to[r] + e, this.value[r]) === !1) + return !1; + } + map(e, t) { + let i = [], s = [], r = [], o = -1, l = -1; + for (let a = 0; a < this.value.length; a++) { + let h = this.value[a], f = this.from[a] + e, c = this.to[a] + e, u, d; + if (f == c) { + let p = t.mapPos(f, h.startSide, h.mapMode); + if (p == null || (u = d = p, h.startSide != h.endSide && (d = t.mapPos(f, h.endSide), d < u))) + continue; + } else if (u = t.mapPos(f, h.startSide), d = t.mapPos(c, h.endSide), u > d || u == d && h.startSide > 0 && h.endSide <= 0) + continue; + (d - u || h.endSide - h.startSide) < 0 || (o < 0 && (o = u), h.point && (l = Math.max(l, d - u)), i.push(h), s.push(u - o), r.push(d - o)); + } + return { mapped: i.length ? new Io(s, r, i, l) : null, pos: o }; + } +} +class G { + constructor(e, t, i, s) { + this.chunkPos = e, this.chunk = t, this.nextLayer = i, this.maxPoint = s; + } + /** + @internal + */ + static create(e, t, i, s) { + return new G(e, t, i, s); + } + /** + @internal + */ + get length() { + let e = this.chunk.length - 1; + return e < 0 ? 0 : Math.max(this.chunkEnd(e), this.nextLayer.length); + } + /** + The number of ranges in the set. + */ + get size() { + if (this.isEmpty) + return 0; + let e = this.nextLayer.size; + for (let t of this.chunk) + e += t.value.length; + return e; + } + /** + @internal + */ + chunkEnd(e) { + return this.chunkPos[e] + this.chunk[e].length; + } + /** + Update the range set, optionally adding new ranges or filtering + out existing ones. + + (Note: The type parameter is just there as a kludge to work + around TypeScript variance issues that prevented `RangeSet` + from being a subtype of `RangeSet` when `X` is a subtype of + `Y`.) + */ + update(e) { + let { add: t = [], sort: i = !1, filterFrom: s = 0, filterTo: r = this.length } = e, o = e.filter; + if (t.length == 0 && !o) + return this; + if (i && (t = t.slice().sort(qr)), this.isEmpty) + return t.length ? G.of(t) : this; + let l = new Sf(this, null, -1).goto(0), a = 0, h = [], f = new Zt(); + for (; l.value || a < t.length; ) + if (a < t.length && (l.from - t[a].from || l.startSide - t[a].value.startSide) >= 0) { + let c = t[a++]; + f.addInner(c.from, c.to, c.value) || h.push(c); + } else + l.rangeIndex == 1 && l.chunkIndex < this.chunk.length && (a == t.length || this.chunkEnd(l.chunkIndex) < t[a].from) && (!o || s > this.chunkEnd(l.chunkIndex) || r < this.chunkPos[l.chunkIndex]) && f.addChunk(this.chunkPos[l.chunkIndex], this.chunk[l.chunkIndex]) ? l.nextChunk() : ((!o || s > l.to || r < l.from || o(l.from, l.to, l.value)) && (f.addInner(l.from, l.to, l.value) || h.push(zr.create(l.from, l.to, l.value))), l.next()); + return f.finishInner(this.nextLayer.isEmpty && !h.length ? G.empty : this.nextLayer.update({ add: h, filter: o, filterFrom: s, filterTo: r })); + } + /** + Map this range set through a set of changes, return the new set. + */ + map(e) { + if (e.empty || this.isEmpty) + return this; + let t = [], i = [], s = -1; + for (let o = 0; o < this.chunk.length; o++) { + let l = this.chunkPos[o], a = this.chunk[o], h = e.touchesRange(l, l + a.length); + if (h === !1) + s = Math.max(s, a.maxPoint), t.push(a), i.push(e.mapPos(l)); + else if (h === !0) { + let { mapped: f, pos: c } = a.map(l, e); + f && (s = Math.max(s, f.maxPoint), t.push(f), i.push(c)); + } + } + let r = this.nextLayer.map(e); + return t.length == 0 ? r : new G(i, t, r || G.empty, s); + } + /** + Iterate over the ranges that touch the region `from` to `to`, + calling `f` for each. There is no guarantee that the ranges will + be reported in any specific order. When the callback returns + `false`, iteration stops. + */ + between(e, t, i) { + if (!this.isEmpty) { + for (let s = 0; s < this.chunk.length; s++) { + let r = this.chunkPos[s], o = this.chunk[s]; + if (t >= r && e <= r + o.length && o.between(r, e - r, t - r, i) === !1) + return; + } + this.nextLayer.between(e, t, i); + } + } + /** + Iterate over the ranges in this set, in order, including all + ranges that end at or after `from`. + */ + iter(e = 0) { + return cn.from([this]).goto(e); + } + /** + @internal + */ + get isEmpty() { + return this.nextLayer == this; + } + /** + Iterate over the ranges in a collection of sets, in order, + starting from `from`. + */ + static iter(e, t = 0) { + return cn.from(e).goto(t); + } + /** + Iterate over two groups of sets, calling methods on `comparator` + to notify it of possible differences. + */ + static compare(e, t, i, s, r = -1) { + let o = e.filter((c) => c.maxPoint > 0 || !c.isEmpty && c.maxPoint >= r), l = t.filter((c) => c.maxPoint > 0 || !c.isEmpty && c.maxPoint >= r), a = Cl(o, l, i), h = new zi(o, a, r), f = new zi(l, a, r); + i.iterGaps((c, u, d) => Al(h, c, f, u, d, s)), i.empty && i.length == 0 && Al(h, 0, f, 0, 0, s); + } + /** + Compare the contents of two groups of range sets, returning true + if they are equivalent in the given range. + */ + static eq(e, t, i = 0, s) { + s == null && (s = 999999999); + let r = e.filter((f) => !f.isEmpty && t.indexOf(f) < 0), o = t.filter((f) => !f.isEmpty && e.indexOf(f) < 0); + if (r.length != o.length) + return !1; + if (!r.length) + return !0; + let l = Cl(r, o), a = new zi(r, l, 0).goto(i), h = new zi(o, l, 0).goto(i); + for (; ; ) { + if (a.to != h.to || !jr(a.active, h.active) || a.point && (!h.point || !a.point.eq(h.point))) + return !1; + if (a.to > s) + return !0; + a.next(), h.next(); + } + } + /** + Iterate over a group of range sets at the same time, notifying + the iterator about the ranges covering every given piece of + content. Returns the open count (see + [`SpanIterator.span`](https://codemirror.net/6/docs/ref/#state.SpanIterator.span)) at the end + of the iteration. + */ + static spans(e, t, i, s, r = -1) { + let o = new zi(e, null, r).goto(t), l = t, a = o.openStart; + for (; ; ) { + let h = Math.min(o.to, i); + if (o.point) { + let f = o.activeForPoint(o.to), c = o.pointFrom < t ? f.length + 1 : o.point.startSide < 0 ? f.length : Math.min(f.length, a); + s.point(l, h, o.point, f, c, o.pointRank), a = Math.min(o.openEnd(h), f.length); + } else + h > l && (s.span(l, h, o.active, a), a = o.openEnd(h)); + if (o.to > i) + return a + (o.point && o.to > i ? 1 : 0); + l = o.to, o.next(); + } + } + /** + Create a range set for the given range or array of ranges. By + default, this expects the ranges to be _sorted_ (by start + position and, if two start at the same position, + `value.startSide`). You can pass `true` as second argument to + cause the method to sort them. + */ + static of(e, t = !1) { + let i = new Zt(); + for (let s of e instanceof zr ? [e] : t ? Rd(e) : e) + i.add(s.from, s.to, s.value); + return i.finish(); + } + /** + Join an array of range sets into a single set. + */ + static join(e) { + if (!e.length) + return G.empty; + let t = e[e.length - 1]; + for (let i = e.length - 2; i >= 0; i--) + for (let s = e[i]; s != G.empty; s = s.nextLayer) + t = new G(s.chunkPos, s.chunk, t, Math.max(s.maxPoint, t.maxPoint)); + return t; + } +} +G.empty = /* @__PURE__ */ new G([], [], null, -1); +function Rd(n) { + if (n.length > 1) + for (let e = n[0], t = 1; t < n.length; t++) { + let i = n[t]; + if (qr(e, i) > 0) + return n.slice().sort(qr); + e = i; + } + return n; +} +G.empty.nextLayer = G.empty; +class Zt { + finishChunk(e) { + this.chunks.push(new Io(this.from, this.to, this.value, this.maxPoint)), this.chunkPos.push(this.chunkStart), this.chunkStart = -1, this.setMaxPoint = Math.max(this.setMaxPoint, this.maxPoint), this.maxPoint = -1, e && (this.from = [], this.to = [], this.value = []); + } + /** + Create an empty builder. + */ + constructor() { + this.chunks = [], this.chunkPos = [], this.chunkStart = -1, this.last = null, this.lastFrom = -1e9, this.lastTo = -1e9, this.from = [], this.to = [], this.value = [], this.maxPoint = -1, this.setMaxPoint = -1, this.nextLayer = null; + } + /** + Add a range. Ranges should be added in sorted (by `from` and + `value.startSide`) order. + */ + add(e, t, i) { + this.addInner(e, t, i) || (this.nextLayer || (this.nextLayer = new Zt())).add(e, t, i); + } + /** + @internal + */ + addInner(e, t, i) { + let s = e - this.lastTo || i.startSide - this.last.endSide; + if (s <= 0 && (e - this.lastFrom || i.startSide - this.last.startSide) < 0) + throw new Error("Ranges must be added sorted by `from` position and `startSide`"); + return s < 0 ? !1 : (this.from.length == 250 && this.finishChunk(!0), this.chunkStart < 0 && (this.chunkStart = e), this.from.push(e - this.chunkStart), this.to.push(t - this.chunkStart), this.last = i, this.lastFrom = e, this.lastTo = t, this.value.push(i), i.point && (this.maxPoint = Math.max(this.maxPoint, t - e)), !0); + } + /** + @internal + */ + addChunk(e, t) { + if ((e - this.lastTo || t.value[0].startSide - this.last.endSide) < 0) + return !1; + this.from.length && this.finishChunk(!0), this.setMaxPoint = Math.max(this.setMaxPoint, t.maxPoint), this.chunks.push(t), this.chunkPos.push(e); + let i = t.value.length - 1; + return this.last = t.value[i], this.lastFrom = t.from[i] + e, this.lastTo = t.to[i] + e, !0; + } + /** + Finish the range set. Returns the new set. The builder can't be + used anymore after this has been called. + */ + finish() { + return this.finishInner(G.empty); + } + /** + @internal + */ + finishInner(e) { + if (this.from.length && this.finishChunk(!1), this.chunks.length == 0) + return e; + let t = G.create(this.chunkPos, this.chunks, this.nextLayer ? this.nextLayer.finishInner(e) : e, this.setMaxPoint); + return this.from = null, t; + } +} +function Cl(n, e, t) { + let i = /* @__PURE__ */ new Map(); + for (let r of n) + for (let o = 0; o < r.chunk.length; o++) + r.chunk[o].maxPoint <= 0 && i.set(r.chunk[o], r.chunkPos[o]); + let s = /* @__PURE__ */ new Set(); + for (let r of e) + for (let o = 0; o < r.chunk.length; o++) { + let l = i.get(r.chunk[o]); + l != null && (t ? t.mapPos(l) : l) == r.chunkPos[o] && !(t != null && t.touchesRange(l, l + r.chunk[o].length)) && s.add(r.chunk[o]); + } + return s; +} +class Sf { + constructor(e, t, i, s = 0) { + this.layer = e, this.skip = t, this.minPoint = i, this.rank = s; + } + get startSide() { + return this.value ? this.value.startSide : 0; + } + get endSide() { + return this.value ? this.value.endSide : 0; + } + goto(e, t = -1e9) { + return this.chunkIndex = this.rangeIndex = 0, this.gotoInner(e, t, !1), this; + } + gotoInner(e, t, i) { + for (; this.chunkIndex < this.layer.chunk.length; ) { + let s = this.layer.chunk[this.chunkIndex]; + if (!(this.skip && this.skip.has(s) || this.layer.chunkEnd(this.chunkIndex) < e || s.maxPoint < this.minPoint)) + break; + this.chunkIndex++, i = !1; + } + if (this.chunkIndex < this.layer.chunk.length) { + let s = this.layer.chunk[this.chunkIndex].findIndex(e - this.layer.chunkPos[this.chunkIndex], t, !0); + (!i || this.rangeIndex < s) && this.setRangeIndex(s); + } + this.next(); + } + forward(e, t) { + (this.to - e || this.endSide - t) < 0 && this.gotoInner(e, t, !0); + } + next() { + for (; ; ) + if (this.chunkIndex == this.layer.chunk.length) { + this.from = this.to = 1e9, this.value = null; + break; + } else { + let e = this.layer.chunkPos[this.chunkIndex], t = this.layer.chunk[this.chunkIndex], i = e + t.from[this.rangeIndex]; + if (this.from = i, this.to = e + t.to[this.rangeIndex], this.value = t.value[this.rangeIndex], this.setRangeIndex(this.rangeIndex + 1), this.minPoint < 0 || this.value.point && this.to - this.from >= this.minPoint) + break; + } + } + setRangeIndex(e) { + if (e == this.layer.chunk[this.chunkIndex].value.length) { + if (this.chunkIndex++, this.skip) + for (; this.chunkIndex < this.layer.chunk.length && this.skip.has(this.layer.chunk[this.chunkIndex]); ) + this.chunkIndex++; + this.rangeIndex = 0; + } else + this.rangeIndex = e; + } + nextChunk() { + this.chunkIndex++, this.rangeIndex = 0, this.next(); + } + compare(e) { + return this.from - e.from || this.startSide - e.startSide || this.rank - e.rank || this.to - e.to || this.endSide - e.endSide; + } +} +class cn { + constructor(e) { + this.heap = e; + } + static from(e, t = null, i = -1) { + let s = []; + for (let r = 0; r < e.length; r++) + for (let o = e[r]; !o.isEmpty; o = o.nextLayer) + o.maxPoint >= i && s.push(new Sf(o, t, i, r)); + return s.length == 1 ? s[0] : new cn(s); + } + get startSide() { + return this.value ? this.value.startSide : 0; + } + goto(e, t = -1e9) { + for (let i of this.heap) + i.goto(e, t); + for (let i = this.heap.length >> 1; i >= 0; i--) + Xs(this.heap, i); + return this.next(), this; + } + forward(e, t) { + for (let i of this.heap) + i.forward(e, t); + for (let i = this.heap.length >> 1; i >= 0; i--) + Xs(this.heap, i); + (this.to - e || this.value.endSide - t) < 0 && this.next(); + } + next() { + if (this.heap.length == 0) + this.from = this.to = 1e9, this.value = null, this.rank = -1; + else { + let e = this.heap[0]; + this.from = e.from, this.to = e.to, this.value = e.value, this.rank = e.rank, e.value && e.next(), Xs(this.heap, 0); + } + } +} +function Xs(n, e) { + for (let t = n[e]; ; ) { + let i = (e << 1) + 1; + if (i >= n.length) + break; + let s = n[i]; + if (i + 1 < n.length && s.compare(n[i + 1]) >= 0 && (s = n[i + 1], i++), t.compare(s) < 0) + break; + n[i] = t, n[e] = s, e = i; + } +} +class zi { + constructor(e, t, i) { + this.minPoint = i, this.active = [], this.activeTo = [], this.activeRank = [], this.minActive = -1, this.point = null, this.pointFrom = 0, this.pointRank = 0, this.to = -1e9, this.endSide = 0, this.openStart = -1, this.cursor = cn.from(e, t, i); + } + goto(e, t = -1e9) { + return this.cursor.goto(e, t), this.active.length = this.activeTo.length = this.activeRank.length = 0, this.minActive = -1, this.to = e, this.endSide = t, this.openStart = -1, this.next(), this; + } + forward(e, t) { + for (; this.minActive > -1 && (this.activeTo[this.minActive] - e || this.active[this.minActive].endSide - t) < 0; ) + this.removeActive(this.minActive); + this.cursor.forward(e, t); + } + removeActive(e) { + Dn(this.active, e), Dn(this.activeTo, e), Dn(this.activeRank, e), this.minActive = Ml(this.active, this.activeTo); + } + addActive(e) { + let t = 0, { value: i, to: s, rank: r } = this.cursor; + for (; t < this.activeRank.length && (r - this.activeRank[t] || s - this.activeTo[t]) > 0; ) + t++; + On(this.active, t, i), On(this.activeTo, t, s), On(this.activeRank, t, r), e && On(e, t, this.cursor.from), this.minActive = Ml(this.active, this.activeTo); + } + // After calling this, if `this.point` != null, the next range is a + // point. Otherwise, it's a regular range, covered by `this.active`. + next() { + let e = this.to, t = this.point; + this.point = null; + let i = this.openStart < 0 ? [] : null; + for (; ; ) { + let s = this.minActive; + if (s > -1 && (this.activeTo[s] - this.cursor.from || this.active[s].endSide - this.cursor.startSide) < 0) { + if (this.activeTo[s] > e) { + this.to = this.activeTo[s], this.endSide = this.active[s].endSide; + break; + } + this.removeActive(s), i && Dn(i, s); + } else if (this.cursor.value) + if (this.cursor.from > e) { + this.to = this.cursor.from, this.endSide = this.cursor.startSide; + break; + } else { + let r = this.cursor.value; + if (!r.point) + this.addActive(i), this.cursor.next(); + else if (t && this.cursor.to == this.to && this.cursor.from < this.cursor.to) + this.cursor.next(); + else { + this.point = r, this.pointFrom = this.cursor.from, this.pointRank = this.cursor.rank, this.to = this.cursor.to, this.endSide = r.endSide, this.cursor.next(), this.forward(this.to, this.endSide); + break; + } + } + else { + this.to = this.endSide = 1e9; + break; + } + } + if (i) { + this.openStart = 0; + for (let s = i.length - 1; s >= 0 && i[s] < e; s--) + this.openStart++; + } + } + activeForPoint(e) { + if (!this.active.length) + return this.active; + let t = []; + for (let i = this.active.length - 1; i >= 0 && !(this.activeRank[i] < this.pointRank); i--) + (this.activeTo[i] > e || this.activeTo[i] == e && this.active[i].endSide >= this.point.endSide) && t.push(this.active[i]); + return t.reverse(); + } + openEnd(e) { + let t = 0; + for (let i = this.activeTo.length - 1; i >= 0 && this.activeTo[i] > e; i--) + t++; + return t; + } +} +function Al(n, e, t, i, s, r) { + n.goto(e), t.goto(i); + let o = i + s, l = i, a = i - e; + for (; ; ) { + let h = n.to + a - t.to || n.endSide - t.endSide, f = h < 0 ? n.to + a : t.to, c = Math.min(f, o); + if (n.point || t.point ? n.point && t.point && (n.point == t.point || n.point.eq(t.point)) && jr(n.activeForPoint(n.to), t.activeForPoint(t.to)) || r.comparePoint(l, c, n.point, t.point) : c > l && !jr(n.active, t.active) && r.compareRange(l, c, n.active, t.active), f > o) + break; + l = f, h <= 0 && n.next(), h >= 0 && t.next(); + } +} +function jr(n, e) { + if (n.length != e.length) + return !1; + for (let t = 0; t < n.length; t++) + if (n[t] != e[t] && !n[t].eq(e[t])) + return !1; + return !0; +} +function Dn(n, e) { + for (let t = e, i = n.length - 1; t < i; t++) + n[t] = n[t + 1]; + n.pop(); +} +function On(n, e, t) { + for (let i = n.length - 1; i >= e; i--) + n[i + 1] = n[i]; + n[e] = t; +} +function Ml(n, e) { + let t = -1, i = 1e9; + for (let s = 0; s < e.length; s++) + (e[s] - i || n[s].endSide - n[t].endSide) < 0 && (t = s, i = e[s]); + return t; +} +function Ri(n, e, t = n.length) { + let i = 0; + for (let s = 0; s < t; ) + n.charCodeAt(s) == 9 ? (i += e - i % e, s++) : (i++, s = ve(n, s)); + return i; +} +function Kr(n, e, t, i) { + for (let s = 0, r = 0; ; ) { + if (r >= e) + return s; + if (s == n.length) + break; + r += n.charCodeAt(s) == 9 ? t - r % t : 1, s = ve(n, s); + } + return i === !0 ? -1 : n.length; +} +const Ur = "ͼ", Tl = typeof Symbol > "u" ? "__" + Ur : Symbol.for(Ur), Gr = typeof Symbol > "u" ? "__styleSet" + Math.floor(Math.random() * 1e8) : Symbol("styleSet"), Dl = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : {}; +class Pt { + // :: (Object diff --git a/src/frontend/Index.svelte b/src/frontend/Index.svelte new file mode 100644 index 0000000000000000000000000000000000000000..ec8f762e10ed4d2e7914bece6c9b5a394da07dcd --- /dev/null +++ b/src/frontend/Index.svelte @@ -0,0 +1,102 @@ + + + + + + + + + + {#if !value && !interactive} + + + + {:else} + + + gradio.dispatch("blur")} + on:focus={() => gradio.dispatch("focus")} + /> + {/if} + diff --git a/src/frontend/package-lock.json b/src/frontend/package-lock.json new file mode 100644 index 0000000000000000000000000000000000000000..96f8be85bc8928684afbe131c66912263f26538f --- /dev/null +++ b/src/frontend/package-lock.json @@ -0,0 +1,2357 @@ +{ + "name": "gradio_logsview", + "version": "0.5.10", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "gradio_logsview", + "version": "0.5.10", + "license": "ISC", + "dependencies": { + "@codemirror/autocomplete": "^6.3.0", + "@codemirror/commands": "^6.1.2", + "@codemirror/lang-css": "^6.1.0", + "@codemirror/lang-html": "^6.4.2", + "@codemirror/lang-javascript": "^6.1.4", + "@codemirror/lang-json": "^6.0.1", + "@codemirror/lang-markdown": "^6.1.0", + "@codemirror/lang-python": "^6.0.4", + "@codemirror/language": "^6.6.0", + "@codemirror/legacy-modes": "^6.3.1", + "@codemirror/lint": "^6.0.0", + "@codemirror/search": "^6.2.2", + "@codemirror/state": "^6.1.2", + "@codemirror/view": "^6.4.1", + "@gradio/atoms": "0.6.1", + "@gradio/icons": "0.3.4", + "@gradio/statustracker": "0.4.10", + "@gradio/upload": "0.8.3", + "@gradio/utils": "0.3.0", + "@gradio/wasm": "0.10.0", + "@lezer/common": "^1.0.2", + "@lezer/highlight": "^1.1.3", + "@lezer/markdown": "^1.0.2", + "cm6-theme-basic-dark": "^0.2.0", + "cm6-theme-basic-light": "^0.2.0", + "codemirror": "^6.0.1" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@codemirror/autocomplete": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.15.0.tgz", + "integrity": "sha512-G2Zm0mXznxz97JhaaOdoEG2cVupn4JjPaS4AcNvZzhOsnnG9YVN68VzfoUw6dYTsIxT6a/cmoFEN47KAWhXaOg==", + "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.3.3", + "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.3.3.tgz", + "integrity": "sha512-dO4hcF0fGT9tu1Pj1D2PvGvxjeGkbC6RGcZw6Qs74TH+Ed1gw98jmUgd2axWvIZEqTeTuFrg1lEB1KV6cK9h1A==", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.4.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.1.0" + } + }, + "node_modules/@codemirror/lang-css": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.2.1.tgz", + "integrity": "sha512-/UNWDNV5Viwi/1lpr/dIXJNWiwDxpw13I4pTUAsNxZdg6E0mI2kTQb0P2iHczg1Tu+H4EBgJR+hYhKiHKko7qg==", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.0.2", + "@lezer/css": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-html": { + "version": "6.4.8", + "resolved": "https://registry.npmjs.org/@codemirror/lang-html/-/lang-html-6.4.8.tgz", + "integrity": "sha512-tE2YK7wDlb9ZpAH6mpTPiYm6rhfdQKVDa5r9IwIFlwwgvVaKsCfuKKZoJGWsmMZIf3FQAuJ5CHMPLymOtg1hXw==", + "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-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-markdown": { + "version": "6.2.4", + "resolved": "https://registry.npmjs.org/@codemirror/lang-markdown/-/lang-markdown-6.2.4.tgz", + "integrity": "sha512-UghkA1vSMs8bT7RSZM6vsIocigyah2bV00eRQuZy76401UmFZdsTsbQNBGdyxRQDOLeEvF5iFwap0BM8LKyd+g==", + "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-python": { + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/@codemirror/lang-python/-/lang-python-6.1.5.tgz", + "integrity": "sha512-hCm+8X6wrnXJCGf+QhmFu1AXkdTVG7dHy0Ly6SI1N3SRPptaMvwX6oNQonOXOMPvmcjiB0xq342KAxX3BYpijw==", + "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/language": { + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.1.tgz", + "integrity": "sha512-5GrXzrhq6k+gL5fjkAwt90nYDmjlzTIJV8THnxNFtNKWotMIlzzN+CpqxqwXOECnUdOndmSeWntVrVcv5axWRQ==", + "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/legacy-modes": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@codemirror/legacy-modes/-/legacy-modes-6.3.3.tgz", + "integrity": "sha512-X0Z48odJ0KIoh/HY8Ltz75/4tDYc9msQf1E/2trlxFaFFhgjpVHjZ/BCXe1Lk7s4Gd67LL/CeEEHNI+xHOiESg==", + "dependencies": { + "@codemirror/language": "^6.0.0" + } + }, + "node_modules/@codemirror/lint": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.5.0.tgz", + "integrity": "sha512-+5YyicIaaAZKU8K43IQi8TBy6mF6giGeWAH7N96Z5LC30Wm5JMjqxOYIE9mxwMG1NbhT2mA3l9hA4uuKUM3E5g==", + "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/view": { + "version": "6.26.1", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.26.1.tgz", + "integrity": "sha512-wLw0t3R9AwOSQThdZ5Onw8QQtem5asE7+bPlnzc57eubPqiuJKIzwjMZ+C42vQett+iva+J8VgFV4RYWDBh5FA==", + "dependencies": { + "@codemirror/state": "^6.4.0", + "style-mod": "^4.1.0", + "w3c-keyname": "^2.2.4" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@formatjs/ecma402-abstract": { + "version": "1.11.4", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.4.tgz", + "integrity": "sha512-EBikYFp2JCdIfGEb5G9dyCkTGDmC57KSHhRQOC3aYxoPWVZvfWCDjZwkGYHN7Lis/fmuWl906bnNTJifDQ3sXw==", + "dependencies": { + "@formatjs/intl-localematcher": "0.2.25", + "tslib": "^2.1.0" + } + }, + "node_modules/@formatjs/fast-memoize": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-1.2.1.tgz", + "integrity": "sha512-Rg0e76nomkz3vF9IPlKeV+Qynok0r7YZjL6syLz4/urSg0IbjPZCB/iYUMNsYA643gh4mgrX3T7KEIFIxJBQeg==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@formatjs/icu-messageformat-parser": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.1.0.tgz", + "integrity": "sha512-Qxv/lmCN6hKpBSss2uQ8IROVnta2r9jd3ymUEIjm2UyIkUCHVcbUVRGL/KS/wv7876edvsPe+hjHVJ4z8YuVaw==", + "dependencies": { + "@formatjs/ecma402-abstract": "1.11.4", + "@formatjs/icu-skeleton-parser": "1.3.6", + "tslib": "^2.1.0" + } + }, + "node_modules/@formatjs/icu-skeleton-parser": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.3.6.tgz", + "integrity": "sha512-I96mOxvml/YLrwU2Txnd4klA7V8fRhb6JG/4hm3VMNmeJo1F03IpV2L3wWt7EweqNLES59SZ4d6hVOPCSf80Bg==", + "dependencies": { + "@formatjs/ecma402-abstract": "1.11.4", + "tslib": "^2.1.0" + } + }, + "node_modules/@formatjs/intl-localematcher": { + "version": "0.2.25", + "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.2.25.tgz", + "integrity": "sha512-YmLcX70BxoSopLFdLr1Ds99NdlTI2oWoLbaUW2M406lxOIPzE1KQhRz2fPUkq34xVZQaihCoU29h0KK7An3bhA==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@gradio/atoms": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@gradio/atoms/-/atoms-0.6.1.tgz", + "integrity": "sha512-u7+cleKA0Et6AhEq5xTiaGIAYPR2He7/JSYcM3Sg+vkFOXhbJTPUnHLub+y9HiseheEmnZDGddFBr+RL5Jaxbg==", + "dependencies": { + "@gradio/icons": "^0.3.4", + "@gradio/utils": "^0.3.0" + } + }, + "node_modules/@gradio/client": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@gradio/client/-/client-0.15.0.tgz", + "integrity": "sha512-WQtLRy7mZYR07UsriSLHh3E/zwv53LzQGVCeEz6ue4YwsqEgaDrDwKIGjnpkL06HaZ94Gy/dAvZvUDI4MCO62g==", + "dependencies": { + "bufferutil": "^4.0.7", + "semiver": "^1.1.0", + "ws": "^8.13.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@gradio/column": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@gradio/column/-/column-0.1.0.tgz", + "integrity": "sha512-P24nqqVnMXBaDA1f/zSN5HZRho4PxP8Dq+7VltPHlmxIEiZYik2AJ4J0LeuIha34FDO0guu/16evdrpvGIUAfw==" + }, + "node_modules/@gradio/icons": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@gradio/icons/-/icons-0.3.4.tgz", + "integrity": "sha512-rtH7u3OiYy9UuO1bnebXkTXgc+D62H6BILrMtM4EfsKGgQQICD0n7NPvbPtS0zpi/fz0ppCdlfFIKKIOeVaeFg==" + }, + "node_modules/@gradio/statustracker": { + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/@gradio/statustracker/-/statustracker-0.4.10.tgz", + "integrity": "sha512-1uM30C6L/E26czWZE+a8w1Y5g4FuVkfR59ZxhfL6KfWyERJmhlA8iFWrCCrS4uPZ6wFDXDsY6Im8jqL15uqPzg==", + "dependencies": { + "@gradio/atoms": "^0.6.1", + "@gradio/column": "^0.1.0", + "@gradio/icons": "^0.3.4", + "@gradio/utils": "^0.3.0" + } + }, + "node_modules/@gradio/theme": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@gradio/theme/-/theme-0.2.0.tgz", + "integrity": "sha512-33c68Nk7oRXLn08OxPfjcPm7S4tXGOUV1I1bVgzdM2YV5o1QBOS1GEnXPZPu/CEYPePLMB6bsDwffrLEyLGWVQ==" + }, + "node_modules/@gradio/upload": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@gradio/upload/-/upload-0.8.3.tgz", + "integrity": "sha512-rufkvHPn1CwEuo/dgDMbSdLAG6m5poTT0hyDYnqdRkIAeBi6gU73xPylKUdQcVBIJvYGexkTU83jij4pnet6yQ==", + "dependencies": { + "@gradio/atoms": "^0.6.1", + "@gradio/client": "^0.15.0", + "@gradio/icons": "^0.3.4", + "@gradio/upload": "^0.8.3", + "@gradio/utils": "^0.3.0", + "@gradio/wasm": "^0.10.0" + } + }, + "node_modules/@gradio/utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@gradio/utils/-/utils-0.3.0.tgz", + "integrity": "sha512-VxP0h7UoWazkdSB875ChvTXWamBwMguuRc+8OyQFZjdj14lcqLEQuj54es3FDBpXOp5GMLFh48Q5FLLjYxMgSg==", + "dependencies": { + "@gradio/theme": "^0.2.0", + "svelte-i18n": "^3.6.0" + } + }, + "node_modules/@gradio/wasm": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@gradio/wasm/-/wasm-0.10.0.tgz", + "integrity": "sha512-ephuiuimvMad6KzNPz/3OdnjgE5wsJdVfAAqu+J0qloetbH42LfeRLsVe5WqGo2WpjzXq5MC8I8MJ7lpQMhUpw==", + "dependencies": { + "@types/path-browserify": "^1.0.0", + "path-browserify": "^1.0.1" + } + }, + "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==", + "peer": true, + "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==", + "peer": true, + "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==", + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "peer": true + }, + "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==", + "peer": true, + "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/css": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.1.8.tgz", + "integrity": "sha512-7JhxupKuMBaWQKjQoLtzhGj83DdnZY9MckEOG5+/iLKNK2ZJqKc6hf6uc0HjwCX7Qlok44jBNqZhHKDhEhZYLA==", + "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.9", + "resolved": "https://registry.npmjs.org/@lezer/html/-/html-1.3.9.tgz", + "integrity": "sha512-MXxeCMPyrcemSLGaTQEZx0dBUH0i+RPl8RN5GwMAzo53nTsd/Unc/t5ZxACeQoyPUM5/GkPLRUs2WliOImzkRA==", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/javascript": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.4.14.tgz", + "integrity": "sha512-GEdUyspTRgc5dwIGebUk+f3BekvqEWVIYsIuAC3pA8e8wcikGwBZRWRa450L0s8noGWuULwnmi4yjxTnYz9PpA==", + "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.0", + "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.0.tgz", + "integrity": "sha512-Wst46p51km8gH0ZUmeNrtpRYmdlRHUpN1DQd3GFAyKANi8WVz8c2jHYTf1CVScFaCjQw1iO3ZZdqGDxQPRErTg==", + "dependencies": { + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@lezer/markdown": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@lezer/markdown/-/markdown-1.2.0.tgz", + "integrity": "sha512-d7MwsfAukZJo1GpPrcPGa3MxaFFOqNp0gbqF+3F7pTeNDOgeJN1muXzx1XXDPt+Ac+/voCzsH7qXqnn+xReG/g==", + "dependencies": { + "@lezer/common": "^1.0.0", + "@lezer/highlight": "^1.0.0" + } + }, + "node_modules/@lezer/python": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@lezer/python/-/python-1.1.13.tgz", + "integrity": "sha512-AdbRAtdQq94PfTNd4kqMEJhH2fqa2JdoyyqqVewY6w34w2Gi6dg2JuOtOgR21Bi0zP9r0KjSSHOUq/tP7FVT8A==", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "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==", + "peer": true + }, + "node_modules/@types/path-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/path-browserify/-/path-browserify-1.0.2.tgz", + "integrity": "sha512-ZkC5IUqqIFPXx3ASTTybTzmQdwHwe2C0u3eL75ldQ6T9E9IWFJodn6hIfbZGab73DfyiHN4Xw15gNxUq2FbvBA==" + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "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==", + "peer": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "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==", + "peer": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/bufferutil": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", + "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==", + "hasInstallScript": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/cli-color": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.4.tgz", + "integrity": "sha512-zlnpg0jNcibNrO7GG9IeHH7maWFeCz+Ja1wx/7tZNU5ASSSSZ+/qZciM0/LHCYxSdqv5h2sdbQ/PXYdOuetXvA==", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.64", + "es6-iterator": "^2.0.3", + "memoizee": "^0.4.15", + "timers-ext": "^0.1.7" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/cm6-theme-basic-dark": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/cm6-theme-basic-dark/-/cm6-theme-basic-dark-0.2.0.tgz", + "integrity": "sha512-+mNNJecRtxS/KkloMDCQF0oTrT6aFGRZTjnBcdT5UG1pcDO4Brq8l1+0KR/8dZ7hub2gOGOzoi3rGFD8GzlH7Q==", + "peerDependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/highlight": "^1.0.0" + } + }, + "node_modules/cm6-theme-basic-light": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/cm6-theme-basic-light/-/cm6-theme-basic-light-0.2.0.tgz", + "integrity": "sha512-1prg2gv44sYfpHscP26uLT/ePrh0mlmVwMSoSd3zYKQ92Ab3jPRLzyCnpyOCQLJbK+YdNs4HvMRqMNYdy4pMhA==", + "peerDependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/highlight": "^1.0.0" + } + }, + "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==", + "peer": true, + "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/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/crelt": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", + "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==" + }, + "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==", + "peer": true, + "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/d": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", + "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", + "dependencies": { + "es5-ext": "^0.10.64", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.12" + } + }, + "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/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/es5-ext": { + "version": "0.10.64", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", + "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", + "hasInstallScript": true, + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", + "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", + "dependencies": { + "d": "^1.0.2", + "ext": "^1.7.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/esbuild": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" + } + }, + "node_modules/esniff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "peer": true, + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dependencies": { + "type": "^2.7.2" + } + }, + "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/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/intl-messageformat": { + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-9.13.0.tgz", + "integrity": "sha512-7sGC7QnSQGa5LZP7bXLDhVDtQOeKGeBFGHF2Y8LVBwYZoQZCgWeKoPGTa5GMG8g/TzDgeXuYJQis7Ggiw2xTOw==", + "dependencies": { + "@formatjs/ecma402-abstract": "1.11.4", + "@formatjs/fast-memoize": "1.2.1", + "@formatjs/icu-messageformat-parser": "2.1.0", + "tslib": "^2.1.0" + } + }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" + }, + "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==", + "peer": true, + "dependencies": { + "@types/estree": "*" + } + }, + "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==", + "peer": true + }, + "node_modules/lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", + "dependencies": { + "es5-ext": "~0.10.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.8", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", + "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", + "peer": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "engines": { + "node": ">=12" + } + }, + "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==", + "peer": true + }, + "node_modules/memoizee": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", + "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.53", + "es6-weak-map": "^2.0.3", + "event-emitter": "^0.3.5", + "is-promise": "^2.2.2", + "lru-queue": "^0.1.0", + "next-tick": "^1.1.0", + "timers-ext": "^0.1.7" + } + }, + "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/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" + }, + "node_modules/node-gyp-build": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.0.tgz", + "integrity": "sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==" + }, + "node_modules/periscopic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", + "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", + "peer": true, + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^3.0.0", + "is-reference": "^3.0.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/semiver": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/semiver/-/semiver-1.1.0.tgz", + "integrity": "sha512-QNI2ChmuioGC1/xjyYwyZYADILWyW6AmS1UH6gDj/SFUUUS4MBAWs/7mxnkRPc/F4iHezDP+O8t0dO8WHiEOdg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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/svelte": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.12.tgz", + "integrity": "sha512-d8+wsh5TfPwqVzbm4/HCXC783/KPHV60NvwitJnyTA5lWn1elhXMNWhXGCJ7PwPa8qFUnyJNIyuIRt2mT0WMug==", + "peer": true, + "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-i18n": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/svelte-i18n/-/svelte-i18n-3.7.4.tgz", + "integrity": "sha512-yGRCNo+eBT4cPuU7IVsYTYjxB7I2V8qgUZPlHnNctJj5IgbJgV78flsRzpjZ/8iUYZrS49oCt7uxlU3AZv/N5Q==", + "dependencies": { + "cli-color": "^2.0.3", + "deepmerge": "^4.2.2", + "esbuild": "^0.19.2", + "estree-walker": "^2", + "intl-messageformat": "^9.13.0", + "sade": "^1.8.1", + "tiny-glob": "^0.2.9" + }, + "bin": { + "svelte-i18n": "dist/cli.js" + }, + "engines": { + "node": ">= 16" + }, + "peerDependencies": { + "svelte": "^3 || ^4" + } + }, + "node_modules/svelte-i18n/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/timers-ext": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", + "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", + "dependencies": { + "es5-ext": "~0.10.46", + "next-tick": "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/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "node_modules/type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" + }, + "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/ws": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "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 + } + } + } + }, + "dependencies": { + "@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "peer": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "@codemirror/autocomplete": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.15.0.tgz", + "integrity": "sha512-G2Zm0mXznxz97JhaaOdoEG2cVupn4JjPaS4AcNvZzhOsnnG9YVN68VzfoUw6dYTsIxT6a/cmoFEN47KAWhXaOg==", + "requires": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0" + } + }, + "@codemirror/commands": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.3.3.tgz", + "integrity": "sha512-dO4hcF0fGT9tu1Pj1D2PvGvxjeGkbC6RGcZw6Qs74TH+Ed1gw98jmUgd2axWvIZEqTeTuFrg1lEB1KV6cK9h1A==", + "requires": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.4.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.1.0" + } + }, + "@codemirror/lang-css": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.2.1.tgz", + "integrity": "sha512-/UNWDNV5Viwi/1lpr/dIXJNWiwDxpw13I4pTUAsNxZdg6E0mI2kTQb0P2iHczg1Tu+H4EBgJR+hYhKiHKko7qg==", + "requires": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.0.2", + "@lezer/css": "^1.0.0" + } + }, + "@codemirror/lang-html": { + "version": "6.4.8", + "resolved": "https://registry.npmjs.org/@codemirror/lang-html/-/lang-html-6.4.8.tgz", + "integrity": "sha512-tE2YK7wDlb9ZpAH6mpTPiYm6rhfdQKVDa5r9IwIFlwwgvVaKsCfuKKZoJGWsmMZIf3FQAuJ5CHMPLymOtg1hXw==", + "requires": { + "@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" + } + }, + "@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==", + "requires": { + "@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" + } + }, + "@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==", + "requires": { + "@codemirror/language": "^6.0.0", + "@lezer/json": "^1.0.0" + } + }, + "@codemirror/lang-markdown": { + "version": "6.2.4", + "resolved": "https://registry.npmjs.org/@codemirror/lang-markdown/-/lang-markdown-6.2.4.tgz", + "integrity": "sha512-UghkA1vSMs8bT7RSZM6vsIocigyah2bV00eRQuZy76401UmFZdsTsbQNBGdyxRQDOLeEvF5iFwap0BM8LKyd+g==", + "requires": { + "@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" + } + }, + "@codemirror/lang-python": { + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/@codemirror/lang-python/-/lang-python-6.1.5.tgz", + "integrity": "sha512-hCm+8X6wrnXJCGf+QhmFu1AXkdTVG7dHy0Ly6SI1N3SRPptaMvwX6oNQonOXOMPvmcjiB0xq342KAxX3BYpijw==", + "requires": { + "@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" + } + }, + "@codemirror/language": { + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.1.tgz", + "integrity": "sha512-5GrXzrhq6k+gL5fjkAwt90nYDmjlzTIJV8THnxNFtNKWotMIlzzN+CpqxqwXOECnUdOndmSeWntVrVcv5axWRQ==", + "requires": { + "@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" + } + }, + "@codemirror/legacy-modes": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@codemirror/legacy-modes/-/legacy-modes-6.3.3.tgz", + "integrity": "sha512-X0Z48odJ0KIoh/HY8Ltz75/4tDYc9msQf1E/2trlxFaFFhgjpVHjZ/BCXe1Lk7s4Gd67LL/CeEEHNI+xHOiESg==", + "requires": { + "@codemirror/language": "^6.0.0" + } + }, + "@codemirror/lint": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.5.0.tgz", + "integrity": "sha512-+5YyicIaaAZKU8K43IQi8TBy6mF6giGeWAH7N96Z5LC30Wm5JMjqxOYIE9mxwMG1NbhT2mA3l9hA4uuKUM3E5g==", + "requires": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "crelt": "^1.0.5" + } + }, + "@codemirror/search": { + "version": "6.5.6", + "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.6.tgz", + "integrity": "sha512-rpMgcsh7o0GuCDUXKPvww+muLA1pDJaFrpq/CCHtpQJYz8xopu4D1hPcKRoDD0YlF8gZaqTNIRa4VRBWyhyy7Q==", + "requires": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "crelt": "^1.0.5" + } + }, + "@codemirror/state": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.1.tgz", + "integrity": "sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A==" + }, + "@codemirror/view": { + "version": "6.26.1", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.26.1.tgz", + "integrity": "sha512-wLw0t3R9AwOSQThdZ5Onw8QQtem5asE7+bPlnzc57eubPqiuJKIzwjMZ+C42vQett+iva+J8VgFV4RYWDBh5FA==", + "requires": { + "@codemirror/state": "^6.4.0", + "style-mod": "^4.1.0", + "w3c-keyname": "^2.2.4" + } + }, + "@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "optional": true + }, + "@esbuild/android-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "optional": true + }, + "@formatjs/ecma402-abstract": { + "version": "1.11.4", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.4.tgz", + "integrity": "sha512-EBikYFp2JCdIfGEb5G9dyCkTGDmC57KSHhRQOC3aYxoPWVZvfWCDjZwkGYHN7Lis/fmuWl906bnNTJifDQ3sXw==", + "requires": { + "@formatjs/intl-localematcher": "0.2.25", + "tslib": "^2.1.0" + } + }, + "@formatjs/fast-memoize": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-1.2.1.tgz", + "integrity": "sha512-Rg0e76nomkz3vF9IPlKeV+Qynok0r7YZjL6syLz4/urSg0IbjPZCB/iYUMNsYA643gh4mgrX3T7KEIFIxJBQeg==", + "requires": { + "tslib": "^2.1.0" + } + }, + "@formatjs/icu-messageformat-parser": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.1.0.tgz", + "integrity": "sha512-Qxv/lmCN6hKpBSss2uQ8IROVnta2r9jd3ymUEIjm2UyIkUCHVcbUVRGL/KS/wv7876edvsPe+hjHVJ4z8YuVaw==", + "requires": { + "@formatjs/ecma402-abstract": "1.11.4", + "@formatjs/icu-skeleton-parser": "1.3.6", + "tslib": "^2.1.0" + } + }, + "@formatjs/icu-skeleton-parser": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.3.6.tgz", + "integrity": "sha512-I96mOxvml/YLrwU2Txnd4klA7V8fRhb6JG/4hm3VMNmeJo1F03IpV2L3wWt7EweqNLES59SZ4d6hVOPCSf80Bg==", + "requires": { + "@formatjs/ecma402-abstract": "1.11.4", + "tslib": "^2.1.0" + } + }, + "@formatjs/intl-localematcher": { + "version": "0.2.25", + "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.2.25.tgz", + "integrity": "sha512-YmLcX70BxoSopLFdLr1Ds99NdlTI2oWoLbaUW2M406lxOIPzE1KQhRz2fPUkq34xVZQaihCoU29h0KK7An3bhA==", + "requires": { + "tslib": "^2.1.0" + } + }, + "@gradio/atoms": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@gradio/atoms/-/atoms-0.6.1.tgz", + "integrity": "sha512-u7+cleKA0Et6AhEq5xTiaGIAYPR2He7/JSYcM3Sg+vkFOXhbJTPUnHLub+y9HiseheEmnZDGddFBr+RL5Jaxbg==", + "requires": { + "@gradio/icons": "^0.3.4", + "@gradio/utils": "^0.3.0" + } + }, + "@gradio/client": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@gradio/client/-/client-0.15.0.tgz", + "integrity": "sha512-WQtLRy7mZYR07UsriSLHh3E/zwv53LzQGVCeEz6ue4YwsqEgaDrDwKIGjnpkL06HaZ94Gy/dAvZvUDI4MCO62g==", + "requires": { + "bufferutil": "^4.0.7", + "semiver": "^1.1.0", + "ws": "^8.13.0" + } + }, + "@gradio/column": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@gradio/column/-/column-0.1.0.tgz", + "integrity": "sha512-P24nqqVnMXBaDA1f/zSN5HZRho4PxP8Dq+7VltPHlmxIEiZYik2AJ4J0LeuIha34FDO0guu/16evdrpvGIUAfw==" + }, + "@gradio/icons": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@gradio/icons/-/icons-0.3.4.tgz", + "integrity": "sha512-rtH7u3OiYy9UuO1bnebXkTXgc+D62H6BILrMtM4EfsKGgQQICD0n7NPvbPtS0zpi/fz0ppCdlfFIKKIOeVaeFg==" + }, + "@gradio/statustracker": { + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/@gradio/statustracker/-/statustracker-0.4.10.tgz", + "integrity": "sha512-1uM30C6L/E26czWZE+a8w1Y5g4FuVkfR59ZxhfL6KfWyERJmhlA8iFWrCCrS4uPZ6wFDXDsY6Im8jqL15uqPzg==", + "requires": { + "@gradio/atoms": "^0.6.1", + "@gradio/column": "^0.1.0", + "@gradio/icons": "^0.3.4", + "@gradio/utils": "^0.3.0" + } + }, + "@gradio/theme": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@gradio/theme/-/theme-0.2.0.tgz", + "integrity": "sha512-33c68Nk7oRXLn08OxPfjcPm7S4tXGOUV1I1bVgzdM2YV5o1QBOS1GEnXPZPu/CEYPePLMB6bsDwffrLEyLGWVQ==" + }, + "@gradio/upload": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@gradio/upload/-/upload-0.8.3.tgz", + "integrity": "sha512-rufkvHPn1CwEuo/dgDMbSdLAG6m5poTT0hyDYnqdRkIAeBi6gU73xPylKUdQcVBIJvYGexkTU83jij4pnet6yQ==", + "requires": { + "@gradio/atoms": "^0.6.1", + "@gradio/client": "^0.15.0", + "@gradio/icons": "^0.3.4", + "@gradio/upload": "^0.8.3", + "@gradio/utils": "^0.3.0", + "@gradio/wasm": "^0.10.0" + } + }, + "@gradio/utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@gradio/utils/-/utils-0.3.0.tgz", + "integrity": "sha512-VxP0h7UoWazkdSB875ChvTXWamBwMguuRc+8OyQFZjdj14lcqLEQuj54es3FDBpXOp5GMLFh48Q5FLLjYxMgSg==", + "requires": { + "@gradio/theme": "^0.2.0", + "svelte-i18n": "^3.6.0" + } + }, + "@gradio/wasm": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@gradio/wasm/-/wasm-0.10.0.tgz", + "integrity": "sha512-ephuiuimvMad6KzNPz/3OdnjgE5wsJdVfAAqu+J0qloetbH42LfeRLsVe5WqGo2WpjzXq5MC8I8MJ7lpQMhUpw==", + "requires": { + "@types/path-browserify": "^1.0.0", + "path-browserify": "^1.0.1" + } + }, + "@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==", + "peer": true, + "requires": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "@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==", + "peer": true + }, + "@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==", + "peer": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "peer": true + }, + "@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==", + "peer": true, + "requires": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "@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==" + }, + "@lezer/css": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.1.8.tgz", + "integrity": "sha512-7JhxupKuMBaWQKjQoLtzhGj83DdnZY9MckEOG5+/iLKNK2ZJqKc6hf6uc0HjwCX7Qlok44jBNqZhHKDhEhZYLA==", + "requires": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "@lezer/highlight": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.0.tgz", + "integrity": "sha512-WrS5Mw51sGrpqjlh3d4/fOwpEV2Hd3YOkp9DBt4k8XZQcoTHZFB7sx030A6OcahF4J1nDQAa3jXlTVVYH50IFA==", + "requires": { + "@lezer/common": "^1.0.0" + } + }, + "@lezer/html": { + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/@lezer/html/-/html-1.3.9.tgz", + "integrity": "sha512-MXxeCMPyrcemSLGaTQEZx0dBUH0i+RPl8RN5GwMAzo53nTsd/Unc/t5ZxACeQoyPUM5/GkPLRUs2WliOImzkRA==", + "requires": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "@lezer/javascript": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.4.14.tgz", + "integrity": "sha512-GEdUyspTRgc5dwIGebUk+f3BekvqEWVIYsIuAC3pA8e8wcikGwBZRWRa450L0s8noGWuULwnmi4yjxTnYz9PpA==", + "requires": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.1.3", + "@lezer/lr": "^1.3.0" + } + }, + "@lezer/json": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.2.tgz", + "integrity": "sha512-xHT2P4S5eeCYECyKNPhr4cbEL9tc8w83SPwRC373o9uEdrvGKTZoJVAGxpOsZckMlEh9W23Pc72ew918RWQOBQ==", + "requires": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "@lezer/lr": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.0.tgz", + "integrity": "sha512-Wst46p51km8gH0ZUmeNrtpRYmdlRHUpN1DQd3GFAyKANi8WVz8c2jHYTf1CVScFaCjQw1iO3ZZdqGDxQPRErTg==", + "requires": { + "@lezer/common": "^1.0.0" + } + }, + "@lezer/markdown": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@lezer/markdown/-/markdown-1.2.0.tgz", + "integrity": "sha512-d7MwsfAukZJo1GpPrcPGa3MxaFFOqNp0gbqF+3F7pTeNDOgeJN1muXzx1XXDPt+Ac+/voCzsH7qXqnn+xReG/g==", + "requires": { + "@lezer/common": "^1.0.0", + "@lezer/highlight": "^1.0.0" + } + }, + "@lezer/python": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@lezer/python/-/python-1.1.13.tgz", + "integrity": "sha512-AdbRAtdQq94PfTNd4kqMEJhH2fqa2JdoyyqqVewY6w34w2Gi6dg2JuOtOgR21Bi0zP9r0KjSSHOUq/tP7FVT8A==", + "requires": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "@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==", + "peer": true + }, + "@types/path-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/path-browserify/-/path-browserify-1.0.2.tgz", + "integrity": "sha512-ZkC5IUqqIFPXx3ASTTybTzmQdwHwe2C0u3eL75ldQ6T9E9IWFJodn6hIfbZGab73DfyiHN4Xw15gNxUq2FbvBA==" + }, + "acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "peer": true + }, + "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==", + "peer": true, + "requires": { + "dequal": "^2.0.3" + } + }, + "axobject-query": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz", + "integrity": "sha512-+60uv1hiVFhHZeO+Lz0RYzsVHy5Wr1ayX0mwda9KPDVLNJgZ1T9Ny7VmFbLDzxsH0D87I86vgj3gFrjTJUYznw==", + "peer": true, + "requires": { + "dequal": "^2.0.3" + } + }, + "bufferutil": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", + "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==", + "requires": { + "node-gyp-build": "^4.3.0" + } + }, + "cli-color": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.4.tgz", + "integrity": "sha512-zlnpg0jNcibNrO7GG9IeHH7maWFeCz+Ja1wx/7tZNU5ASSSSZ+/qZciM0/LHCYxSdqv5h2sdbQ/PXYdOuetXvA==", + "requires": { + "d": "^1.0.1", + "es5-ext": "^0.10.64", + "es6-iterator": "^2.0.3", + "memoizee": "^0.4.15", + "timers-ext": "^0.1.7" + } + }, + "cm6-theme-basic-dark": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/cm6-theme-basic-dark/-/cm6-theme-basic-dark-0.2.0.tgz", + "integrity": "sha512-+mNNJecRtxS/KkloMDCQF0oTrT6aFGRZTjnBcdT5UG1pcDO4Brq8l1+0KR/8dZ7hub2gOGOzoi3rGFD8GzlH7Q==", + "requires": {} + }, + "cm6-theme-basic-light": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/cm6-theme-basic-light/-/cm6-theme-basic-light-0.2.0.tgz", + "integrity": "sha512-1prg2gv44sYfpHscP26uLT/ePrh0mlmVwMSoSd3zYKQ92Ab3jPRLzyCnpyOCQLJbK+YdNs4HvMRqMNYdy4pMhA==", + "requires": {} + }, + "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==", + "peer": true, + "requires": { + "@jridgewell/sourcemap-codec": "^1.4.15", + "@types/estree": "^1.0.1", + "acorn": "^8.10.0", + "estree-walker": "^3.0.3", + "periscopic": "^3.1.0" + } + }, + "codemirror": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz", + "integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==", + "requires": { + "@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" + } + }, + "crelt": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", + "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==" + }, + "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==", + "peer": true, + "requires": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + } + }, + "d": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", + "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", + "requires": { + "es5-ext": "^0.10.64", + "type": "^2.7.2" + } + }, + "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==" + }, + "dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "peer": true + }, + "es5-ext": { + "version": "0.10.64", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", + "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", + "requires": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", + "next-tick": "^1.1.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-symbol": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", + "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", + "requires": { + "d": "^1.0.2", + "ext": "^1.7.0" + } + }, + "es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "requires": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, + "esbuild": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "requires": { + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" + } + }, + "esniff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", + "requires": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + } + }, + "estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "peer": true, + "requires": { + "@types/estree": "^1.0.0" + } + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "requires": { + "type": "^2.7.2" + } + }, + "globalyzer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", + "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==" + }, + "globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==" + }, + "intl-messageformat": { + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-9.13.0.tgz", + "integrity": "sha512-7sGC7QnSQGa5LZP7bXLDhVDtQOeKGeBFGHF2Y8LVBwYZoQZCgWeKoPGTa5GMG8g/TzDgeXuYJQis7Ggiw2xTOw==", + "requires": { + "@formatjs/ecma402-abstract": "1.11.4", + "@formatjs/fast-memoize": "1.2.1", + "@formatjs/icu-messageformat-parser": "2.1.0", + "tslib": "^2.1.0" + } + }, + "is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" + }, + "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==", + "peer": true, + "requires": { + "@types/estree": "*" + } + }, + "locate-character": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", + "peer": true + }, + "lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", + "requires": { + "es5-ext": "~0.10.2" + } + }, + "magic-string": { + "version": "0.30.8", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", + "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", + "peer": true, + "requires": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "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==", + "peer": true + }, + "memoizee": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", + "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", + "requires": { + "d": "^1.0.1", + "es5-ext": "^0.10.53", + "es6-weak-map": "^2.0.3", + "event-emitter": "^0.3.5", + "is-promise": "^2.2.2", + "lru-queue": "^0.1.0", + "next-tick": "^1.1.0", + "timers-ext": "^0.1.7" + } + }, + "mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==" + }, + "next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" + }, + "node-gyp-build": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.0.tgz", + "integrity": "sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==" + }, + "path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==" + }, + "periscopic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", + "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", + "peer": true, + "requires": { + "@types/estree": "^1.0.0", + "estree-walker": "^3.0.0", + "is-reference": "^3.0.0" + } + }, + "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==", + "requires": { + "mri": "^1.1.0" + } + }, + "semiver": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/semiver/-/semiver-1.1.0.tgz", + "integrity": "sha512-QNI2ChmuioGC1/xjyYwyZYADILWyW6AmS1UH6gDj/SFUUUS4MBAWs/7mxnkRPc/F4iHezDP+O8t0dO8WHiEOdg==" + }, + "source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "peer": true + }, + "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==" + }, + "svelte": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.12.tgz", + "integrity": "sha512-d8+wsh5TfPwqVzbm4/HCXC783/KPHV60NvwitJnyTA5lWn1elhXMNWhXGCJ7PwPa8qFUnyJNIyuIRt2mT0WMug==", + "peer": true, + "requires": { + "@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" + } + }, + "svelte-i18n": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/svelte-i18n/-/svelte-i18n-3.7.4.tgz", + "integrity": "sha512-yGRCNo+eBT4cPuU7IVsYTYjxB7I2V8qgUZPlHnNctJj5IgbJgV78flsRzpjZ/8iUYZrS49oCt7uxlU3AZv/N5Q==", + "requires": { + "cli-color": "^2.0.3", + "deepmerge": "^4.2.2", + "esbuild": "^0.19.2", + "estree-walker": "^2", + "intl-messageformat": "^9.13.0", + "sade": "^1.8.1", + "tiny-glob": "^0.2.9" + }, + "dependencies": { + "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==" + } + } + }, + "timers-ext": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", + "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", + "requires": { + "es5-ext": "~0.10.46", + "next-tick": "1" + } + }, + "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==", + "requires": { + "globalyzer": "0.1.0", + "globrex": "^0.1.2" + } + }, + "tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" + }, + "w3c-keyname": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", + "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==" + }, + "ws": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "requires": {} + } + } +} diff --git a/src/frontend/package.json b/src/frontend/package.json new file mode 100644 index 0000000000000000000000000000000000000000..82c7d4fe50bcd1e62b3c3180a333bf62ea11e834 --- /dev/null +++ b/src/frontend/package.json @@ -0,0 +1,44 @@ +{ + "name": "gradio_logsview", + "version": "0.5.10", + "description": "Gradio UI packages", + "type": "module", + "author": "", + "license": "ISC", + "private": false, + "dependencies": { + "@codemirror/autocomplete": "^6.3.0", + "@codemirror/commands": "^6.1.2", + "@codemirror/lang-css": "^6.1.0", + "@codemirror/lang-html": "^6.4.2", + "@codemirror/lang-javascript": "^6.1.4", + "@codemirror/lang-json": "^6.0.1", + "@codemirror/lang-markdown": "^6.1.0", + "@codemirror/lang-python": "^6.0.4", + "@codemirror/language": "^6.6.0", + "@codemirror/legacy-modes": "^6.3.1", + "@codemirror/lint": "^6.0.0", + "@codemirror/search": "^6.2.2", + "@codemirror/state": "^6.1.2", + "@codemirror/view": "^6.4.1", + "@gradio/atoms": "0.6.1", + "@gradio/icons": "0.3.4", + "@gradio/statustracker": "0.4.10", + "@gradio/upload": "0.8.3", + "@gradio/utils": "0.3.0", + "@gradio/wasm": "0.10.0", + "@lezer/common": "^1.0.2", + "@lezer/highlight": "^1.1.3", + "@lezer/markdown": "^1.0.2", + "cm6-theme-basic-dark": "^0.2.0", + "cm6-theme-basic-light": "^0.2.0", + "codemirror": "^6.0.1" + }, + "main_changeset": true, + "main": "./Index.svelte", + "exports": { + ".": "./Index.svelte", + "./example": "./Example.svelte", + "./package.json": "./package.json" + } +} \ No newline at end of file diff --git a/src/frontend/shared/Code.svelte b/src/frontend/shared/Code.svelte new file mode 100644 index 0000000000000000000000000000000000000000..cd5ccb8942818d560cae6ab38de51f66494d6acc --- /dev/null +++ b/src/frontend/shared/Code.svelte @@ -0,0 +1,258 @@ + + +
+
+
+ + diff --git a/src/frontend/shared/Copy.svelte b/src/frontend/shared/Copy.svelte new file mode 100644 index 0000000000000000000000000000000000000000..cc886131bc85afaf57b9a016c54f4a690a91e641 --- /dev/null +++ b/src/frontend/shared/Copy.svelte @@ -0,0 +1,68 @@ + + + + + diff --git a/src/frontend/shared/Download.svelte b/src/frontend/shared/Download.svelte new file mode 100644 index 0000000000000000000000000000000000000000..5639c0a800c030b35d38a3b13eed4cdf68c807e1 --- /dev/null +++ b/src/frontend/shared/Download.svelte @@ -0,0 +1,88 @@ + + +
+ + + {#if copied} + + {/if} + +
+ + diff --git a/src/frontend/shared/Widgets.svelte b/src/frontend/shared/Widgets.svelte new file mode 100644 index 0000000000000000000000000000000000000000..584c1944077ad6961a76aa4ddae37ae86d17f040 --- /dev/null +++ b/src/frontend/shared/Widgets.svelte @@ -0,0 +1,35 @@ + + +
+ + +
+ + diff --git a/src/frontend/shared/extensions.ts b/src/frontend/shared/extensions.ts new file mode 100644 index 0000000000000000000000000000000000000000..9193acbeca876d8788a5f54f578f8eff2c2652f1 --- /dev/null +++ b/src/frontend/shared/extensions.ts @@ -0,0 +1,48 @@ +import type { Extension } from "@codemirror/state"; +import { + lineNumbers, + highlightSpecialChars, + drawSelection, + rectangularSelection, + crosshairCursor, + keymap +} from "@codemirror/view"; +export { EditorView } from "@codemirror/view"; +import { EditorState } from "@codemirror/state"; +import { + foldGutter, + indentOnInput, + syntaxHighlighting, + defaultHighlightStyle, + foldKeymap +} from "@codemirror/language"; +import { history, defaultKeymap, historyKeymap } from "@codemirror/commands"; +import { + closeBrackets, + closeBracketsKeymap, + completionKeymap +} from "@codemirror/autocomplete"; +import { lintKeymap } from "@codemirror/lint"; + +export const basicSetup: Extension = /*@__PURE__*/ ((): Extension[] => [ + lineNumbers(), + highlightSpecialChars(), + history(), + foldGutter(), + drawSelection(), + EditorState.allowMultipleSelections.of(true), + indentOnInput(), + syntaxHighlighting(defaultHighlightStyle, { fallback: true }), + closeBrackets(), + rectangularSelection(), + crosshairCursor(), + + keymap.of([ + ...closeBracketsKeymap, + ...defaultKeymap, + ...historyKeymap, + ...foldKeymap, + ...completionKeymap, + ...lintKeymap + ]) +])(); diff --git a/src/frontend/shared/frontmatter.ts b/src/frontend/shared/frontmatter.ts new file mode 100644 index 0000000000000000000000000000000000000000..78e6a1ab66fbdd15a8ad958df373f6bd7e406936 --- /dev/null +++ b/src/frontend/shared/frontmatter.ts @@ -0,0 +1,61 @@ +import type { + Element, + MarkdownExtension, + BlockContext, + Line +} from "@lezer/markdown"; +import { parseMixed } from "@lezer/common"; +import { yaml } from "@codemirror/legacy-modes/mode/yaml"; +import { foldInside, foldNodeProp, StreamLanguage } from "@codemirror/language"; +import { styleTags, tags } from "@lezer/highlight"; + +const frontMatterFence = /^---\s*$/m; + +export const frontmatter: MarkdownExtension = { + defineNodes: [{ name: "Frontmatter", block: true }, "FrontmatterMark"], + props: [ + styleTags({ + Frontmatter: [tags.documentMeta, tags.monospace], + FrontmatterMark: tags.processingInstruction + }), + foldNodeProp.add({ + Frontmatter: foldInside, + FrontmatterMark: () => null + }) + ], + wrap: parseMixed((node) => { + const { parser } = StreamLanguage.define(yaml); + if (node.type.name === "Frontmatter") { + return { + parser, + overlay: [{ from: node.from + 4, to: node.to - 4 }] + }; + } + return null; + }), + parseBlock: [ + { + name: "Frontmatter", + before: "HorizontalRule", + parse: (cx: BlockContext, line: Line): boolean => { + let end: number | undefined = undefined; + const children = new Array(); + if (cx.lineStart === 0 && frontMatterFence.test(line.text)) { + children.push(cx.elt("FrontmatterMark", 0, 4)); + while (cx.nextLine()) { + if (frontMatterFence.test(line.text)) { + end = cx.lineStart + 4; + break; + } + } + if (end !== undefined) { + children.push(cx.elt("FrontmatterMark", end - 4, end)); + cx.addElement(cx.elt("Frontmatter", 0, end, children)); + } + return true; + } + return false; + } + } + ] +}; diff --git a/src/frontend/shared/language.ts b/src/frontend/shared/language.ts new file mode 100644 index 0000000000000000000000000000000000000000..a265b6d1d6734feca1264a875a3fa635842201bd --- /dev/null +++ b/src/frontend/shared/language.ts @@ -0,0 +1,101 @@ +import type { Extension } from "@codemirror/state"; +import { StreamLanguage } from "@codemirror/language"; +import { sql } from "@codemirror/legacy-modes/mode/sql"; + +const possible_langs = [ + "python", + "markdown", + "json", + "html", + "css", + "javascript", + "typescript", + "yaml", + "dockerfile", + "shell", + "r", + "sql" +]; + +const sql_dialects = [ + "standardSQL", + "msSQL", + "mySQL", + "mariaDB", + "sqlite", + "cassandra", + "plSQL", + "hive", + "pgSQL", + "gql", + "gpSQL", + "sparkSQL", + "esper" +] as const; + +const lang_map: Record Promise) | undefined> = { + python: () => import("@codemirror/lang-python").then((m) => m.python()), + markdown: async () => { + const [md, frontmatter] = await Promise.all([ + import("@codemirror/lang-markdown"), + import("./frontmatter") + ]); + return md.markdown({ extensions: [frontmatter.frontmatter] }); + }, + json: () => import("@codemirror/lang-json").then((m) => m.json()), + html: () => import("@codemirror/lang-html").then((m) => m.html()), + css: () => import("@codemirror/lang-css").then((m) => m.css()), + javascript: () => + import("@codemirror/lang-javascript").then((m) => m.javascript()), + typescript: () => + import("@codemirror/lang-javascript").then((m) => + m.javascript({ typescript: true }) + ), + yaml: () => + import("@codemirror/legacy-modes/mode/yaml").then((m) => + StreamLanguage.define(m.yaml) + ), + dockerfile: () => + import("@codemirror/legacy-modes/mode/dockerfile").then((m) => + StreamLanguage.define(m.dockerFile) + ), + shell: () => + import("@codemirror/legacy-modes/mode/shell").then((m) => + StreamLanguage.define(m.shell) + ), + r: () => + import("@codemirror/legacy-modes/mode/r").then((m) => + StreamLanguage.define(m.r) + ), + sql: () => + import("@codemirror/legacy-modes/mode/sql").then((m) => + StreamLanguage.define(m.standardSQL) + ), + ...Object.fromEntries( + sql_dialects.map((dialect) => [ + "sql-" + dialect, + () => + import("@codemirror/legacy-modes/mode/sql").then((m) => + StreamLanguage.define(m[dialect]) + ) + ]) + ) +} as const; + +const alias_map: Record = { + py: "python", + md: "markdown", + js: "javascript", + ts: "typescript", + sh: "shell" +}; + +export async function getLanguageExtension( + lang: string +): Promise { + const _lang = lang_map[lang] || lang_map[alias_map[lang]] || undefined; + if (_lang) { + return _lang(); + } + return undefined; +} diff --git a/src/pyproject.toml b/src/pyproject.toml new file mode 100644 index 0000000000000000000000000000000000000000..ca5a39cf27244727490ebef31a69d9e1b1f74154 --- /dev/null +++ b/src/pyproject.toml @@ -0,0 +1,42 @@ +[build-system] +requires = [ + "hatchling", + "hatch-requirements-txt", + "hatch-fancy-pypi-readme>=22.5.0", +] +build-backend = "hatchling.build" + +[project] +name = "gradio_logsview" +version = "0.0.1" +description = "Visualize logs in your Gradio app" +readme = "README.md" +license = "MIT" +requires-python = ">=3.8" +authors = [{ name = "YOUR NAME", email = "YOUREMAIL@domain.com" }] +keywords = ["gradio-custom-component", "gradio-template-Code", "logging", "subprocess", "process"] +# Add dependencies here +dependencies = ["gradio>=4.0,<5.0"] +classifiers = [ + 'Development Status :: 3 - Alpha', + 'License :: OSI Approved :: Apache Software License', + 'Operating System :: OS Independent', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3 :: Only', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', + 'Topic :: Scientific/Engineering', + 'Topic :: Scientific/Engineering :: Artificial Intelligence', + 'Topic :: Scientific/Engineering :: Visualization', +] + +[project.optional-dependencies] +dev = ["build", "twine"] + +[tool.hatch.build] +artifacts = ["/backend/gradio_logsview/templates", "*.pyi", "backend/gradio_logsview/templates"] + +[tool.hatch.build.targets.wheel] +packages = ["/backend/gradio_logsview"]