add search to gallery page

This commit is contained in:
Brian Beck 2025-12-20 15:03:11 -08:00
parent 5abc2a6647
commit 69de613bae
28 changed files with 367 additions and 131 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
.gallery-module__zlwOTG__GalleryPage{flex-direction:column}.gallery-module__zlwOTG__Tools{text-align:center;z-index:2;background:rgba(0,0,0,.7);flex:none;grid-template-columns:1fr auto 1fr;justify-content:space-between;align-items:center;gap:10px;padding:10px;display:grid;position:-webkit-sticky;position:sticky;top:0}.gallery-module__zlwOTG__Tools select:focus{outline:none;box-shadow:0 0 1px 1px rgba(0,0,0,.5),0 0 2px 3px #98ffd4}.gallery-module__zlwOTG__HeaderEnd{justify-content:space-between;align-items:center;gap:20px;display:flex}.gallery-module__zlwOTG__DownloadSection{align-items:center;gap:8px;display:flex}.gallery-module__zlwOTG__PackVersion{color:rgba(127,180,166,.6);font-size:11px}.gallery-module__zlwOTG__DownloadButton{color:#f7ffdc;letter-spacing:-.03em;text-shadow:0 -1px rgba(25,39,34,.4);cursor:pointer;background:0 0,linear-gradient(#43a782,#0f5957);border:0;border-radius:4px;margin-left:3px;padding:4px 8px 5px;font-size:13px;font-weight:500;text-decoration:none;display:inline-block}.gallery-module__zlwOTG__DownloadButton:active{transform:translateY(1px)}.gallery-module__zlwOTG__Back{color:#fff;justify-self:start;align-items:center;gap:4px;font-size:14px;text-decoration:none;display:inline-flex}.gallery-module__zlwOTG__IconLink{color:rgba(255,255,255,.3);place-content:center;justify-self:end;margin-left:auto;display:grid}.gallery-module__zlwOTG__IconLink:hover{color:#fff}.gallery-module__zlwOTG__Gallery{background:#0c1f28;flex:none;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));width:100%;display:grid}.gallery-module__zlwOTG__Skin{text-align:center;padding-bottom:32px;font-size:12px;position:relative;overflow:hidden}.gallery-module__zlwOTG__Preview{width:100%;height:auto;display:block}.gallery-module__zlwOTG__DownloadHiRes{align-items:center;gap:.5em;margin-left:auto;font-size:11px;display:flex}.gallery-module__zlwOTG__HiResSelect{font-size:11px}.gallery-module__zlwOTG__Detail{background:rgba(0,0,0,.2);border-radius:6px;justify-content:space-between;align-items:center;gap:8px;padding:5px 9px;display:flex;position:absolute;bottom:8px;left:6px;right:6px;box-shadow:inset 0 1px 10px rgba(0,0,0,.3)}.gallery-module__zlwOTG__LoadInEditor,.gallery-module__zlwOTG__DownloadSkin{color:#28d9b2;visibility:hidden;place-content:center;font-size:24px;display:grid}.gallery-module__zlwOTG__DownloadSkin{cursor:pointer;background:0 0;border:0;margin:0;padding:0;font-size:17px}.gallery-module__zlwOTG__Detail:hover .gallery-module__zlwOTG__LoadInEditor,.gallery-module__zlwOTG__Detail:hover .gallery-module__zlwOTG__DownloadSkin{visibility:visible}.gallery-module__zlwOTG__Name{white-space:nowrap;color:rgba(158,192,209,.9);border-radius:9999px;padding:3px 10px}.gallery-module__zlwOTG__Detail:hover .gallery-module__zlwOTG__Name{color:#fff}@keyframes gallery-module__zlwOTG__spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.gallery-module__zlwOTG__Spinner{flex:none;margin:auto;font-size:64px;animation:2s linear infinite gallery-module__zlwOTG__spin}.gallery-module__zlwOTG__DownloadSpinner{flex:none;margin:auto;font-size:20px;animation:2s linear infinite gallery-module__zlwOTG__spin}@media (max-width:1023px){.gallery-module__zlwOTG__Tools{grid-template-columns:auto auto 1fr;justify-content:space-between}}@media (max-width:719px){.gallery-module__zlwOTG__PackVersion{display:none}}@media (max-width:639px){.gallery-module__zlwOTG__Back .gallery-module__zlwOTG__Label,.gallery-module__zlwOTG__DownloadButton,.gallery-module__zlwOTG__DownloadHiRes{display:none}.gallery-module__zlwOTG__Tools{grid-template-columns:1fr auto 1fr}}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
.gallery-module__zlwOTG__GalleryPage{flex-direction:column}.gallery-module__zlwOTG__Tools{text-align:center;z-index:2;background:rgba(0,0,0,.7);flex:none;grid-template-columns:1fr auto 1fr;justify-content:space-between;align-items:center;gap:10px;padding:10px;display:grid;position:-webkit-sticky;position:sticky;top:0}.gallery-module__zlwOTG__Tools a:link:focus-visible{outline:none;box-shadow:0 0 1px 1px rgba(0,0,0,.5),0 0 2px 3px #98ffd4}.gallery-module__zlwOTG__Tools button:focus-visible{outline:none;box-shadow:0 0 1px 1px rgba(0,0,0,.5),0 0 2px 3px #98ffd4}.gallery-module__zlwOTG__Tools select:focus-visible{outline:none;box-shadow:0 0 1px 1px rgba(0,0,0,.5),0 0 2px 3px #98ffd4}.gallery-module__zlwOTG__Tools input:focus-visible{outline:none;box-shadow:0 0 1px 1px rgba(0,0,0,.5),0 0 2px 3px #98ffd4}.gallery-module__zlwOTG__InputContainer{position:relative}.gallery-module__zlwOTG__HeaderEnd{justify-content:space-between;align-items:center;gap:20px;display:flex}.gallery-module__zlwOTG__DownloadSection{align-items:center;gap:8px;display:flex}.gallery-module__zlwOTG__PackVersion{color:rgba(127,180,166,.6);font-size:11px}.gallery-module__zlwOTG__DownloadButton{color:#f7ffdc;letter-spacing:-.03em;text-shadow:0 -1px rgba(25,39,34,.4);cursor:pointer;background:0 0,linear-gradient(#43a782,#0f5957);border:0;border-radius:3px;margin:0 0 0 3px;padding:4px 8px;font-size:13px;font-weight:500;text-decoration:none;display:inline-block}.gallery-module__zlwOTG__DownloadButton:active{transform:translateY(1px)}.gallery-module__zlwOTG__Back{color:#fff;justify-self:start;align-items:center;gap:4px;font-size:14px;text-decoration:none;display:inline-flex}.gallery-module__zlwOTG__IconLink{color:rgba(255,255,255,.3);place-content:center;justify-self:end;margin-left:auto;display:grid}.gallery-module__zlwOTG__IconLink:hover{color:#fff}.gallery-module__zlwOTG__Gallery{background:#0c1f28;flex:none;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));width:100%;display:grid}.gallery-module__zlwOTG__Skin{text-align:center;padding-bottom:32px;font-size:12px;position:relative;overflow:hidden}.gallery-module__zlwOTG__Preview{width:100%;height:auto;display:block}.gallery-module__zlwOTG__DownloadHiRes{align-items:center;gap:.5em;margin-left:auto;font-size:11px;display:flex}.gallery-module__zlwOTG__HiResSelect{font-size:11px}.gallery-module__zlwOTG__Detail{background:rgba(0,0,0,.2);border-radius:6px;justify-content:space-between;align-items:center;gap:8px;padding:5px 9px;display:flex;position:absolute;bottom:8px;left:6px;right:6px;box-shadow:inset 0 1px 10px rgba(0,0,0,.3)}.gallery-module__zlwOTG__LoadInEditor,.gallery-module__zlwOTG__DownloadSkin{color:#28d9b2;visibility:hidden;place-content:center;font-size:24px;display:grid}.gallery-module__zlwOTG__DownloadSkin{cursor:pointer;background:0 0;border:0;margin:0;padding:0;font-size:17px}.gallery-module__zlwOTG__Detail:hover .gallery-module__zlwOTG__LoadInEditor,.gallery-module__zlwOTG__Detail:hover .gallery-module__zlwOTG__DownloadSkin{visibility:visible}.gallery-module__zlwOTG__Name{white-space:nowrap;color:rgba(158,192,209,.9);border-radius:9999px;padding:3px 10px}.gallery-module__zlwOTG__Detail:hover .gallery-module__zlwOTG__Name{color:#fff}@keyframes gallery-module__zlwOTG__spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.gallery-module__zlwOTG__Spinner{flex:none;margin:auto;font-size:64px;animation:2s linear infinite gallery-module__zlwOTG__spin}.gallery-module__zlwOTG__DownloadSpinner{flex:none;margin:auto;font-size:20px;animation:2s linear infinite gallery-module__zlwOTG__spin}.gallery-module__zlwOTG__HeaderMain{align-items:center;gap:12px;display:flex}.gallery-module__zlwOTG__SearchButton{color:#28d9b2;cursor:pointer;background:0 0;border:0;place-content:center;margin:0;padding:3px 4px;font-size:18px;display:grid}.gallery-module__zlwOTG__SearchInput{border:1px solid #666;border-radius:2px;margin:0;padding:4px 6px 3px;position:absolute;left:0;right:0}@media (max-width:1023px){.gallery-module__zlwOTG__Tools{grid-template-columns:auto auto 1fr;justify-content:space-between}}@media (max-width:719px){.gallery-module__zlwOTG__PackVersion{display:none}}@media (max-width:639px){.gallery-module__zlwOTG__Back .gallery-module__zlwOTG__Label,.gallery-module__zlwOTG__DownloadButton,.gallery-module__zlwOTG__DownloadHiRes{display:none}.gallery-module__zlwOTG__Tools{grid-template-columns:1fr auto 1fr}}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,21 +1,22 @@
1:"$Sreact.fragment" 1:"$Sreact.fragment"
2:I[39756,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"default"] 2:I[12985,["/t2-model-skinner/_next/static/chunks/993ba35625024c1a.js"],"NuqsAdapter"]
3:I[37457,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"default"] 3:I[39756,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"default"]
4:I[47257,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"ClientPageRoot"] 4:I[37457,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"default"]
5:I[25500,["/t2-model-skinner/_next/static/chunks/64f1e5c6f9fa52f6.js","/t2-model-skinner/_next/static/chunks/d63fc3798baf75bd.js","/t2-model-skinner/_next/static/chunks/5ab6fafee44106c4.js","/t2-model-skinner/_next/static/chunks/e233a54f1de7eeb5.js"],"default"] 5:I[47257,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"ClientPageRoot"]
8:I[97367,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"OutletBoundary"] 6:I[25500,["/t2-model-skinner/_next/static/chunks/993ba35625024c1a.js","/t2-model-skinner/_next/static/chunks/64f1e5c6f9fa52f6.js","/t2-model-skinner/_next/static/chunks/d63fc3798baf75bd.js","/t2-model-skinner/_next/static/chunks/d9f21d966613a96e.js","/t2-model-skinner/_next/static/chunks/40cecef8385b39df.js"],"default"]
a:I[11533,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"AsyncMetadataOutlet"] 9:I[97367,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"OutletBoundary"]
c:I[97367,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"ViewportBoundary"] b:I[11533,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"AsyncMetadataOutlet"]
e:I[97367,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"MetadataBoundary"] d:I[97367,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"ViewportBoundary"]
f:"$Sreact.suspense" f:I[97367,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"MetadataBoundary"]
11:I[68027,[],"default"] 10:"$Sreact.suspense"
12:I[68027,["/t2-model-skinner/_next/static/chunks/993ba35625024c1a.js"],"default"]
:HL["/t2-model-skinner/_next/static/chunks/795c34bef1c92210.css","style"] :HL["/t2-model-skinner/_next/static/chunks/795c34bef1c92210.css","style"]
:HL["/t2-model-skinner/_next/static/chunks/185de9d007942943.css","style"] :HL["/t2-model-skinner/_next/static/chunks/42cdb402ed9b36c5.css","style"]
0:{"P":null,"b":"j6qxrfkqjS29T75m1W9mo","p":"/t2-model-skinner","c":["","gallery",""],"i":false,"f":[[["",{"children":["gallery",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/t2-model-skinner/_next/static/chunks/795c34bef1c92210.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]]}],{"children":["gallery",["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":["__PAGE__",["$","$1","c",{"children":[["$","$L4",null,{"Component":"$5","searchParams":{},"params":{},"promises":["$@6","$@7"]}],[["$","link","0",{"rel":"stylesheet","href":"/t2-model-skinner/_next/static/chunks/185de9d007942943.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/t2-model-skinner/_next/static/chunks/64f1e5c6f9fa52f6.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/t2-model-skinner/_next/static/chunks/d63fc3798baf75bd.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/t2-model-skinner/_next/static/chunks/5ab6fafee44106c4.js","async":true,"nonce":"$undefined"}],["$","script","script-3",{"src":"/t2-model-skinner/_next/static/chunks/e233a54f1de7eeb5.js","async":true,"nonce":"$undefined"}]],["$","$L8",null,{"children":["$L9",["$","$La",null,{"promise":"$@b"}]]}]]}],{},null,false]},null,false]},null,false],["$","$1","h",{"children":[null,[["$","$Lc",null,{"children":"$Ld"}],null],["$","$Le",null,{"children":["$","div",null,{"hidden":true,"children":["$","$f",null,{"fallback":null,"children":"$L10"}]}]}]]}],false]],"m":"$undefined","G":["$11",[["$","link","0",{"rel":"stylesheet","href":"/t2-model-skinner/_next/static/chunks/795c34bef1c92210.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]]],"s":false,"S":true} 0:{"P":null,"b":"J3alfdEmlnJa3MT95j6-5","p":"/t2-model-skinner","c":["","gallery",""],"i":false,"f":[[["",{"children":["gallery",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/t2-model-skinner/_next/static/chunks/795c34bef1c92210.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/t2-model-skinner/_next/static/chunks/993ba35625024c1a.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L2",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L4",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]}]]}],{"children":["gallery",["$","$1","c",{"children":[null,["$","$L3",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L4",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":["__PAGE__",["$","$1","c",{"children":[["$","$L5",null,{"Component":"$6","searchParams":{},"params":{},"promises":["$@7","$@8"]}],[["$","link","0",{"rel":"stylesheet","href":"/t2-model-skinner/_next/static/chunks/42cdb402ed9b36c5.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/t2-model-skinner/_next/static/chunks/64f1e5c6f9fa52f6.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/t2-model-skinner/_next/static/chunks/d63fc3798baf75bd.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/t2-model-skinner/_next/static/chunks/d9f21d966613a96e.js","async":true,"nonce":"$undefined"}],["$","script","script-3",{"src":"/t2-model-skinner/_next/static/chunks/40cecef8385b39df.js","async":true,"nonce":"$undefined"}]],["$","$L9",null,{"children":["$La",["$","$Lb",null,{"promise":"$@c"}]]}]]}],{},null,false]},null,false]},null,false],["$","$1","h",{"children":[null,[["$","$Ld",null,{"children":"$Le"}],null],["$","$Lf",null,{"children":["$","div",null,{"hidden":true,"children":["$","$10",null,{"fallback":null,"children":"$L11"}]}]}]]}],false]],"m":"$undefined","G":["$12",[["$","link","0",{"rel":"stylesheet","href":"/t2-model-skinner/_next/static/chunks/795c34bef1c92210.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]]],"s":false,"S":true}
6:{} 7:{}
7:"$0:f:0:1:2:children:2:children:1:props:children:0:props:params" 8:"$0:f:0:1:2:children:2:children:1:props:children:0:props:params"
d:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]] e:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
9:null a:null
12:I[27201,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"IconMark"] 13:I[27201,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"IconMark"]
b:{"metadata":[["$","title","0",{"children":"T2 Model Viewer & Skinner"}],["$","meta","1",{"name":"description","content":"Get skinned. 😎"}],["$","link","2",{"rel":"icon","href":"/t2-model-skinner/icon.png?icon.2911bba1.png","sizes":"108x128","type":"image/png"}],["$","$L12","3",{}]],"error":null,"digest":"$undefined"} c:{"metadata":[["$","title","0",{"children":"T2 Model Viewer & Skinner"}],["$","meta","1",{"name":"description","content":"Get skinned. 😎"}],["$","link","2",{"rel":"icon","href":"/t2-model-skinner/icon.png?icon.2911bba1.png","sizes":"108x128","type":"image/png"}],["$","$L13","3",{}]],"error":null,"digest":"$undefined"}
10:"$b:metadata" 11:"$c:metadata"

File diff suppressed because one or more lines are too long

View file

@ -1,21 +1,22 @@
1:"$Sreact.fragment" 1:"$Sreact.fragment"
2:I[39756,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"default"] 2:I[12985,["/t2-model-skinner/_next/static/chunks/993ba35625024c1a.js"],"NuqsAdapter"]
3:I[37457,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"default"] 3:I[39756,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"default"]
4:I[47257,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"ClientPageRoot"] 4:I[37457,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"default"]
5:I[52683,["/t2-model-skinner/_next/static/chunks/502774dbda501837.js","/t2-model-skinner/_next/static/chunks/d63fc3798baf75bd.js","/t2-model-skinner/_next/static/chunks/43ceca71888c9b70.js","/t2-model-skinner/_next/static/chunks/d92306cd027784a6.js","/t2-model-skinner/_next/static/chunks/a55df98dcb3b60ad.js"],"default"] 5:I[47257,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"ClientPageRoot"]
8:I[97367,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"OutletBoundary"] 6:I[52683,["/t2-model-skinner/_next/static/chunks/993ba35625024c1a.js","/t2-model-skinner/_next/static/chunks/502774dbda501837.js","/t2-model-skinner/_next/static/chunks/d63fc3798baf75bd.js","/t2-model-skinner/_next/static/chunks/43ceca71888c9b70.js","/t2-model-skinner/_next/static/chunks/5f9470a691b55cfe.js","/t2-model-skinner/_next/static/chunks/a55df98dcb3b60ad.js"],"default"]
a:I[11533,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"AsyncMetadataOutlet"] 9:I[97367,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"OutletBoundary"]
c:I[97367,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"ViewportBoundary"] b:I[11533,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"AsyncMetadataOutlet"]
e:I[97367,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"MetadataBoundary"] d:I[97367,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"ViewportBoundary"]
f:"$Sreact.suspense" f:I[97367,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"MetadataBoundary"]
11:I[68027,[],"default"] 10:"$Sreact.suspense"
12:I[68027,["/t2-model-skinner/_next/static/chunks/993ba35625024c1a.js"],"default"]
:HL["/t2-model-skinner/_next/static/chunks/795c34bef1c92210.css","style"] :HL["/t2-model-skinner/_next/static/chunks/795c34bef1c92210.css","style"]
:HL["/t2-model-skinner/_next/static/chunks/df18f9fdc6a3cb7c.css","style"] :HL["/t2-model-skinner/_next/static/chunks/df18f9fdc6a3cb7c.css","style"]
0:{"P":null,"b":"j6qxrfkqjS29T75m1W9mo","p":"/t2-model-skinner","c":["",""],"i":false,"f":[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/t2-model-skinner/_next/static/chunks/795c34bef1c92210.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]]}],{"children":["__PAGE__",["$","$1","c",{"children":[["$","$L4",null,{"Component":"$5","searchParams":{},"params":{},"promises":["$@6","$@7"]}],[["$","link","0",{"rel":"stylesheet","href":"/t2-model-skinner/_next/static/chunks/df18f9fdc6a3cb7c.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/t2-model-skinner/_next/static/chunks/502774dbda501837.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/t2-model-skinner/_next/static/chunks/d63fc3798baf75bd.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/t2-model-skinner/_next/static/chunks/43ceca71888c9b70.js","async":true,"nonce":"$undefined"}],["$","script","script-3",{"src":"/t2-model-skinner/_next/static/chunks/d92306cd027784a6.js","async":true,"nonce":"$undefined"}],["$","script","script-4",{"src":"/t2-model-skinner/_next/static/chunks/a55df98dcb3b60ad.js","async":true,"nonce":"$undefined"}]],["$","$L8",null,{"children":["$L9",["$","$La",null,{"promise":"$@b"}]]}]]}],{},null,false]},null,false],["$","$1","h",{"children":[null,[["$","$Lc",null,{"children":"$Ld"}],null],["$","$Le",null,{"children":["$","div",null,{"hidden":true,"children":["$","$f",null,{"fallback":null,"children":"$L10"}]}]}]]}],false]],"m":"$undefined","G":["$11",[["$","link","0",{"rel":"stylesheet","href":"/t2-model-skinner/_next/static/chunks/795c34bef1c92210.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]]],"s":false,"S":true} 0:{"P":null,"b":"J3alfdEmlnJa3MT95j6-5","p":"/t2-model-skinner","c":["",""],"i":false,"f":[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/t2-model-skinner/_next/static/chunks/795c34bef1c92210.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/t2-model-skinner/_next/static/chunks/993ba35625024c1a.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L2",null,{"children":["$","$L3",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L4",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]}]]}],{"children":["__PAGE__",["$","$1","c",{"children":[["$","$L5",null,{"Component":"$6","searchParams":{},"params":{},"promises":["$@7","$@8"]}],[["$","link","0",{"rel":"stylesheet","href":"/t2-model-skinner/_next/static/chunks/df18f9fdc6a3cb7c.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/t2-model-skinner/_next/static/chunks/502774dbda501837.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/t2-model-skinner/_next/static/chunks/d63fc3798baf75bd.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/t2-model-skinner/_next/static/chunks/43ceca71888c9b70.js","async":true,"nonce":"$undefined"}],["$","script","script-3",{"src":"/t2-model-skinner/_next/static/chunks/5f9470a691b55cfe.js","async":true,"nonce":"$undefined"}],["$","script","script-4",{"src":"/t2-model-skinner/_next/static/chunks/a55df98dcb3b60ad.js","async":true,"nonce":"$undefined"}]],["$","$L9",null,{"children":["$La",["$","$Lb",null,{"promise":"$@c"}]]}]]}],{},null,false]},null,false],["$","$1","h",{"children":[null,[["$","$Ld",null,{"children":"$Le"}],null],["$","$Lf",null,{"children":["$","div",null,{"hidden":true,"children":["$","$10",null,{"fallback":null,"children":"$L11"}]}]}]]}],false]],"m":"$undefined","G":["$12",[["$","link","0",{"rel":"stylesheet","href":"/t2-model-skinner/_next/static/chunks/795c34bef1c92210.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]]],"s":false,"S":true}
6:{} 7:{}
7:"$0:f:0:1:2:children:1:props:children:0:props:params" 8:"$0:f:0:1:2:children:1:props:children:0:props:params"
d:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]] e:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
9:null a:null
12:I[27201,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"IconMark"] 13:I[27201,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"IconMark"]
b:{"metadata":[["$","title","0",{"children":"T2 Model Viewer & Skinner"}],["$","meta","1",{"name":"description","content":"Get skinned. 😎"}],["$","link","2",{"rel":"icon","href":"/t2-model-skinner/icon.png?icon.2911bba1.png","sizes":"108x128","type":"image/png"}],["$","$L12","3",{}]],"error":null,"digest":"$undefined"} c:{"metadata":[["$","title","0",{"children":"T2 Model Viewer & Skinner"}],["$","meta","1",{"name":"description","content":"Get skinned. 😎"}],["$","link","2",{"rel":"icon","href":"/t2-model-skinner/icon.png?icon.2911bba1.png","sizes":"108x128","type":"image/png"}],["$","$L13","3",{}]],"error":null,"digest":"$undefined"}
10:"$b:metadata" 11:"$c:metadata"

114
package-lock.json generated
View file

@ -20,7 +20,9 @@
"globby": "^15.0.0", "globby": "^15.0.0",
"jszip": "^3.10.1", "jszip": "^3.10.1",
"lodash.orderby": "^4.6.0", "lodash.orderby": "^4.6.0",
"match-sorter": "^8.2.0",
"next": "^15.5.6", "next": "^15.5.6",
"nuqs": "^2.8.5",
"pngjs": "^7.0.0", "pngjs": "^7.0.0",
"react": "^19.2.0", "react": "^19.2.0",
"react-dom": "^19.2.0", "react-dom": "^19.2.0",
@ -309,6 +311,15 @@
"node": ">=6.0.0" "node": ">=6.0.0"
} }
}, },
"node_modules/@babel/runtime": {
"version": "7.28.4",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz",
"integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/template": { "node_modules/@babel/template": {
"version": "7.27.2", "version": "7.27.2",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
@ -1582,6 +1593,12 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/@standard-schema/spec": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz",
"integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==",
"license": "MIT"
},
"node_modules/@swc/helpers": { "node_modules/@swc/helpers": {
"version": "0.5.15", "version": "0.5.15",
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
@ -5304,6 +5321,16 @@
"semver": "bin/semver.js" "semver": "bin/semver.js"
} }
}, },
"node_modules/match-sorter": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-8.2.0.tgz",
"integrity": "sha512-qRVB7wYMJXizAWR4TKo5UYwgW7oAVzA8V9jve0wGzRvV91ou9dcqL+/2gJtD0PZ/Pm2Fq6cVT4VHXHmDFVMGRA==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.23.8",
"remove-accents": "0.5.0"
}
},
"node_modules/math-intrinsics": { "node_modules/math-intrinsics": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
@ -5474,9 +5501,9 @@
"devOptional": true "devOptional": true
}, },
"node_modules/nan": { "node_modules/nan": {
"version": "2.23.0", "version": "2.24.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.23.0.tgz", "resolved": "https://registry.npmjs.org/nan/-/nan-2.24.0.tgz",
"integrity": "sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ==", "integrity": "sha512-Vpf9qnVW1RaDkoNKFUvfxqAbtI8ncb8OJlqZ9wwpXzWPEsvsB1nvdUi6oYrHIkQ1Y/tMDnr1h4nczS0VB9Xykg==",
"license": "MIT", "license": "MIT",
"optional": true "optional": true
}, },
@ -5516,6 +5543,7 @@
"resolved": "https://registry.npmjs.org/next/-/next-15.5.6.tgz", "resolved": "https://registry.npmjs.org/next/-/next-15.5.6.tgz",
"integrity": "sha512-zTxsnI3LQo3c9HSdSf91O1jMNsEzIXDShXd4wVdg9y5shwLqBXi4ZtUUJyB86KGVSJLZx0PFONvO54aheGX8QQ==", "integrity": "sha512-zTxsnI3LQo3c9HSdSf91O1jMNsEzIXDShXd4wVdg9y5shwLqBXi4ZtUUJyB86KGVSJLZx0PFONvO54aheGX8QQ==",
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@next/env": "15.5.6", "@next/env": "15.5.6",
"@swc/helpers": "0.5.15", "@swc/helpers": "0.5.15",
@ -5668,6 +5696,43 @@
"set-blocking": "^2.0.0" "set-blocking": "^2.0.0"
} }
}, },
"node_modules/nuqs": {
"version": "2.8.5",
"resolved": "https://registry.npmjs.org/nuqs/-/nuqs-2.8.5.tgz",
"integrity": "sha512-ndhnNB9eLX/bsiGFkBNsrfOWf3BCbzBMD+b5GkD5o2Q96Q+llHnoUlZsrO3tgJKZZV7LLlVCvFKdj+sjBITRzg==",
"license": "MIT",
"dependencies": {
"@standard-schema/spec": "1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/franky47"
},
"peerDependencies": {
"@remix-run/react": ">=2",
"@tanstack/react-router": "^1",
"next": ">=14.2.0",
"react": ">=18.2.0 || ^19.0.0-0",
"react-router": "^5 || ^6 || ^7",
"react-router-dom": "^5 || ^6 || ^7"
},
"peerDependenciesMeta": {
"@remix-run/react": {
"optional": true
},
"@tanstack/react-router": {
"optional": true
},
"next": {
"optional": true
},
"react-router": {
"optional": true
},
"react-router-dom": {
"optional": true
}
}
},
"node_modules/nwsapi": { "node_modules/nwsapi": {
"version": "2.2.22", "version": "2.2.22",
"resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.22.tgz", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.22.tgz",
@ -6226,6 +6291,12 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/remove-accents": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.5.0.tgz",
"integrity": "sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==",
"license": "MIT"
},
"node_modules/require-from-string": { "node_modules/require-from-string": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
@ -7819,6 +7890,11 @@
"@babel/types": "^7.28.4" "@babel/types": "^7.28.4"
} }
}, },
"@babel/runtime": {
"version": "7.28.4",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz",
"integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ=="
},
"@babel/template": { "@babel/template": {
"version": "7.27.2", "version": "7.27.2",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
@ -8484,6 +8560,11 @@
"resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz",
"integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==" "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ=="
}, },
"@standard-schema/spec": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz",
"integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA=="
},
"@swc/helpers": { "@swc/helpers": {
"version": "0.5.15", "version": "0.5.15",
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
@ -11010,6 +11091,15 @@
} }
} }
}, },
"match-sorter": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-8.2.0.tgz",
"integrity": "sha512-qRVB7wYMJXizAWR4TKo5UYwgW7oAVzA8V9jve0wGzRvV91ou9dcqL+/2gJtD0PZ/Pm2Fq6cVT4VHXHmDFVMGRA==",
"requires": {
"@babel/runtime": "^7.23.8",
"remove-accents": "0.5.0"
}
},
"math-intrinsics": { "math-intrinsics": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
@ -11127,8 +11217,8 @@
"devOptional": true "devOptional": true
}, },
"nan": { "nan": {
"version": "https://registry.npmjs.org/nan/-/nan-2.23.0.tgz", "version": "https://registry.npmjs.org/nan/-/nan-2.24.0.tgz",
"integrity": "sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ==", "integrity": "sha512-Vpf9qnVW1RaDkoNKFUvfxqAbtI8ncb8OJlqZ9wwpXzWPEsvsB1nvdUi6oYrHIkQ1Y/tMDnr1h4nczS0VB9Xykg==",
"optional": true "optional": true
}, },
"nanoid": { "nanoid": {
@ -11153,6 +11243,7 @@
"version": "15.5.6", "version": "15.5.6",
"resolved": "https://registry.npmjs.org/next/-/next-15.5.6.tgz", "resolved": "https://registry.npmjs.org/next/-/next-15.5.6.tgz",
"integrity": "sha512-zTxsnI3LQo3c9HSdSf91O1jMNsEzIXDShXd4wVdg9y5shwLqBXi4ZtUUJyB86KGVSJLZx0PFONvO54aheGX8QQ==", "integrity": "sha512-zTxsnI3LQo3c9HSdSf91O1jMNsEzIXDShXd4wVdg9y5shwLqBXi4ZtUUJyB86KGVSJLZx0PFONvO54aheGX8QQ==",
"peer": true,
"requires": { "requires": {
"@next/env": "15.5.6", "@next/env": "15.5.6",
"@next/swc-darwin-arm64": "15.5.6", "@next/swc-darwin-arm64": "15.5.6",
@ -11246,6 +11337,14 @@
"set-blocking": "^2.0.0" "set-blocking": "^2.0.0"
} }
}, },
"nuqs": {
"version": "2.8.5",
"resolved": "https://registry.npmjs.org/nuqs/-/nuqs-2.8.5.tgz",
"integrity": "sha512-ndhnNB9eLX/bsiGFkBNsrfOWf3BCbzBMD+b5GkD5o2Q96Q+llHnoUlZsrO3tgJKZZV7LLlVCvFKdj+sjBITRzg==",
"requires": {
"@standard-schema/spec": "1.0.0"
}
},
"nwsapi": { "nwsapi": {
"version": "2.2.22", "version": "2.2.22",
"resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.22.tgz", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.22.tgz",
@ -11624,6 +11723,11 @@
"set-function-name": "^2.0.2" "set-function-name": "^2.0.2"
} }
}, },
"remove-accents": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.5.0.tgz",
"integrity": "sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A=="
},
"require-from-string": { "require-from-string": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",

View file

@ -25,7 +25,9 @@
"globby": "^15.0.0", "globby": "^15.0.0",
"jszip": "^3.10.1", "jszip": "^3.10.1",
"lodash.orderby": "^4.6.0", "lodash.orderby": "^4.6.0",
"match-sorter": "^8.2.0",
"next": "^15.5.6", "next": "^15.5.6",
"nuqs": "^2.8.5",
"pngjs": "^7.0.0", "pngjs": "^7.0.0",
"react": "^19.2.0", "react": "^19.2.0",
"react-dom": "^19.2.0", "react-dom": "^19.2.0",

View file

@ -17,11 +17,18 @@
z-index: 2; z-index: 2;
} }
.Tools select:focus { .Tools a:link:focus-visible,
.Tools button:focus-visible,
.Tools select:focus-visible,
.Tools input:focus-visible {
outline: none; outline: none;
box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.5), 0 0 2px 3px rgb(152, 255, 212); box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.5), 0 0 2px 3px rgb(152, 255, 212);
} }
.InputContainer {
position: relative;
}
.HeaderEnd { .HeaderEnd {
display: flex; display: flex;
align-items: center; align-items: center;
@ -43,8 +50,8 @@
.DownloadButton { .DownloadButton {
display: inline-block; display: inline-block;
border: 0; border: 0;
border-radius: 4px; border-radius: 3px;
padding: 4px 8px 5px 8px; padding: 4px 8px;
background: rgb(14, 114, 98), background: rgb(14, 114, 98),
linear-gradient(to bottom, rgb(67, 167, 130), rgb(15, 89, 87)); linear-gradient(to bottom, rgb(67, 167, 130), rgb(15, 89, 87));
color: rgb(247, 255, 220); color: rgb(247, 255, 220);
@ -53,7 +60,7 @@
letter-spacing: -0.03em; letter-spacing: -0.03em;
text-decoration: none; text-decoration: none;
text-shadow: 0 -1px 0 rgba(25, 39, 34, 0.4); text-shadow: 0 -1px 0 rgba(25, 39, 34, 0.4);
margin-left: 3px; margin: 0 0 0 3px;
cursor: pointer; cursor: pointer;
} }
@ -190,6 +197,34 @@
animation: spin 2s linear infinite; animation: spin 2s linear infinite;
} }
.HeaderMain {
display: flex;
align-items: center;
gap: 12px;
}
.SearchButton {
display: grid;
place-content: center;
margin: 0;
padding: 3px 4px;
border: 0;
background: transparent;
font-size: 18px;
color: rgb(40, 217, 178);
cursor: pointer;
}
.SearchInput {
position: absolute;
left: 0;
right: 0;
margin: 0;
padding: 4px 6px 3px 6px;
border: 1px solid #666;
border-radius: 2px;
}
@media (max-width: 1023px) { @media (max-width: 1023px) {
.Tools { .Tools {
grid-template-columns: auto auto 1fr; grid-template-columns: auto auto 1fr;

View file

@ -1,15 +1,22 @@
"use client"; "use client";
import { Suspense, useEffect, useMemo, useRef, useState } from "react"; import {
import { CgSpinnerTwo } from "react-icons/cg"; Suspense,
import { BsBadge3dFill } from "react-icons/bs"; useDeferredValue,
import { FaDownload } from "react-icons/fa"; useEffect,
import { FaChevronLeft } from "react-icons/fa"; useMemo,
import { useRouter, usePathname, useSearchParams } from "next/navigation"; useRef,
import orderBy from "lodash.orderby"; useState,
import useManifest from "../../useManifest"; } from "react";
import styles from "./gallery.module.css";
import Head from "next/head"; import Head from "next/head";
import Link from "next/link"; import Link from "next/link";
import { CgSpinnerTwo } from "react-icons/cg";
import { BsBadge3dFill } from "react-icons/bs";
import { FaDownload, FaChevronLeft, FaSearch, FaTimes } from "react-icons/fa";
import { useQueryState } from "nuqs";
import orderBy from "lodash.orderby";
import { matchSorter } from "match-sorter";
import useManifest from "../../useManifest";
import styles from "./gallery.module.css";
import { collectFiles, createZipFile, saveZipFile } from "../../exportUtils"; import { collectFiles, createZipFile, saveZipFile } from "../../exportUtils";
import { modelToModelType, modelTypes } from "../../importUtils"; import { modelToModelType, modelTypes } from "../../importUtils";
import modelConfig from "../../models"; import modelConfig from "../../models";
@ -102,12 +109,20 @@ function skinDataToList(
} }
function Gallery() { function Gallery() {
const router = useRouter();
const pathname = usePathname();
const searchParams = useSearchParams();
const hiResSelectRef = useRef<HTMLSelectElement>(null); const hiResSelectRef = useRef<HTMLSelectElement>(null);
const [searchQuery, setSearchQuery] = useQueryState("q", {
defaultValue: "",
clearOnDefault: true,
});
const [browseMode, setBrowseMode] = useState<"select" | "search">(
searchQuery.trim() ? "search" : "select"
);
const deferredSearchQuery = useDeferredValue(searchQuery);
const [manifest, isLoaded] = useManifest(); const [manifest, isLoaded] = useManifest();
const [selectedModel, setSelectedModel] = useState("lmale"); const [selectedModel, setSelectedModel] = useQueryState("filter", {
defaultValue: "lmale",
clearOnDefault: false,
});
const [isPreparingDownload, setPreparingDownload] = useState(false); const [isPreparingDownload, setPreparingDownload] = useState(false);
const [hiResDownload, setHiResDownload] = useState<"prompt" | "yes" | "no">( const [hiResDownload, setHiResDownload] = useState<"prompt" | "yes" | "no">(
"prompt" "prompt"
@ -215,14 +230,46 @@ function Gallery() {
} }
}, [isNew, isPack, selectedModel, manifest]); }, [isNew, isPack, selectedModel, manifest]);
const filteredSkins = isNew || isPack ? selectedSkinList : customSkins; const allSkins = useMemo(() => {
if (!manifest.customSkins) return [];
return skinDataToList(manifest.customSkins);
}, [manifest.customSkins]);
const filter = searchParams.get("filter") || "lmale"; const hasSearchInput = deferredSearchQuery.trim().length > 0;
const searchResults = useMemo(() => {
if (!hasSearchInput) {
return [];
}
return matchSorter(allSkins, deferredSearchQuery, {
keys: ["name"],
});
}, [allSkins, deferredSearchQuery, hasSearchInput]);
const filteredSkins =
browseMode === "search" && hasSearchInput
? searchResults
: isNew || isPack
? selectedSkinList
: customSkins;
useEffect(() => { useEffect(() => {
setPreparingDownload(false); setPreparingDownload(false);
setSelectedModel(filter); }, [selectedModel]);
}, [filter]);
const searchRef = useRef<HTMLInputElement>(null);
const selectRef = useRef<HTMLSelectElement>(null);
useEffect(() => {
switch (browseMode) {
case "search":
searchRef.current?.focus();
break;
case "select":
selectRef.current?.focus();
break;
}
}, [browseMode]);
return ( return (
<> <>
@ -230,66 +277,108 @@ function Gallery() {
<title>Tribes 2 Skin Gallery</title> <title>Tribes 2 Skin Gallery</title>
</Head> </Head>
<main className={styles.GalleryPage}> <main className={styles.GalleryPage}>
<div className={styles.Tools}> <header className={styles.Tools}>
<Link className={styles.Back} href="../"> <Link className={styles.Back} href="../">
<FaChevronLeft size={12} className={styles.Icon} />{" "} <FaChevronLeft size={12} className={styles.Icon} />{" "}
<span className={styles.Label}>Back to Editor</span> <span className={styles.Label}>Back to Editor</span>
</Link> </Link>
<select <div className={styles.HeaderMain}>
tabIndex={0} <button
id="ModelSelect" className={styles.SearchButton}
aria-label="Player model" title={browseMode === "select" ? "Search" : "Close search mode"}
onChange={(event) => { onClick={() => {
router.push(`${pathname}?filter=${event.target.value}`); setBrowseMode((mode) =>
}} mode === "select" ? "search" : "select"
value={selectedModel} );
> setSearchQuery("");
<option value="new">All new skins </option> }}
<optgroup label="Packs"> >
{packList.map((packName) => ( {browseMode === "select" ? <FaSearch /> : <FaTimes />}
<option value={packName} key={packName}> </button>
{packName} <div className={styles.InputContainer}>
</option> <input
))} type="text"
</optgroup> ref={searchRef}
<optgroup label="Players" data-model-type="player"> className={styles.SearchInput}
<option value="lmale">Human Male &bull; Light</option> hidden={browseMode === "select"}
<option value="mmale">Human Male &bull; Medium</option> placeholder={`Search ${allSkins.length.toLocaleString()} skins…`}
<option value="hmale">Human Male &bull; Heavy</option> value={searchQuery}
<option value="lfemale">Human Female &bull; Light</option> onChange={(e) => setSearchQuery(e.target.value)}
<option value="mfemale">Human Female &bull; Medium</option> onKeyDown={(e) => {
<option value="hfemale">Human Female &bull; Heavy</option> if (e.key === "Escape") {
<option value="lbioderm">Bioderm &bull; Light</option> setBrowseMode("select");
<option value="mbioderm">Bioderm &bull; Medium</option> setSearchQuery("");
<option value="hbioderm">Bioderm &bull; Heavy</option> }
</optgroup> }}
<optgroup label="Weapons" data-model-type="weapon"> />
<option value="disc">Disc Launcher</option> <select
<option value="chaingun">Chaingun</option> ref={selectRef}
<option value="grenade_launcher">Grenade Launcher</option> id="ModelSelect"
<option value="sniper">Laser Rifle</option> aria-label="Player model"
<option value="plasmathrower">Plasma Cannon</option> onChange={(event) => {
<option value="energy">Blaster</option> setSelectedModel(event.target.value);
<option value="shocklance">Shocklance</option> }}
<option value="elf">ELF Projector</option> value={selectedModel}
<option value="missile">Missile Launcher</option> style={{
<option value="mortar">Mortar</option> visibility: browseMode === "search" ? "hidden" : "visible",
<option value="repair">Repair Pack</option> }}
<option value="targeting">Targeting Laser</option> >
</optgroup> <option value="new">All new skins </option>
<optgroup label="Vehicles" data-model-type="vehicle"> <optgroup label="Packs">
<option value="vehicle_grav_scout">Wildcat Grav Cycle</option> {packList.map((packName) => (
<option value="vehicle_grav_tank">Beowulf Assault Tank</option> <option value={packName} key={packName}>
<option value="vehicle_land_mpbbase"> {packName}
Jericho Mobile Point Base </option>
</option> ))}
<option value="vehicle_air_scout">Shrike Scout Fighter</option> </optgroup>
<option value="vehicle_air_bomber">Thundersword Bomber</option> <optgroup label="Players" data-model-type="player">
<option value="vehicle_air_hapc">HAVOC Gunship Transport</option> <option value="lmale">Human Male &bull; Light</option>
</optgroup> <option value="mmale">Human Male &bull; Medium</option>
</select> <option value="hmale">Human Male &bull; Heavy</option>
<option value="lfemale">Human Female &bull; Light</option>
<option value="mfemale">Human Female &bull; Medium</option>
<option value="hfemale">Human Female &bull; Heavy</option>
<option value="lbioderm">Bioderm &bull; Light</option>
<option value="mbioderm">Bioderm &bull; Medium</option>
<option value="hbioderm">Bioderm &bull; Heavy</option>
</optgroup>
<optgroup label="Weapons" data-model-type="weapon">
<option value="disc">Disc Launcher</option>
<option value="chaingun">Chaingun</option>
<option value="grenade_launcher">Grenade Launcher</option>
<option value="sniper">Laser Rifle</option>
<option value="plasmathrower">Plasma Cannon</option>
<option value="energy">Blaster</option>
<option value="shocklance">Shocklance</option>
<option value="elf">ELF Projector</option>
<option value="missile">Missile Launcher</option>
<option value="mortar">Mortar</option>
<option value="repair">Repair Pack</option>
<option value="targeting">Targeting Laser</option>
</optgroup>
<optgroup label="Vehicles" data-model-type="vehicle">
<option value="vehicle_grav_scout">Wildcat Grav Cycle</option>
<option value="vehicle_grav_tank">
Beowulf Assault Tank
</option>
<option value="vehicle_land_mpbbase">
Jericho Mobile Point Base
</option>
<option value="vehicle_air_scout">
Shrike Scout Fighter
</option>
<option value="vehicle_air_bomber">
Thundersword Bomber
</option>
<option value="vehicle_air_hapc">
HAVOC Gunship Transport
</option>
</optgroup>
</select>
</div>
</div>
<div className={styles.HeaderEnd}> <div className={styles.HeaderEnd}>
{isPack ? ( {browseMode === "select" && isPack ? (
<div className={styles.DownloadSection}> <div className={styles.DownloadSection}>
<button <button
type="button" type="button"
@ -338,7 +427,7 @@ function Gallery() {
</select> </select>
</div> </div>
</div> </div>
</div> </header>
{isLoaded ? ( {isLoaded ? (
<div className={styles.Gallery}> <div className={styles.Gallery}>
{filteredSkins.map((name) => { {filteredSkins.map((name) => {

View file

@ -1,3 +1,4 @@
import { NuqsAdapter } from "nuqs/adapters/next/app";
import "./global.css"; import "./global.css";
export const metadata = { export const metadata = {
@ -12,7 +13,9 @@ export default function RootLayout({
}) { }) {
return ( return (
<html lang="en"> <html lang="en">
<body>{children}</body> <body>
<NuqsAdapter>{children}</NuqsAdapter>
</body>
</html> </html>
); );
} }