maomao88 commited on
Commit
c3173d9
·
1 Parent(s): c2ff64d

add frontend display

Browse files
Dockerfile CHANGED
@@ -30,11 +30,6 @@ RUN npm install && npm run build
30
  # Back to backend
31
  WORKDIR /app/backend
32
 
33
- #COPY --chown=user ./requirements.txt requirements.txt
34
- #RUN pip install --no-cache-dir --upgrade -r requirements.txt
35
-
36
- #COPY --chown=user . /app
37
-
38
  # Expose port
39
  EXPOSE 7860
40
 
 
30
  # Back to backend
31
  WORKDIR /app/backend
32
 
 
 
 
 
 
33
  # Expose port
34
  EXPOSE 7860
35
 
README.md CHANGED
@@ -9,3 +9,31 @@ short_description: visualize model structure
9
  ---
10
 
11
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  ---
10
 
11
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
12
+
13
+
14
+ # Run the app locally
15
+
16
+ ### Frontend
17
+
18
+ 1. Install dependencies:
19
+ ```
20
+ npm i
21
+ ```
22
+
23
+ 2. Run the app:
24
+ ```commandline
25
+ npm run dev
26
+ ```
27
+
28
+ ### Backend
29
+
30
+ 1. Start virtual env
31
+
32
+ 2. Go to the **backend** directory
33
+
34
+ 3. Install dependencies
35
+
36
+ 4. Run the app
37
+ ```commandline
38
+ uvicorn app:app --reload --host 0.0.0.0 --port 8000
39
+ ```
backend/__pycache__/app.cpython-313.pyc CHANGED
Binary files a/backend/__pycache__/app.cpython-313.pyc and b/backend/__pycache__/app.cpython-313.pyc differ
 
backend/__pycache__/hf_model_utils.cpython-313.pyc ADDED
Binary file (4.81 kB). View file
 
backend/app.py CHANGED
@@ -1,7 +1,9 @@
1
- from fastapi import FastAPI
2
  from fastapi.middleware.cors import CORSMiddleware
3
  from fastapi.staticfiles import StaticFiles
 
4
  from pathlib import Path
 
5
 
6
  app = FastAPI()
7
 
@@ -20,6 +22,24 @@ app.add_middleware(
20
  def greet_json():
21
  return {"Hello": "World!"}
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  # Serve frontend build under / (but exclude /api)
24
  frontend_path = Path(__file__).parent.parent / "frontend" / "dist"
25
 
 
1
+ from fastapi import FastAPI, Query
2
  from fastapi.middleware.cors import CORSMiddleware
3
  from fastapi.staticfiles import StaticFiles
4
+ from fastapi.responses import JSONResponse
5
  from pathlib import Path
6
+ from hf_model_utils import get_model_structure
7
 
8
  app = FastAPI()
9
 
 
22
  def greet_json():
23
  return {"Hello": "World!"}
24
 
25
+ @app.get("/api/model")
26
+ def get_model_info(
27
+ name: str = Query(..., description="Name of the model on Hugging Face"),
28
+ model_type: str | None = Query(None, description="Optional model type identifier")
29
+ ):
30
+ """
31
+ Get model structure info for a given Hugging Face model.
32
+ Example: /api/model?name=bert-base-uncased
33
+ """
34
+ try:
35
+ info = get_model_structure(name, model_type)
36
+ return JSONResponse(content={"success": True, "data": info})
37
+ except Exception as e:
38
+ return JSONResponse(
39
+ status_code=500,
40
+ content={"success": False, "error": str(e)},
41
+ )
42
+
43
  # Serve frontend build under / (but exclude /api)
44
  frontend_path = Path(__file__).parent.parent / "frontend" / "dist"
45
 
backend/hf_model_utils.py CHANGED
@@ -2,9 +2,12 @@ import torch
2
  import torch.nn as nn
3
  import json
4
  import hashlib
5
- import torch
6
  import gc
7
- from transformers import AutoConfig, AutoModel
 
 
 
 
8
 
9
 
10
  def module_hash(module):
@@ -60,4 +63,45 @@ def hf_style_structural_dict(module):
60
  i += count
61
  result["children"] = child_dict
62
 
63
- return result
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  import torch.nn as nn
3
  import json
4
  import hashlib
 
5
  import gc
6
+ from transformers import AutoConfig, AutoModel, AutoModelForCausalLM, AutoModelForMaskedLM
7
+ from accelerate import init_empty_weights
8
+
9
+
10
+ model_structure_cache = {}
11
 
12
 
13
  def module_hash(module):
 
63
  i += count
64
  result["children"] = child_dict
65
 
66
+ return result
67
+
68
+
69
+
70
+ def get_model_structure(model_name: str, model_type: str | None):
71
+ # 1. Check if it's already cached
72
+ if model_name in model_structure_cache:
73
+ return model_structure_cache[model_name]
74
+
75
+ print(model_type)
76
+ # 2. If not cached, build the structure
77
+ if model_type == "causal":
78
+ config = AutoConfig.from_pretrained(model_name, trust_remote_code=True)
79
+ with init_empty_weights():
80
+ model = AutoModelForCausalLM.from_config(config, trust_remote_code=True)
81
+ if model_type == "masked":
82
+ config = AutoConfig.from_pretrained("model_name")
83
+ with init_empty_weights():
84
+ model = AutoModelForMaskedLM.from_config(config)
85
+ else:
86
+ config = AutoConfig.from_pretrained(model_name, trust_remote_code=True)
87
+ with torch.device("meta"):
88
+ model = AutoModel.from_config(config, trust_remote_code=True)
89
+ print(model)
90
+
91
+ structure = {
92
+ "model_type": config.model_type,
93
+ "hidden_size": getattr(config, "hidden_size", None),
94
+ "num_hidden_layers": getattr(config, "num_hidden_layers", None),
95
+ "num_attention_heads": getattr(config, "num_attention_heads", None),
96
+ "layers": hf_style_structural_dict(model)
97
+ }
98
+
99
+ # 3. Free memory
100
+ del model
101
+ gc.collect()
102
+ torch.cuda.empty_cache() # only if using GPU
103
+
104
+ # 4. Save JSON in cache
105
+ model_structure_cache[model_name] = structure
106
+
107
+ return structure # JSON-serializable
backend/node_modules/.package-lock.json ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ {
2
+ "name": "backend",
3
+ "lockfileVersion": 3,
4
+ "requires": true,
5
+ "packages": {}
6
+ }
backend/package-lock.json ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ {
2
+ "name": "backend",
3
+ "lockfileVersion": 3,
4
+ "requires": true,
5
+ "packages": {}
6
+ }
backend/package.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {}
backend/requirements.txt CHANGED
@@ -9,6 +9,7 @@ fsspec==2025.9.0
9
  h11==0.16.0
10
  hf-xet==1.1.10
11
  httptools==0.6.4
 
12
  idna==3.10
13
  Jinja2==3.1.6
14
  MarkupSafe==3.0.2
@@ -38,3 +39,5 @@ uvicorn==0.35.0
38
  uvloop==0.21.0
39
  watchfiles==1.1.0
40
  websockets==15.0.1
 
 
 
9
  h11==0.16.0
10
  hf-xet==1.1.10
11
  httptools==0.6.4
12
+ huggingface-hub==0.35.0
13
  idna==3.10
14
  Jinja2==3.1.6
15
  MarkupSafe==3.0.2
 
39
  uvloop==0.21.0
40
  watchfiles==1.1.0
41
  websockets==15.0.1
42
+ flash_attn==2.8.3
43
+ accelerate==1.10.1
frontend/package-lock.json CHANGED
@@ -8,8 +8,10 @@
8
  "name": "frontend",
9
  "version": "0.0.0",
10
  "dependencies": {
 
11
  "react": "^19.1.1",
12
- "react-dom": "^19.1.1"
 
13
  },
14
  "devDependencies": {
15
  "@eslint/js": "^9.33.0",
@@ -312,7 +314,6 @@
312
  "cpu": [
313
  "ppc64"
314
  ],
315
- "dev": true,
316
  "license": "MIT",
317
  "optional": true,
318
  "os": [
@@ -329,7 +330,6 @@
329
  "cpu": [
330
  "arm"
331
  ],
332
- "dev": true,
333
  "license": "MIT",
334
  "optional": true,
335
  "os": [
@@ -346,7 +346,6 @@
346
  "cpu": [
347
  "arm64"
348
  ],
349
- "dev": true,
350
  "license": "MIT",
351
  "optional": true,
352
  "os": [
@@ -363,7 +362,6 @@
363
  "cpu": [
364
  "x64"
365
  ],
366
- "dev": true,
367
  "license": "MIT",
368
  "optional": true,
369
  "os": [
@@ -380,7 +378,6 @@
380
  "cpu": [
381
  "arm64"
382
  ],
383
- "dev": true,
384
  "license": "MIT",
385
  "optional": true,
386
  "os": [
@@ -397,7 +394,6 @@
397
  "cpu": [
398
  "x64"
399
  ],
400
- "dev": true,
401
  "license": "MIT",
402
  "optional": true,
403
  "os": [
@@ -414,7 +410,6 @@
414
  "cpu": [
415
  "arm64"
416
  ],
417
- "dev": true,
418
  "license": "MIT",
419
  "optional": true,
420
  "os": [
@@ -431,7 +426,6 @@
431
  "cpu": [
432
  "x64"
433
  ],
434
- "dev": true,
435
  "license": "MIT",
436
  "optional": true,
437
  "os": [
@@ -448,7 +442,6 @@
448
  "cpu": [
449
  "arm"
450
  ],
451
- "dev": true,
452
  "license": "MIT",
453
  "optional": true,
454
  "os": [
@@ -465,7 +458,6 @@
465
  "cpu": [
466
  "arm64"
467
  ],
468
- "dev": true,
469
  "license": "MIT",
470
  "optional": true,
471
  "os": [
@@ -482,7 +474,6 @@
482
  "cpu": [
483
  "ia32"
484
  ],
485
- "dev": true,
486
  "license": "MIT",
487
  "optional": true,
488
  "os": [
@@ -499,7 +490,6 @@
499
  "cpu": [
500
  "loong64"
501
  ],
502
- "dev": true,
503
  "license": "MIT",
504
  "optional": true,
505
  "os": [
@@ -516,7 +506,6 @@
516
  "cpu": [
517
  "mips64el"
518
  ],
519
- "dev": true,
520
  "license": "MIT",
521
  "optional": true,
522
  "os": [
@@ -533,7 +522,6 @@
533
  "cpu": [
534
  "ppc64"
535
  ],
536
- "dev": true,
537
  "license": "MIT",
538
  "optional": true,
539
  "os": [
@@ -550,7 +538,6 @@
550
  "cpu": [
551
  "riscv64"
552
  ],
553
- "dev": true,
554
  "license": "MIT",
555
  "optional": true,
556
  "os": [
@@ -567,7 +554,6 @@
567
  "cpu": [
568
  "s390x"
569
  ],
570
- "dev": true,
571
  "license": "MIT",
572
  "optional": true,
573
  "os": [
@@ -584,7 +570,6 @@
584
  "cpu": [
585
  "x64"
586
  ],
587
- "dev": true,
588
  "license": "MIT",
589
  "optional": true,
590
  "os": [
@@ -601,7 +586,6 @@
601
  "cpu": [
602
  "arm64"
603
  ],
604
- "dev": true,
605
  "license": "MIT",
606
  "optional": true,
607
  "os": [
@@ -618,7 +602,6 @@
618
  "cpu": [
619
  "x64"
620
  ],
621
- "dev": true,
622
  "license": "MIT",
623
  "optional": true,
624
  "os": [
@@ -635,7 +618,6 @@
635
  "cpu": [
636
  "arm64"
637
  ],
638
- "dev": true,
639
  "license": "MIT",
640
  "optional": true,
641
  "os": [
@@ -652,7 +634,6 @@
652
  "cpu": [
653
  "x64"
654
  ],
655
- "dev": true,
656
  "license": "MIT",
657
  "optional": true,
658
  "os": [
@@ -669,7 +650,6 @@
669
  "cpu": [
670
  "arm64"
671
  ],
672
- "dev": true,
673
  "license": "MIT",
674
  "optional": true,
675
  "os": [
@@ -686,7 +666,6 @@
686
  "cpu": [
687
  "x64"
688
  ],
689
- "dev": true,
690
  "license": "MIT",
691
  "optional": true,
692
  "os": [
@@ -703,7 +682,6 @@
703
  "cpu": [
704
  "arm64"
705
  ],
706
- "dev": true,
707
  "license": "MIT",
708
  "optional": true,
709
  "os": [
@@ -720,7 +698,6 @@
720
  "cpu": [
721
  "ia32"
722
  ],
723
- "dev": true,
724
  "license": "MIT",
725
  "optional": true,
726
  "os": [
@@ -737,7 +714,6 @@
737
  "cpu": [
738
  "x64"
739
  ],
740
- "dev": true,
741
  "license": "MIT",
742
  "optional": true,
743
  "os": [
@@ -953,11 +929,22 @@
953
  "url": "https://github.com/sponsors/nzakas"
954
  }
955
  },
 
 
 
 
 
 
 
 
 
 
 
 
956
  "node_modules/@jridgewell/gen-mapping": {
957
  "version": "0.3.13",
958
  "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
959
  "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
960
- "dev": true,
961
  "license": "MIT",
962
  "dependencies": {
963
  "@jridgewell/sourcemap-codec": "^1.5.0",
@@ -968,7 +955,6 @@
968
  "version": "2.3.5",
969
  "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
970
  "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
971
- "dev": true,
972
  "license": "MIT",
973
  "dependencies": {
974
  "@jridgewell/gen-mapping": "^0.3.5",
@@ -979,7 +965,6 @@
979
  "version": "3.1.2",
980
  "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
981
  "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
982
- "dev": true,
983
  "license": "MIT",
984
  "engines": {
985
  "node": ">=6.0.0"
@@ -989,14 +974,12 @@
989
  "version": "1.5.5",
990
  "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
991
  "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
992
- "dev": true,
993
  "license": "MIT"
994
  },
995
  "node_modules/@jridgewell/trace-mapping": {
996
  "version": "0.3.31",
997
  "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
998
  "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
999
- "dev": true,
1000
  "license": "MIT",
1001
  "dependencies": {
1002
  "@jridgewell/resolve-uri": "^3.1.0",
@@ -1004,9 +987,9 @@
1004
  }
1005
  },
1006
  "node_modules/@rolldown/pluginutils": {
1007
- "version": "1.0.0-beta.34",
1008
- "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.34.tgz",
1009
- "integrity": "sha512-LyAREkZHP5pMom7c24meKmJCdhf2hEyvam2q0unr3or9ydwDL+DJ8chTF6Av/RFPb3rH8UFBdMzO5MxTZW97oA==",
1010
  "dev": true,
1011
  "license": "MIT"
1012
  },
@@ -1017,7 +1000,6 @@
1017
  "cpu": [
1018
  "arm"
1019
  ],
1020
- "dev": true,
1021
  "license": "MIT",
1022
  "optional": true,
1023
  "os": [
@@ -1031,7 +1013,6 @@
1031
  "cpu": [
1032
  "arm64"
1033
  ],
1034
- "dev": true,
1035
  "license": "MIT",
1036
  "optional": true,
1037
  "os": [
@@ -1045,7 +1026,6 @@
1045
  "cpu": [
1046
  "arm64"
1047
  ],
1048
- "dev": true,
1049
  "license": "MIT",
1050
  "optional": true,
1051
  "os": [
@@ -1059,7 +1039,6 @@
1059
  "cpu": [
1060
  "x64"
1061
  ],
1062
- "dev": true,
1063
  "license": "MIT",
1064
  "optional": true,
1065
  "os": [
@@ -1073,7 +1052,6 @@
1073
  "cpu": [
1074
  "arm64"
1075
  ],
1076
- "dev": true,
1077
  "license": "MIT",
1078
  "optional": true,
1079
  "os": [
@@ -1087,7 +1065,6 @@
1087
  "cpu": [
1088
  "x64"
1089
  ],
1090
- "dev": true,
1091
  "license": "MIT",
1092
  "optional": true,
1093
  "os": [
@@ -1101,7 +1078,6 @@
1101
  "cpu": [
1102
  "arm"
1103
  ],
1104
- "dev": true,
1105
  "license": "MIT",
1106
  "optional": true,
1107
  "os": [
@@ -1115,7 +1091,6 @@
1115
  "cpu": [
1116
  "arm"
1117
  ],
1118
- "dev": true,
1119
  "license": "MIT",
1120
  "optional": true,
1121
  "os": [
@@ -1129,7 +1104,6 @@
1129
  "cpu": [
1130
  "arm64"
1131
  ],
1132
- "dev": true,
1133
  "license": "MIT",
1134
  "optional": true,
1135
  "os": [
@@ -1143,7 +1117,6 @@
1143
  "cpu": [
1144
  "arm64"
1145
  ],
1146
- "dev": true,
1147
  "license": "MIT",
1148
  "optional": true,
1149
  "os": [
@@ -1157,7 +1130,6 @@
1157
  "cpu": [
1158
  "loong64"
1159
  ],
1160
- "dev": true,
1161
  "license": "MIT",
1162
  "optional": true,
1163
  "os": [
@@ -1171,7 +1143,6 @@
1171
  "cpu": [
1172
  "ppc64"
1173
  ],
1174
- "dev": true,
1175
  "license": "MIT",
1176
  "optional": true,
1177
  "os": [
@@ -1185,7 +1156,6 @@
1185
  "cpu": [
1186
  "riscv64"
1187
  ],
1188
- "dev": true,
1189
  "license": "MIT",
1190
  "optional": true,
1191
  "os": [
@@ -1199,7 +1169,6 @@
1199
  "cpu": [
1200
  "riscv64"
1201
  ],
1202
- "dev": true,
1203
  "license": "MIT",
1204
  "optional": true,
1205
  "os": [
@@ -1213,7 +1182,6 @@
1213
  "cpu": [
1214
  "s390x"
1215
  ],
1216
- "dev": true,
1217
  "license": "MIT",
1218
  "optional": true,
1219
  "os": [
@@ -1227,7 +1195,6 @@
1227
  "cpu": [
1228
  "x64"
1229
  ],
1230
- "dev": true,
1231
  "license": "MIT",
1232
  "optional": true,
1233
  "os": [
@@ -1241,7 +1208,6 @@
1241
  "cpu": [
1242
  "x64"
1243
  ],
1244
- "dev": true,
1245
  "license": "MIT",
1246
  "optional": true,
1247
  "os": [
@@ -1255,7 +1221,6 @@
1255
  "cpu": [
1256
  "arm64"
1257
  ],
1258
- "dev": true,
1259
  "license": "MIT",
1260
  "optional": true,
1261
  "os": [
@@ -1269,7 +1234,6 @@
1269
  "cpu": [
1270
  "arm64"
1271
  ],
1272
- "dev": true,
1273
  "license": "MIT",
1274
  "optional": true,
1275
  "os": [
@@ -1283,7 +1247,6 @@
1283
  "cpu": [
1284
  "ia32"
1285
  ],
1286
- "dev": true,
1287
  "license": "MIT",
1288
  "optional": true,
1289
  "os": [
@@ -1297,13 +1260,274 @@
1297
  "cpu": [
1298
  "x64"
1299
  ],
1300
- "dev": true,
1301
  "license": "MIT",
1302
  "optional": true,
1303
  "os": [
1304
  "win32"
1305
  ]
1306
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1307
  "node_modules/@types/babel__core": {
1308
  "version": "7.20.5",
1309
  "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
@@ -1353,7 +1577,6 @@
1353
  "version": "1.0.8",
1354
  "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
1355
  "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
1356
- "dev": true,
1357
  "license": "MIT"
1358
  },
1359
  "node_modules/@types/json-schema": {
@@ -1384,16 +1607,16 @@
1384
  }
1385
  },
1386
  "node_modules/@vitejs/plugin-react": {
1387
- "version": "5.0.2",
1388
- "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.0.2.tgz",
1389
- "integrity": "sha512-tmyFgixPZCx2+e6VO9TNITWcCQl8+Nl/E8YbAyPVv85QCc7/A3JrdfG2A8gIzvVhWuzMOVrFW1aReaNxrI6tbw==",
1390
  "dev": true,
1391
  "license": "MIT",
1392
  "dependencies": {
1393
- "@babel/core": "^7.28.3",
1394
  "@babel/plugin-transform-react-jsx-self": "^7.27.1",
1395
  "@babel/plugin-transform-react-jsx-source": "^7.27.1",
1396
- "@rolldown/pluginutils": "1.0.0-beta.34",
1397
  "@types/babel__core": "^7.20.5",
1398
  "react-refresh": "^0.17.0"
1399
  },
@@ -1496,9 +1719,9 @@
1496
  }
1497
  },
1498
  "node_modules/browserslist": {
1499
- "version": "4.26.0",
1500
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.26.0.tgz",
1501
- "integrity": "sha512-P9go2WrP9FiPwLv3zqRD/Uoxo0RSHjzFCiQz7d4vbmwNqQFo9T9WCeP/Qn5EbcKQY6DBbkxEXNcpJOmncNrb7A==",
1502
  "dev": true,
1503
  "funding": [
1504
  {
@@ -1516,7 +1739,7 @@
1516
  ],
1517
  "license": "MIT",
1518
  "dependencies": {
1519
- "baseline-browser-mapping": "^2.8.2",
1520
  "caniuse-lite": "^1.0.30001741",
1521
  "electron-to-chromium": "^1.5.218",
1522
  "node-releases": "^2.0.21",
@@ -1540,9 +1763,9 @@
1540
  }
1541
  },
1542
  "node_modules/caniuse-lite": {
1543
- "version": "1.0.30001741",
1544
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001741.tgz",
1545
- "integrity": "sha512-QGUGitqsc8ARjLdgAfxETDhRbJ0REsP6O3I96TAth/mVjh2cYzN2u+3AzPP3aVSm2FehEItaJw1xd+IGBXWeSw==",
1546
  "dev": true,
1547
  "funding": [
1548
  {
@@ -1577,6 +1800,15 @@
1577
  "url": "https://github.com/chalk/chalk?sponsor=1"
1578
  }
1579
  },
 
 
 
 
 
 
 
 
 
1580
  "node_modules/color-convert": {
1581
  "version": "2.0.1",
1582
  "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -1658,18 +1890,39 @@
1658
  "dev": true,
1659
  "license": "MIT"
1660
  },
 
 
 
 
 
 
 
 
 
1661
  "node_modules/electron-to-chromium": {
1662
- "version": "1.5.218",
1663
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.218.tgz",
1664
- "integrity": "sha512-uwwdN0TUHs8u6iRgN8vKeWZMRll4gBkz+QMqdS7DDe49uiK68/UX92lFb61oiFPrpYZNeZIqa4bA7O6Aiasnzg==",
1665
  "dev": true,
1666
  "license": "ISC"
1667
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
1668
  "node_modules/esbuild": {
1669
  "version": "0.25.9",
1670
  "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz",
1671
  "integrity": "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==",
1672
- "dev": true,
1673
  "hasInstallScript": true,
1674
  "license": "MIT",
1675
  "bin": {
@@ -1933,7 +2186,6 @@
1933
  "version": "6.5.0",
1934
  "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
1935
  "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
1936
- "dev": true,
1937
  "license": "MIT",
1938
  "engines": {
1939
  "node": ">=12.0.0"
@@ -2002,7 +2254,6 @@
2002
  "version": "2.3.3",
2003
  "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
2004
  "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
2005
- "dev": true,
2006
  "hasInstallScript": true,
2007
  "license": "MIT",
2008
  "optional": true,
@@ -2049,6 +2300,12 @@
2049
  "url": "https://github.com/sponsors/sindresorhus"
2050
  }
2051
  },
 
 
 
 
 
 
2052
  "node_modules/has-flag": {
2053
  "version": "4.0.0",
2054
  "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -2126,6 +2383,15 @@
2126
  "dev": true,
2127
  "license": "ISC"
2128
  },
 
 
 
 
 
 
 
 
 
2129
  "node_modules/js-tokens": {
2130
  "version": "4.0.0",
2131
  "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -2217,6 +2483,234 @@
2217
  "node": ">= 0.8.0"
2218
  }
2219
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2220
  "node_modules/locate-path": {
2221
  "version": "6.0.0",
2222
  "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
@@ -2250,6 +2744,15 @@
2250
  "yallist": "^3.0.2"
2251
  }
2252
  },
 
 
 
 
 
 
 
 
 
2253
  "node_modules/minimatch": {
2254
  "version": "3.1.2",
2255
  "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@@ -2263,6 +2766,42 @@
2263
  "node": "*"
2264
  }
2265
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2266
  "node_modules/ms": {
2267
  "version": "2.1.3",
2268
  "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@@ -2274,7 +2813,6 @@
2274
  "version": "3.3.11",
2275
  "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
2276
  "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
2277
- "dev": true,
2278
  "funding": [
2279
  {
2280
  "type": "github",
@@ -2390,14 +2928,12 @@
2390
  "version": "1.1.1",
2391
  "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
2392
  "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
2393
- "dev": true,
2394
  "license": "ISC"
2395
  },
2396
  "node_modules/picomatch": {
2397
  "version": "4.0.3",
2398
  "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
2399
  "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
2400
- "dev": true,
2401
  "license": "MIT",
2402
  "engines": {
2403
  "node": ">=12"
@@ -2410,7 +2946,6 @@
2410
  "version": "8.5.6",
2411
  "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
2412
  "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
2413
- "dev": true,
2414
  "funding": [
2415
  {
2416
  "type": "opencollective",
@@ -2500,7 +3035,6 @@
2500
  "version": "4.50.2",
2501
  "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.50.2.tgz",
2502
  "integrity": "sha512-BgLRGy7tNS9H66aIMASq1qSYbAAJV6Z6WR4QYTvj5FgF15rZ/ympT1uixHXwzbZUBDbkvqUI1KR0fH1FhMaQ9w==",
2503
- "dev": true,
2504
  "license": "MIT",
2505
  "dependencies": {
2506
  "@types/estree": "1.0.8"
@@ -2580,7 +3114,6 @@
2580
  "version": "1.2.1",
2581
  "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
2582
  "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
2583
- "dev": true,
2584
  "license": "BSD-3-Clause",
2585
  "engines": {
2586
  "node": ">=0.10.0"
@@ -2612,11 +3145,55 @@
2612
  "node": ">=8"
2613
  }
2614
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2615
  "node_modules/tinyglobby": {
2616
  "version": "0.2.15",
2617
  "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
2618
  "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
2619
- "dev": true,
2620
  "license": "MIT",
2621
  "dependencies": {
2622
  "fdir": "^6.5.0",
@@ -2687,7 +3264,6 @@
2687
  "version": "7.1.5",
2688
  "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.5.tgz",
2689
  "integrity": "sha512-4cKBO9wR75r0BeIWWWId9XK9Lj6La5X846Zw9dFfzMRw38IlTk2iCcUt6hsyiDRcPidc55ZParFYDXi0nXOeLQ==",
2690
- "dev": true,
2691
  "license": "MIT",
2692
  "dependencies": {
2693
  "esbuild": "^0.25.0",
 
8
  "name": "frontend",
9
  "version": "0.0.0",
10
  "dependencies": {
11
+ "@tailwindcss/vite": "^4.1.13",
12
  "react": "^19.1.1",
13
+ "react-dom": "^19.1.1",
14
+ "tailwindcss": "^4.1.13"
15
  },
16
  "devDependencies": {
17
  "@eslint/js": "^9.33.0",
 
314
  "cpu": [
315
  "ppc64"
316
  ],
 
317
  "license": "MIT",
318
  "optional": true,
319
  "os": [
 
330
  "cpu": [
331
  "arm"
332
  ],
 
333
  "license": "MIT",
334
  "optional": true,
335
  "os": [
 
346
  "cpu": [
347
  "arm64"
348
  ],
 
349
  "license": "MIT",
350
  "optional": true,
351
  "os": [
 
362
  "cpu": [
363
  "x64"
364
  ],
 
365
  "license": "MIT",
366
  "optional": true,
367
  "os": [
 
378
  "cpu": [
379
  "arm64"
380
  ],
 
381
  "license": "MIT",
382
  "optional": true,
383
  "os": [
 
394
  "cpu": [
395
  "x64"
396
  ],
 
397
  "license": "MIT",
398
  "optional": true,
399
  "os": [
 
410
  "cpu": [
411
  "arm64"
412
  ],
 
413
  "license": "MIT",
414
  "optional": true,
415
  "os": [
 
426
  "cpu": [
427
  "x64"
428
  ],
 
429
  "license": "MIT",
430
  "optional": true,
431
  "os": [
 
442
  "cpu": [
443
  "arm"
444
  ],
 
445
  "license": "MIT",
446
  "optional": true,
447
  "os": [
 
458
  "cpu": [
459
  "arm64"
460
  ],
 
461
  "license": "MIT",
462
  "optional": true,
463
  "os": [
 
474
  "cpu": [
475
  "ia32"
476
  ],
 
477
  "license": "MIT",
478
  "optional": true,
479
  "os": [
 
490
  "cpu": [
491
  "loong64"
492
  ],
 
493
  "license": "MIT",
494
  "optional": true,
495
  "os": [
 
506
  "cpu": [
507
  "mips64el"
508
  ],
 
509
  "license": "MIT",
510
  "optional": true,
511
  "os": [
 
522
  "cpu": [
523
  "ppc64"
524
  ],
 
525
  "license": "MIT",
526
  "optional": true,
527
  "os": [
 
538
  "cpu": [
539
  "riscv64"
540
  ],
 
541
  "license": "MIT",
542
  "optional": true,
543
  "os": [
 
554
  "cpu": [
555
  "s390x"
556
  ],
 
557
  "license": "MIT",
558
  "optional": true,
559
  "os": [
 
570
  "cpu": [
571
  "x64"
572
  ],
 
573
  "license": "MIT",
574
  "optional": true,
575
  "os": [
 
586
  "cpu": [
587
  "arm64"
588
  ],
 
589
  "license": "MIT",
590
  "optional": true,
591
  "os": [
 
602
  "cpu": [
603
  "x64"
604
  ],
 
605
  "license": "MIT",
606
  "optional": true,
607
  "os": [
 
618
  "cpu": [
619
  "arm64"
620
  ],
 
621
  "license": "MIT",
622
  "optional": true,
623
  "os": [
 
634
  "cpu": [
635
  "x64"
636
  ],
 
637
  "license": "MIT",
638
  "optional": true,
639
  "os": [
 
650
  "cpu": [
651
  "arm64"
652
  ],
 
653
  "license": "MIT",
654
  "optional": true,
655
  "os": [
 
666
  "cpu": [
667
  "x64"
668
  ],
 
669
  "license": "MIT",
670
  "optional": true,
671
  "os": [
 
682
  "cpu": [
683
  "arm64"
684
  ],
 
685
  "license": "MIT",
686
  "optional": true,
687
  "os": [
 
698
  "cpu": [
699
  "ia32"
700
  ],
 
701
  "license": "MIT",
702
  "optional": true,
703
  "os": [
 
714
  "cpu": [
715
  "x64"
716
  ],
 
717
  "license": "MIT",
718
  "optional": true,
719
  "os": [
 
929
  "url": "https://github.com/sponsors/nzakas"
930
  }
931
  },
932
+ "node_modules/@isaacs/fs-minipass": {
933
+ "version": "4.0.1",
934
+ "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz",
935
+ "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==",
936
+ "license": "ISC",
937
+ "dependencies": {
938
+ "minipass": "^7.0.4"
939
+ },
940
+ "engines": {
941
+ "node": ">=18.0.0"
942
+ }
943
+ },
944
  "node_modules/@jridgewell/gen-mapping": {
945
  "version": "0.3.13",
946
  "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
947
  "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
 
948
  "license": "MIT",
949
  "dependencies": {
950
  "@jridgewell/sourcemap-codec": "^1.5.0",
 
955
  "version": "2.3.5",
956
  "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
957
  "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
 
958
  "license": "MIT",
959
  "dependencies": {
960
  "@jridgewell/gen-mapping": "^0.3.5",
 
965
  "version": "3.1.2",
966
  "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
967
  "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
 
968
  "license": "MIT",
969
  "engines": {
970
  "node": ">=6.0.0"
 
974
  "version": "1.5.5",
975
  "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
976
  "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
 
977
  "license": "MIT"
978
  },
979
  "node_modules/@jridgewell/trace-mapping": {
980
  "version": "0.3.31",
981
  "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
982
  "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
 
983
  "license": "MIT",
984
  "dependencies": {
985
  "@jridgewell/resolve-uri": "^3.1.0",
 
987
  }
988
  },
989
  "node_modules/@rolldown/pluginutils": {
990
+ "version": "1.0.0-beta.35",
991
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.35.tgz",
992
+ "integrity": "sha512-slYrCpoxJUqzFDDNlvrOYRazQUNRvWPjXA17dAOISY3rDMxX6k8K4cj2H+hEYMHF81HO3uNd5rHVigAWRM5dSg==",
993
  "dev": true,
994
  "license": "MIT"
995
  },
 
1000
  "cpu": [
1001
  "arm"
1002
  ],
 
1003
  "license": "MIT",
1004
  "optional": true,
1005
  "os": [
 
1013
  "cpu": [
1014
  "arm64"
1015
  ],
 
1016
  "license": "MIT",
1017
  "optional": true,
1018
  "os": [
 
1026
  "cpu": [
1027
  "arm64"
1028
  ],
 
1029
  "license": "MIT",
1030
  "optional": true,
1031
  "os": [
 
1039
  "cpu": [
1040
  "x64"
1041
  ],
 
1042
  "license": "MIT",
1043
  "optional": true,
1044
  "os": [
 
1052
  "cpu": [
1053
  "arm64"
1054
  ],
 
1055
  "license": "MIT",
1056
  "optional": true,
1057
  "os": [
 
1065
  "cpu": [
1066
  "x64"
1067
  ],
 
1068
  "license": "MIT",
1069
  "optional": true,
1070
  "os": [
 
1078
  "cpu": [
1079
  "arm"
1080
  ],
 
1081
  "license": "MIT",
1082
  "optional": true,
1083
  "os": [
 
1091
  "cpu": [
1092
  "arm"
1093
  ],
 
1094
  "license": "MIT",
1095
  "optional": true,
1096
  "os": [
 
1104
  "cpu": [
1105
  "arm64"
1106
  ],
 
1107
  "license": "MIT",
1108
  "optional": true,
1109
  "os": [
 
1117
  "cpu": [
1118
  "arm64"
1119
  ],
 
1120
  "license": "MIT",
1121
  "optional": true,
1122
  "os": [
 
1130
  "cpu": [
1131
  "loong64"
1132
  ],
 
1133
  "license": "MIT",
1134
  "optional": true,
1135
  "os": [
 
1143
  "cpu": [
1144
  "ppc64"
1145
  ],
 
1146
  "license": "MIT",
1147
  "optional": true,
1148
  "os": [
 
1156
  "cpu": [
1157
  "riscv64"
1158
  ],
 
1159
  "license": "MIT",
1160
  "optional": true,
1161
  "os": [
 
1169
  "cpu": [
1170
  "riscv64"
1171
  ],
 
1172
  "license": "MIT",
1173
  "optional": true,
1174
  "os": [
 
1182
  "cpu": [
1183
  "s390x"
1184
  ],
 
1185
  "license": "MIT",
1186
  "optional": true,
1187
  "os": [
 
1195
  "cpu": [
1196
  "x64"
1197
  ],
 
1198
  "license": "MIT",
1199
  "optional": true,
1200
  "os": [
 
1208
  "cpu": [
1209
  "x64"
1210
  ],
 
1211
  "license": "MIT",
1212
  "optional": true,
1213
  "os": [
 
1221
  "cpu": [
1222
  "arm64"
1223
  ],
 
1224
  "license": "MIT",
1225
  "optional": true,
1226
  "os": [
 
1234
  "cpu": [
1235
  "arm64"
1236
  ],
 
1237
  "license": "MIT",
1238
  "optional": true,
1239
  "os": [
 
1247
  "cpu": [
1248
  "ia32"
1249
  ],
 
1250
  "license": "MIT",
1251
  "optional": true,
1252
  "os": [
 
1260
  "cpu": [
1261
  "x64"
1262
  ],
 
1263
  "license": "MIT",
1264
  "optional": true,
1265
  "os": [
1266
  "win32"
1267
  ]
1268
  },
1269
+ "node_modules/@tailwindcss/node": {
1270
+ "version": "4.1.13",
1271
+ "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.13.tgz",
1272
+ "integrity": "sha512-eq3ouolC1oEFOAvOMOBAmfCIqZBJuvWvvYWh5h5iOYfe1HFC6+GZ6EIL0JdM3/niGRJmnrOc+8gl9/HGUaaptw==",
1273
+ "license": "MIT",
1274
+ "dependencies": {
1275
+ "@jridgewell/remapping": "^2.3.4",
1276
+ "enhanced-resolve": "^5.18.3",
1277
+ "jiti": "^2.5.1",
1278
+ "lightningcss": "1.30.1",
1279
+ "magic-string": "^0.30.18",
1280
+ "source-map-js": "^1.2.1",
1281
+ "tailwindcss": "4.1.13"
1282
+ }
1283
+ },
1284
+ "node_modules/@tailwindcss/oxide": {
1285
+ "version": "4.1.13",
1286
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.13.tgz",
1287
+ "integrity": "sha512-CPgsM1IpGRa880sMbYmG1s4xhAy3xEt1QULgTJGQmZUeNgXFR7s1YxYygmJyBGtou4SyEosGAGEeYqY7R53bIA==",
1288
+ "hasInstallScript": true,
1289
+ "license": "MIT",
1290
+ "dependencies": {
1291
+ "detect-libc": "^2.0.4",
1292
+ "tar": "^7.4.3"
1293
+ },
1294
+ "engines": {
1295
+ "node": ">= 10"
1296
+ },
1297
+ "optionalDependencies": {
1298
+ "@tailwindcss/oxide-android-arm64": "4.1.13",
1299
+ "@tailwindcss/oxide-darwin-arm64": "4.1.13",
1300
+ "@tailwindcss/oxide-darwin-x64": "4.1.13",
1301
+ "@tailwindcss/oxide-freebsd-x64": "4.1.13",
1302
+ "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.13",
1303
+ "@tailwindcss/oxide-linux-arm64-gnu": "4.1.13",
1304
+ "@tailwindcss/oxide-linux-arm64-musl": "4.1.13",
1305
+ "@tailwindcss/oxide-linux-x64-gnu": "4.1.13",
1306
+ "@tailwindcss/oxide-linux-x64-musl": "4.1.13",
1307
+ "@tailwindcss/oxide-wasm32-wasi": "4.1.13",
1308
+ "@tailwindcss/oxide-win32-arm64-msvc": "4.1.13",
1309
+ "@tailwindcss/oxide-win32-x64-msvc": "4.1.13"
1310
+ }
1311
+ },
1312
+ "node_modules/@tailwindcss/oxide-android-arm64": {
1313
+ "version": "4.1.13",
1314
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.13.tgz",
1315
+ "integrity": "sha512-BrpTrVYyejbgGo57yc8ieE+D6VT9GOgnNdmh5Sac6+t0m+v+sKQevpFVpwX3pBrM2qKrQwJ0c5eDbtjouY/+ew==",
1316
+ "cpu": [
1317
+ "arm64"
1318
+ ],
1319
+ "license": "MIT",
1320
+ "optional": true,
1321
+ "os": [
1322
+ "android"
1323
+ ],
1324
+ "engines": {
1325
+ "node": ">= 10"
1326
+ }
1327
+ },
1328
+ "node_modules/@tailwindcss/oxide-darwin-arm64": {
1329
+ "version": "4.1.13",
1330
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.13.tgz",
1331
+ "integrity": "sha512-YP+Jksc4U0KHcu76UhRDHq9bx4qtBftp9ShK/7UGfq0wpaP96YVnnjFnj3ZFrUAjc5iECzODl/Ts0AN7ZPOANQ==",
1332
+ "cpu": [
1333
+ "arm64"
1334
+ ],
1335
+ "license": "MIT",
1336
+ "optional": true,
1337
+ "os": [
1338
+ "darwin"
1339
+ ],
1340
+ "engines": {
1341
+ "node": ">= 10"
1342
+ }
1343
+ },
1344
+ "node_modules/@tailwindcss/oxide-darwin-x64": {
1345
+ "version": "4.1.13",
1346
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.13.tgz",
1347
+ "integrity": "sha512-aAJ3bbwrn/PQHDxCto9sxwQfT30PzyYJFG0u/BWZGeVXi5Hx6uuUOQEI2Fa43qvmUjTRQNZnGqe9t0Zntexeuw==",
1348
+ "cpu": [
1349
+ "x64"
1350
+ ],
1351
+ "license": "MIT",
1352
+ "optional": true,
1353
+ "os": [
1354
+ "darwin"
1355
+ ],
1356
+ "engines": {
1357
+ "node": ">= 10"
1358
+ }
1359
+ },
1360
+ "node_modules/@tailwindcss/oxide-freebsd-x64": {
1361
+ "version": "4.1.13",
1362
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.13.tgz",
1363
+ "integrity": "sha512-Wt8KvASHwSXhKE/dJLCCWcTSVmBj3xhVhp/aF3RpAhGeZ3sVo7+NTfgiN8Vey/Fi8prRClDs6/f0KXPDTZE6nQ==",
1364
+ "cpu": [
1365
+ "x64"
1366
+ ],
1367
+ "license": "MIT",
1368
+ "optional": true,
1369
+ "os": [
1370
+ "freebsd"
1371
+ ],
1372
+ "engines": {
1373
+ "node": ">= 10"
1374
+ }
1375
+ },
1376
+ "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
1377
+ "version": "4.1.13",
1378
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.13.tgz",
1379
+ "integrity": "sha512-mbVbcAsW3Gkm2MGwA93eLtWrwajz91aXZCNSkGTx/R5eb6KpKD5q8Ueckkh9YNboU8RH7jiv+ol/I7ZyQ9H7Bw==",
1380
+ "cpu": [
1381
+ "arm"
1382
+ ],
1383
+ "license": "MIT",
1384
+ "optional": true,
1385
+ "os": [
1386
+ "linux"
1387
+ ],
1388
+ "engines": {
1389
+ "node": ">= 10"
1390
+ }
1391
+ },
1392
+ "node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
1393
+ "version": "4.1.13",
1394
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.13.tgz",
1395
+ "integrity": "sha512-wdtfkmpXiwej/yoAkrCP2DNzRXCALq9NVLgLELgLim1QpSfhQM5+ZxQQF8fkOiEpuNoKLp4nKZ6RC4kmeFH0HQ==",
1396
+ "cpu": [
1397
+ "arm64"
1398
+ ],
1399
+ "license": "MIT",
1400
+ "optional": true,
1401
+ "os": [
1402
+ "linux"
1403
+ ],
1404
+ "engines": {
1405
+ "node": ">= 10"
1406
+ }
1407
+ },
1408
+ "node_modules/@tailwindcss/oxide-linux-arm64-musl": {
1409
+ "version": "4.1.13",
1410
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.13.tgz",
1411
+ "integrity": "sha512-hZQrmtLdhyqzXHB7mkXfq0IYbxegaqTmfa1p9MBj72WPoDD3oNOh1Lnxf6xZLY9C3OV6qiCYkO1i/LrzEdW2mg==",
1412
+ "cpu": [
1413
+ "arm64"
1414
+ ],
1415
+ "license": "MIT",
1416
+ "optional": true,
1417
+ "os": [
1418
+ "linux"
1419
+ ],
1420
+ "engines": {
1421
+ "node": ">= 10"
1422
+ }
1423
+ },
1424
+ "node_modules/@tailwindcss/oxide-linux-x64-gnu": {
1425
+ "version": "4.1.13",
1426
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.13.tgz",
1427
+ "integrity": "sha512-uaZTYWxSXyMWDJZNY1Ul7XkJTCBRFZ5Fo6wtjrgBKzZLoJNrG+WderJwAjPzuNZOnmdrVg260DKwXCFtJ/hWRQ==",
1428
+ "cpu": [
1429
+ "x64"
1430
+ ],
1431
+ "license": "MIT",
1432
+ "optional": true,
1433
+ "os": [
1434
+ "linux"
1435
+ ],
1436
+ "engines": {
1437
+ "node": ">= 10"
1438
+ }
1439
+ },
1440
+ "node_modules/@tailwindcss/oxide-linux-x64-musl": {
1441
+ "version": "4.1.13",
1442
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.13.tgz",
1443
+ "integrity": "sha512-oXiPj5mi4Hdn50v5RdnuuIms0PVPI/EG4fxAfFiIKQh5TgQgX7oSuDWntHW7WNIi/yVLAiS+CRGW4RkoGSSgVQ==",
1444
+ "cpu": [
1445
+ "x64"
1446
+ ],
1447
+ "license": "MIT",
1448
+ "optional": true,
1449
+ "os": [
1450
+ "linux"
1451
+ ],
1452
+ "engines": {
1453
+ "node": ">= 10"
1454
+ }
1455
+ },
1456
+ "node_modules/@tailwindcss/oxide-wasm32-wasi": {
1457
+ "version": "4.1.13",
1458
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.13.tgz",
1459
+ "integrity": "sha512-+LC2nNtPovtrDwBc/nqnIKYh/W2+R69FA0hgoeOn64BdCX522u19ryLh3Vf3F8W49XBcMIxSe665kwy21FkhvA==",
1460
+ "bundleDependencies": [
1461
+ "@napi-rs/wasm-runtime",
1462
+ "@emnapi/core",
1463
+ "@emnapi/runtime",
1464
+ "@tybys/wasm-util",
1465
+ "@emnapi/wasi-threads",
1466
+ "tslib"
1467
+ ],
1468
+ "cpu": [
1469
+ "wasm32"
1470
+ ],
1471
+ "license": "MIT",
1472
+ "optional": true,
1473
+ "dependencies": {
1474
+ "@emnapi/core": "^1.4.5",
1475
+ "@emnapi/runtime": "^1.4.5",
1476
+ "@emnapi/wasi-threads": "^1.0.4",
1477
+ "@napi-rs/wasm-runtime": "^0.2.12",
1478
+ "@tybys/wasm-util": "^0.10.0",
1479
+ "tslib": "^2.8.0"
1480
+ },
1481
+ "engines": {
1482
+ "node": ">=14.0.0"
1483
+ }
1484
+ },
1485
+ "node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
1486
+ "version": "4.1.13",
1487
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.13.tgz",
1488
+ "integrity": "sha512-dziTNeQXtoQ2KBXmrjCxsuPk3F3CQ/yb7ZNZNA+UkNTeiTGgfeh+gH5Pi7mRncVgcPD2xgHvkFCh/MhZWSgyQg==",
1489
+ "cpu": [
1490
+ "arm64"
1491
+ ],
1492
+ "license": "MIT",
1493
+ "optional": true,
1494
+ "os": [
1495
+ "win32"
1496
+ ],
1497
+ "engines": {
1498
+ "node": ">= 10"
1499
+ }
1500
+ },
1501
+ "node_modules/@tailwindcss/oxide-win32-x64-msvc": {
1502
+ "version": "4.1.13",
1503
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.13.tgz",
1504
+ "integrity": "sha512-3+LKesjXydTkHk5zXX01b5KMzLV1xl2mcktBJkje7rhFUpUlYJy7IMOLqjIRQncLTa1WZZiFY/foAeB5nmaiTw==",
1505
+ "cpu": [
1506
+ "x64"
1507
+ ],
1508
+ "license": "MIT",
1509
+ "optional": true,
1510
+ "os": [
1511
+ "win32"
1512
+ ],
1513
+ "engines": {
1514
+ "node": ">= 10"
1515
+ }
1516
+ },
1517
+ "node_modules/@tailwindcss/vite": {
1518
+ "version": "4.1.13",
1519
+ "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.13.tgz",
1520
+ "integrity": "sha512-0PmqLQ010N58SbMTJ7BVJ4I2xopiQn/5i6nlb4JmxzQf8zcS5+m2Cv6tqh+sfDwtIdjoEnOvwsGQ1hkUi8QEHQ==",
1521
+ "license": "MIT",
1522
+ "dependencies": {
1523
+ "@tailwindcss/node": "4.1.13",
1524
+ "@tailwindcss/oxide": "4.1.13",
1525
+ "tailwindcss": "4.1.13"
1526
+ },
1527
+ "peerDependencies": {
1528
+ "vite": "^5.2.0 || ^6 || ^7"
1529
+ }
1530
+ },
1531
  "node_modules/@types/babel__core": {
1532
  "version": "7.20.5",
1533
  "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
 
1577
  "version": "1.0.8",
1578
  "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
1579
  "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
 
1580
  "license": "MIT"
1581
  },
1582
  "node_modules/@types/json-schema": {
 
1607
  }
1608
  },
1609
  "node_modules/@vitejs/plugin-react": {
1610
+ "version": "5.0.3",
1611
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.0.3.tgz",
1612
+ "integrity": "sha512-PFVHhosKkofGH0Yzrw1BipSedTH68BFF8ZWy1kfUpCtJcouXXY0+racG8sExw7hw0HoX36813ga5o3LTWZ4FUg==",
1613
  "dev": true,
1614
  "license": "MIT",
1615
  "dependencies": {
1616
+ "@babel/core": "^7.28.4",
1617
  "@babel/plugin-transform-react-jsx-self": "^7.27.1",
1618
  "@babel/plugin-transform-react-jsx-source": "^7.27.1",
1619
+ "@rolldown/pluginutils": "1.0.0-beta.35",
1620
  "@types/babel__core": "^7.20.5",
1621
  "react-refresh": "^0.17.0"
1622
  },
 
1719
  }
1720
  },
1721
  "node_modules/browserslist": {
1722
+ "version": "4.26.2",
1723
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.26.2.tgz",
1724
+ "integrity": "sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A==",
1725
  "dev": true,
1726
  "funding": [
1727
  {
 
1739
  ],
1740
  "license": "MIT",
1741
  "dependencies": {
1742
+ "baseline-browser-mapping": "^2.8.3",
1743
  "caniuse-lite": "^1.0.30001741",
1744
  "electron-to-chromium": "^1.5.218",
1745
  "node-releases": "^2.0.21",
 
1763
  }
1764
  },
1765
  "node_modules/caniuse-lite": {
1766
+ "version": "1.0.30001743",
1767
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001743.tgz",
1768
+ "integrity": "sha512-e6Ojr7RV14Un7dz6ASD0aZDmQPT/A+eZU+nuTNfjqmRrmkmQlnTNWH0SKmqagx9PeW87UVqapSurtAXifmtdmw==",
1769
  "dev": true,
1770
  "funding": [
1771
  {
 
1800
  "url": "https://github.com/chalk/chalk?sponsor=1"
1801
  }
1802
  },
1803
+ "node_modules/chownr": {
1804
+ "version": "3.0.0",
1805
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz",
1806
+ "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==",
1807
+ "license": "BlueOak-1.0.0",
1808
+ "engines": {
1809
+ "node": ">=18"
1810
+ }
1811
+ },
1812
  "node_modules/color-convert": {
1813
  "version": "2.0.1",
1814
  "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
 
1890
  "dev": true,
1891
  "license": "MIT"
1892
  },
1893
+ "node_modules/detect-libc": {
1894
+ "version": "2.1.0",
1895
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.0.tgz",
1896
+ "integrity": "sha512-vEtk+OcP7VBRtQZ1EJ3bdgzSfBjgnEalLTp5zjJrS+2Z1w2KZly4SBdac/WDU3hhsNAZ9E8SC96ME4Ey8MZ7cg==",
1897
+ "license": "Apache-2.0",
1898
+ "engines": {
1899
+ "node": ">=8"
1900
+ }
1901
+ },
1902
  "node_modules/electron-to-chromium": {
1903
+ "version": "1.5.220",
1904
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.220.tgz",
1905
+ "integrity": "sha512-TWXijEwR1ggr4BdAKrb1nMNqYLTx1/4aD1fkeZU+FVJGTKu53/T7UyHKXlqEX3Ub02csyHePbHmkvnrjcaYzMA==",
1906
  "dev": true,
1907
  "license": "ISC"
1908
  },
1909
+ "node_modules/enhanced-resolve": {
1910
+ "version": "5.18.3",
1911
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz",
1912
+ "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==",
1913
+ "license": "MIT",
1914
+ "dependencies": {
1915
+ "graceful-fs": "^4.2.4",
1916
+ "tapable": "^2.2.0"
1917
+ },
1918
+ "engines": {
1919
+ "node": ">=10.13.0"
1920
+ }
1921
+ },
1922
  "node_modules/esbuild": {
1923
  "version": "0.25.9",
1924
  "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz",
1925
  "integrity": "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==",
 
1926
  "hasInstallScript": true,
1927
  "license": "MIT",
1928
  "bin": {
 
2186
  "version": "6.5.0",
2187
  "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
2188
  "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
 
2189
  "license": "MIT",
2190
  "engines": {
2191
  "node": ">=12.0.0"
 
2254
  "version": "2.3.3",
2255
  "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
2256
  "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
 
2257
  "hasInstallScript": true,
2258
  "license": "MIT",
2259
  "optional": true,
 
2300
  "url": "https://github.com/sponsors/sindresorhus"
2301
  }
2302
  },
2303
+ "node_modules/graceful-fs": {
2304
+ "version": "4.2.11",
2305
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
2306
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
2307
+ "license": "ISC"
2308
+ },
2309
  "node_modules/has-flag": {
2310
  "version": "4.0.0",
2311
  "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
 
2383
  "dev": true,
2384
  "license": "ISC"
2385
  },
2386
+ "node_modules/jiti": {
2387
+ "version": "2.5.1",
2388
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.5.1.tgz",
2389
+ "integrity": "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==",
2390
+ "license": "MIT",
2391
+ "bin": {
2392
+ "jiti": "lib/jiti-cli.mjs"
2393
+ }
2394
+ },
2395
  "node_modules/js-tokens": {
2396
  "version": "4.0.0",
2397
  "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
 
2483
  "node": ">= 0.8.0"
2484
  }
2485
  },
2486
+ "node_modules/lightningcss": {
2487
+ "version": "1.30.1",
2488
+ "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz",
2489
+ "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==",
2490
+ "license": "MPL-2.0",
2491
+ "dependencies": {
2492
+ "detect-libc": "^2.0.3"
2493
+ },
2494
+ "engines": {
2495
+ "node": ">= 12.0.0"
2496
+ },
2497
+ "funding": {
2498
+ "type": "opencollective",
2499
+ "url": "https://opencollective.com/parcel"
2500
+ },
2501
+ "optionalDependencies": {
2502
+ "lightningcss-darwin-arm64": "1.30.1",
2503
+ "lightningcss-darwin-x64": "1.30.1",
2504
+ "lightningcss-freebsd-x64": "1.30.1",
2505
+ "lightningcss-linux-arm-gnueabihf": "1.30.1",
2506
+ "lightningcss-linux-arm64-gnu": "1.30.1",
2507
+ "lightningcss-linux-arm64-musl": "1.30.1",
2508
+ "lightningcss-linux-x64-gnu": "1.30.1",
2509
+ "lightningcss-linux-x64-musl": "1.30.1",
2510
+ "lightningcss-win32-arm64-msvc": "1.30.1",
2511
+ "lightningcss-win32-x64-msvc": "1.30.1"
2512
+ }
2513
+ },
2514
+ "node_modules/lightningcss-darwin-arm64": {
2515
+ "version": "1.30.1",
2516
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz",
2517
+ "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==",
2518
+ "cpu": [
2519
+ "arm64"
2520
+ ],
2521
+ "license": "MPL-2.0",
2522
+ "optional": true,
2523
+ "os": [
2524
+ "darwin"
2525
+ ],
2526
+ "engines": {
2527
+ "node": ">= 12.0.0"
2528
+ },
2529
+ "funding": {
2530
+ "type": "opencollective",
2531
+ "url": "https://opencollective.com/parcel"
2532
+ }
2533
+ },
2534
+ "node_modules/lightningcss-darwin-x64": {
2535
+ "version": "1.30.1",
2536
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz",
2537
+ "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==",
2538
+ "cpu": [
2539
+ "x64"
2540
+ ],
2541
+ "license": "MPL-2.0",
2542
+ "optional": true,
2543
+ "os": [
2544
+ "darwin"
2545
+ ],
2546
+ "engines": {
2547
+ "node": ">= 12.0.0"
2548
+ },
2549
+ "funding": {
2550
+ "type": "opencollective",
2551
+ "url": "https://opencollective.com/parcel"
2552
+ }
2553
+ },
2554
+ "node_modules/lightningcss-freebsd-x64": {
2555
+ "version": "1.30.1",
2556
+ "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz",
2557
+ "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==",
2558
+ "cpu": [
2559
+ "x64"
2560
+ ],
2561
+ "license": "MPL-2.0",
2562
+ "optional": true,
2563
+ "os": [
2564
+ "freebsd"
2565
+ ],
2566
+ "engines": {
2567
+ "node": ">= 12.0.0"
2568
+ },
2569
+ "funding": {
2570
+ "type": "opencollective",
2571
+ "url": "https://opencollective.com/parcel"
2572
+ }
2573
+ },
2574
+ "node_modules/lightningcss-linux-arm-gnueabihf": {
2575
+ "version": "1.30.1",
2576
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz",
2577
+ "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==",
2578
+ "cpu": [
2579
+ "arm"
2580
+ ],
2581
+ "license": "MPL-2.0",
2582
+ "optional": true,
2583
+ "os": [
2584
+ "linux"
2585
+ ],
2586
+ "engines": {
2587
+ "node": ">= 12.0.0"
2588
+ },
2589
+ "funding": {
2590
+ "type": "opencollective",
2591
+ "url": "https://opencollective.com/parcel"
2592
+ }
2593
+ },
2594
+ "node_modules/lightningcss-linux-arm64-gnu": {
2595
+ "version": "1.30.1",
2596
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz",
2597
+ "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==",
2598
+ "cpu": [
2599
+ "arm64"
2600
+ ],
2601
+ "license": "MPL-2.0",
2602
+ "optional": true,
2603
+ "os": [
2604
+ "linux"
2605
+ ],
2606
+ "engines": {
2607
+ "node": ">= 12.0.0"
2608
+ },
2609
+ "funding": {
2610
+ "type": "opencollective",
2611
+ "url": "https://opencollective.com/parcel"
2612
+ }
2613
+ },
2614
+ "node_modules/lightningcss-linux-arm64-musl": {
2615
+ "version": "1.30.1",
2616
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz",
2617
+ "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==",
2618
+ "cpu": [
2619
+ "arm64"
2620
+ ],
2621
+ "license": "MPL-2.0",
2622
+ "optional": true,
2623
+ "os": [
2624
+ "linux"
2625
+ ],
2626
+ "engines": {
2627
+ "node": ">= 12.0.0"
2628
+ },
2629
+ "funding": {
2630
+ "type": "opencollective",
2631
+ "url": "https://opencollective.com/parcel"
2632
+ }
2633
+ },
2634
+ "node_modules/lightningcss-linux-x64-gnu": {
2635
+ "version": "1.30.1",
2636
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz",
2637
+ "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==",
2638
+ "cpu": [
2639
+ "x64"
2640
+ ],
2641
+ "license": "MPL-2.0",
2642
+ "optional": true,
2643
+ "os": [
2644
+ "linux"
2645
+ ],
2646
+ "engines": {
2647
+ "node": ">= 12.0.0"
2648
+ },
2649
+ "funding": {
2650
+ "type": "opencollective",
2651
+ "url": "https://opencollective.com/parcel"
2652
+ }
2653
+ },
2654
+ "node_modules/lightningcss-linux-x64-musl": {
2655
+ "version": "1.30.1",
2656
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz",
2657
+ "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==",
2658
+ "cpu": [
2659
+ "x64"
2660
+ ],
2661
+ "license": "MPL-2.0",
2662
+ "optional": true,
2663
+ "os": [
2664
+ "linux"
2665
+ ],
2666
+ "engines": {
2667
+ "node": ">= 12.0.0"
2668
+ },
2669
+ "funding": {
2670
+ "type": "opencollective",
2671
+ "url": "https://opencollective.com/parcel"
2672
+ }
2673
+ },
2674
+ "node_modules/lightningcss-win32-arm64-msvc": {
2675
+ "version": "1.30.1",
2676
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz",
2677
+ "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==",
2678
+ "cpu": [
2679
+ "arm64"
2680
+ ],
2681
+ "license": "MPL-2.0",
2682
+ "optional": true,
2683
+ "os": [
2684
+ "win32"
2685
+ ],
2686
+ "engines": {
2687
+ "node": ">= 12.0.0"
2688
+ },
2689
+ "funding": {
2690
+ "type": "opencollective",
2691
+ "url": "https://opencollective.com/parcel"
2692
+ }
2693
+ },
2694
+ "node_modules/lightningcss-win32-x64-msvc": {
2695
+ "version": "1.30.1",
2696
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz",
2697
+ "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==",
2698
+ "cpu": [
2699
+ "x64"
2700
+ ],
2701
+ "license": "MPL-2.0",
2702
+ "optional": true,
2703
+ "os": [
2704
+ "win32"
2705
+ ],
2706
+ "engines": {
2707
+ "node": ">= 12.0.0"
2708
+ },
2709
+ "funding": {
2710
+ "type": "opencollective",
2711
+ "url": "https://opencollective.com/parcel"
2712
+ }
2713
+ },
2714
  "node_modules/locate-path": {
2715
  "version": "6.0.0",
2716
  "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
 
2744
  "yallist": "^3.0.2"
2745
  }
2746
  },
2747
+ "node_modules/magic-string": {
2748
+ "version": "0.30.19",
2749
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.19.tgz",
2750
+ "integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==",
2751
+ "license": "MIT",
2752
+ "dependencies": {
2753
+ "@jridgewell/sourcemap-codec": "^1.5.5"
2754
+ }
2755
+ },
2756
  "node_modules/minimatch": {
2757
  "version": "3.1.2",
2758
  "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
 
2766
  "node": "*"
2767
  }
2768
  },
2769
+ "node_modules/minipass": {
2770
+ "version": "7.1.2",
2771
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
2772
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
2773
+ "license": "ISC",
2774
+ "engines": {
2775
+ "node": ">=16 || 14 >=14.17"
2776
+ }
2777
+ },
2778
+ "node_modules/minizlib": {
2779
+ "version": "3.0.2",
2780
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz",
2781
+ "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==",
2782
+ "license": "MIT",
2783
+ "dependencies": {
2784
+ "minipass": "^7.1.2"
2785
+ },
2786
+ "engines": {
2787
+ "node": ">= 18"
2788
+ }
2789
+ },
2790
+ "node_modules/mkdirp": {
2791
+ "version": "3.0.1",
2792
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz",
2793
+ "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==",
2794
+ "license": "MIT",
2795
+ "bin": {
2796
+ "mkdirp": "dist/cjs/src/bin.js"
2797
+ },
2798
+ "engines": {
2799
+ "node": ">=10"
2800
+ },
2801
+ "funding": {
2802
+ "url": "https://github.com/sponsors/isaacs"
2803
+ }
2804
+ },
2805
  "node_modules/ms": {
2806
  "version": "2.1.3",
2807
  "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
 
2813
  "version": "3.3.11",
2814
  "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
2815
  "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
 
2816
  "funding": [
2817
  {
2818
  "type": "github",
 
2928
  "version": "1.1.1",
2929
  "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
2930
  "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
 
2931
  "license": "ISC"
2932
  },
2933
  "node_modules/picomatch": {
2934
  "version": "4.0.3",
2935
  "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
2936
  "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
 
2937
  "license": "MIT",
2938
  "engines": {
2939
  "node": ">=12"
 
2946
  "version": "8.5.6",
2947
  "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
2948
  "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
 
2949
  "funding": [
2950
  {
2951
  "type": "opencollective",
 
3035
  "version": "4.50.2",
3036
  "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.50.2.tgz",
3037
  "integrity": "sha512-BgLRGy7tNS9H66aIMASq1qSYbAAJV6Z6WR4QYTvj5FgF15rZ/ympT1uixHXwzbZUBDbkvqUI1KR0fH1FhMaQ9w==",
 
3038
  "license": "MIT",
3039
  "dependencies": {
3040
  "@types/estree": "1.0.8"
 
3114
  "version": "1.2.1",
3115
  "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
3116
  "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
 
3117
  "license": "BSD-3-Clause",
3118
  "engines": {
3119
  "node": ">=0.10.0"
 
3145
  "node": ">=8"
3146
  }
3147
  },
3148
+ "node_modules/tailwindcss": {
3149
+ "version": "4.1.13",
3150
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.13.tgz",
3151
+ "integrity": "sha512-i+zidfmTqtwquj4hMEwdjshYYgMbOrPzb9a0M3ZgNa0JMoZeFC6bxZvO8yr8ozS6ix2SDz0+mvryPeBs2TFE+w==",
3152
+ "license": "MIT"
3153
+ },
3154
+ "node_modules/tapable": {
3155
+ "version": "2.2.3",
3156
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.3.tgz",
3157
+ "integrity": "sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg==",
3158
+ "license": "MIT",
3159
+ "engines": {
3160
+ "node": ">=6"
3161
+ },
3162
+ "funding": {
3163
+ "type": "opencollective",
3164
+ "url": "https://opencollective.com/webpack"
3165
+ }
3166
+ },
3167
+ "node_modules/tar": {
3168
+ "version": "7.4.3",
3169
+ "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz",
3170
+ "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==",
3171
+ "license": "ISC",
3172
+ "dependencies": {
3173
+ "@isaacs/fs-minipass": "^4.0.0",
3174
+ "chownr": "^3.0.0",
3175
+ "minipass": "^7.1.2",
3176
+ "minizlib": "^3.0.1",
3177
+ "mkdirp": "^3.0.1",
3178
+ "yallist": "^5.0.0"
3179
+ },
3180
+ "engines": {
3181
+ "node": ">=18"
3182
+ }
3183
+ },
3184
+ "node_modules/tar/node_modules/yallist": {
3185
+ "version": "5.0.0",
3186
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz",
3187
+ "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==",
3188
+ "license": "BlueOak-1.0.0",
3189
+ "engines": {
3190
+ "node": ">=18"
3191
+ }
3192
+ },
3193
  "node_modules/tinyglobby": {
3194
  "version": "0.2.15",
3195
  "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
3196
  "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
 
3197
  "license": "MIT",
3198
  "dependencies": {
3199
  "fdir": "^6.5.0",
 
3264
  "version": "7.1.5",
3265
  "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.5.tgz",
3266
  "integrity": "sha512-4cKBO9wR75r0BeIWWWId9XK9Lj6La5X846Zw9dFfzMRw38IlTk2iCcUt6hsyiDRcPidc55ZParFYDXi0nXOeLQ==",
 
3267
  "license": "MIT",
3268
  "dependencies": {
3269
  "esbuild": "^0.25.0",
frontend/package.json CHANGED
@@ -10,8 +10,10 @@
10
  "preview": "vite preview"
11
  },
12
  "dependencies": {
 
13
  "react": "^19.1.1",
14
- "react-dom": "^19.1.1"
 
15
  },
16
  "devDependencies": {
17
  "@eslint/js": "^9.33.0",
 
10
  "preview": "vite preview"
11
  },
12
  "dependencies": {
13
+ "@tailwindcss/vite": "^4.1.13",
14
  "react": "^19.1.1",
15
+ "react-dom": "^19.1.1",
16
+ "tailwindcss": "^4.1.13"
17
  },
18
  "devDependencies": {
19
  "@eslint/js": "^9.33.0",
frontend/src/App.css CHANGED
@@ -1,42 +0,0 @@
1
- #root {
2
- max-width: 1280px;
3
- margin: 0 auto;
4
- padding: 2rem;
5
- text-align: center;
6
- }
7
-
8
- .logo {
9
- height: 6em;
10
- padding: 1.5em;
11
- will-change: filter;
12
- transition: filter 300ms;
13
- }
14
- .logo:hover {
15
- filter: drop-shadow(0 0 2em #646cffaa);
16
- }
17
- .logo.react:hover {
18
- filter: drop-shadow(0 0 2em #61dafbaa);
19
- }
20
-
21
- @keyframes logo-spin {
22
- from {
23
- transform: rotate(0deg);
24
- }
25
- to {
26
- transform: rotate(360deg);
27
- }
28
- }
29
-
30
- @media (prefers-reduced-motion: no-preference) {
31
- a:nth-of-type(2) .logo {
32
- animation: logo-spin infinite 20s linear;
33
- }
34
- }
35
-
36
- .card {
37
- padding: 2em;
38
- }
39
-
40
- .read-the-docs {
41
- color: #888;
42
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
frontend/src/App.jsx CHANGED
@@ -1,26 +1,86 @@
1
- import { useEffect, useState } from "react";
2
- import reactLogo from './assets/react.svg'
3
- import viteLogo from '/vite.svg'
4
- import './App.css'
5
 
 
 
 
 
 
 
6
 
 
 
 
 
 
7
 
8
- function App() {
9
- const [message, setMessage] = useState("");
 
 
 
 
10
 
11
- useEffect(() => {
12
- fetch("/api/hello") // backend dev server
13
- .then(res => res.json())
14
- .then(data => setMessage(data.Hello))
15
- .catch(err => console.error(err));
16
- }, []);
 
 
 
 
 
 
 
 
17
 
18
  return (
19
- <div style={{ textAlign: "center", marginTop: "2rem" }}>
20
- <h1>React + FastAPI</h1>
21
- <p>Message from backend: {message}</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  </div>
23
  );
24
  }
25
-
26
- export default App;
 
1
+ import { useState } from "react";
2
+ import ModelInputBar from "./components/ModelInputBar";
3
+ import ModelLayersCard from "./components/ModelLayersCard";
 
4
 
5
+ export default function App() {
6
+ const [modelName, setModelName] = useState("");
7
+ const [selectedOption, setSelectedOption] = useState("none");
8
+ const [structure, setStructure] = useState(null);
9
+ const [loading, setLoading] = useState(false);
10
+ const [error, setError] = useState("");
11
 
12
+ const fetchModelStructure = async () => {
13
+ if (!modelName) return;
14
+ setLoading(true);
15
+ setError("");
16
+ setStructure(null);
17
 
18
+ try {
19
+ // append options as query params when provided
20
+ const params = new URLSearchParams({ name: modelName });
21
+ if (selectedOption && selectedOption !== "none") {
22
+ params.append("model_type", selectedOption);
23
+ }
24
 
25
+ const res = await fetch(`/api/model?${params.toString()}`);
26
+ if (!res.ok) {
27
+ throw new Error(`Error: ${res.status}`);
28
+ }
29
+ const data = await res.json();
30
+ console.log("data: ", data)
31
+ setStructure(data?.data);
32
+ } catch (err) {
33
+ console.log('err: ', err)
34
+ setError("Failed to fetch model structure. Please check the model name.");
35
+ } finally {
36
+ setLoading(false);
37
+ }
38
+ };
39
 
40
  return (
41
+ <div className="min-h-screen bg-gradient-to-br from-slate-100 to-slate-200 flex flex-col items-center p-6">
42
+ <div className="w-full max-w-3xl bg-white rounded-2xl shadow-lg p-6">
43
+ {/* Header */}
44
+ <h1 className="text-3xl font-bold text-center text-slate-800 mb-4">
45
+ Hugging Face Model Structure Viewer
46
+ </h1>
47
+ <p className="text-center text-slate-500 mb-6">
48
+ Enter a model name (e.g. <code>deepseek-ai/deepseek-moe-16b-base</code>) to view its
49
+ architecture.
50
+ </p>
51
+
52
+ {/* Input Bar */}
53
+ <ModelInputBar
54
+ modelName={modelName}
55
+ setModelName={setModelName}
56
+ selectedOption={selectedOption}
57
+ setSelectedOption={setSelectedOption}
58
+ loading={loading}
59
+ fetchModelStructure={fetchModelStructure}
60
+ />
61
+ {error && (
62
+ <div className="text-red-600 text-center font-medium mb-4">{error}</div>
63
+ )}
64
+
65
+ {/* Model Structure */}
66
+ {structure && (
67
+ <div className="max-h-[500px] overflow-y-auto bg-slate-50 rounded-xl p-4 border border-slate-200 shadow-inner">
68
+ <pre className="text-sm text-slate-800 whitespace-pre-wrap">
69
+ {structure.model_type}
70
+ </pre>
71
+ </div>
72
+ )}
73
+ </div>
74
+
75
+ {/* Model Layers Card */}
76
+ {structure && (
77
+ <ModelLayersCard layers={structure?.layers?.children || {}} />
78
+ )}
79
+
80
+ {/* Footer */}
81
+ <footer className="mt-8 text-slate-500 text-sm text-center">
82
+ Built with React + FastAPI
83
+ </footer>
84
  </div>
85
  );
86
  }
 
 
frontend/src/components/ModelInputBar.jsx ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState } from "react";
2
+
3
+ export default function ModelInputBar({ modelName, setModelName, selectedOption, setSelectedOption, loading, fetchModelStructure }) {
4
+ // Single selection: user can pick one of several fetch options
5
+ const options = [
6
+ { label: "Not Sure", value: "none" },
7
+ { label: "Causal Language Models (e.g. GPT, LLaMA, Phi, Mistral)", value: "causal" },
8
+ { label: "Masked Language Models (BERT, RoBERTa, DistilBERT)", value: "masked" },
9
+ { label: "Sequence Classification (text classification, sentiment analysis)", value: "sequence" },
10
+ { label: "Token Classification (NER, POS tagging)", value: "token" },
11
+ { label: "Question Answering Models (e.g. BERT QA, RoBERTa QA)", value: "qa" },
12
+ { label: "Text Generation Models (e.g. T5, BART)", value: "generation" },
13
+ { label: "Seq2Seq (encoder-decoder, e.g. T5, BART, MarianMT)", value: "s2s" },
14
+ { label: "Vision models (image classification, CLIP vision tower, etc.)", value: "vision" },
15
+ ];
16
+
17
+ // const [selectedOption, setSelectedOption] = useState(options[0].value);
18
+
19
+ const handleFetch = () => {
20
+ fetchModelStructure();
21
+ };
22
+
23
+ return (
24
+ <div className="flex flex-col gap-2 mb-4 w-full">
25
+ <div className="flex gap-2 w-full">
26
+ <input
27
+ type="text"
28
+ value={modelName}
29
+ onChange={(e) => setModelName(e.target.value)}
30
+ placeholder="e.g. deepseek-ai/deepseek-moe-16b-base"
31
+ className="flex-1 px-4 py-2 rounded-lg border border-slate-200 focus:outline-none focus:ring-2 focus:ring-sky-300"
32
+ onKeyDown={(e) => {
33
+ if (e.key === "Enter") handleFetch();
34
+ }}
35
+ aria-label="Model name"
36
+ />
37
+
38
+ <button
39
+ onClick={handleFetch}
40
+ disabled={loading}
41
+ className={`px-4 py-2 rounded-lg font-medium text-white ${
42
+ loading ? "bg-slate-400 cursor-wait" : "bg-sky-600 hover:bg-sky-700"
43
+ }`}
44
+ >
45
+ {loading ? "Loading..." : "Fetch"}
46
+ </button>
47
+ </div>
48
+
49
+ <div className="flex flex-wrap items-center gap-4 text-sm text-slate-700">
50
+ {options.map((option) => (
51
+ <label key={option.value} className="flex items-center gap-2">
52
+ <input
53
+ type="radio"
54
+ name="fetchOption"
55
+ value={option.value}
56
+ checked={selectedOption === option.value}
57
+ onChange={(e) => setSelectedOption(e.target.value)}
58
+ className="w-4 h-4"
59
+ />
60
+ <span>{option.label}</span>
61
+ </label>
62
+ ))}
63
+ </div>
64
+ </div>
65
+ );
66
+ }
frontend/src/components/ModelLayersCard.jsx ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from "react";
2
+
3
+ function LayerNode({ node }) {
4
+ if (!node) return null;
5
+
6
+ const name = node.class_name || node.name || "<unknown>";
7
+ const shape = node.params?.weight?.shape || [];
8
+
9
+ // Normalize children: object map
10
+ let children = [];
11
+ if (node.children && typeof node.children === "object") {
12
+ children = Object.values(node.children);
13
+ }
14
+
15
+ return (
16
+ <div className="pl-2">
17
+ <div className="flex items-center gap-2">
18
+ <div className="text-sm text-slate-800 font-medium">{name}</div>
19
+ <div className="text-xs text-slate-500">{shape.join(" x ")}</div>
20
+ </div>
21
+
22
+ {children.length > 0 && (
23
+ <div className="pl-4 mt-2 border-l border-slate-100">
24
+ {children.map((child, idx) => (
25
+ <LayerNode key={idx} node={child} />
26
+ ))}
27
+ </div>
28
+ )}
29
+ </div>
30
+ );
31
+ }
32
+
33
+ export default function ModelLayersCard({ layers = {} }) {
34
+ let rootNodes = [];
35
+
36
+ if (layers && typeof layers === "object") {
37
+ if (layers.children && typeof layers.children === "object") {
38
+ rootNodes = Object.values(layers.children);
39
+ } else {
40
+ // Fallback: convert the top-level keyed object into an array
41
+ rootNodes = Object.values(layers);
42
+ }
43
+ }
44
+
45
+ if (!rootNodes || rootNodes.length === 0) {
46
+ return null;
47
+ }
48
+
49
+ return (
50
+ <div className="w-full max-w-3xl mt-6 bg-white rounded-2xl shadow-lg p-4">
51
+ <h2 className="text-lg font-semibold text-slate-800 mb-3">Model Layers</h2>
52
+ <div className="space-y-2">
53
+ {rootNodes.map((node, idx) => (
54
+ <LayerNode key={idx} node={node} />
55
+ ))}
56
+ </div>
57
+ </div>
58
+ );
59
+ }
frontend/src/index.css CHANGED
@@ -1,68 +1 @@
1
- :root {
2
- font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
3
- line-height: 1.5;
4
- font-weight: 400;
5
-
6
- color-scheme: light dark;
7
- color: rgba(255, 255, 255, 0.87);
8
- background-color: #242424;
9
-
10
- font-synthesis: none;
11
- text-rendering: optimizeLegibility;
12
- -webkit-font-smoothing: antialiased;
13
- -moz-osx-font-smoothing: grayscale;
14
- }
15
-
16
- a {
17
- font-weight: 500;
18
- color: #646cff;
19
- text-decoration: inherit;
20
- }
21
- a:hover {
22
- color: #535bf2;
23
- }
24
-
25
- body {
26
- margin: 0;
27
- display: flex;
28
- place-items: center;
29
- min-width: 320px;
30
- min-height: 100vh;
31
- }
32
-
33
- h1 {
34
- font-size: 3.2em;
35
- line-height: 1.1;
36
- }
37
-
38
- button {
39
- border-radius: 8px;
40
- border: 1px solid transparent;
41
- padding: 0.6em 1.2em;
42
- font-size: 1em;
43
- font-weight: 500;
44
- font-family: inherit;
45
- background-color: #1a1a1a;
46
- cursor: pointer;
47
- transition: border-color 0.25s;
48
- }
49
- button:hover {
50
- border-color: #646cff;
51
- }
52
- button:focus,
53
- button:focus-visible {
54
- outline: 4px auto -webkit-focus-ring-color;
55
- }
56
-
57
- @media (prefers-color-scheme: light) {
58
- :root {
59
- color: #213547;
60
- background-color: #ffffff;
61
- }
62
- a:hover {
63
- color: #747bff;
64
- }
65
- button {
66
- background-color: #f9f9f9;
67
- }
68
- }
 
1
+ @import "tailwindcss";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
frontend/vite.config.js CHANGED
@@ -1,8 +1,12 @@
1
  import { defineConfig } from 'vite'
2
  import react from '@vitejs/plugin-react'
 
3
 
4
  export default defineConfig({
5
- plugins: [react()],
 
 
 
6
  server: {
7
  proxy: {
8
  '/api': {
 
1
  import { defineConfig } from 'vite'
2
  import react from '@vitejs/plugin-react'
3
+ import tailwindcss from '@tailwindcss/vite'
4
 
5
  export default defineConfig({
6
+ plugins: [
7
+ react(),
8
+ tailwindcss(),
9
+ ],
10
  server: {
11
  proxy: {
12
  '/api': {