polymo 0.1.2__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. polymo-0.2.0/PKG-INFO +101 -0
  2. polymo-0.2.0/README.md +77 -0
  3. {polymo-0.1.2 → polymo-0.2.0}/pyproject.toml +11 -1
  4. {polymo-0.1.2 → polymo-0.2.0}/src/polymo/builder/static/examples/githubrepos.yml +2 -1
  5. polymo-0.2.0/src/polymo/builder/static/examples/incremental-state.json +11 -0
  6. polymo-0.2.0/src/polymo/builder/static/main.css +1 -0
  7. polymo-0.2.0/src/polymo/builder/static/main.js +117 -0
  8. {polymo-0.1.2 → polymo-0.2.0}/src/polymo/config.py +158 -1
  9. polymo-0.2.0/src/polymo/rest_client.py +800 -0
  10. polymo-0.1.2/PKG-INFO +0 -83
  11. polymo-0.1.2/README.md +0 -60
  12. polymo-0.1.2/src/polymo/builder/static/main.css +0 -1
  13. polymo-0.1.2/src/polymo/builder/static/main.js +0 -117
  14. polymo-0.1.2/src/polymo/rest_client.py +0 -416
  15. {polymo-0.1.2 → polymo-0.2.0}/src/polymo/__init__.py +0 -0
  16. {polymo-0.1.2 → polymo-0.2.0}/src/polymo/builder/__init__.py +0 -0
  17. {polymo-0.1.2 → polymo-0.2.0}/src/polymo/builder/app.py +0 -0
  18. {polymo-0.1.2 → polymo-0.2.0}/src/polymo/builder/static/examples/jsonplaceholder.yml +0 -0
  19. {polymo-0.1.2 → polymo-0.2.0}/src/polymo/builder/static/favicon.ico +0 -0
  20. {polymo-0.1.2 → polymo-0.2.0}/src/polymo/builder/static/index.html +0 -0
  21. {polymo-0.1.2 → polymo-0.2.0}/src/polymo/builder/static/logo.png +0 -0
  22. {polymo-0.1.2 → polymo-0.2.0}/src/polymo/builder/static/logo192.png +0 -0
  23. {polymo-0.1.2 → polymo-0.2.0}/src/polymo/builder/static/mockServiceWorker.js +0 -0
  24. {polymo-0.1.2 → polymo-0.2.0}/src/polymo/builder/templates/index.html +0 -0
  25. {polymo-0.1.2 → polymo-0.2.0}/src/polymo/cli.py +0 -0
  26. {polymo-0.1.2 → polymo-0.2.0}/src/polymo/datasource.py +0 -0
  27. {polymo-0.1.2 → polymo-0.2.0}/src/polymo/py.typed +0 -0
  28. {polymo-0.1.2 → polymo-0.2.0}/src/polymo/scripts/__init__.py +0 -0
  29. {polymo-0.1.2 → polymo-0.2.0}/src/polymo/scripts/smoke.py +0 -0
polymo-0.2.0/PKG-INFO ADDED
@@ -0,0 +1,101 @@
1
+ Metadata-Version: 2.3
2
+ Name: polymo
3
+ Version: 0.2.0
4
+ Summary: API ingestion for PySpark
5
+ Author: Daniel Tom
6
+ Author-email: Daniel Tom <d.e.tom89@gmail.com>
7
+ Requires-Dist: fsspec>=2025.9.0
8
+ Requires-Dist: httpx>=0.26
9
+ Requires-Dist: jinja2>=3.1.6
10
+ Requires-Dist: pyyaml>=6.0.1
11
+ Requires-Dist: polymo[builder,smoke] ; extra == 'all'
12
+ Requires-Dist: fastapi>=0.110 ; extra == 'builder'
13
+ Requires-Dist: uvicorn>=0.24 ; extra == 'builder'
14
+ Requires-Dist: jinja2>=3.1.6 ; extra == 'builder'
15
+ Requires-Dist: pyspark>=4 ; extra == 'builder'
16
+ Requires-Dist: pyarrow>=13 ; extra == 'builder'
17
+ Requires-Dist: pyspark>=4 ; extra == 'smoke'
18
+ Requires-Dist: pyarrow>=13 ; extra == 'smoke'
19
+ Requires-Python: >=3.10
20
+ Provides-Extra: all
21
+ Provides-Extra: builder
22
+ Provides-Extra: smoke
23
+ Description-Content-Type: text/markdown
24
+
25
+ <p align="center">
26
+ <img src="builder-ui/public/logo.png" alt="Polymo" width="220">
27
+ </p>
28
+
29
+ Polymo turns REST APIs into Spark DataFrames with a single declarative configuration file. The library builds on top of the DataSource V2 implementation for PySpark 4, while the companion builder UI helps you design, validate, and preview connectors without writing code.
30
+
31
+ ## Highlights
32
+ - Visual builder keeps a form-based editor and live YAML in sync, with validation and previews.
33
+ - Configuration is plain YAML: describe the base URL, pagination, query parameters, and optional record selectors—no custom code required.
34
+ - Spark-native DataSource exposes `spark.read.format("polymo")`, so connectors slot into existing ETL jobs, notebooks, or scheduled (lakeflow) pipelines.
35
+ - Fast sampling pipeline shows both DataFrame output and raw API pages, making it easy to debug response shapes and headers.
36
+ - Jinja templating, environment variable lookups, and runtime Spark options let you parameterise connectors for different environments.
37
+ - Incremental sync support seeds API cursors from JSON state files (local or remote via `fsspec`) and updates them automatically between runs.
38
+
39
+ ## Install
40
+
41
+ ```bash
42
+ # Lightweight core package with only httpx, pydantic and jinja2 dependencies
43
+ pip install polymo
44
+ # Adds Spark, FastAPI/uvicorn and frontend assets for the builder UI
45
+ pip install "polymo[builder]"
46
+
47
+ ```
48
+
49
+ Polymo requires PySpark 4.x. The CLI enforces this requirement before launching the builder or smoke test helpers.
50
+
51
+ ## Quick Start
52
+
53
+ 1. **Describe a stream** in YAML:
54
+
55
+ ```yaml
56
+ version: 0.1
57
+ source:
58
+ type: rest
59
+ base_url: https://jsonplaceholder.typicode.com
60
+ stream:
61
+ path: /posts
62
+ params:
63
+ _limit: 20
64
+ infer_schema: true
65
+ ```
66
+
67
+ 2. **Read the API with Spark**:
68
+
69
+ ```python
70
+ from pyspark.sql import SparkSession
71
+ from polymo import ApiReader
72
+
73
+ spark = SparkSession.builder.getOrCreate()
74
+ spark.dataSource.register(ApiReader)
75
+
76
+ df = (
77
+ spark.read.format("polymo")
78
+ .option("config_path", "./config.yml")
79
+ .option("token", "<YOUR_BEARER_TOKEN>")
80
+ .load()
81
+
82
+ df.show()
83
+ ```
84
+
85
+ 3. **Use the builder UI** to iterate faster:
86
+
87
+ ```bash
88
+ polymo builder --port 9000
89
+ ```
90
+
91
+ The browser app walks you through the same settings, validates the YAML against the Python backend, runs sample requests, and lets you save polished configs.
92
+
93
+ ## Project Pieces
94
+ - `src/polymo/` – PySpark DataSource, config validation, and REST client.
95
+ - `polymo builder` – FastAPI backend with a React/Tailwind single-page app under `builder-ui/`.
96
+ - `examples/` – Ready-to-run connector samples used by the smoke test and the builder landing screen.
97
+
98
+ ## Where to Next
99
+ Read the docs [here](https://dan1elt0m.github.io/polymo/)
100
+
101
+ Contributions and early feedback welcome!
polymo-0.2.0/README.md ADDED
@@ -0,0 +1,77 @@
1
+ <p align="center">
2
+ <img src="builder-ui/public/logo.png" alt="Polymo" width="220">
3
+ </p>
4
+
5
+ Polymo turns REST APIs into Spark DataFrames with a single declarative configuration file. The library builds on top of the DataSource V2 implementation for PySpark 4, while the companion builder UI helps you design, validate, and preview connectors without writing code.
6
+
7
+ ## Highlights
8
+ - Visual builder keeps a form-based editor and live YAML in sync, with validation and previews.
9
+ - Configuration is plain YAML: describe the base URL, pagination, query parameters, and optional record selectors—no custom code required.
10
+ - Spark-native DataSource exposes `spark.read.format("polymo")`, so connectors slot into existing ETL jobs, notebooks, or scheduled (lakeflow) pipelines.
11
+ - Fast sampling pipeline shows both DataFrame output and raw API pages, making it easy to debug response shapes and headers.
12
+ - Jinja templating, environment variable lookups, and runtime Spark options let you parameterise connectors for different environments.
13
+ - Incremental sync support seeds API cursors from JSON state files (local or remote via `fsspec`) and updates them automatically between runs.
14
+
15
+ ## Install
16
+
17
+ ```bash
18
+ # Lightweight core package with only httpx, pydantic and jinja2 dependencies
19
+ pip install polymo
20
+ # Adds Spark, FastAPI/uvicorn and frontend assets for the builder UI
21
+ pip install "polymo[builder]"
22
+
23
+ ```
24
+
25
+ Polymo requires PySpark 4.x. The CLI enforces this requirement before launching the builder or smoke test helpers.
26
+
27
+ ## Quick Start
28
+
29
+ 1. **Describe a stream** in YAML:
30
+
31
+ ```yaml
32
+ version: 0.1
33
+ source:
34
+ type: rest
35
+ base_url: https://jsonplaceholder.typicode.com
36
+ stream:
37
+ path: /posts
38
+ params:
39
+ _limit: 20
40
+ infer_schema: true
41
+ ```
42
+
43
+ 2. **Read the API with Spark**:
44
+
45
+ ```python
46
+ from pyspark.sql import SparkSession
47
+ from polymo import ApiReader
48
+
49
+ spark = SparkSession.builder.getOrCreate()
50
+ spark.dataSource.register(ApiReader)
51
+
52
+ df = (
53
+ spark.read.format("polymo")
54
+ .option("config_path", "./config.yml")
55
+ .option("token", "<YOUR_BEARER_TOKEN>")
56
+ .load()
57
+
58
+ df.show()
59
+ ```
60
+
61
+ 3. **Use the builder UI** to iterate faster:
62
+
63
+ ```bash
64
+ polymo builder --port 9000
65
+ ```
66
+
67
+ The browser app walks you through the same settings, validates the YAML against the Python backend, runs sample requests, and lets you save polished configs.
68
+
69
+ ## Project Pieces
70
+ - `src/polymo/` – PySpark DataSource, config validation, and REST client.
71
+ - `polymo builder` – FastAPI backend with a React/Tailwind single-page app under `builder-ui/`.
72
+ - `examples/` – Ready-to-run connector samples used by the smoke test and the builder landing screen.
73
+
74
+ ## Where to Next
75
+ Read the docs [here](https://dan1elt0m.github.io/polymo/)
76
+
77
+ Contributions and early feedback welcome!
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "polymo"
3
- version = "0.1.2"
3
+ version = "0.2.0"
4
4
  description = "API ingestion for PySpark"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -8,6 +8,7 @@ authors = [
8
8
  ]
9
9
  requires-python = ">=3.10"
10
10
  dependencies = [
11
+ "fsspec>=2025.9.0",
11
12
  "httpx>=0.26",
12
13
  "jinja2>=3.1.6",
13
14
  "pyyaml>=6.0.1",
@@ -33,6 +34,15 @@ all = [
33
34
  dev = [
34
35
  "pytest>=8.4.2",
35
36
  ]
37
+ docs = [
38
+ "mkdocs>=1.4.2",
39
+ "mkdocs-material>=9.1.4",
40
+ "mkdocs-gen-files>=0.4,<0.6",
41
+ "mkdocs-literate-nav>=0.6.0",
42
+ "mkdocstrings[python]>=0.20,<0.30",
43
+ "mkautodoc>=0.2.0",
44
+ "pymdown-extensions>=10.0.1",
45
+ ]
36
46
 
37
47
  [project.scripts]
38
48
  polymo = "polymo.cli:main"
@@ -10,6 +10,7 @@ stream:
10
10
  type: none
11
11
  record_selector:
12
12
  field_path:
13
+ - '*'
13
14
  - owner
14
15
  record_filter: null
15
- cast_to_schema_types: false
16
+ cast_to_schema_types: false
@@ -0,0 +1,11 @@
1
+ {
2
+ "streams": {
3
+ "issues@https://api.github.com": {
4
+ "cursor_param": "since",
5
+ "cursor_field": "updated_at",
6
+ "cursor_value": "2024-03-22T18:15:00Z",
7
+ "mode": "updated_at",
8
+ "updated_at": "2024-03-22T18:16:05Z"
9
+ }
10
+ }
11
+ }
@@ -0,0 +1 @@
1
+ @import"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap";*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Inter,system-ui,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:JetBrains Mono,ui-monospace,SFMono-Regular,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.\!container{width:100%!important}.container{width:100%}@media (min-width: 640px){.\!container{max-width:640px!important}.container{max-width:640px}}@media (min-width: 768px){.\!container{max-width:768px!important}.container{max-width:768px}}@media (min-width: 1024px){.\!container{max-width:1024px!important}.container{max-width:1024px}}@media (min-width: 1280px){.\!container{max-width:1280px!important}.container{max-width:1280px}}@media (min-width: 1536px){.\!container{max-width:1536px!important}.container{max-width:1536px}}.pointer-events-none{pointer-events:none}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.-right-2{right:-.5rem}.-top-2{top:-.5rem}.left-1\/2{left:50%}.right-0{right:0}.right-3{right:.75rem}.top-0{top:0}.top-1\/2{top:50%}.top-full{top:100%}.z-10{z-index:10}.z-20{z-index:20}.z-50{z-index:50}.mx-auto{margin-left:auto;margin-right:auto}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.mt-auto{margin-top:auto}.inline-block{display:inline-block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.contents{display:contents}.hidden{display:none}.h-10{height:2.5rem}.h-12{height:3rem}.h-16{height:4rem}.h-2{height:.5rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-\[520px\]{height:520px}.h-full{height:100%}.min-h-\[260px\]{min-height:260px}.min-h-\[96px\]{min-height:96px}.min-h-screen{min-height:100vh}.w-10{width:2.5rem}.w-12{width:3rem}.w-16{width:4rem}.w-2{width:.5rem}.w-24{width:6rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-48{width:12rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-60{width:15rem}.w-7{width:1.75rem}.w-8{width:2rem}.w-9{width:2.25rem}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.w-max{width:-moz-max-content;width:max-content}.min-w-0{min-width:0px}.min-w-full{min-width:100%}.min-w-max{min-width:-moz-max-content;min-width:max-content}.max-w-2xl{max-width:42rem}.max-w-4xl{max-width:56rem}.max-w-7xl{max-width:80rem}.max-w-\[140px\]{max-width:140px}.max-w-full{max-width:100%}.max-w-md{max-width:28rem}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.-translate-x-1\/2{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-2{--tw-translate-y: .5rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-90{--tw-rotate: 90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize-none{resize:none}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-stretch{align-items:stretch}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-12{gap:3rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-5{gap:1.25rem}.gap-6{gap:1.5rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.25rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(2rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem * var(--tw-space-y-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-t{border-top-width:1px}.border-border{--tw-border-opacity: 1;border-color:rgb(219 216 224 / var(--tw-border-opacity, 1))}.border-border\/60{border-color:#dbd8e099}.border-border\/70{border-color:#dbd8e0b3}.border-error\/40{border-color:#e5484d66}.border-red-7{--tw-border-opacity: 1;border-color:rgb(244 169 170 / var(--tw-border-opacity, 1))}.border-red-7\/50{border-color:#f4a9aa80}.bg-background{--tw-bg-opacity: 1;background-color:rgb(250 249 251 / var(--tw-bg-opacity, 1))}.bg-background\/50{background-color:#faf9fb80}.bg-background\/60{background-color:#faf9fb99}.bg-background\/70{background-color:#faf9fbb3}.bg-background\/80{background-color:#faf9fbcc}.bg-black\/50{background-color:#00000080}.bg-blue-4\/50{background-color:#d5efff80}.bg-blue-5{--tw-bg-opacity: 1;background-color:rgb(194 229 255 / var(--tw-bg-opacity, 1))}.bg-blue-9{--tw-bg-opacity: 1;background-color:rgb(0 144 255 / var(--tw-bg-opacity, 1))}.bg-current{background-color:currentColor}.bg-error{--tw-bg-opacity: 1;background-color:rgb(229 72 77 / var(--tw-bg-opacity, 1))}.bg-red-3{--tw-bg-opacity: 1;background-color:rgb(254 235 236 / var(--tw-bg-opacity, 1))}.bg-red-3\/50{background-color:#feebec80}.bg-red-3\/60{background-color:#feebec99}.bg-red-9{--tw-bg-opacity: 1;background-color:rgb(229 72 77 / var(--tw-bg-opacity, 1))}.bg-slate-12{--tw-bg-opacity: 1;background-color:rgb(28 32 36 / var(--tw-bg-opacity, 1))}.bg-slate-2{--tw-bg-opacity: 1;background-color:rgb(249 249 251 / var(--tw-bg-opacity, 1))}.bg-surface{--tw-bg-opacity: 1;background-color:rgb(242 239 243 / var(--tw-bg-opacity, 1))}.bg-surface\/70{background-color:#f2eff3b3}.bg-surface\/80{background-color:#f2eff3cc}.bg-surface\/90{background-color:#f2eff3e6}.bg-surface\/95{background-color:#f2eff3f2}.object-contain{-o-object-fit:contain;object-fit:contain}.p-1{padding:.25rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pr-9{padding-right:2.25rem}.pt-1{padding-top:.25rem}.pt-2{padding-top:.5rem}.text-left{text-align:left}.text-center{text-align:center}.align-top{vertical-align:top}.align-bottom{vertical-align:bottom}.font-mono{font-family:JetBrains Mono,ui-monospace,SFMono-Regular,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.leading-5{line-height:1.25rem}.leading-relaxed{line-height:1.625}.leading-snug{line-height:1.375}.leading-tight{line-height:1.25}.tracking-wide{letter-spacing:.025em}.text-background-foreground{--tw-text-opacity: 1;color:rgb(33 31 38 / var(--tw-text-opacity, 1))}.text-blue-11{--tw-text-opacity: 1;color:rgb(13 116 206 / var(--tw-text-opacity, 1))}.text-blue-9{--tw-text-opacity: 1;color:rgb(0 144 255 / var(--tw-text-opacity, 1))}.text-error{--tw-text-opacity: 1;color:rgb(229 72 77 / var(--tw-text-opacity, 1))}.text-muted{--tw-text-opacity: 1;color:rgb(188 186 199 / var(--tw-text-opacity, 1))}.text-red-11{--tw-text-opacity: 1;color:rgb(206 44 49 / var(--tw-text-opacity, 1))}.text-slate-10{--tw-text-opacity: 1;color:rgb(128 131 141 / var(--tw-text-opacity, 1))}.text-slate-11{--tw-text-opacity: 1;color:rgb(96 100 108 / var(--tw-text-opacity, 1))}.text-slate-12{--tw-text-opacity: 1;color:rgb(28 32 36 / var(--tw-text-opacity, 1))}.text-slate-9{--tw-text-opacity: 1;color:rgb(139 141 152 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.accent-blue-9{accent-color:#0090ff}.opacity-0{opacity:0}.shadow-inner{--tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / .05);--tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-soft{--tw-shadow: 0 10px 40px -15px rgba(15, 23, 42, .25);--tw-shadow-colored: 0 10px 40px -15px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid transparent;outline-offset:2px}.ring-1{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-border\/40{--tw-ring-color: rgb(219 216 224 / .4)}.blur{--tw-blur: blur(8px);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur{--tw-backdrop-blur: blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-filter{-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}:root{color-scheme:light dark}body{--tw-bg-opacity: 1;background-color:rgb(250 249 251 / var(--tw-bg-opacity, 1));font-family:Inter,system-ui,sans-serif;--tw-text-opacity: 1;color:rgb(33 31 38 / var(--tw-text-opacity, 1));-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.dark body{background-color:#282a36}.theme-fade{animation:theme-fade .24s ease-out}@keyframes theme-fade{0%{opacity:.4;filter:saturate(.6) brightness(.9)}to{opacity:1;filter:none}}.animate-param-enter{animation:param-enter .22s ease-out}@keyframes param-enter{0%{opacity:0;transform:scale(.97) translateY(4px)}to{opacity:1;transform:scale(1) translateY(0)}}.modern-select{width:100%;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.5rem;border-width:1px;--tw-border-opacity: 1;border-color:rgb(219 216 224 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(250 249 251 / var(--tw-bg-opacity, 1));padding:.5rem 2.25rem .5rem .75rem;font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(28 32 36 / var(--tw-text-opacity, 1));--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.dark .modern-select{background-color:#282a36;border-color:#44475a;color:#f8f8f2}.modern-select:focus-visible{--tw-border-opacity: 1;border-color:rgb(142 200 246 / var(--tw-border-opacity, 1));outline:2px solid transparent;outline-offset:2px}.modern-select:is(.dark *){--tw-border-opacity: 1;border-color:rgb(68 71 90 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(48 50 65 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(248 248 242 / var(--tw-text-opacity, 1))}.modern-select:focus-visible:is(.dark *){--tw-border-opacity: 1;border-color:rgb(189 147 249 / var(--tw-border-opacity, 1))}.dark input:not([type=checkbox]),.dark textarea,.dark select{--tw-border-opacity: 1;border-color:rgb(68 71 90 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(48 50 65 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(248 248 242 / var(--tw-text-opacity, 1))}.dark input:not([type=checkbox])::-moz-placeholder,.dark textarea::-moz-placeholder,.dark select::-moz-placeholder{--tw-placeholder-opacity: 1;color:rgb(98 114 164 / var(--tw-placeholder-opacity, 1))}.dark input:not([type=checkbox])::placeholder,.dark textarea::placeholder,.dark select::placeholder{--tw-placeholder-opacity: 1;color:rgb(98 114 164 / var(--tw-placeholder-opacity, 1))}.dark ::-moz-placeholder{--tw-text-opacity: 1;color:rgb(98 114 164 / var(--tw-text-opacity, 1))}.dark ::placeholder{--tw-text-opacity: 1;color:rgb(98 114 164 / var(--tw-text-opacity, 1))}.dark .bg-background{background-color:#282a36!important}.dark .bg-surface{background-color:#303241!important}.dark .border-border{border-color:#44475a!important}.dark .text-muted{color:#6272a4!important}.dark .shadow-soft{box-shadow:0 10px 40px -15px #000000a6}.dark .text-slate-12,.dark .text-slate-11,.dark .text-slate-10{color:#f8f8f2!important}.dark .text-slate-9,.dark .text-slate-8{color:#6272a4!important}.dark .group:hover.bg-background\/60{background-color:#484c5e8c!important}.radix-scroll-area-scrollbar{display:flex;touch-action:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;background-color:transparent;padding:.125rem;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;transition-timing-function:cubic-bezier(0,0,.2,1)}.radix-scroll-area-thumb{flex:1 1 0%;border-radius:9999px;--tw-bg-opacity: 1;background-color:rgb(188 186 199 / var(--tw-bg-opacity, 1))}.radix-scroll-area-thumb:hover{--tw-bg-opacity: 1;background-color:rgb(142 140 153 / var(--tw-bg-opacity, 1))}.radix-scroll-area-thumb:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(68 71 90 / var(--tw-bg-opacity, 1))}.radix-scroll-area-thumb:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(98 114 164 / var(--tw-bg-opacity, 1))}button:focus-visible,input:focus-visible,textarea:focus-visible,select:focus-visible{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000);--tw-ring-opacity: 1;--tw-ring-color: rgb(142 200 246 / var(--tw-ring-opacity, 1));--tw-ring-offset-width: 2px;--tw-ring-offset-color: #f2eff3}button:focus-visible:is(.dark *),input:focus-visible:is(.dark *),textarea:focus-visible:is(.dark *),select:focus-visible:is(.dark *){--tw-ring-opacity: 1;--tw-ring-color: rgb(189 147 249 / var(--tw-ring-opacity, 1));--tw-ring-offset-color: #303241}[data-status=success]{--tw-text-opacity: 1;color:rgb(48 164 108 / var(--tw-text-opacity, 1))}[data-status=warn],[data-status=warning]{--tw-text-opacity: 1;color:rgb(255 197 61 / var(--tw-text-opacity, 1))}[data-status=error]{--tw-text-opacity: 1;color:rgb(229 72 77 / var(--tw-text-opacity, 1))}[data-status=info]{--tw-text-opacity: 1;color:rgb(13 116 206 / var(--tw-text-opacity, 1))}[data-status=info]:is(.dark *){--tw-text-opacity: 1;color:rgb(189 147 249 / var(--tw-text-opacity, 1))}pre{overflow-x:auto;border-radius:.5rem;--tw-bg-opacity: 1;background-color:rgb(249 249 251 / var(--tw-bg-opacity, 1));padding:1rem;font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(28 32 36 / var(--tw-text-opacity, 1))}.dark pre{color:#f8f8f2}pre:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(48 50 65 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(248 248 242 / var(--tw-text-opacity, 1))}.dark table thead tr{background-color:#ffffff0a!important}.dark table tbody tr.even\:bg-slate-2\/40{background-color:#ffffff05!important}.dark table tbody tr:hover{background-color:#bd93f91f!important}.prism-container{position:relative;height:100%;font-family:JetBrains Mono,ui-monospace,SFMono-Regular,monospace;font-size:.875rem;line-height:1.25rem}.prism-editor{position:absolute;top:0;right:0;bottom:0;left:0;height:100%;width:100%;resize:none;background-color:transparent;line-height:1.25rem;color:transparent;caret-color:#fff;outline:2px solid transparent;outline-offset:2px}.prism-highlight{pointer-events:none;white-space:pre-wrap;overflow-wrap:break-word;text-align:left;font-family:JetBrains Mono,ui-monospace,SFMono-Regular,monospace;line-height:1.25rem}.dark .prism-highlight{color:#f8f8f2}.prism-highlight .token.comment{color:#6272a4}.prism-highlight .token.key{color:#ff79c6}.prism-highlight .token.punctuation{color:#f8f8f2}.prism-highlight .token.string{color:#f1fa8c}.prism-highlight .token.number{color:#bd93f9}.prism-highlight .token.boolean{color:#ffb86c}.prism-highlight .token.null{color:#f55}.prism-highlight .token.directive{color:#8be9fd}.prism-highlight{position:relative;--ch: .62ch}.prism-highlight .editor-line{position:relative;padding-left:0}.prism-highlight .editor-line:before{content:attr(data-line);position:absolute;left:-.75rem;transform:translate(-100%);width:3rem;text-align:right;padding-right:.75rem;color:#64748b;font-size:.75rem;line-height:1.25rem;font-variant-numeric:tabular-nums;opacity:.65}.dark .prism-highlight .editor-line:before{color:#6272a4;opacity:.55}.prism-highlight .editor-line.error{background:#ff55551a;box-shadow:inset 0 0 0 1px #ff555559}.dark .prism-highlight .editor-line.error{background:#ff55552b;box-shadow:inset 0 0 0 1px #ff555573}.prism-highlight .editor-line .col-marker{position:absolute;top:0;bottom:0;width:2px;background:#f55;left:calc(var(--col) * var(--ch));pointer-events:none;opacity:.4}.dark .prism-highlight .editor-line .col-marker{background:#f55;opacity:.55}.prism-highlight .editor-line .err-char{background:linear-gradient(transparent 70%,#ff55558c 70%);border-radius:2px}.dark .prism-highlight .editor-line .err-char{background:linear-gradient(transparent 65%,#ff5555bf 65%)}.prism-highlight::-webkit-scrollbar{width:10px;height:10px}.prism-highlight::-webkit-scrollbar-track{background:transparent}.prism-highlight::-webkit-scrollbar-thumb{background:#64748b59;border-radius:6px}.dark .prism-highlight::-webkit-scrollbar-thumb{background:#f8f8f233}.prism-highlight::-webkit-scrollbar-thumb:hover{background:#64748b8c}.dark .prism-highlight::-webkit-scrollbar-thumb:hover{background:#f8f8f259}.prism-highlight,.prism-highlight .editor-line,.prism-highlight .line-content{pointer-events:none}.prism-editor{color:transparent;text-shadow:none}.dark .prism-editor{color:transparent}.prism-editor{caret-color:#111}.dark .prism-editor{caret-color:#f8f8f2}[role=tooltip]{animation:fadeIn .12s ease-out}@keyframes fadeIn{0%{opacity:0;transform:translate(-50%,4px)}to{opacity:1;transform:translate(-50%)}}.dark .btn-accent{--tw-bg-opacity: 1;background-color:rgb(189 147 249 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(248 248 242 / var(--tw-text-opacity, 1))}.dark .btn-accent:hover{--tw-bg-opacity: 1;background-color:rgb(255 121 198 / var(--tw-bg-opacity, 1))}.dark .border-accent{--tw-border-opacity: 1;border-color:rgb(189 147 249 / var(--tw-border-opacity, 1))}.validate-flash-success{animation:validateFlashSuccess 4s ease-in-out forwards}.validate-flash-error{animation:validateFlashError 4s ease-in-out forwards}@keyframes validateFlashSuccess{0%,85%{background:#30a46c;color:#fff}to{background:transparent;color:inherit}}@keyframes validateFlashError{0%,85%{background:#e5484d;color:#fff}to{background:transparent;color:inherit}}.dark button.validate-flash-success,.dark .validate-flash-success{animation:darkValidateFlashSuccess 4s ease-in-out forwards;position:relative}.dark button.validate-flash-error,.dark .validate-flash-error{animation:darkValidateFlashError 4s ease-in-out forwards;position:relative}.dark button.validate-flash-success:after,.dark .validate-flash-success:after,.dark button.validate-flash-error:after,.dark .validate-flash-error:after{content:"";position:absolute;top:0;right:0;bottom:0;left:0;border-radius:inherit;pointer-events:none}.dark button.validate-flash-success:after,.dark .validate-flash-success:after{background:radial-gradient(circle at 30% 30%,#50fa7b59,#50fa7b0d)}.dark button.validate-flash-error:after,.dark .validate-flash-error:after{background:radial-gradient(circle at 30% 30%,#f556,#ff55550f)}@keyframes darkValidateFlashSuccess{0%,85%{background-color:#50fa7b40!important;color:#fff!important;border-color:#50fa7b8c!important;box-shadow:0 0 #50fa7b99,0 0 16px 4px #50fa7b59}to{background-color:transparent!important;color:inherit!important;border-color:var(--border-color,rgba(100,100,120,.4))!important;box-shadow:none}}@keyframes darkValidateFlashError{0%,85%{background-color:#ff555547!important;color:#fff!important;border-color:#ff55558c!important;box-shadow:0 0 #f559,0 0 16px 4px #ff555561}to{background-color:transparent!important;color:inherit!important;border-color:var(--border-color,rgba(100,100,120,.4))!important;box-shadow:none}}.dark .bg-blue-9{transition:background-color .3s ease,box-shadow .4s ease}.dark .bg-blue-9:hover{box-shadow:0 0 #bd93f900,0 0 12px 2px #bd93f959}.even\:bg-slate-2\/40:nth-child(2n){background-color:#f9f9fb66}.hover\:scale-105:hover{--tw-scale-x: 1.05;--tw-scale-y: 1.05;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:border-blue-7:hover{--tw-border-opacity: 1;border-color:rgb(142 200 246 / var(--tw-border-opacity, 1))}.hover\:border-blue-7\/60:hover{border-color:#8ec8f699}.hover\:border-red-7:hover{--tw-border-opacity: 1;border-color:rgb(244 169 170 / var(--tw-border-opacity, 1))}.hover\:bg-blue-10:hover{--tw-bg-opacity: 1;background-color:rgb(5 136 240 / var(--tw-bg-opacity, 1))}.hover\:bg-blue-3\/20:hover{background-color:#e6f4fe33}.hover\:bg-blue-3\/40:hover{background-color:#e6f4fe66}.hover\:bg-blue-3\/50:hover{background-color:#e6f4fe80}.hover\:bg-blue-3\/60:hover{background-color:#e6f4fe99}.hover\:bg-red-10:hover{--tw-bg-opacity: 1;background-color:rgb(220 62 66 / var(--tw-bg-opacity, 1))}.hover\:bg-red-3\/40:hover{background-color:#feebec66}.hover\:bg-red-3\/60:hover{background-color:#feebec99}.hover\:bg-slate-3:hover{--tw-bg-opacity: 1;background-color:rgb(240 240 243 / var(--tw-bg-opacity, 1))}.hover\:text-blue-11:hover{--tw-text-opacity: 1;color:rgb(13 116 206 / var(--tw-text-opacity, 1))}.hover\:text-red-10:hover{--tw-text-opacity: 1;color:rgb(220 62 66 / var(--tw-text-opacity, 1))}.hover\:text-red-9:hover{--tw-text-opacity: 1;color:rgb(229 72 77 / var(--tw-text-opacity, 1))}.hover\:text-slate-12:hover{--tw-text-opacity: 1;color:rgb(28 32 36 / var(--tw-text-opacity, 1))}.hover\:shadow-md:hover{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.hover\:shadow-sm:hover{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.focus\:border-blue-7:focus{--tw-border-opacity: 1;border-color:rgb(142 200 246 / var(--tw-border-opacity, 1))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-blue-7:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(142 200 246 / var(--tw-ring-opacity, 1))}.focus-visible\:border-blue-7:focus-visible{--tw-border-opacity: 1;border-color:rgb(142 200 246 / var(--tw-border-opacity, 1))}.focus-visible\:bg-blue-9:focus-visible{--tw-bg-opacity: 1;background-color:rgb(0 144 255 / var(--tw-bg-opacity, 1))}.focus-visible\:text-white:focus-visible{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.focus-visible\:opacity-100:focus-visible{opacity:1}.focus-visible\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\:ring-1:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-blue-5:focus-visible{--tw-ring-opacity: 1;--tw-ring-color: rgb(194 229 255 / var(--tw-ring-opacity, 1))}.focus-visible\:ring-blue-7:focus-visible{--tw-ring-opacity: 1;--tw-ring-color: rgb(142 200 246 / var(--tw-ring-opacity, 1))}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.group:hover .group-hover\:border-blue-7\/50{border-color:#8ec8f680}.group:hover .group-hover\:bg-blue-5\/80{background-color:#c2e5ffcc}.group:hover .group-hover\:opacity-100{opacity:1}.data-\[state\=active\]\:border-b-2[data-state=active]{border-bottom-width:2px}.data-\[state\=active\]\:border-blue-9[data-state=active]{--tw-border-opacity: 1;border-color:rgb(0 144 255 / var(--tw-border-opacity, 1))}.data-\[state\=active\]\:bg-blue-9[data-state=active]{--tw-bg-opacity: 1;background-color:rgb(0 144 255 / var(--tw-bg-opacity, 1))}.data-\[state\=checked\]\:bg-blue-4[data-state=checked]{--tw-bg-opacity: 1;background-color:rgb(213 239 255 / var(--tw-bg-opacity, 1))}.data-\[state\=active\]\:text-blue-11[data-state=active]{--tw-text-opacity: 1;color:rgb(13 116 206 / var(--tw-text-opacity, 1))}.data-\[state\=active\]\:text-white[data-state=active]{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.data-\[state\=active\]\:shadow-sm[data-state=active]{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}@supports (backdrop-filter: var(--tw)){.supports-\[backdrop-filter\]\:bg-slate-2\/75{background-color:#f9f9fbbf}}.dark\:border-\[\#2c313a\]:is(.dark *){--tw-border-opacity: 1;border-color:rgb(44 49 58 / var(--tw-border-opacity, 1))}.dark\:border-drac-border:is(.dark *){--tw-border-opacity: 1;border-color:rgb(68 71 90 / var(--tw-border-opacity, 1))}.dark\:border-drac-border\/40:is(.dark *){border-color:#44475a66}.dark\:border-drac-border\/50:is(.dark *){border-color:#44475a80}.dark\:border-drac-border\/60:is(.dark *){border-color:#44475a99}.dark\:border-drac-red\/40:is(.dark *){border-color:#f556}.dark\:border-red-9\/30:is(.dark *){border-color:#e5484d4d}.dark\:border-slate-6:is(.dark *){--tw-border-opacity: 1;border-color:rgb(217 217 224 / var(--tw-border-opacity, 1))}.dark\:bg-\[\#1d2026\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(29 32 38 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#1f232b\]\/60:is(.dark *){background-color:#1f232b99}.dark\:bg-\[\#1f232b\]\/80:is(.dark *){background-color:#1f232bcc}.dark\:bg-\[\#242a33\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(36 42 51 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#262c35\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(38 44 53 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#272d38\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(39 45 56 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#282a36\]\/70:is(.dark *){background-color:#282a36b3}.dark\:bg-\[\#2d3541\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(45 53 65 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#303745\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(48 55 69 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#313341\]\/50:is(.dark *){background-color:#31334180}.dark\:bg-blue-7\/40:is(.dark *){background-color:#8ec8f666}.dark\:bg-blue-9\/20:is(.dark *){background-color:#0090ff33}.dark\:bg-drac-accent:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(189 147 249 / var(--tw-bg-opacity, 1))}.dark\:bg-drac-base:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(40 42 54 / var(--tw-bg-opacity, 1))}.dark\:bg-drac-red\/25:is(.dark *){background-color:#ff555540}.dark\:bg-drac-surface:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(48 50 65 / var(--tw-bg-opacity, 1))}.dark\:bg-drac-surface\/60:is(.dark *){background-color:#30324199}.dark\:bg-drac-surface\/80:is(.dark *){background-color:#303241cc}.dark\:bg-red-9\/15:is(.dark *){background-color:#e5484d26}.dark\:bg-red-9\/20:is(.dark *){background-color:#e5484d33}.dark\:bg-slate-1:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(252 252 253 / var(--tw-bg-opacity, 1))}.dark\:bg-slate-2:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(249 249 251 / var(--tw-bg-opacity, 1))}.dark\:text-blue-9:is(.dark *){--tw-text-opacity: 1;color:rgb(0 144 255 / var(--tw-text-opacity, 1))}.dark\:text-drac-accent:is(.dark *){--tw-text-opacity: 1;color:rgb(189 147 249 / var(--tw-text-opacity, 1))}.dark\:text-drac-foreground:is(.dark *){--tw-text-opacity: 1;color:rgb(248 248 242 / var(--tw-text-opacity, 1))}.dark\:text-drac-foreground\/80:is(.dark *){color:#f8f8f2cc}.dark\:text-drac-foreground\/90:is(.dark *){color:#f8f8f2e6}.dark\:text-drac-muted:is(.dark *){--tw-text-opacity: 1;color:rgb(98 114 164 / var(--tw-text-opacity, 1))}.dark\:text-red-9:is(.dark *){--tw-text-opacity: 1;color:rgb(229 72 77 / var(--tw-text-opacity, 1))}.dark\:text-slate-12:is(.dark *){--tw-text-opacity: 1;color:rgb(28 32 36 / var(--tw-text-opacity, 1))}.dark\:accent-drac-accent:is(.dark *){accent-color:#bd93f9}.dark\:shadow-\[0_8px_24px_-6px_rgba\(0\,0\,0\,0\.7\)\]:is(.dark *){--tw-shadow: 0 8px 24px -6px rgba(0,0,0,.7);--tw-shadow-colored: 0 8px 24px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.dark\:ring-drac-border\/30:is(.dark *){--tw-ring-color: rgb(68 71 90 / .3)}.dark\:hover\:border-drac-accent:hover:is(.dark *){--tw-border-opacity: 1;border-color:rgb(189 147 249 / var(--tw-border-opacity, 1))}.dark\:hover\:border-drac-accent\/60:hover:is(.dark *){border-color:#bd93f999}.dark\:hover\:border-drac-red\/80:hover:is(.dark *){border-color:#f55c}.dark\:hover\:bg-\[\#273242\]:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(39 50 66 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-\[\#283546\]:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(40 53 70 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-\[\#383f4c\]:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(56 63 76 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-\[\#3a3f4b\]:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(58 63 75 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-blue-9\/20:hover:is(.dark *){background-color:#0090ff33}.dark\:hover\:bg-blue-9\/25:hover:is(.dark *){background-color:#0090ff40}.dark\:hover\:bg-blue-9\/30:hover:is(.dark *){background-color:#0090ff4d}.dark\:hover\:bg-drac-base\/60:hover:is(.dark *){background-color:#282a3699}.dark\:hover\:text-drac-accent:hover:is(.dark *){--tw-text-opacity: 1;color:rgb(189 147 249 / var(--tw-text-opacity, 1))}.dark\:hover\:text-drac-foreground:hover:is(.dark *){--tw-text-opacity: 1;color:rgb(248 248 242 / var(--tw-text-opacity, 1))}.dark\:hover\:text-drac-red:hover:is(.dark *){--tw-text-opacity: 1;color:rgb(255 85 85 / var(--tw-text-opacity, 1))}.dark\:hover\:shadow-\[0_0_8px_rgba\(80\,250\,123\,0\.15\)\]:hover:is(.dark *){--tw-shadow: 0 0 8px rgba(80,250,123,.15);--tw-shadow-colored: 0 0 8px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.dark\:focus\:border-drac-accent:focus:is(.dark *){--tw-border-opacity: 1;border-color:rgb(189 147 249 / var(--tw-border-opacity, 1))}.dark\:focus\:ring-drac-accent:focus:is(.dark *){--tw-ring-opacity: 1;--tw-ring-color: rgb(189 147 249 / var(--tw-ring-opacity, 1))}.dark\:focus-visible\:border-drac-accent:focus-visible:is(.dark *){--tw-border-opacity: 1;border-color:rgb(189 147 249 / var(--tw-border-opacity, 1))}.dark\:focus-visible\:bg-drac-accent:focus-visible:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(189 147 249 / var(--tw-bg-opacity, 1))}.dark\:focus-visible\:ring-drac-accent:focus-visible:is(.dark *){--tw-ring-opacity: 1;--tw-ring-color: rgb(189 147 249 / var(--tw-ring-opacity, 1))}.dark\:focus-visible\:ring-drac-accent\/40:focus-visible:is(.dark *){--tw-ring-color: rgb(189 147 249 / .4)}.group:hover .dark\:group-hover\:bg-blue-9\/30:is(.dark *){background-color:#0090ff4d}.dark\:data-\[state\=active\]\:border-drac-accent[data-state=active]:is(.dark *){--tw-border-opacity: 1;border-color:rgb(189 147 249 / var(--tw-border-opacity, 1))}.dark\:data-\[state\=active\]\:text-drac-accent[data-state=active]:is(.dark *){--tw-text-opacity: 1;color:rgb(189 147 249 / var(--tw-text-opacity, 1))}@supports (backdrop-filter: var(--tw)){.dark\:supports-\[backdrop-filter\]\:bg-drac-surface\/70:is(.dark *){background-color:#303241b3}}@media (min-width: 768px){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:flex-row{flex-direction:row}.md\:items-center{align-items:center}.md\:gap-6{gap:1.5rem}}@media (min-width: 1024px){.lg\:grid-cols-\[minmax\(0\,1fr\)_minmax\(200px\,auto\)\]{grid-template-columns:minmax(0,1fr) minmax(200px,auto)}.lg\:items-end{align-items:flex-end}.lg\:px-6{padding-left:1.5rem;padding-right:1.5rem}}.\[\&_td\]\:whitespace-nowrap td{white-space:nowrap}.\[\&_td\]\:whitespace-pre-wrap td{white-space:pre-wrap}