PageSourceSearch

https://devpages.io/_next/static/immutable/chunks/3ls_wi1n24zt9.js

js devpages.io collected 2026-09-29 09:07:38 UTC 46,560 bytes, 3 lines download raw bytes

1(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,76838,e=>{"use strict";let t=(0,e.i(75254).default)("badge-check",[["path",{d:"M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z",key:"3c2336"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]]);e.s(["BadgeCheck",0,t],76838)},50682,e=>{"use strict";let t=(0,e.i(75254).default)("github",[["path",{d:"M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4",key:"tonef"}],["path",{d:"M9 18c-4.51 2-5-2-7-2",key:"9comsn"}]]);e.s(["Github",0,t],50682)},31278,e=>{"use strict";let t=(0,e.i(75254).default)("loader-circle",[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]]);e.s(["Loader2",0,t],31278)},83086,e=>{"use strict";let t=(0,e.i(75254).default)("sparkles",[["path",{d:"M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z",key:"1s2grr"}],["path",{d:"M20 2v4",key:"1rf3ol"}
1],["path",{d:"M22 4h-4",key:"gwowj6"}],["circle",{cx:"4",cy:"20",r:"2",key:"6kqj1y"}]]);e.s(["Sparkles",0,t],83086)},25652,e=>{"use strict";let t=(0,e.i(75254).default)("trending-up",[["path",{d:"M16 7h6v6",key:"box55l"}],["path",{d:"m22 7-8.5 8.5-5-5L2 17",key:"1t1m79"}]]);e.s(["TrendingUp",0,t],25652)},5500,(e,t,a)=>{"use strict";e.i(47167),Object.defineProperty(a,"__esModule",{value:!0}),Object.defineProperty(a,"Image",{enumerable:!0,get:function(){return k}});let n=e.r(55682),i=e.r(90809),o=e.r(43476),r=i._(e.r(71645)),s=n._(e.r(74080)),l=n._(e.r(25633)),d=e.r(8927),c=e.r(87690),h=e.r(18556),u=e.r(65856),p=n._(e.r(1948)),m=e.r(18581),g={deviceSizes:[640,750,828,1080,1200,1920,2048,3840],imageSizes:[32,48,64,96,128,256,384],qualities:[75],path:"/_next/image",loader:"default",dangerouslyAllowSVG:!1,unoptimized:!1};function f(e,t,a,n,i,o,r){let s=e?.src;e&&e["data-loaded-src"]!==s&&(e["data-loaded-src"]=s,("decode"in e?e.decode():Promise.resolve()).catch(()=>{}).then(()=>{if(e.parentElement&&e.isConnected){if("empty"!==t&&i(!0),a?.current){let t=new Event("load");Object.defineProperty(t,"target",{writable:!1,value:e});let n=!1,i=!1;a.current({...t,nativeEvent:t,currentTarget:e,target:e,isDefaultPrevented:()=>n,isPropagationStopped:()=>i,persist:()=>{},preventDefault:()=>{n=!0,t.preventDefault()},stopPropagation:()=>{i=!0,t.stopPropagation()}})}n?.current&&n.current(e)}}))}function y(e){return r.use?{fetchPriority:e}:{fetchpriority:e}}"u"<typeof window&&(globalThis.__NEXT_IMAGE_IMPORTED=!0);let w="u"<typeof window?r.useEffect:r.useLayoutEffect,b=(0,r.forwardRef)(({src:e,srcSet:t,sizes:a,height:n,width:i,decoding:s,className:l,style:d,fetchPriority:c,placeholder:h,loading:u,unoptimized:p,fill:g,onLoadRef:b,onLoadingCompleteRef:v,setBlurComplete:k,setShowAltText:x,sizesInput:S,onLoad:C,onError:P,..._},j)=>{let T=(0,r.useRef)(!1),I=(0,r.useRef)(null);w(()=>{let{current:e}=T,{current:t}=I;e||null===t||(P&&(t.src=t.src),t.complete&&f(t,h,b,v,k,p,S),T.current=!0)},[e,h,b,v,P,p,S]);let O=(0,m.useMergedRef)(j,I);return(0,o.jsx)("img",{..._,...y(c),loading:u,width:i,height:n,decoding:s,"data-nimg":g?"fill":"1",className:l,style:d,sizes:a,srcSet:t,src:e,ref:O,onLoad:e=>{f(e.currentTarget,h,b,v,k,p,S)},onError:e=>{x(!0),"empty"!==h&&k(!0),P&&P(e)}})});function v({isAppRouter:e,imgAttributes:t}){let a={as:"image",imageSrcSet:t.srcSet,imageSizes:t.sizes,crossOrigin:t.crossOrigin,referrerPolicy:t.referrerPolicy,...y(t.fetchPriority)};return e&&s.default.preload?(s.default.preload(t.src,a),null):(0,o.jsx)(l.default,{children:(0,o.jsx)("link",{rel:"preload",href:t.srcSet?void 0:t.src,...a},"__nimg-"+t.src+t.srcSet+t.sizes)})}let k=(0,r.forwardRef)((e,t)=>{let a=(0,r.useContext)(u.RouterContext),n=(0,r.useContext)(h.ImageConfigContext),i=(0,r.useMemo)(()=>{let e=g||n||c.imageConfigDefault,t=[...e.deviceSizes,...e.imageSizes].sort((e,t)=>e-t),a=e.deviceSizes.sort((e,t)=>e-t),i=e.qualities?.sort((e,t)=>e-t);return{...e,allSizes:t,deviceSizes:a,qualities:i,localPatterns:"u"<typeof window?n?.localPatterns:e.localPatterns}},[n]),{onLoad:s,onLoadingComplete:l}=e,m=(0,r.useRef)(s);(0,r.useEffect)(()=>{m.current=s},[s]);let f=(0,r.useRef)(l);(0,r.useEffect)(()=>{f.current=l},[l]);let[y,w]=(0,r.useState)(!1),[k,x]=(0,r.useState)(!1),{props:S,meta:C}=(0,d.getImgProps)(e,{defaultLoader:p.default,imgConf:i,blurComplete:y,showAltText:k});return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(b,{...S,unoptimized:C.unoptimized,placeholder:C.placeholder,fill:C.fill,onLoadRef:m,onLoadingCompleteRef:f,setBlurComplete:w,setShowAltText:x,sizesInput:e.sizes,ref:t}),C.preload?(0,o.jsx)(v,{isAppRouter:!a,imgAttributes:S}):null]})});("function"==typeof a.default||"object"==typeof a.default&&null!==a.default)&&void 0===a.default.__esModule&&(Object.defineProperty(a.default,"__esModule",{value:!0}),Object.assign(a.default,a),t.exports=a.default)},18815,(e,t,a)=>{"use strict";function n(e,t){let a=e||75;return t?.qualities?.length?t.qualities.reduce((e,t)=>Math.abs(t-a)<Math.abs(e-a)?t:e,t.qualities[0]):a}Object.defineProperty(a,"__esModule",{value:!0}),Object.defineProperty(a,"findClosestQuality",{enumerable:!0,get:function(){return n}})},8927,(e,t,a)=>{"use strict";e.i(47167),Object.defineProperty(a,"__esModule",{value:!0}),Object.defineProperty(a,"getImgProps",{enumerable:!0,get:function(){return d}});let n=e.r(43369),i=e.r(67423),o=e.r(87690),r=["-moz-initial","fill","none","scale-down",void 0];function s(e){return void 0!==e.default}function l(e){return void 0===e?e:"number"==typeof e?Number.isFinite(e)?e:NaN:"string"==typeof e&&/^[0-9]+$/.test(e)?parseInt(e,10):NaN}function d({src:e,sizes:t,unoptimized:a=!1,priority:c=!1,preload:h=!1,loading:u,className:p,quality:m,width:g,height:f,fill:y=!1,style:w,overrideSrc:b,onLoad:v,onLoadingComplete:k,placeholder:x="empty",blurDataURL:S,fetchPriority:C,decoding:P="async",layout:_,objectFit:j,objectPosition:T,lazyBoundary:I,lazyRoot:O,...A},E){var M;let R,D,q,{imgConf:z,showAltText:N,blurComplete:$,defaultLoader:B}=E,U=z||o.imageConfigDefault;if("allSizes"in U)R=U;else{let e=[...U.deviceSizes,...U.imageSizes].sort((e,t)=>
1e-t),t=U.deviceSizes.sort((e,t)=>e-t),a=U.qualities?.sort((e,t)=>e-t);R={...U,allSizes:e,deviceSizes:t,qualities:a}}if(void 0===B)throw Object.defineProperty(Error("images.loaderFile detected but the file is missing default export.\nRead more: https://nextjs.org/docs/messages/invalid-images-config"),"__NEXT_ERROR_CODE",{value:"E163",enumerable:!1,configurable:!0});let F=A.loader||B;delete A.loader,delete A.srcSet;let L="__next_img_default"in F;if(L){if("custom"===R.loader)throw Object.defineProperty(Error(`Image with src "${e}" is missing "loader" prop.
2Read more: https://nextjs.org/docs/messages/next-image-missing-loader`),"__NEXT_ERROR_CODE",{value:"E252",enumerable:!1,configurable:!0})}else{let e=F;F=t=>{let{config:a,...n}=t;return e(n)}}if(_){"fill"===_&&(y=!0);let e={intrinsic:{maxWidth:"100%",height:"auto"},responsive:{width:"100%",height:"auto"}}[_];e&&(w={...w,...e});let a={responsive:"100vw",fill:"100vw"}[_];a&&!t&&(t=a)}let G="",H=l(g),W=l(f);if((M=e)&&"object"==typeof M&&(s(M)||void 0!==M.src)){let t=s(e)?e.default:e;if(!t.src)throw Object.defineProperty(Error(`An object should only be passed to the image component src parameter if it comes from a static image import. It must include src. Received ${JSON.stringify(t)}`),"__NEXT_ERROR_CODE",{value:"E460",enumerable:!1,configurable:!0});if(!t.height||!t.width)throw Object.defineProperty(Error(`An object should only be passed to the image component src parameter if it comes from a static image import. It must include height and width. Received ${JSON.stringify(t)}`),"__NEXT_ERROR_CODE",{value:"E48",enumerable:!1,configurable:!0});if(D=t.blurWidth,q=t.blurHeight,S=S||t.blurDataURL,G=t.src,!y)if(H||W){if(H&&!W){let e=H/t.width;W=Math.round(t.height*e)}else if(!H&&W){let e=W/t.height;H=Math.round(t.width*e)}}else H=t.width,W=t.height}let V=!c&&!h&&("lazy"===u||void 0===u);(!(e="string"==typeof e?e:G)||e.startsWith("data:")||e.startsWith("blob:"))&&(a=!0,V=!1),R.unoptimized&&(a=!0),L&&!R.dangerouslyAllowSVG&&e.split("?",1)[0].endsWith(".svg")&&(a=!0);let Q=l(m),K=Object.assign(y?{position:"absolute",height:"100%",width:"100%",left:0,top:0,right:0,bottom:0,objectFit:j,objectPosition:T}:{},N?{}:{color:"transparent"},w),J=$||"empty"===x?null:"blur"===x?`url("data:image/svg+xml;charset=utf-8,${(0,i.getImageBlurSvg)({widthInt:H,heightInt:W,blurWidth:D,blurHeight:q,blurDataURL:S||"",objectFit:K.objectFit})}")`:`url("${x}")`,X=r.includes(K.objectFit)?"fill"===K.objectFit?"100% 100%":"cover":K.objectFit,Y=J?{backgroundSize:X,backgroundPosition:K.objectPosition||"50% 50%",backgroundRepeat:"no-repeat",backgroundImage:J}:{},Z=function({config:e,src:t,unoptimized:a,width:i,quality:o,sizes:r,loader:s}){if(a){if(t.startsWith("/")&&!t.startsWith("//")){let e=(0,n.getDeploymentId)();if(t.includes("/_next/static/immutable")&&!(0,n.getAssetToken)())e=void 0;else if(e){let a=t.indexOf("?");if(-1!==a){let n=new URLSearchParams(t.slice(a+1));n.get("dpl")||(n.append("dpl",e),t=t.slice(0,a)+"?"+n.toString())}else t+=`?dpl=${e}`}}return{src:t,srcSet:void 0,sizes:void 0}}let{widths:l,kind:d}=function({deviceSizes:e,allSizes:t}
2,a,n){if(n){let a=/(^|\s)(1?\d?\d)vw/g,i=[];for(let e;e=a.exec(n);)i.push(parseInt(e[2]));if(i.length){let a=.01*Math.min(...i);return{widths:t.filter(t=>t>=e[0]*a),kind:"w"}}return{widths:t,kind:"w"}}return"number"!=typeof a?{widths:e,kind:"w"}:{widths:[...new Set([a,2*a].map(e=>t.find(t=>t>=e)||t[t.length-1]))],kind:"x"}}(e,i,r),c=l.length-1;return{sizes:r||"w"!==d?r:"100vw",srcSet:l.map((a,n)=>`${s({config:e,src:t,quality:o,width:a})} ${"w"===d?a:n+1}${d}`).join(", "),src:s({config:e,src:t,quality:o,width:l[c]})}}({config:R,src:e,unoptimized:a,width:H,quality:Q,sizes:t,loader:F}),ee=V?"lazy":u;return{props:{...A,loading:ee,fetchPriority:C,width:H,height:W,decoding:P,className:p,style:{...K,...Y},sizes:Z.sizes,srcSet:Z.srcSet,src:b||Z.src},meta:{unoptimized:a,preload:h||c,placeholder:x,fill:y}}}},25633,(e,t,a)=>{"use strict";e.i(47167),Object.defineProperty(a,"__esModule",{value:!0});var n={default:function(){return g},defaultHead:function(){return h}};for(var i in n)Object.defineProperty(a,i,{enumerable:!0,get:n[i]});let o=e.r(55682),r=e.r(90809),s=e.r(43476),l=r._(e.r(71645)),d=o._(e.r(98879)),c=e.r(42732);function h(){return[(0,s.jsx)("meta",{charSet:"utf-8"},"charset"),(0,s.jsx)("meta",{name:"viewport",content:"width=device-width"},"viewport")]}function u(e,t){return"string"==typeof t||"number"==typeof t?e:t.type===l.default.Fragment?e.concat(l.default.Children.toArray(t.props.children).reduce((e,t)=>"string"==typeof t||"number"==typeof t?e:e.concat(t),[])):e.concat(t)}let p=["name","httpEquiv","charSet","itemProp"];function m(e){let t,a,n,i;return e.reduce(u,[]).reverse().concat(h().reverse()).filter((t=new Set,a=new Set,n=new Set,i={},e=>{let o=!0,r=!1;if(e.key&&"number"!=typeof e.key&&e.key.indexOf("$")>0){r=!0;let a=e.key.slice(e.key.indexOf("$")+1);t.has(a)?o=!1:t.add(a)}switch(e.type){case"title":case"base":a.has(e.type)?o=!1:a.add(e.type);break;case"meta":for(let t=0,a=p.length;t<a;t++){let a=p[t];if(e.props.hasOwnProperty(a))if("charSet"===a)n.has(a)?o=!1:n.add(a);else{let t=e.props[a],n=i[a]||new Set;("name"!==a||!r)&&n.has(t)?o=!1:(n.add(t),i[a]=n)}}}return o})).reverse().map((e,t)=>{let a=e.key||t;return l.default.cloneElement(e,{key:a})})}let g=function({children:e}){let t=(0,l.useContext)(c.HeadManagerContext);return(0,s.jsx)(d.default,{reduceComponentsToState:m,headManager:t,children:e})};("function"==typeof a.default||"object"==typeof a.default&&null!==a.default)&&void 0===a.default.__esModule&&(Object.defineProperty(a.default,"__esModule",{value:!0}),Object.assign(a.default,a),t.exports=a.default)},67423,(e,t,a)=>{"use strict";function n({widthInt:e,heightInt:t,blurWidth:a,blurHeight:i,blurDataURL:o,objectFit:r}){let s=a?40*a:e,l=i?40*i:t,d=s&&l?`viewBox='0 0 ${s} ${l}'`:"";return`%3Csvg xmlns='http://www.w3.org/2000/svg' ${d}%3E%3Cfilter id='b' color-interpolation-filters='sRGB'%3E%3CfeGaussianBlur stdDeviation='20'/%3E%3CfeColorMatrix values='1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 100 -1' result='s'/%3E%3CfeFlood x='0' y='0' width='100%25' height='100%25'/%3E%3CfeComposite operator='out' in='s'/%3E%3CfeComposite in2='SourceGraphic'/%3E%3CfeGaussianBlur stdDeviation='20'/%3E%3C/filter%3E%3Cimage width='100%25' height='100%25' x='0' y='0' preserveAspectRatio='${d?"none":"contain"===r?"xMidYMid":"cover"===r?"xMidYMid slice":"none"}' style='filter: url(%23b);' href='${o}'/%3E%3C/svg%3E`}Object.defineProperty(a,"__esModule",{value:!0}),Object.defineProperty(a,"getImageBlurSvg",{enumerable:!0,get:function(){return n}})},18556,(e,t,a)=>{"use strict";e.i(47167),Object.defineProperty(a,"__esModule",{value:!0}),Object.defineProperty(a,"ImageConfigContext",{enumerable:!0,get:function(){return o}});let n=e.r(55682)._(e.r(71645)),i=e.r(87690),o=n.default.createContext(i.imageConfigDefault)},65856,(e,t,a)=>{"use strict";e.i(47167),Object.defineProperty(a,"__esModule",{value:!0}),Object.defineProperty(a,"RouterContext",{enumerable:!0,get:function(){return n}});let n=e.r(55682)._(e.r(71645)).default.createContext(null)},87690,(e,t,a)=>{"use strict";Object.defineProperty(a,"__esModule",{value:!0});var n={VALID_LOADERS:function(){return o},imageConfigDefault:function(){return r}};for(var i in n)Object.defineProperty(a,i,{enumerable:!0,get:n[i]});let o=["default","imgix","cloudinary","akamai","custom"],r={deviceSizes:[640,750,828,1080,1200,1920,2048,3840],imageSizes:[32,48,64,96,128,256,384],path:"/_next/image",loader:"default",loaderFile:"",domains:[],disableStaticImages:!1,minimumCacheTTL:14400,formats:["image/webp"],maximumDiskCacheSize:void 0,maximumRedirects:3,maximumResponseBody:5e7,dangerouslyAllowLocalIP:!1,dangerouslyAllowSVG:!1,
2contentSecurityPolicy:"script-src 'none'; frame-src 'none'; sandbox;",contentDispositionType:"attachment",localPatterns:void 0,remotePatterns:[],qualities:[75],unoptimized:!1,customCacheHandler:!1}},1948,(e,t,a)=>{"use strict";e.i(47167),Object.defineProperty(a,"__esModule",{value:!0}),Object.defineProperty(a,"default",{enumerable:!0,get:function(){return r}});let n=e.r(18815),i=e.r(43369);function o({config:e,src:t,width:a,quality:r}){let s=(0,i.getDeploymentId)();if(t.startsWith("/")&&!t.startsWith("//"))if(t.includes("/_next/static/immutable")&&!(0,i.getAssetToken)())s=void 0;else{let e=t.indexOf("?");if(-1!==e){let a=new URLSearchParams(t.slice(e+1)),n=a.get("dpl");if(n){s=n,a.delete("dpl");let i=a.toString();t=t.slice(0,e)+(i?"?"+i:"")}}}if(t.startsWith("/")&&t.includes("?")&&e.localPatterns?.length===1&&"**"===e.localPatterns[0].pathname&&""===e.localPatterns[0].search)throw Object.defineProperty(Error(`Image with src "${t}" is using a query string which is not configured in images.localPatterns.
3Read more: https://nextjs.org/docs/messages/next-image-unconfigured-localpatterns`),"__NEXT_ERROR_CODE",{value:"E871",enumerable:!1,configurable:!0});let l=(0,n.findClosestQuality)(r,e);return`${e.path}?url=${encodeURIComponent(t)}&w=${a}&q=${l}${t.startsWith("/")&&s?`&dpl=${s}`:""}`}o.__next_img_default=!0;let r=o},98879,(e,t,a)=>{"use strict";Object.defineProperty(a,"__esModule",{value:!0}),Object.defineProperty(a,"default",{enumerable:!0,get:function(){return s}});let n=e.r(71645),i="u"<typeof window,o=i?()=>{}:n.useLayoutEffect,r=i?()=>{}:n.useEffect;function s(e){let{headManager:t,reduceComponentsToState:a}=e;function s(){if(t&&t.mountedInstances){let e=n.Children.toArray(Array.from(t.mountedInstances).filter(Boolean));t.updateHead(a(e))}}return i&&(t?.mountedInstances?.add(e.children),s()),o(()=>(t?.mountedInstances?.add(e.children),()=>{t?.mountedInstances?.delete(e.children)})),o(()=>(t&&(t._pendingUpdate=s),()=>{t&&(t._pendingUpdate=s)})),r(()=>(t&&t._pendingUpdate&&(t._pendingUpdate(),t._pendingUpdate=null),()=>{t&&t._pendingUpdate&&(t._pendingUpdate(),t._pendingUpdate=null)})),null}},23898,e=>{"use strict";var t=e.i(43476),a=e.i(22016),n=e.i(18566),i=e.i(71930);let o=(0,e.i(75254).default)("bookmark-check",[["path",{d:"m19 21-7-4-7 4V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2Z",key:"169p4p"}],["path",{d:"m9 10 2 2 4-4",key:"1gnqz4"}]]);var r=e.i(31278),s=e.i(75157),l=e.i(22379),d=e.i(17816);function c(e){let t=/^\/(?!\/)/.test(e)?e:"/";return`/signin?next=${encodeURIComponent(t)}`}function h({toolSlug:e,toolName:l,variant:u="icon",className:p}){let m=(0,n.useRouter)(),g=(0,n.usePathname)(),{isBookmarked:f,isSignedIn:y,isLoading:w,isPending:b,error:v,toggle:k}=(0,d.useBookmark)(e),x=!w&&!y,S="Sign in to save tools."===v,C=b?r.Loader2:f?o:i.Bookmark,P=x?`Bookmark ${l} (sign in required)`:`Bookmark ${l}`,_=(0,t.jsxs)("button",{type:"button",onClick:function(){if(x){let e=`${window.location.pathname}${window.location.search}`;m.push(c(e));return}k()},"aria-pressed":x?void 0:f,"aria-label":P,"aria-busy":b||void 0,title:v??void 0,className:(0,s.cn)("inline-flex shrink-0 items-center justify-center rounded-lg border transition-colors","icon"===u?"h-9 w-9":"h-9 gap-2 px-3 text-sm font-medium",f?"border-hairline-strong bg-surface-raised text-foreground":"border-hairline bg-surface text-neutral-400 hover:bg-surface-raised hover:text-foreground",b&&"opacity-70",p),children:[(0,t.jsx)(C,{size:"icon"===u?17:15,"aria-hidden":"true",className:(0,s.cn)("shrink-0",b&&"animate-spin")}),"label"===u&&(0,t.jsx)("span",{children:"Bookmark"})]});return"icon"===u?(0,t.jsxs)(t.Fragment,{children:[_,(0,t.jsx)("span",{role:"status","aria-live":"polite",className:"sr-only",children:v??""})]}):(0,t.jsxs)("span",{className:"inline-flex flex-col items-start gap-1",children:[_,v&&(0,t.jsxs)("span",{role:"status","aria-live":"polite",className:"text-xs text-neutral-400",children:[v," ",S&&(0,t.jsx)(a.default,{href:c(g),className:"font-medium text-foreground underline underline-offset-2",children:"Sign in"})]})]})}function u(e){return l.AUTH_ENABLED?(0,t.jsx)(h,{...e}):null}e.s(["BookmarkButton",0,u,"default",0,u],23898)},21194,e=>{"use strict";var t=e.i(71645),a=e.i(66027),n=e.i(54616),i=e.i(12598);let o="devpages_voter_id",r="devpages_voted_slugs";function s(){try{let e=window.localStorage.getItem(r);if(!e)return new Set;let t=JSON.parse(e);return Array.isArray(t)?new Set(t):new Set}catch{return new Set}}let l=["vote-counts"];async function d(){let e=await fetch("/api/votes");if(!e.ok)throw Error("Failed to load vote counts");return(await e.json()).data??{}}e.s(["useVote",0,function(e){let c=(0,i.useQueryClient)(),{data:h,isLoading:u}=(0,a.useQuery)({queryKey:l,queryFn:d,staleTime:6e4,retry:1}),[p,m]=(0,t.useState)(!1);(0,t.useEffect)(()=>{m(s().has(e))},[e]);let g=(0,n.useMutation)({mutationFn:async t=>{let a=function(){try{let e=window.localStorage.getItem(o);if(e)return e;let t=crypto.randomUUID();return window.localStorage.setItem(o,t),t}catch{return null}}();if(!a)throw Error("Voting needs local storage to be available.");let n=await fetch("/api/votes",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({toolSlug:e,voterId:a,action:t})});if(!n.ok){let e=await n.json().catch(()=>null);throw Error(e?.error??"Couldn't register your vote.")}return t},onMutate:async t=>{await c.cancelQueries({queryKey:l});let a=c.getQueryData(l);return c.setQueryData(l,a=>{let n=a?.[e]??0,i="vote"===t?n+1:Math.max(0,n-1);return{...a??{},[e]:i}}),m("vote"===t),{previous:a,wasVoted:p}},onError:(e,t,a)=>{a?.previous&&c.setQueryData(l,a.previous),m(a?.wasVoted??!1)},onSuccess:t=>{let a=s();"vote"===t?a.add(e):a.delete(e);try{window.localStorage.setItem(r,JSON.stringify([...a]))}catch{}},onSettled:()=>{c.invalidateQueries({queryKey:l})}}),f=(0,t.useCallback)(()=>{g.mutate(p?"unvote":"vote")},[p,g]);return{count:h?.[e]??0,hasVoted:p,isLoading:u,isPending:g.isPending,error:g.error,toggle:f}}],21194)},3030,e=>{"use strict";e.s(["categories",0,[{id:"9",name:"Generative AI",description:"Models and platforms for generating text, images, and code — from hosted APIs to open weights you can run yourself.",icon:"brain",slug:"generative-ai",intro:["Generative AI tooling splits along one main line: hosted APIs you call, and open-weight models you run. Hosted providers give you the strongest models with no infrastru
3cture to manage, billed per token. Open weights cost more effort and hardware but keep your data in-house and remove per-call pricing — which matters once volume grows or the data is sensitive.","The second thing worth deciding early is how much you want the provider to own. A raw completion API leaves orchestration, retries, evaluation and prompt management to you. Higher-level platforms bundle those, at the cost of portability. Teams that expect to switch models tend to keep a thin abstraction and lose the convenience.","Pricing here moves faster than almost any other category, and per-token rates published today are frequently stale within months. Treat cost as something to re-check against the vendor's own pricing page rather than a fixed property of the tool."]},{id:"1",name:"AI/ML Tools",description:"Platforms for building, training, deploying and hosting machine learning models and AI applications.",icon:"cpu",slug:"ai-ml",intro:["This category covers the layer beneath the models themselves: places to find and host weights, run inference, track experiments, and ship an ML feature without standing up your own GPU fleet.","The practical question is usually where the boundary sits between what you build and what you rent. Inference-as-a-service is the fastest path to a working feature and the easiest to reason about operationally. Managed training and fine-tuning platforms make sense once you have proprietary data worth adapting a model to. Self-hosting is a real option now that open weights are strong, but it's an infrastructure commitment, not a checkbox.","Model hubs matter more than they first appear: the availability of weights, licences, and a community porting models to usable formats often decides what's actually buildable, independent of which model benchmarks best."]},{id:"2",name:"DevOps",description:"CI/CD, containers, infrastructure automation, and the internal platforms teams build on top of them.",icon:"settings",slug:"devops",intro:["DevOps tooling spans a wide range: pipelines that build and ship code, container tooling, infrastructure-as-code, and the developer portals and platform layers that tie them together.","The most consequential choice is usually CI/CD, because it's the one every change flows through. Managed runners bundled with your host (the CI built into your Git provider, for example) are the lowest-friction option and are hard to beat for small teams. Standalone servers give you more control over runners, plugins and self-hosting, at the cost of maintaining them. Both do the job; the difference is who carries the operational weight.","The other pattern worth naming is the internal developer platform. Once a team is large enough that nobody can hold the whole system in their head, service catalogs and developer portals stop being overhead and start being the thing that makes the rest usable. Below that size, they're usually premature."]},{id:"3",name:"Cloud Infrastructure",description:"Hyperscalers, application platforms, and hosting — from raw compute to deploy-on-push.",icon:"cloud",slug:"cloud",intro:["Cloud options fall roughly into three tiers. Hyperscalers give you every primitive and expect you to assemble them. Application platforms trade breadth for a good default path — push a repo, get a deployment, with a curated set of services around it. Simpler VPS-style hosts sit in between, offering predictable pricing and less surface area.","The honest trade-off is control versus the amount of infrastructure you want to think about. A hyperscaler will do anything you need eventually, but you'll spend real time on IAM, networking and glue. A platform gets a product live in an afternoon and starts to chafe when you need something it didn't anticipate.","Cost is the part most teams misjudge. Headline compute prices are comparable across providers; the surprises are in egress, managed service premiums, and the operational time you spend. Model the whole bill, not the instance price."]},{id:"4",name:"Observability",description:"Metrics, logs, traces, and error tracking — the tools that tell you what production is actually doing.",icon:"activity",slug:"observability",intro:["Observability tooling answers three separate questions, and it helps to keep them apart: what is the system doing right now (metrics), what happened in this specific case (logs and traces), and what broke for this user (error tracking). Many tools cover more than one; few cover all three equally well.","The main decision is commercial rather than technical. Open-source stacks give you the same core capability with no per-host or per-GB bill, and cost you the time to run them. Commercial platforms are genuinely good and genuinely expensive, and the expense scales with exactly the thing you want more of — data. Teams frequently start open-source, hit an operational wall, and buy; others buy first and later move high-volume telemetry back in-house to control spend.","Whatever you pick, the instrumentation is the durable asset. Standardised, vendor-neutral instrumentation is what makes switching possible later; proprietary agents are what makes it painful."]},{id:"5",name:"APIs",description:"Designing, testing, documenting and consuming APIs — clients, specs, gateways and query layers.",icon:"code",slug:"apis",intro:["API tooling covers the whole lifecycle: designing a contract, testing against it, publishing docs, and giving consumers something pleasant to work with.","The first fork is the paradigm. REST is the default and stays the right answer for most public and internal APIs — it's cacheable, well-understood, and every client speaks it. Query layers like GraphQL earn their complexity when clients genuinely need to shape their own responses and you'd otherwise be maintaining a growing set of bespoke endpoints. Choosing it for a single first-party frontend usually costs more than it returns.","The second is spec-first versus code-first. Writing the contract before the implementation keeps consumers and producers honest and makes generated clients and docs fall out for free. Code-first is faster to start and tends to drift. Either way, the tools in this category are largely about keeping the spec, the implementation and the documentation from disagreeing."]},{id:"6",name:"Frameworks",description:"Frontend and full-stack frameworks for building web applications.",icon:"layers",slug:"frameworks",intro:["Framework choice is the decision teams argue about most and regret least — the mainstream options are all capable, and the differences that matter are rarely the ones benchmarks measure.","What actually decides it: the rendering model you need (a static marketing site, an app behind a login, and something needing server rendering for SEO have genuinely different requirements), how much the framework decides for you, and how easily you can hire or onboard people who already know it. Ecosystem depth compounds — the library you need at month six is more likely to exist for a popular framework.","The meaningful split is between libraries that render views and full-stack frameworks that also own routing, data fetching and deployment. The latter save a lot of assembly and give up 
3some freedom about how the pieces fit. Neither is the wrong answer; picking a full-stack framework and then fighting its conventions is."]},{id:"7",name:"Databases",description:"Relational, document, key-value and search stores, plus the managed platforms that run them.",icon:"database",slug:"databases",intro:["The useful way to read this category is by data model, not by brand. Relational databases give you schemas, joins and transactional guarantees, and remain the correct default for most applications. Document stores relax the schema in exchange for flexibility, which helps when the shape of the data genuinely varies and hurts when it didn't need to. Key-value stores are built for speed and simple access patterns. Search engines exist because querying text well is a different problem from querying rows.","Most applications need one primary store and, eventually, a cache. The common mistake is reaching for a second database to solve a problem the first one already handles — modern relational engines do JSON, full-text search and queuing perfectly well at small and medium scale, and one system you understand deeply beats three you half-run.","The other decision is managed versus self-hosted. Managed platforms handle backups, upgrades and failover, which are exactly the things that hurt most when neglected. Self-hosting is cheaper in cash and more expensive in attention."]},{id:"8",name:"Security",description:"Scanning, secrets management, identity, and the tooling that finds problems before attackers do.",icon:"shield",slug:"security",intro:["Security tooling here covers a few distinct jobs: finding vulnerabilities in your own code, finding them in your dependencies, managing secrets, and handling identity and access.","Dependency scanning is the highest-return starting point for most teams — the majority of exploitable surface arrives through packages nobody reviewed, and automated alerts on known CVEs are cheap to adopt. Static analysis of your own code is next, though it needs tuning: a scanner that cries wolf gets ignored, which is worse than not having one.","Secrets management and identity are less about finding problems and more about not creating them. Hardcoded credentials remain one of the most common real-world breaches, and the fix is boring and effective. Treat the tools in this category as complements rather than alternatives: they address different failure modes, and none of them substitute for the others."]},{id:"10",name:"Finance Tools",description:"Payments, billing, banking APIs and accounting tools for developers and the products they build.",icon:"dollar-sign",slug:"finance-tools",intro:["This category covers the money layer: taking payments, running subscriptions, connecting to bank data, and the accounting that follows.","For payments, the practical decision is how much of the regulatory and operational burden you want to outsource. Full-stack processors handle card data, compliance scope, fraud tooling and payouts behind one API — expensive per transaction, and dramatically cheaper than doing it yourself. What varies most between them is not the API but the coverage: which countries, which payment methods, and what happens when a payment fails.","Billing is where teams underestimate the work. Subscriptions sound simple until proration, upgrades, dunning, tax and refunds arrive. It's worth checking whether your processor's billing layer covers your model before building your own on top of raw charges."]},{id:"11",name:"Learning Platforms",description:"Courses, interactive tutorials and structured curricula for learning programming and tech skills.",icon:"book",slug:"learning-platforms",intro:["Learning platforms differ mostly in structure and incentive. Free, non-profit curricula tend to be project-heavy and self-directed. Marketplace platforms have enormous range and uneven quality, because anyone can publish. Subscription libraries aimed at professionals are more consistent and more expensive. University-affiliated platforms sit closest to formal instruction, with the pacing that implies.","The honest advice is that the platform matters less than whether the format matches how y
3ou actually learn and whether the material is current. Fast-moving topics date badly, and a highly-rated course recorded three years ago may teach patterns the ecosystem has since abandoned — check when it was last updated before the star rating.","For most people the binding constraint is finishing, not access. Interactive platforms that make you write code tend to beat video libraries on completion, whatever the catalogue size."]},{id:"12",name:"Design",description:"Interface and product design tools — vector editors, prototyping, design systems, and the handoff into code.",icon:"layers",slug:"design",intro:["Design tooling for software teams covers a few jobs that used to need separate applications: drawing interfaces, prototyping behaviour, maintaining a component library, and handing all of it to the people who implement it.","The dividing line that matters most is browser-based and multiplayer versus native and single-user. Collaborative editors made review and handoff enormously cheaper — a link is always the current version — and they tie you to a hosted service and a proprietary file format. Native tools remain faster on large files and keep your work on disk, at the cost of the shared-cursor workflow most teams now expect. Anything promising to turn a design file into production code deserves scepticism proportional to how much of your UI is genuinely generic.","The durable artefact is not the file, it's the system: named tokens for colour, type and spacing, and components that exist in both the design tool and the codebase under the same names. Teams that skip that step end up with beautiful mockups and an interface that doesn't match them, whichever tool they used."]},{id:"13",name:"No-Code & Low-Code",description:"Visual builders for apps, websites, internal tools and automations, plus the platforms that back them.",icon:"workflow",slug:"no-code",intro:["No-code and low-code platforms are not competing with frameworks at the same layer. They win where an application is mostly forms, tables and workflow over a data source that already exists — internal tools, admin panels, back-office processes, marketing sites — and where the alternative is a backlog ticket nobody will get to.","The trade-off is the ceiling. Every platform is fast until you need the thing it didn't anticipate, and then you're either writing code inside someone else's runtime or rebuilding. Before committing anything load-bearing, the questions worth answering are what the escape hatch looks like, whether you can export your data and logic in a usable form, and how pricing behaves as usage grows — per
3-seat, per-run and per-record models diverge sharply once a tool succeeds internally.","Low-code sits between the two: real code where it's needed, generated scaffolding everywhere else. That tends to age better than pure no-code for anything a developer will maintain, because the parts you inevitably outgrow are the parts you can already read."]},{id:"14",name:"Productivity & Collaboration",description:"Issue trackers, docs and wikis, chat, and whiteboards — the tools teams coordinate work in.",icon:"zap",slug:"productivity",intro:["This category covers where the work is described rather than where it runs: issue tracking and planning, shared documents and wikis, team chat, and the diagramming and whiteboard tools that sit around them.","The recurring choice is suite versus best-of-breed. A single vendor covering tracking, docs and chat gives you one login, linked references between them and one bill. Assembling the best tool for each job usually produces a better daily experience and leaves you maintaining the integrations between them. Both work; the failure mode is picking best-of-breed and then not doing the integration work, so nobody knows which system is authoritative.","Two things are worth weighing more than feature lists. The first is how much process the tool imposes — heavyweight trackers are genuinely useful for organisations that need audit trails and portfolio views, and pure overhead for a team of six. The second is exit cost: issue history and internal documentation are among the hardest things to move between vendors, so a tool that's merely adequate but easy to export from is often the safer bet."]},{id:"15",name:"Testing & QA",description:"Test runners, browser and device automation, load testing, and the services that run them at scale.",icon:"terminal",slug:"testing",intro:["Testing tools divide by what they exercise: unit and integration runners that call your code directly, browser automation that drives a real UI, device and browser clouds that do it on hardware you don't own, and load tools that ask what happens under pressure. This is distinct from CI, which is the thing that runs them — the pipeline is a DevOps decision, the test stack is this one.","The economics are the same everywhere. Tests close to the code are fast, stable and cheap to keep; tests that drive a whole browser catch the failures that matter most to users and cost far more in runtime and maintenance. Modern browser automation has narrowed the flakiness gap considerably by waiting on state rather than sleeping, but an end-to-e
3nd suite is still a system you own and debug, not a box you tick.","Cross-browser and real-device testing is where buying beats building for almost everyone: maintaining a device lab is a job, and the hosted grids exist because it's a bad job. Visual regression and load testing are worth adding when you have a specific reason — a UI that changes often, or a launch with a number attached — rather than as default infrastructure."]},{id:"16",name:"Mobile Development",description:"Native and cross-platform frameworks, build and release automation, crash reporting, and app distribution.",icon:"box",slug:"mobile",intro:["Mobile has its own toolchain because it has its own constraints: two platforms with different languages and conventions, a release that has to pass review, and users who may sit on an old version for months.","The first decision is native versus cross-platform, and the honest framing is what you're optimising. Native gives you the platform's own idioms, immediate access to new OS features, and two codebases to keep in step. Cross-platform frameworks remove most of that duplication and are entirely capable of shipping serious products; the cost arrives at the edges, where platform APIs diverge and you end up writing native modules anyway. The size and skills of the team usually decide this more sensibly than any benchmark.","The surrounding tooling matters more than newcomers expect. Signing, build automation, beta distribution, crash reporting and staged rollouts are the difference between shipping weekly and shipping when someone has a free afternoon. Store rules — particularly around in-app purchases and what a review will reject — are a product constraint, not an implementation detail, and they belong in planning rather than in the week you submit."]},{id:"17",name:"Data & Analytics",description:"Pipelines, warehouses, transformation, BI and product analytics — moving data and making sense of it.",icon:"activity",slug:"data-analytics",intro:["This category is about the data you analyse, not the data your application serves and not the telemetry that tells you production is healthy. Databases are the stores; observability answers what the system is doing; the tools here move data between systems, reshape it, and put it in front of people who ask business and product questions.","The prevailing pattern is to land raw data in a warehouse first and transform it there, rather than transforming in flight. It's easier to fix a modelling mistake when the source data is still sitting untouched, and it separates the ingestion problem from the definitions problem. Managed connectors are the fast path and are priced by volume in a way that surprises teams whose volume grows; hand-written pipelines are cheap until a source API changes and someone has to notice.","Product analytics is a different discipline again, and the tooling is rarely the hard part. What decides whether it's useful is the event schema: a small, deliberately named set of events consistently instrumented beats an exhaustive one nobody trusts. Consent, retention and whether analytics data can leave your infrastructure are constraints to settle before instrumenting, not after."]},{id:"18",name:"CMS & Content",description:"Headless and traditional content management, structured content APIs, and publishing platforms.",icon:"globe",slug:"cms",intro:["Content management splits into systems that own the whole site — content, templates and rendering together — and headless systems that store structured content and hand it to whatever frontend you build. A third approach keeps content as files in the repository, reviewed and deployed like code.","Coupled platforms get a site live quickly and come with an editing experience non-technical people already understand, including themes, plugins and preview. Headless gives developers complete freedom over the frontend and gives editors nothing for free: previews, draft states and a sensible editing UI become your responsibility, and skipping them is the usual reason a headless migration is resented by the people who publish. Git-based content is excellent for documentation and developer-authored material and a poor fit for anyone unwilling to open a pull request.","The decision that outlives the vendor is the content model. Fields and relationships that reflect what the content actually is — rather than how one design happens to lay it out — survive redesigns and migrations. Content modelled around a specific page template has to be re-modelled the moment that template changes."]},{id:"19",name:"Version Control & Code Hosting",description:"Git hosting and forges, code review, code search, and the tooling around how changes get merged.",icon:"server",slug:"version-control",intro:["Git won, so this category is less about version control itself and more about what sits around it: where repositories live, how changes are reviewed, how people find code, and what else the host bundles in.","Hosted forges differ mainly in how much they include. Some are deliberately broad, covering issues, CI, packages and deployment in one product, which is genuinely convenient and makes the host harder to leave. Others stay closer to hosting and review and expect you to bring the rest. Self-hosted forges exist for organisations with compliance or air-gap requirements, and for people who object to their code living on someone else's servers; they're capable, and they're another service to run.","Review is where the real bottleneck usually is. Large pull requests get shallow reviews, and the tooling that helps — stacked or dependent changes, good code search, ownership rules that route reviews to the right people — matters more as the repository and the team grow. Monorepos put specific pressure on this: the hosting is rarely the problem, the tooling that has to reason about which parts of a large tree changed is."]},{id:"20",name:"Documentation",description:"Docs site generators, hosted documentation platforms, API reference tooling and internal knowledge bases.",icon:"book",slug:"documentation",intro:["Documentation tools are for writing and publishing reference material — product docs, API references, internal knowledge bases. That's a different job from a CMS aimed at marketing and editorial content, and a different job again from courses that teach a subject from scratch.","The main fork is docs-as-code versus a hosted editor. Keeping docs in the repository means they're reviewed alongside the change that made them necessary, versioned with the softw
3are, and editable by anyone comfortable with a pull request — which is a real filter. Hosted platforms with a visual editor open contribution to support, product and sales, and put the content somewhere your release process doesn't reach. Teams whose docs are mostly written by engineers tend to be happier with the first; teams where they aren't tend to be happier with the second.","Generated API reference is worth automating from the spec or the source, because hand-maintained reference is wrong within a release or two. It is not a substitute for explanatory guides, which nothing generates for you. The failure mode in this category is almost never the tooling — it's documentation that quietly stops matching the product, so favour whatever setup makes updating docs part of shipping rather than a separate task."]},{id:"21",name:"AI Agents & Assistants",description:"Agent frameworks, coding assistants, and the memory, tool-calling and sandbox infrastructure they run on.",icon:"bot",slug:"ai-agents",intro:["An agent is a model given tools and a loop: it decides what to call, reads the result, and decides again. Almost everything in this category is one of two things — a framework for writing that loop, or a piece of infrastructure the loop needs. Separating those two is the first useful distinction, because the frameworks compete with each other and the infrastructure mostly does not.","The frameworks differ less in what they can express than in how much they hide. Thin libraries leave orchestration, retries and state to you and stay easy to debug when a run goes wrong. Higher-level builders get a working agent faster and are harder to reason about at 2am. Visual builders trade both for accessibility to people who will not be reading a stack trace at all.","The infrastructure half is where the practical problems live: giving an agent a sandbox so generated code cannot touch your machine, giving it durable memory across sessions, letting it browse the real web, and authenticating it against third-party APIs without handing it your credentials. These are unglamorous and they are usually what determines whether an agent survives contact with production.","Coding assistants sit slightly apart. They are agents, but the loop is wrapped in an editor and the evaluation is subjective — whether it fits how you work matters more than any benchmark, which is why this is a category worth trying rather than reading about."]}]])},20349,e=>{"use strict";e.i(90522);var t=e.i(66565);e.s(["formatStars",0,function(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${Math.round(e/1e3)}k`:String(e)},"getStarsUpdatedAt",0,function(){return t.default.generatedAt}])}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.