OpenAI is shockingly good at unminifying code

Written by on .

engineering
openai
ai use cases

  1. Overview
    1. Key Components and Functions

      While browsing the Internet for inspiration, I came across an interesting-looking component.

      Reactive Network Hackathon

      I thought the block with the running ASCII art looked cool, but I couldn't quite figure out how it was implemented, so I started looking at the source code.

      I found the code that looked like it might be doing the job, but it was minified.

      const { floor: ra, abs: KE, min: QE } = Math, O5 = ["reactive.network REACTIVE.NETWORK", "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~<>i!lI;:,^`'. .:â–‘â–’â–“â–ˆ"], G7 = Date.now() % 3 ? O5[1] : O5[0], V5 = G7.length, JE = { fps: 60 }; function eT(e, t, n, r) { const i = t.time * 8e-5, s = QE(t.cols, t.rows), o = t.metrics.aspect * 0.2, l = { x: ((4 * (e.x - t.cols / 6.25)) / s) * o, y: (5 * (e.y - t.rows / 4)) / s }, u = ra(KE(YE(l) - i) * V5 + (ra(e.x / 1) % 2) * 2) % V5; return G7[u]; } const tT = () => { const e = j.useRef(null), [t, n] = j.useState({ height: null, width: null }); return ( j.useEffect(() => { function r() { n({ height: window.innerHeight, width: window.innerWidth }); } if (typeof window < "u") return n({ height: window.innerHeight, width: window.innerWidth }), window.addEventListener("resize", r), () => window.removeEventListener("resize", r); }, []), j.useEffect(() => { const r = e.current; if (!r) return; const i = 12, s = ra(t.width / i) * 1.6, o = ra(t.height / i), l = { aspect: s / o }, u = setInterval(() => { let c = ""; for (let d = 0; d < o; d++) { for (let f = 0; f < s; f++) c += eT({ x: f, y: d }, { cols: s, rows: o, metrics: l, time: Date.now() }); c += ` `; } r.textContent = c; }, 1e3 / JE.fps); return () => clearInterval(u); }, [t]), a.jsx("div", { style: { position: "absolute", top: 0, left: 0, width: "100%", height: "100%" }, children: a.jsx("div", { ref: e, style: { width: "100%", height: "100%", whiteSpace: "pre", overflow: "hidden" } }) }) ); }; function nT(e) { return Math.cos(e.x * e.x - e.y * e.y); } const { floor: ia, abs: rT, min: iT } = Math, D5 = ["reactive.network REACTIVE.NETWORK", "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~<>i!lI;:,^`'. .:â–‘â–’â–“â–ˆ"], X7 = Date.now() % 3 ? D5[1] : D5[0], F5 = X7.length, sT = { fps: 60 }; function oT(e, t, n, r) { const i = t.time * 8e-5, s = iT(t.cols, t.rows), o = t.metrics.aspect * 0.2, l = { x: ((4 * (e.x - t.cols / 6.25)) / s) * o, y: (5 * (e.y - t.rows / 4)) / s }, u = ia(rT(nT(l) - i) * F5 + (ia(e.x / 1) % 2) * 2) % F5; return X7[u]; } const aT = () => { const e = j.useRef(null), [t, n] = j.useState({ height: null, width: null }); return ( j.useEffect(() => { function r() { n({ height: window.innerHeight, width: window.innerWidth }); } if (typeof window < "u") return n({ height: window.innerHeight, width: window.innerWidth }), window.addEventListener("resize", r), () => window.removeEventListener("resize", r); }, []), j.useEffect(() => { const r = e.current; if (!r) return; const i = 12, s = ia(t.width / i) * 1.6, o = ia(t.height / i), l = { aspect: s / o }, u = setInterval(() => { let c = ""; for (let d = 0; d < o; d++) { for (let f = 0; f < s; f++) c += oT({ x: f, y: d }, { cols: s, rows: o, metrics: l, time: Date.now() }); c += ` `; } r.textContent = c; }, 1e3 / sT.fps); return () => clearInterval(u); }, [t]), a.jsx("div", { style: { position: "absolute", top: 0, left: 0, width: "100%", height: "100%" }, children: a.jsx("div", { ref: e, style: { width: "100%", height: "100%", whiteSpace: "pre", overflow: "hidden" } }) }) ); },

      Usually, I would just powerthrough reading the minimized code to understand the implementation (or look for a .map file to restore the original code). However, I realized that I never tried asking ChatGPT to do it for me... So I copied all of the above code and asked ChatGPT to "explain the code". Here is the response:

      The provided code is quite complex, but I'll break it down into a more understandable format, explaining its different parts and their functionalities.

      Overview

      The code defines several functions and components using JavaScript, specifically in the context of a React application. It deals with generating some dynamic text content, presumably ASCII art or some kind of visual effect using characters from a predefined set. Additionally, it includes utility functions for event handling, performance timing, and HTML content conversion.

      Key Components and Functions

      1. Character Set Selection:
        const { floor: ra, abs: KE, min: QE } = Math; const O5 = ["reactive.network REACTIVE.NETWORK", "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~<>i!lI;:,^`'. .:â–‘â–’â–“â–ˆ"]; const G7 = Date.now() % 3 ? O5[1] : O5[0]; const V5 = G7.length;
        • This part of the code imports some common Math functions (floor, abs, and min) and defines two sets of characters, stored in O5.
        • Based on the current time (Date.now() % 3), it selects one of these sets (G7) to use later.
        • The length of the selected character set is stored in V5.
      2. Dynamic Character Selection Function:
        function eT(e, t, n, r) { const i = t.time * 8e-5; const s = QE(t.cols, t.rows); const o = t.metrics.aspect * 0.2; const l = { x: ((4 * (e.x - t.cols / 6.25)) / s) * o, y: (5 * (e.y - t.rows / 4)) / s }; const u = ra(KE(YE(l) - i) * V5 + (ra(e.x / 1) % 2) * 2) % V5; return G7[u]; }
        • The eT function generates a character based on the input position (e.x, e.y) and the current time (t.time).
        • It adjusts the position using some aspect ratio calculations and selects a character from G7 based on a combination of the position and time.
        • The purpose of YE function isn't directly clear from the code, but it seems to be a custom function used in this calculation.
      3. React Component (tT) for Displaying Dynamic Content:
        const tT = () => { const e = j.useRef(null); const [t, n] = j.useState({ height: null, width: null }); j.useEffect(() => { function r() { n({ height: window.innerHeight, width: window.innerWidth }); } if (typeof window < "u") { n({ height: window.innerHeight, width: window.innerWidth }); window.addEventListener("resize", r); return () => window.removeEventListener("resize", r); } }, []); j.useEffect(() => { const r = e.current; if (!r) return; const i = 12; const s = ra(t.width / i) * 1.6; const o = ra(t.height / i); const l = { aspect: s / o }; const u = setInterval(() => { let c = ""; for (let d = 0; d < o; d++) { for (let f = 0; f < s; f++) c += eT({ x: f, y: d }, { cols: s, rows: o, metrics: l, time: Date.now() }); c += ` `; } r.textContent = c; }, 1e3 / JE.fps); return () => clearInterval(u); }, [t]); return a.jsx("div", { style: { position: "absolute", top: 0, left: 0, width: "100%", height: "100%" }, children: a.jsx("div", { ref: e, style: { width: "100%", height: "100%", whiteSpace: "pre", overflow: "hidden" } }) }); };
        • This is a React component that sets up an interval to periodically update the content of a div element (e.current) with dynamically generated characters.
        • It calculates the number of columns (s) and rows (o) based on the window size and then fills the div with characters generated by the eT function.
        • The effect runs at a specified frames per second (JE.fps).

      I followed up asking to "implement equivalent code in TypeScript and make it human readable" and got the following response:

      import React, { useEffect, useRef, useState } from 'react'; const selectedCharacterSet = "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~<>i!lI;:,^`'. .:â–‘â–’â–“â–ˆ"; const characterSetLength = selectedCharacterSet.length; const calculateCharacter = ( x: number, y: number, cols: number, rows: number, aspect: number, time: number, ): string => { const timeFactor = time * 0.000_08; const size = Math.min(cols, rows); const aspectRatio = aspect * 0.2; const position = { x: ((4 * (x - cols / 6.25)) / size) * aspectRatio, y: (5 * (y - rows / 4)) / size, }; const index = Math.floor( Math.abs( Math.cos(position.x * position.x - position.y * position.y) - timeFactor, ) * characterSetLength + (Math.floor(x) % 2) * 2, ) % characterSetLength; return selectedCharacterSet[index]; }; type Size = { height: null | number; width: null | number; }; const AsciiArtGenerator: React.FC = () => { const textRef = useRef<HTMLDivElement>(null); const [size, setSize] = useState<Size>({ height: null, width: null }); useEffect(() => { const handleResize = () => { setSize({ height: window.innerHeight, width: window.innerWidth }); }; // Initial size setting handleResize(); window.addEventListener('resize', handleResize); return () => { window.removeEventListener('resize', handleResize); }; }, []); useEffect(() => { const element = textRef.current; if (!element || !size.width || !size.height) return undefined; const cols = Math.floor(size.width / 12) * 1.6; const rows = Math.floor(size.height / 12); const aspectRatio = cols / rows; const intervalId = setInterval(() => { let content = ''; for (let y = 0; y < rows; y++) { for (let x = 0; x < cols; x++) { content += calculateCharacter( x, y, cols, rows, aspectRatio, Date.now(), ); } content += '\n'; } element.textContent = content; }, 1_000 / 60); // 60 fps return () => { clearInterval(intervalId); }; }, [size]); return ( <div ref={textRef} style={{ height: '100%', overflow: 'hidden', whiteSpace: 'pre', width: '100%', }} /> ); }; export default () => { return <AsciiArtGenerator />; };

      To my surprise, the response is not only good enough, but it is also very readable.

      Here is the above component in action:

      l^`:▒B8*apqQLXXnntt(({{]}?[?[?[]{}()ttxxzXCLwqho&%▒░'^ll~~-_]-?~~l; ▒WaOYt[I &hQXf|[]-}{jcmo░l(zd&.I_-]<I▒MLtl▓pY/{-}|Xp░~cd░;--+^BQ(.az|?[|LW>u*.+-+ or;kc}]1UM+J$l]~'p(█ +ii;:. ▓█8&*oddZZLLYUczuvnvxvnvuzcYYCCOOppao&8█▓ ,:ii++?-]-?~~l;.░8*wCx)<,█MwLuf{}-]](fYZM░>)YqB.!~]-+;.#Zt~▓hYj}]?|uw%ifqB:<]+l█dj!WQt}-(vh.|m▒l?_l%Q_$Ct?}jp.jk^~]IBz!k ?+_<<ll^^..██%8##hadbwqZwOmOmOmZqwddhh##88$█:.`^II>>_+?-]-?~~lI'.BWdOcf?i.@hmYu|1?]?{)xXq#.!|zd&.;+_]~!.8Zn+ aQj)?[{nLW^(C& <_?!.oU_░wv{][r0$~UM,~]> dj'kn{-|Y%~Q@i-_ k)░L ]-]_-~~!i;;``..▓▓@@88MW#Mo#o#oM*WM8&@B▓▓::''::!!~<-_?-]-?~~!l` $8hqUu1_,:WkQYj/}[-[[|rUmW░>1Xw8:I<?--l`8dv['&0v)[-{tJk._Xk░I--+^@O/`#Yt?[)Yh,/d▒>--:BJ-%Q|[]xw'/h._-iBCi#u -_]-]_-~+>>ll::`` .░:▓▒█▓$█@█$▓█▒▓:░ `':,ll>>+~-_]-]-?~+!!^'▓@*bQXt{i^█Wp0cx){?]?{)xXw*:I)vw#:,~_]+<`▓kJ1lBdzt[]]|uqBitw8,>]_i░au+@wr1-{jm@-Y&`_-~.hf:bc}]1Y#<YB;?+,hj.w/ ~~?_]-]-?+_<~i>Il:;^,'^.` ' ' '.`',^;:lIii~<_+?_]-]-?++i!,^░█WomLut?i.█*dCzf|[[-[[|jYO#█I]u0#█,!--?>I▒MQr>:hLj)?]{xC#.{Y*░i+]<,8Z)^aJ([?|zo'tw▒l?_lB0?▓0j?[/Z▓)w.>]i:O[8J{ ii+~?_]-]-?_-~+>~i>l!Il;I:I:I:I:l;!l>!<>+~-+?-]-]-?++>i:,.░%WbmYu)?I'B#wQvr)1?]?{1rcOk$`?fQk$ !~]-_I'8dv}`8Zc(}-}|Xq█ixm@`+-?l.hz~▓mu{]]jQB>Xo`<]<^oclMz(-{nh,uo,+?;%z!ku] :;>>++?_]-]-?_?+_~+<~i<i>!>!>!>!<i~>+~_+-_?-]-]-?+_>>I;' $Bob0Ur(+l.$odCXj/}[-]])/cCb&'>/zdW.,~_]+<^▒aQ|>█hUr}[?)jQo`]Ua.I--+^$Zf,WJf]]{cp }O%I+]!:q/ bx{-|Y8<C%!_-'ot.Zf? .`II<>_+?_]-]-]_?_-+_~_<+<+<+<+<_~_+-_?_]-]-]-?+_<<ll^'░█W*qOXn1?I'@Mp0zn|)]]-[}txJmM▓l[u0*$^l_-]<!.%wc?^Wwv/]]]/vq%!/Z&^i?_< MU}:kc|?[(Jo;fb▒>_-:@L[$O/[?f0▒}w▒<-~░q[█J|- ░.^,!!~<_+?_]-]-]-?_?_-+-+-+-+-+-_?_?-]-]-]-?+-<~!!:, :@8adQUr|-i.▓Mk0Uxf1{?]?{)rcOk@'_|Jp%:I>?--i:█*Lj>:hQr)?]}jYa░-ub$;~]+!▓hn~@wr1-{fO8~v# ~-_`Wc<WJ)][nq`th _->$Q~&c1- $▓ ';;ii+~-_?-]-]-]-]_?_?_?_?_?_?_]-]-]-]-?_-~+>>I;`.▒█W*pZYu|[i,▒%hqJzf/}[-]])|uUp#:;{xOa█.i~]-_l`%kz):$qU/1-[1nQW'1Y*░!+]<;BqtlMQt{-1xq▓]U8^_-~.arIhz{]}chInM^-_l&YIon{? 8B░.^,ll<>_+-_?-]-]-]-]-]-]-]-]-]-]-]-]-?_-+_<<!!,, :@%*kZLvj}_:.BMpOXu/([[-[[|fzLk8'>|zqM:^<+]_+; Wwn]'&Oc(}-}(cZB;/L& >_]>^W01^aJ|[-(vk.)0$:-->▒d|`pv}]1Y#<X%:?+:*u^bj[] M8▓▒'`;;ii~~_+?_]-]-]-]-]-]-]-]-]-]-]-]_?+-~+i>II``░▒%WkpQYr|->`░&omLvx(1]]-[}/rUO*@:_jUk& :~_]_<,░*Of_:#Qu)[-{|Yq█!rZB'~-?!'#C[.bX)[?|zo`tm▒I?_!$w1.mx[])C&_J$I?+^hr qt[] *W$▓ .::!!<<_+-_?_]-]-]-]-]-]-]-]-]-]-?_-+_<~!i;:'.▒█&#dwJzf)+! ▓MhOJnj)1?]-}{txJmM▓I?xCa%';+_]+>`▓hQ/<▒oCn1[-{/Ud░<nw$^+-?l aU-:pz1[?tY#,jq░l?_l@O[░Or][(QB]L▓l]~`bt:m/[[ o#@$. ,,ll<>+~-_?_]-]-]-]-]-]-]-]-]-]_?_-~_<<!!::. █$M*pZUv/{<I.$*b0Unf1{?]-}{fnLwW▒![uQo@`I+_]+>'█kC(>█aJx{[-1tJk:~vq█,+--l.hX+░qc1]]tUW;xd.!]+I%0?▒0j][|0@[0▒!]<'d/▒O|][ a#B$. ,,ll<>+~-+?_?-]-]-]-]-]-]-]-]-]_?_-~+><!!:,. █@MoqZYv/{<I:$*bQUxf1{?]-}1fnLq&░![uQ*@`I__]+>'█kC(i█hUx{[-1fCk.+vp█,+--I.hX+▒wv{]]fUW;xd.!]+I%Q?▓0j?[|0@}0▒!]<.p|▒O|]} o#@$. ,,ll<>+~-_?_]-]-]-]-]-]-]-]-]-]_?_-~_<<!!::. █$M*pZUv/{<I.$*b0Unf1{?]-}{fnLwW▒![uQo@`I+_]+>'█kC(>█aJx{[-1tJk:~vq█,+--l.hX+░qc1]]tUW;xd.!]+I%0?▒0j][|0@[0▒!]<'d/▒O|][ *W$▓ .::!!<<_+-_?_]-]-]-]-]-]-]-]-]-]-?_-+_<~!i;:'.▒█&#dwJzf)+! ▓MhOJnj)1?]-}{txJmM▓I?xCa%';+_]+>`▓hQ/<▒oCn1[-{/Ud░<nw$^+-?l aU-:pz1[?tY#,jq░l?_l@O[░Or][(QB]L▓l]~`bt:m/[[ M8▓▒'`;;ii~~_+?_]-]-]-]-]-]-]-]-]-]-]-]_?+-~+i>II``░▒%WkpQYr|->`░&omLvx(1]]-[}/rUO*@:_jUk& :~_]_<,░*Of_:#Qu)[-{|Yq█!rZB'~-?!'#C[.bX)[?|zo`tm▒I?_!$w1.mx[])C&_J$I?+^hr qt[] 8B░.^,ll<>_+-_?-]-]-]-]-]-]-]-]-]-]-]-]-?_-+_<<!!,, :@%*kZLvj}_:.BMpOXu/([[-[[|fzLk8'>|zqM:^<+]_+; Wwn]'&Oc(}-}(cZB;/L& >_]>^W01^aJ|[-(vk.)0$:-->▒d|`pv}]1Y#<X%:?+:*u^bj[] $▓ ';;ii+~-_?-]-]-]-]_?_?_?_?_?_?_]-]-]-]-?_-~+>>I;`.▒█W*pZYu|[i,▒%hqJzf/}[-]])|uUp#:;{xOa█.i~]-_l`%kz):$qU/1-[1nQW'1Y*░!+]<;BqtlMQt{-1xq▓]U8^_-~.arIhz{]}chInM^-_l&YIon{? ░.^,!!~<_+?_]-]-]-?_?_-+-+-+-+-+-_?_?-]-]-]-?+-<~!!:, :@8adQUr|-i.▓Mk0Uxf1{?]?{)rcOk@'_|Jp%:I>?--i:█*Lj>:hQr)?]}jYa░-ub$;~]+!▓hn~@wr1-{fO8~v# ~-_`Wc<WJ)][nq`th _->$Q~&c1- .`II<>_+?_]-]-]_?_-+_~_<+<+<+<+<_~_+-_?_]-]-]-?+_<<ll^'░█W*qOXn1?I'@Mp0zn|)]]-[}txJmM▓l[u0*$^l_-]<!.%wc?^Wwv/]]]/vq%!/Z&^i?_< MU}:kc|?[(Jo;fb▒>_-:@L[$O/[?f0▒}w▒<-~░q[█J|- :;>>++?_]-]-?_?+_~+<~i<i>!>!>!>!<i~>+~_+-_?-]-]-?+_>>I;' $Bob0Ur(+l.$odCXj/}[-]])/cCb&'>/zdW.,~_]+<^▒aQ|>█hUr}[?)jQo`]Ua.I--+^$Zf,WJf]]{cp }O%I+]!:q/ bx{-|Y8<C%!_-'ot.Zf? ii+~?_]-]-?_-~+>~i>l!Il;I:I:I:I:l;!l>!<>+~-+?-]-]-?++>i:,.░%WbmYu)?I'B#wQvr)1?]?{1rcOk$`?fQk$ !~]-_I'8dv}`8Zc(}-}|Xq█ixm@`+-?l.hz~▓mu{]]jQB>Xo`<]<^oclMz(-{nh,uo,+?;%z!ku] ~~-_]-]_?+_<~i>Il:;^,'^.` ' ' '.`',^;:lIii~<_+?_]-]-?++i!,^░█WomLut?i.█*dCzf|[[-[[|jYO#█I]u0#█,!--?>I▒MQr>:hLj)?]{xC#.{Y*░i+]<,8Z)^aJ([?|co'tw▒l?_lB0?▓0j?[/Z▓)w.>]i:O[8J{ -_]-]_-~+>>ll::`` .░:▓▒█▓$█@█$▓█▒▓:░ `':,ll>>+~-_]-]-?~+!l^'▓@*bQXt{i^█Wp0cx){?]?{)xXw*:I)vw#:,~_]+<`▓kJ1lBdzt[]]|uqBitw8,>]_i░au+@wr1-{jm@-Y&`_-~.hf:bc}]1Y#<YB;?+,hj.w/ ]-]_-~~!i;;``..▓▓@@88MW*Mo#o#oM*WM8&@B▓▓::''::!!~<-_?-]-?~~!l` $8hqUu1_,:WkQYj/}[-[[|rUmW░>1Xw8:I<?--l`8dv['&0v)[-{tJk._Xk░I--+^@O/`#Yt?[)Yh,/d▒>--:BJ-%Q|[]xw'/h._-iBCi#u ?+_<<ll^^..██%8##haddwqZwOmOmOmZqwddhh##88$█:.`^II>>_+?-]-?~~lI'.BWdOcf?i.@hmYu|1?]?{)xXq#.!|zd&.;+_]~!.8Zn+ aQj)?[{nLW^(C& <_?!.oU_▒wv{][r0$~UM,~]> dj'kn{-|Y%~Q@i-_ k)░L +ii;:. ▓█8&*oddZZLLYUczuvnvxunvuzcYYCCOOppao&8█▓ ,:ii++?-]-?~~l;.░8*wCx)<,█MwLuf{}-]](fYZM░>)YqB.!~]-+;.#Zt~▓hYj}]?|uw%ifqB:<]+l█dj!WQt}-(vh.|m▒l?_l%Q_$Ct?}jp.jk^~]IBz!k l^`:▒B8*apqQLXXnntt(({{]}?[?[?[]{}()ttxxzXCLwqho&%▒░'^ll~~-_]-?~~l; ▒WaOYt[I &hQXf|[]-}{jcmo░l(zd&.I_-]<I▒MLtl▓pY/{-}|Xp░~cd░;--+^BQ(.az|?[|LM>u*.+-+ or;kc}]1UM+J$l]~'p(█ █@M*dqQCcuft1{--<>ll:;^,'^'^',`:,lI>>__}{/tnvJLwpo#B$..:I><-_]-?+~l:.▓MkLc)_^▓oqYu|1?]?1/cQo$l}zw8:l<]-+::oQ(!Bpct]][fYa:[z*:i_]i'*J-░wu}][xZ▒?Q8I+?l▒O1▓Zt[?jZ (k _-i%Jl Whd0Lcu/(]?>i:, ▒▒@$8%W8M&M&M8W%8@@▓▓. ^,!i-?)|xvJQpbM8▓:^:i>__]-?+~l::█*dJn[>.Bb0vj1}-][/xLd@^[nwM.:+-]<I▒#C/;@wz(}-{tCa`}L#'i?_i░au<8Of}-)uh./w░!]+;WUi&X(-1u*lY&l_-'a| OXvt(?_l;. █$8&*obkqpmwOZ0Z0Z0ZOmZqqbbooW&$█. :I+-)/uzQZh*B█.`l!++]-?+~l::$oqXj-I▓WmJr/[[-}1rXpW'+xQM▓;>?-_;.*Q(!%qv/]]}rCM`(L8'~--I▒qr;WUt?[(J*lxo +-+ af,du[](LB}O:>]i▒Q /[_l:.░B8*appOOCCXYczuvnuxurnxuxvuccYXCJ00qpho&%▒:,I+?|fzJwbW%:.;l~+?-]+~l:░@hmc/~^Bo0Xt)]]?1/z0#▒<|Ck▓`<_]~!:WQfl$wz(}-1fQ#:(Z8,<]+I@w|,hY)[]fCB<UM:~]!░m)▓mt[]rm'to'-_IM ; ▒%WhbZOJUccxxfj|/(|1(1){){){){(1|)/|ftxxvvUU0OdkM&▓::l-}juLZaM█:,;<~?-]++l:░BkOu)i.&bJu({?]]|rCd$:1cb%`!---l'Wmf<$dc/]]}rCW,/0B^+-_,@0( hv(-}fm$[L@;?_l%L+BU|-{uoIY&l__. Wkd0QXzxxtt)({1[}][?[?[-]-]-]-]-]?[?[]}[1{()//rxczLQqbM8░.l<{/cJqh%█',><--]_+l:░Bb0x{I:*wXx1}-[}fcwM'+nO&:!~]_<'@wu<░dY|}-{fQ#:(Z%:~]~:80} pv{][nw.{m█i_-^&cioX{]1J&?Q▒i]i Lzvjj(({{][?]-]-]-]?[?[?}]}]}]}?[?[?]-]-]-]?[]{}((fjucCQpk&@ ,~[fv0qMB.`!>--]_+l:░%dQj[,▓hOvf}[-})nJh$i(Ch▒,~_]<;$kv]:oYf[][jU#`|0B^_-_^BL{░px1-1nb /q:i]~^an^hx{-/L▒1d._- f))[}?]-]-[?}]{}){()/(t|f/f/f/f|t(/)(1)}{]}?[-]-]?}[11tfucLObo@░:>{tY0hW▒ Ii__]__!:░%dCt?`@dQx/[]?1/XZ8']up8`!--_;.aC}^*Qf1-}|Jh`{0&,<]~:80[:wu}]{cb^tk:~-+ h/'wx][tq ja,+ [-]-]?}[11||ffnxcvXXJULJQC0L0CQJLUJXYvcxnfj|/1)[}?[-]-[]11tfvX0w*8:^+}xYqa@░:l+_]__!:░%pC/_.%qJj(]]?(jLb▒!tC#▒l~]_> 80t;%Ou{]?/ch:{J&'+-_,BL{░px1-)ua`rb.<]> q|░m/[]np:u&: []{{||jrvcUJ0Oqqkk**WM%&B%@%@%B8%W&*#hhppZOCJzcxr//11][-]-[]1)frXCqh%░;~|nQp&█`;~+]--i;░%pJ|~.&ZYt1?][/um#`?cq$`<_]<:@dx+█dv|?[1cw░_U*'>]+IBZ{ qu}]{zk:ja +-<▒q{▒Qt-{noIU% tfucJLmqho&8█▓ ,,ll>>+~-+?_?+-~+><ll:,. ▒▓%8oapwQCzvjf))[[-]-[[)|xvCZo8 ;]/YO*B ,<~]--i;:%pU(<░#0z|{-[}jXb@!(Q*.I---I.aJ['hJ/}-1rm%~uo:>-?;▓Z| bn1-1ua^xk'<]i:Z{@Q(]}z*~J Omho%@: :I~_}{//xxccYYCJLCQCQCQJCYUccnxtt1{_+lI'.$B*awZUXxr()[[-]?}}|fcUwh@ >[xJbW░`i~?-?>I:%pU)i▓*Lv(}-[1nL*:-ndB,>?_~'BOf;8Qx}]]jJ&;rq░l?_i▓d/^bc{]}vd,fa +-<▓m]$J|-1c&~ ▒ ;!-[|fvcCLmwkk**&W%8@B█@█@█@█B$%BW&*#hkqwQLzcj/}?iI.:%WbqLUnr()[[-]?{)juCm#@^<|vma█ l>?-?<l.BpY1!█aJn1[-}(zZ%,)U*░!+]+l▓hv-▓dv(?[(Yk`1ZBI+]i bx:*z(-{xb.fd.<]i:Z}BL)]{YW (fcYOmkaW&$█::'',,I;lIili!>!>!>liI!;I,:'`..▓█8&ohwZUzj/]+;'█%hpLUnj)1]]-[[(tcJd#░:]fLd%░;i--?<! BpY1l@kUx{[-{/Ud▒irZB'<_?i`WO),oC/}-)xq█]U&`+-+.#v>MJ)]]xm (d:~-~▒q[█J|-)z ko8B░:`^II>i~<_+-_?_]-]-]-]-]-]-]-]_?_?+_~+i>Il^^.:@%*hm0zn)]!,▒BapCXrt{}?]?{)rv0d%.<1zZM█,l_-]~! @dY{lBbXj}]?)jQa.-Xb▒:_--;░dv>█Zu{]]jC8!vk.i]+;&C+$Lf?[tZ▓1m:i]> w)$Q(]} ^,!!~~-_?-]-]-?_-+_~+<~>~><i<>~>~<+~_+-_?-]-]-]_-~~i!:,.░%WkqJc/}i,▓8kmYvt([[-[[|fY0o@:_rJh%'I+_]+i.$dU{I%dzf[]?(xZW;1Q#.!?-~'8L(.oX/?[)Xk^(q$!_?I▓O)▒wf}?/C$-O$>-+ k)░Q/- -_]-]_?+_><l!:;`^ .:.▒░█▒$▓$▓$▒█░▒.:. ``::ll>>+~-_]-]_?~~!l`.▓BodLX/}!^$MqQvr){?]?{(nYq#.l)cqM.,~_]+>'█bU{I%pct[]]/vpB>fq%:<]+!▒hu~Bmr1-{jm$?U8^_-<:kt,bv}]1UM~U@I?+^hf:m/ -~~!l,^..█$&&oobdmw00CLUJYUXUYJULC0QmmddaoW&@$:.`^ll<<-_]-]_-<>:^░$*bLz|?;.&hQYj|[[-[}tnQd@'?j0a▓`>+]_<^▓kJ{I8qv/]][fXh▒-vh▓l+]<:8Z)^hU([?/YM;xb i]~,#X!WX(-1uo;cM;_?,Mr^w '▒█&MkdOQXzrj()[]++i>Il:;,:^:,;:lIii~~]]))frczL0pb#W$▓.'Il<~--]-?~<I,░$*dJn{<.$hmXx){?]])tX0#▒i1YpB !~]_~,▒hC1I8wu|]][jU* {UM.>_?!.aX~█Zn[]}uw:[OBl_?I█Q[$O/[]xw'ta'__l&X; ZUzj/[?il`'▒▓%%##hhddwqZwOmOmOwZqwdphh*#8%█▓.'I!_]|fcYOwaM$▒'^!i__]-?~~I,▒Bhmct+:$#ZUj|[]-})xYd8^-nOW░I<]-+::aL1I8wu|?]}xL&,/0B`+--;▓wf,#Y/?[|CMiu#.+-~.k/`pn]]|0$1m.>]!▓C >^.█B#opq0QYYvvrxfj/t(/)|)|)|)|)/(t/ftxrvuXYLQwqa*%$.`!~{|uYZpM%░.;l++]-?~<;`█&qCf[:░*wXx)}-[[tuOa░!/Uo$:>?-_;.*Q)I8mn(?]{uOBlxw▓:--+`8J[▒px1-1xp:)Z▒l?+;WYiWz)-)zW<L@i-+: pQCzvrj||{1[}][?]-]-]-]-]-]-]-]-]-]-]-]?[?}[1{|(fjvcJLqdM8░'!+)jY0k#█::I~+]-?~>^.8aLu[!▓MZYf(]]?)fUwB`}vd8`!---l.#0(l8mn(?[1vm▓<ck.l?_>:an>WL/[?/U&!z*,~]!░Z1█O/[]np:nW,?+ |{{][-]-]?[]{})1|(t|ftrfrjxjxjxfrtf/t(|1)}{][?]-]-[]{}||rnYCwbW@.;-1uUqa@░,I~+]-->l █aZu1I░omcf}[-})uL*▒~tO# I_-?!'WZ|l8mx)?[)zp:-U*'i]+l$w(`bz{][nm.{w▓>-_`#x;bv[]|0▓(p'~ ]?}}))ttnnzXCCZZppkkoa#*WM&M&MW#Mo*khppZZLLXXunff((}}?]-]?}[(|ruJ0k#▓.>]jzwh@░:l+_]_+l^█MZc}!█*Qc|{-[}jzp%;{Jk▒,+-?i^8mt!8mx)-[(Yb.}QW,<]~:WC-▓Or]]1U*!uM`_-i$O-@U|-1cW<Q$ uvJLwqa*%@░:^,l!++]]{{()/(/|/(/)({1]]++i!,^.:@B#opqQCcvft11][-]?}{/fcUmk%░l-fzwo$.Ii--]~>^░#wu1:▓bLr|]]]|x0o.+vw@'<_]>,%qf>%mx)-[|Ua^)mBI+]>'avl&U/?}tZ█{O▒!]~^ax'dj}?rw^x @▒`:<_{(rnXY00qqhh**WM8&B8B8B8B&8WW*#hhppO0UYux|1-~;^░█WoqZUzrf)1]]-[])|xc0p&▒I-jYdM░`i~?--i;▒WZc]:%dYr{[-{/Yq█ltQ&.i_]<;@dr<Bwx)-}|C*;/p█!_?l░qt'hu1-1ua,na^~]l▓L-&U{]1CB uX0mka&8▓▓ ^^I;!l>i<>~<+<+<+<+<+>~i>!i;I,,..▒▓%8ohwOYct)_>`.%#pZYvf|}}-]?{)rvQp&░![uLa%.;~_]_~,:#mx].8Zz|{-[1uQW'{Xo▒l~]~l█kn~@wx)-}/LM!jk░>--;$Q{▓mf}?/JB+QB!--'*f`wr?}r : ,:!i~~-_?-]-]-]_?_?+-+-~_~_~_+-+-_?_]-]-]-?_-~+ii;:..$%okOCnt?<`░WaZCuj){?]?}1jv0dB ~(Yw&▒;i--?>;▒MQr~ o0x(?][fXk▓+xd@:<]+!▒av_$qx)-}tQ&>no.~-_^&X+&L([]xm.|k.+->█O_8z)- ?-]-]_-~~iiII^,.':.▓▒$█@$B@%@B$B█$▒▓::..^^I;i!~<-_?-]-?+_ii:^░█MaZJr(~;▒%bZXn|1?]-}1rcZa▓:}xZo▒`>+]_~,░aQ|i$kYj}]?(nm&I(OW`i]_>.#z?▓pn)-}t08~cM'+-+.*xIaX{]{zoic8:?+:*n'pf

      Comparing the outputs, it looks like LLM response overlooked a few implementation details, but it is still a good enough implementation to learn from. Definitely a neat use case I've not considered before!

      Update (2024-08-29): Initially, I thought that the LLM didn't replicate the logic accurately because the output was missing a few characters visible in the original component (e.g., ░▒▓█). However, a user on HN forum pointed out that it was likely a copy-paste error.

      Upon further investigation, I discovered that the original code contains different characters than what I pasted into ChatGPT. This appears to be an encoding issue, as I was able to get the correct characters after downloading the script. After updating the code to use the correct characters, the output is now identical to the original component.

      I apologize, GPT-4, for mistakenly accusing you of making mistakes.

      Written by Frank Fiegel (@punkpeye)