From 5efccffede5995e029d6150888bc6065befa6de0 Mon Sep 17 00:00:00 2001 From: tiennm99 Date: Mon, 27 Apr 2026 09:19:18 +0700 Subject: [PATCH] feat: add classic/modern dual-mode with HSL color classifier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Classic mode reproduces the 2018 toidicodedao image and its 5 hardcoded element cards verbatim. Modern mode renders a data-driven grid built from GitHub Linguist colors classified into Ngũ Hành elements via a deterministic HSL rule set. Toggle persists via URL hash; both panels coexist in DOM with a CSS opacity fade. Includes a collapsed debug panel listing skipped (no color) and borderline (near hue boundary) entries. - data/github-colors.json: vendored from ozh/github-colors (722 entries) - js/classify-element.js: pure HSL classifier (664 lang sample, 22/22 fixtures pass) - js/mode-toggle.js: tablist with hash persistence + arrow-key nav - js/render-elements.js: chip rendering with YIQ contrast + debug panel - js/main.js: fetch + classify + render entry point - style.css: segmented toggle, panel fade, chip pill, debug-panel, mobile --- data/github-colors.json | 2890 +++++++++++++++++ index.html | 101 +- js/classify-element.js | 58 + js/classify-element.test.html | 78 + js/main.js | 51 + js/mode-toggle.js | 70 + js/render-elements.js | 96 + .../phase-01-data-and-classifier.md | 155 + .../phase-02-dual-mode-shell.md | 248 ++ .../phase-03-render-modern-grid.md | 214 ++ .../phase-04-style-polish.md | 272 ++ .../phase-05-debug-verify-panel.md | 177 + .../260427-0854-color-element-mapping/plan.md | 87 + ...er-260427-0854-nguhanh-color-classifier.md | 295 ++ ...cher-260427-0855-github-language-colors.md | 258 ++ style.css | 147 + 16 files changed, 5164 insertions(+), 33 deletions(-) create mode 100644 data/github-colors.json create mode 100644 js/classify-element.js create mode 100644 js/classify-element.test.html create mode 100644 js/main.js create mode 100644 js/mode-toggle.js create mode 100644 js/render-elements.js create mode 100644 plans/260427-0854-color-element-mapping/phase-01-data-and-classifier.md create mode 100644 plans/260427-0854-color-element-mapping/phase-02-dual-mode-shell.md create mode 100644 plans/260427-0854-color-element-mapping/phase-03-render-modern-grid.md create mode 100644 plans/260427-0854-color-element-mapping/phase-04-style-polish.md create mode 100644 plans/260427-0854-color-element-mapping/phase-05-debug-verify-panel.md create mode 100644 plans/260427-0854-color-element-mapping/plan.md create mode 100644 plans/reports/researcher-260427-0854-nguhanh-color-classifier.md create mode 100644 plans/reports/researcher-260427-0855-github-language-colors.md diff --git a/data/github-colors.json b/data/github-colors.json new file mode 100644 index 0000000..1b38bf1 --- /dev/null +++ b/data/github-colors.json @@ -0,0 +1,2890 @@ +{ + "1C Enterprise": { + "color": "#814CCC", + "url": "https://github.com/trending?l=1C-Enterprise" + }, + "2-Dimensional Array": { + "color": "#38761D", + "url": "https://github.com/trending?l=2-Dimensional-Array" + }, + "4D": { + "color": "#004289", + "url": "https://github.com/trending?l=4D" + }, + "ABAP": { + "color": "#E8274B", + "url": "https://github.com/trending?l=ABAP" + }, + "ABAP CDS": { + "color": "#555e25", + "url": "https://github.com/trending?l=ABAP-CDS" + }, + "ActionScript": { + "color": "#882B0F", + "url": "https://github.com/trending?l=ActionScript" + }, + "Ada": { + "color": "#02f88c", + "url": "https://github.com/trending?l=Ada" + }, + "Adblock Filter List": { + "color": "#800000", + "url": "https://github.com/trending?l=Adblock-Filter-List" + }, + "Adobe Font Metrics": { + "color": "#fa0f00", + "url": "https://github.com/trending?l=Adobe-Font-Metrics" + }, + "Agda": { + "color": "#315665", + "url": "https://github.com/trending?l=Agda" + }, + "AGS Script": { + "color": "#B9D9FF", + "url": "https://github.com/trending?l=AGS-Script" + }, + "AIDL": { + "color": "#34EB6B", + "url": "https://github.com/trending?l=AIDL" + }, + "Aiken": { + "color": "#640ff8", + "url": "https://github.com/trending?l=Aiken" + }, + "AL": { + "color": "#3AA2B5", + "url": "https://github.com/trending?l=AL" + }, + "ALGOL": { + "color": "#D1E0DB", + "url": "https://github.com/trending?l=ALGOL" + }, + "Alloy": { + "color": "#64C800", + "url": "https://github.com/trending?l=Alloy" + }, + "Alpine Abuild": { + "color": "#0D597F", + "url": "https://github.com/trending?l=Alpine-Abuild" + }, + "Altium Designer": { + "color": "#A89663", + "url": "https://github.com/trending?l=Altium-Designer" + }, + "AMPL": { + "color": "#E6EFBB", + "url": "https://github.com/trending?l=AMPL" + }, + "AngelScript": { + "color": "#C7D7DC", + "url": "https://github.com/trending?l=AngelScript" + }, + "Answer Set Programming": { + "color": "#A9CC29", + "url": "https://github.com/trending?l=Answer-Set-Programming" + }, + "Ant Build System": { + "color": "#A9157E", + "url": "https://github.com/trending?l=Ant-Build-System" + }, + "Antlers": { + "color": "#ff269e", + "url": "https://github.com/trending?l=Antlers" + }, + "ANTLR": { + "color": "#9DC3FF", + "url": "https://github.com/trending?l=ANTLR" + }, + "ApacheConf": { + "color": "#d12127", + "url": "https://github.com/trending?l=ApacheConf" + }, + "Apex": { + "color": "#1797c0", + "url": "https://github.com/trending?l=Apex" + }, + "API Blueprint": { + "color": "#2ACCA8", + "url": "https://github.com/trending?l=API-Blueprint" + }, + "APL": { + "color": "#5A8164", + "url": "https://github.com/trending?l=APL" + }, + "Apollo Guidance Computer": { + "color": "#0B3D91", + "url": "https://github.com/trending?l=Apollo-Guidance-Computer" + }, + "AppleScript": { + "color": "#101F1F", + "url": "https://github.com/trending?l=AppleScript" + }, + "Arc": { + "color": "#aa2afe", + "url": "https://github.com/trending?l=Arc" + }, + "AsciiDoc": { + "color": "#73a0c5", + "url": "https://github.com/trending?l=AsciiDoc" + }, + "ASL": { + "color": null, + "url": "https://github.com/trending?l=ASL" + }, + "ASP.NET": { + "color": "#9400ff", + "url": "https://github.com/trending?l=ASP.NET" + }, + "AspectJ": { + "color": "#a957b0", + "url": "https://github.com/trending?l=AspectJ" + }, + "Assembly": { + "color": "#6E4C13", + "url": "https://github.com/trending?l=Assembly" + }, + "Astro": { + "color": "#ff5a03", + "url": "https://github.com/trending?l=Astro" + }, + "Asymptote": { + "color": "#ff0000", + "url": "https://github.com/trending?l=Asymptote" + }, + "ATS": { + "color": "#1ac620", + "url": "https://github.com/trending?l=ATS" + }, + "Augeas": { + "color": "#9CC134", + "url": "https://github.com/trending?l=Augeas" + }, + "AutoHotkey": { + "color": "#6594b9", + "url": "https://github.com/trending?l=AutoHotkey" + }, + "AutoIt": { + "color": "#1C3552", + "url": "https://github.com/trending?l=AutoIt" + }, + "Avro IDL": { + "color": "#0040FF", + "url": "https://github.com/trending?l=Avro-IDL" + }, + "Awk": { + "color": "#c30e9b", + "url": "https://github.com/trending?l=Awk" + }, + "B (Formal Method)": { + "color": "#8aa8c5", + "url": "https://github.com/trending?l=B-(Formal-Method)" + }, + "B4X": { + "color": "#00e4ff", + "url": "https://github.com/trending?l=B4X" + }, + "Ballerina": { + "color": "#FF5000", + "url": "https://github.com/trending?l=Ballerina" + }, + "BASIC": { + "color": "#ff0000", + "url": "https://github.com/trending?l=BASIC" + }, + "Batchfile": { + "color": "#C1F12E", + "url": "https://github.com/trending?l=Batchfile" + }, + "Beef": { + "color": "#a52f4e", + "url": "https://github.com/trending?l=Beef" + }, + "Befunge": { + "color": null, + "url": "https://github.com/trending?l=Befunge" + }, + "Berry": { + "color": "#15A13C", + "url": "https://github.com/trending?l=Berry" + }, + "BibTeX": { + "color": "#778899", + "url": "https://github.com/trending?l=BibTeX" + }, + "BibTeX Style": { + "color": null, + "url": "https://github.com/trending?l=BibTeX-Style" + }, + "Bicep": { + "color": "#519aba", + "url": "https://github.com/trending?l=Bicep" + }, + "Bikeshed": { + "color": "#5562ac", + "url": "https://github.com/trending?l=Bikeshed" + }, + "Bison": { + "color": "#6A463F", + "url": "https://github.com/trending?l=Bison" + }, + "BitBake": { + "color": "#00bce4", + "url": "https://github.com/trending?l=BitBake" + }, + "Blade": { + "color": "#f7523f", + "url": "https://github.com/trending?l=Blade" + }, + "BlitzBasic": { + "color": "#00FFAE", + "url": "https://github.com/trending?l=BlitzBasic" + }, + "BlitzMax": { + "color": "#cd6400", + "url": "https://github.com/trending?l=BlitzMax" + }, + "Bluespec": { + "color": "#12223c", + "url": "https://github.com/trending?l=Bluespec" + }, + "Bluespec BH": { + "color": "#12223c", + "url": "https://github.com/trending?l=Bluespec-BH" + }, + "Boo": { + "color": "#d4bec1", + "url": "https://github.com/trending?l=Boo" + }, + "Boogie": { + "color": "#c80fa0", + "url": "https://github.com/trending?l=Boogie" + }, + "BQN": { + "color": "#2b7067", + "url": "https://github.com/trending?l=BQN" + }, + "Brainfuck": { + "color": "#2F2530", + "url": "https://github.com/trending?l=Brainfuck" + }, + "BrighterScript": { + "color": "#66AABB", + "url": "https://github.com/trending?l=BrighterScript" + }, + "Brightscript": { + "color": "#662D91", + "url": "https://github.com/trending?l=Brightscript" + }, + "Browserslist": { + "color": "#ffd539", + "url": "https://github.com/trending?l=Browserslist" + }, + "Bru": { + "color": "#F4AA41", + "url": "https://github.com/trending?l=Bru" + }, + "BuildStream": { + "color": "#006bff", + "url": "https://github.com/trending?l=BuildStream" + }, + "C": { + "color": "#555555", + "url": "https://github.com/trending?l=C" + }, + "C#": { + "color": "#178600", + "url": "https://github.com/trending?l=Csharp" + }, + "C++": { + "color": "#f34b7d", + "url": "https://github.com/trending?l=C++" + }, + "C2hs Haskell": { + "color": null, + "url": "https://github.com/trending?l=C2hs-Haskell" + }, + "C3": { + "color": "#2563eb", + "url": "https://github.com/trending?l=C3" + }, + "Cabal Config": { + "color": "#483465", + "url": "https://github.com/trending?l=Cabal-Config" + }, + "Caddyfile": { + "color": "#22b638", + "url": "https://github.com/trending?l=Caddyfile" + }, + "Cadence": { + "color": "#00ef8b", + "url": "https://github.com/trending?l=Cadence" + }, + "Cairo": { + "color": "#ff4a48", + "url": "https://github.com/trending?l=Cairo" + }, + "Cairo Zero": { + "color": "#ff4a48", + "url": "https://github.com/trending?l=Cairo-Zero" + }, + "CameLIGO": { + "color": "#3be133", + "url": "https://github.com/trending?l=CameLIGO" + }, + "Cangjie": { + "color": "#00868B", + "url": "https://github.com/trending?l=Cangjie" + }, + "CAP CDS": { + "color": "#0092d1", + "url": "https://github.com/trending?l=CAP-CDS" + }, + "Cap'n Proto": { + "color": "#c42727", + "url": "https://github.com/trending?l=Cap'n-Proto" + }, + "Carbon": { + "color": "#222222", + "url": "https://github.com/trending?l=Carbon" + }, + "CartoCSS": { + "color": null, + "url": "https://github.com/trending?l=CartoCSS" + }, + "Ceylon": { + "color": "#dfa535", + "url": "https://github.com/trending?l=Ceylon" + }, + "Chapel": { + "color": "#8dc63f", + "url": "https://github.com/trending?l=Chapel" + }, + "Charity": { + "color": null, + "url": "https://github.com/trending?l=Charity" + }, + "ChucK": { + "color": "#3f8000", + "url": "https://github.com/trending?l=ChucK" + }, + "Circom": { + "color": "#707575", + "url": "https://github.com/trending?l=Circom" + }, + "Cirru": { + "color": "#ccccff", + "url": "https://github.com/trending?l=Cirru" + }, + "Clarion": { + "color": "#db901e", + "url": "https://github.com/trending?l=Clarion" + }, + "Clarity": { + "color": "#5546ff", + "url": "https://github.com/trending?l=Clarity" + }, + "Classic ASP": { + "color": "#6a40fd", + "url": "https://github.com/trending?l=Classic-ASP" + }, + "Clean": { + "color": "#3F85AF", + "url": "https://github.com/trending?l=Clean" + }, + "Click": { + "color": "#E4E6F3", + "url": "https://github.com/trending?l=Click" + }, + "CLIPS": { + "color": "#00A300", + "url": "https://github.com/trending?l=CLIPS" + }, + "Clojure": { + "color": "#db5855", + "url": "https://github.com/trending?l=Clojure" + }, + "Closure Templates": { + "color": "#0d948f", + "url": "https://github.com/trending?l=Closure-Templates" + }, + "Cloud Firestore Security Rules": { + "color": "#FFA000", + "url": "https://github.com/trending?l=Cloud-Firestore-Security-Rules" + }, + "Clue": { + "color": "#0009b5", + "url": "https://github.com/trending?l=Clue" + }, + "CMake": { + "color": "#DA3434", + "url": "https://github.com/trending?l=CMake" + }, + "COBOL": { + "color": null, + "url": "https://github.com/trending?l=COBOL" + }, + "CodeQL": { + "color": "#140f46", + "url": "https://github.com/trending?l=CodeQL" + }, + "CoffeeScript": { + "color": "#244776", + "url": "https://github.com/trending?l=CoffeeScript" + }, + "ColdFusion": { + "color": "#ed2cd6", + "url": "https://github.com/trending?l=ColdFusion" + }, + "ColdFusion CFC": { + "color": "#ed2cd6", + "url": "https://github.com/trending?l=ColdFusion-CFC" + }, + "COLLADA": { + "color": "#F1A42B", + "url": "https://github.com/trending?l=COLLADA" + }, + "Common Lisp": { + "color": "#3fb68b", + "url": "https://github.com/trending?l=Common-Lisp" + }, + "Common Workflow Language": { + "color": "#B5314C", + "url": "https://github.com/trending?l=Common-Workflow-Language" + }, + "Component Pascal": { + "color": "#B0CE4E", + "url": "https://github.com/trending?l=Component-Pascal" + }, + "Cooklang": { + "color": "#E15A29", + "url": "https://github.com/trending?l=Cooklang" + }, + "Cool": { + "color": null, + "url": "https://github.com/trending?l=Cool" + }, + "CQL": { + "color": "#006091", + "url": "https://github.com/trending?l=CQL" + }, + "crontab": { + "color": "#ead7ac", + "url": "https://github.com/trending?l=crontab" + }, + "Crystal": { + "color": "#000100", + "url": "https://github.com/trending?l=Crystal" + }, + "CSON": { + "color": "#244776", + "url": "https://github.com/trending?l=CSON" + }, + "Csound": { + "color": "#1a1a1a", + "url": "https://github.com/trending?l=Csound" + }, + "Csound Document": { + "color": "#1a1a1a", + "url": "https://github.com/trending?l=Csound-Document" + }, + "Csound Score": { + "color": "#1a1a1a", + "url": "https://github.com/trending?l=Csound-Score" + }, + "CSS": { + "color": "#663399", + "url": "https://github.com/trending?l=CSS" + }, + "CSV": { + "color": "#237346", + "url": "https://github.com/trending?l=CSV" + }, + "Cuda": { + "color": "#3A4E3A", + "url": "https://github.com/trending?l=Cuda" + }, + "CUE": { + "color": "#5886E1", + "url": "https://github.com/trending?l=CUE" + }, + "Curry": { + "color": "#531242", + "url": "https://github.com/trending?l=Curry" + }, + "CWeb": { + "color": "#00007a", + "url": "https://github.com/trending?l=CWeb" + }, + "Cycript": { + "color": null, + "url": "https://github.com/trending?l=Cycript" + }, + "Cylc": { + "color": "#00b3fd", + "url": "https://github.com/trending?l=Cylc" + }, + "Cypher": { + "color": "#34c0eb", + "url": "https://github.com/trending?l=Cypher" + }, + "Cython": { + "color": "#fedf5b", + "url": "https://github.com/trending?l=Cython" + }, + "D": { + "color": "#ba595e", + "url": "https://github.com/trending?l=D" + }, + "D2": { + "color": "#526ee8", + "url": "https://github.com/trending?l=D2" + }, + "Dafny": { + "color": "#FFEC25", + "url": "https://github.com/trending?l=Dafny" + }, + "Darcs Patch": { + "color": "#8eff23", + "url": "https://github.com/trending?l=Darcs-Patch" + }, + "Dart": { + "color": "#00B4AB", + "url": "https://github.com/trending?l=Dart" + }, + "Daslang": { + "color": "#d3d3d3", + "url": "https://github.com/trending?l=Daslang" + }, + "DataWeave": { + "color": "#003a52", + "url": "https://github.com/trending?l=DataWeave" + }, + "Debian Package Control File": { + "color": "#D70751", + "url": "https://github.com/trending?l=Debian-Package-Control-File" + }, + "DenizenScript": { + "color": "#FBEE96", + "url": "https://github.com/trending?l=DenizenScript" + }, + "Dhall": { + "color": "#dfafff", + "url": "https://github.com/trending?l=Dhall" + }, + "DIGITAL Command Language": { + "color": null, + "url": "https://github.com/trending?l=DIGITAL-Command-Language" + }, + "DirectX 3D File": { + "color": "#aace60", + "url": "https://github.com/trending?l=DirectX-3D-File" + }, + "DM": { + "color": "#447265", + "url": "https://github.com/trending?l=DM" + }, + "Dockerfile": { + "color": "#384d54", + "url": "https://github.com/trending?l=Dockerfile" + }, + "Dogescript": { + "color": "#cca760", + "url": "https://github.com/trending?l=Dogescript" + }, + "Dotenv": { + "color": "#e5d559", + "url": "https://github.com/trending?l=Dotenv" + }, + "DTrace": { + "color": null, + "url": "https://github.com/trending?l=DTrace" + }, + "Dune": { + "color": "#89421e", + "url": "https://github.com/trending?l=Dune" + }, + "Dylan": { + "color": "#6c616e", + "url": "https://github.com/trending?l=Dylan" + }, + "E": { + "color": "#ccce35", + "url": "https://github.com/trending?l=E" + }, + "Earthly": { + "color": "#2af0ff", + "url": "https://github.com/trending?l=Earthly" + }, + "Easybuild": { + "color": "#069406", + "url": "https://github.com/trending?l=Easybuild" + }, + "eC": { + "color": "#913960", + "url": "https://github.com/trending?l=eC" + }, + "Ecere Projects": { + "color": "#913960", + "url": "https://github.com/trending?l=Ecere-Projects" + }, + "ECL": { + "color": "#8a1267", + "url": "https://github.com/trending?l=ECL" + }, + "ECLiPSe": { + "color": "#001d9d", + "url": "https://github.com/trending?l=ECLiPSe" + }, + "Ecmarkup": { + "color": "#eb8131", + "url": "https://github.com/trending?l=Ecmarkup" + }, + "Edge": { + "color": "#0dffe0", + "url": "https://github.com/trending?l=Edge" + }, + "EdgeQL": { + "color": "#31A7FF", + "url": "https://github.com/trending?l=EdgeQL" + }, + "EditorConfig": { + "color": "#fff1f2", + "url": "https://github.com/trending?l=EditorConfig" + }, + "Eiffel": { + "color": "#4d6977", + "url": "https://github.com/trending?l=Eiffel" + }, + "EJS": { + "color": "#a91e50", + "url": "https://github.com/trending?l=EJS" + }, + "Elixir": { + "color": "#6e4a7e", + "url": "https://github.com/trending?l=Elixir" + }, + "Elm": { + "color": "#60B5CC", + "url": "https://github.com/trending?l=Elm" + }, + "Elvish": { + "color": "#55BB55", + "url": "https://github.com/trending?l=Elvish" + }, + "Elvish Transcript": { + "color": "#55BB55", + "url": "https://github.com/trending?l=Elvish-Transcript" + }, + "Emacs Lisp": { + "color": "#c065db", + "url": "https://github.com/trending?l=Emacs-Lisp" + }, + "EmberScript": { + "color": "#FFF4F3", + "url": "https://github.com/trending?l=EmberScript" + }, + "EQ": { + "color": "#a78649", + "url": "https://github.com/trending?l=EQ" + }, + "Erlang": { + "color": "#B83998", + "url": "https://github.com/trending?l=Erlang" + }, + "Euphoria": { + "color": "#FF790B", + "url": "https://github.com/trending?l=Euphoria" + }, + "F#": { + "color": "#b845fc", + "url": "https://github.com/trending?l=Fsharp" + }, + "F*": { + "color": "#572e30", + "url": "https://github.com/trending?l=F*" + }, + "Factor": { + "color": "#636746", + "url": "https://github.com/trending?l=Factor" + }, + "Fancy": { + "color": "#7b9db4", + "url": "https://github.com/trending?l=Fancy" + }, + "Fantom": { + "color": "#14253c", + "url": "https://github.com/trending?l=Fantom" + }, + "Faust": { + "color": "#c37240", + "url": "https://github.com/trending?l=Faust" + }, + "Fennel": { + "color": "#fff3d7", + "url": "https://github.com/trending?l=Fennel" + }, + "FIGlet Font": { + "color": "#FFDDBB", + "url": "https://github.com/trending?l=FIGlet-Font" + }, + "Filebench WML": { + "color": "#F6B900", + "url": "https://github.com/trending?l=Filebench-WML" + }, + "Filterscript": { + "color": null, + "url": "https://github.com/trending?l=Filterscript" + }, + "FIRRTL": { + "color": "#2f632f", + "url": "https://github.com/trending?l=FIRRTL" + }, + "fish": { + "color": "#4aae47", + "url": "https://github.com/trending?l=fish" + }, + "FlatBuffers": { + "color": "#ed284a", + "url": "https://github.com/trending?l=FlatBuffers" + }, + "Flix": { + "color": "#d44a45", + "url": "https://github.com/trending?l=Flix" + }, + "Fluent": { + "color": "#ffcc33", + "url": "https://github.com/trending?l=Fluent" + }, + "FLUX": { + "color": "#88ccff", + "url": "https://github.com/trending?l=FLUX" + }, + "Forth": { + "color": "#341708", + "url": "https://github.com/trending?l=Forth" + }, + "Fortran": { + "color": "#4d41b1", + "url": "https://github.com/trending?l=Fortran" + }, + "Fortran Free Form": { + "color": "#4d41b1", + "url": "https://github.com/trending?l=Fortran-Free-Form" + }, + "FreeBASIC": { + "color": "#141AC9", + "url": "https://github.com/trending?l=FreeBASIC" + }, + "FreeMarker": { + "color": "#0050b2", + "url": "https://github.com/trending?l=FreeMarker" + }, + "Frege": { + "color": "#00cafe", + "url": "https://github.com/trending?l=Frege" + }, + "Futhark": { + "color": "#5f021f", + "url": "https://github.com/trending?l=Futhark" + }, + "G-code": { + "color": "#D08CF2", + "url": "https://github.com/trending?l=G-code" + }, + "Game Maker Language": { + "color": "#71b417", + "url": "https://github.com/trending?l=Game-Maker-Language" + }, + "GAML": { + "color": "#FFC766", + "url": "https://github.com/trending?l=GAML" + }, + "GAMS": { + "color": "#f49a22", + "url": "https://github.com/trending?l=GAMS" + }, + "GAP": { + "color": "#0000cc", + "url": "https://github.com/trending?l=GAP" + }, + "GCC Machine Description": { + "color": "#FFCFAB", + "url": "https://github.com/trending?l=GCC-Machine-Description" + }, + "GDB": { + "color": null, + "url": "https://github.com/trending?l=GDB" + }, + "GDScript": { + "color": "#355570", + "url": "https://github.com/trending?l=GDScript" + }, + "GDShader": { + "color": "#478CBF", + "url": "https://github.com/trending?l=GDShader" + }, + "GEDCOM": { + "color": "#003058", + "url": "https://github.com/trending?l=GEDCOM" + }, + "Gemfile.lock": { + "color": "#701516", + "url": "https://github.com/trending?l=Gemfile.lock" + }, + "Gemini": { + "color": "#ff6900", + "url": "https://github.com/trending?l=Gemini" + }, + "Genero 4gl": { + "color": "#63408e", + "url": "https://github.com/trending?l=Genero-4gl" + }, + "Genero per": { + "color": "#d8df39", + "url": "https://github.com/trending?l=Genero-per" + }, + "Genie": { + "color": "#fb855d", + "url": "https://github.com/trending?l=Genie" + }, + "Genshi": { + "color": "#951531", + "url": "https://github.com/trending?l=Genshi" + }, + "Gentoo Ebuild": { + "color": "#9400ff", + "url": "https://github.com/trending?l=Gentoo-Ebuild" + }, + "Gentoo Eclass": { + "color": "#9400ff", + "url": "https://github.com/trending?l=Gentoo-Eclass" + }, + "Gerber Image": { + "color": "#d20b00", + "url": "https://github.com/trending?l=Gerber-Image" + }, + "Gherkin": { + "color": "#5B2063", + "url": "https://github.com/trending?l=Gherkin" + }, + "Git Attributes": { + "color": "#F44D27", + "url": "https://github.com/trending?l=Git-Attributes" + }, + "Git Commit": { + "color": "#F44D27", + "url": "https://github.com/trending?l=Git-Commit" + }, + "Git Config": { + "color": "#F44D27", + "url": "https://github.com/trending?l=Git-Config" + }, + "Git Revision List": { + "color": "#F44D27", + "url": "https://github.com/trending?l=Git-Revision-List" + }, + "Gleam": { + "color": "#ffaff3", + "url": "https://github.com/trending?l=Gleam" + }, + "Glimmer JS": { + "color": "#F5835F", + "url": "https://github.com/trending?l=Glimmer-JS" + }, + "Glimmer TS": { + "color": "#3178c6", + "url": "https://github.com/trending?l=Glimmer-TS" + }, + "GLSL": { + "color": "#5686a5", + "url": "https://github.com/trending?l=GLSL" + }, + "Glyph": { + "color": "#c1ac7f", + "url": "https://github.com/trending?l=Glyph" + }, + "Gnuplot": { + "color": "#f0a9f0", + "url": "https://github.com/trending?l=Gnuplot" + }, + "Go": { + "color": "#00ADD8", + "url": "https://github.com/trending?l=Go" + }, + "Go Checksums": { + "color": "#00ADD8", + "url": "https://github.com/trending?l=Go-Checksums" + }, + "Go Module": { + "color": "#00ADD8", + "url": "https://github.com/trending?l=Go-Module" + }, + "Go Template": { + "color": "#00ADD8", + "url": "https://github.com/trending?l=Go-Template" + }, + "Go Workspace": { + "color": "#00ADD8", + "url": "https://github.com/trending?l=Go-Workspace" + }, + "Godot Resource": { + "color": "#355570", + "url": "https://github.com/trending?l=Godot-Resource" + }, + "Golo": { + "color": "#88562A", + "url": "https://github.com/trending?l=Golo" + }, + "Gosu": { + "color": "#82937f", + "url": "https://github.com/trending?l=Gosu" + }, + "Grace": { + "color": "#615f8b", + "url": "https://github.com/trending?l=Grace" + }, + "Gradle": { + "color": "#02303a", + "url": "https://github.com/trending?l=Gradle" + }, + "Gradle Kotlin DSL": { + "color": "#02303a", + "url": "https://github.com/trending?l=Gradle-Kotlin-DSL" + }, + "Grammatical Framework": { + "color": "#ff0000", + "url": "https://github.com/trending?l=Grammatical-Framework" + }, + "GraphQL": { + "color": "#e10098", + "url": "https://github.com/trending?l=GraphQL" + }, + "Graphviz (DOT)": { + "color": "#2596be", + "url": "https://github.com/trending?l=Graphviz-(DOT)" + }, + "Groovy": { + "color": "#4298b8", + "url": "https://github.com/trending?l=Groovy" + }, + "Groovy Server Pages": { + "color": "#4298b8", + "url": "https://github.com/trending?l=Groovy-Server-Pages" + }, + "GSC": { + "color": "#FF6800", + "url": "https://github.com/trending?l=GSC" + }, + "Hack": { + "color": "#878787", + "url": "https://github.com/trending?l=Hack" + }, + "Haml": { + "color": "#ece2a9", + "url": "https://github.com/trending?l=Haml" + }, + "Handlebars": { + "color": "#f7931e", + "url": "https://github.com/trending?l=Handlebars" + }, + "HAProxy": { + "color": "#106da9", + "url": "https://github.com/trending?l=HAProxy" + }, + "Harbour": { + "color": "#0e60e3", + "url": "https://github.com/trending?l=Harbour" + }, + "Hare": { + "color": "#9d7424", + "url": "https://github.com/trending?l=Hare" + }, + "Haskell": { + "color": "#5e5086", + "url": "https://github.com/trending?l=Haskell" + }, + "Haxe": { + "color": "#df7900", + "url": "https://github.com/trending?l=Haxe" + }, + "HCL": { + "color": "#844FBA", + "url": "https://github.com/trending?l=HCL" + }, + "HIP": { + "color": "#4F3A4F", + "url": "https://github.com/trending?l=HIP" + }, + "HiveQL": { + "color": "#dce200", + "url": "https://github.com/trending?l=HiveQL" + }, + "HLSL": { + "color": "#aace60", + "url": "https://github.com/trending?l=HLSL" + }, + "HOCON": { + "color": "#9ff8ee", + "url": "https://github.com/trending?l=HOCON" + }, + "HolyC": { + "color": "#ffefaf", + "url": "https://github.com/trending?l=HolyC" + }, + "hoon": { + "color": "#00b171", + "url": "https://github.com/trending?l=hoon" + }, + "Hosts File": { + "color": "#308888", + "url": "https://github.com/trending?l=Hosts-File" + }, + "HTML": { + "color": "#e34c26", + "url": "https://github.com/trending?l=HTML" + }, + "HTML+ECR": { + "color": "#2e1052", + "url": "https://github.com/trending?l=HTML+ECR" + }, + "HTML+EEX": { + "color": "#6e4a7e", + "url": "https://github.com/trending?l=HTML+EEX" + }, + "HTML+ERB": { + "color": "#701516", + "url": "https://github.com/trending?l=HTML+ERB" + }, + "HTML+PHP": { + "color": "#4f5d95", + "url": "https://github.com/trending?l=HTML+PHP" + }, + "HTML+Razor": { + "color": "#512be4", + "url": "https://github.com/trending?l=HTML+Razor" + }, + "HTTP": { + "color": "#005C9C", + "url": "https://github.com/trending?l=HTTP" + }, + "Hurl": { + "color": "#FF0288", + "url": "https://github.com/trending?l=Hurl" + }, + "HXML": { + "color": "#f68712", + "url": "https://github.com/trending?l=HXML" + }, + "Hy": { + "color": "#7790B2", + "url": "https://github.com/trending?l=Hy" + }, + "HyPhy": { + "color": null, + "url": "https://github.com/trending?l=HyPhy" + }, + "iCalendar": { + "color": "#ec564c", + "url": "https://github.com/trending?l=iCalendar" + }, + "IDL": { + "color": "#a3522f", + "url": "https://github.com/trending?l=IDL" + }, + "Idris": { + "color": "#b30000", + "url": "https://github.com/trending?l=Idris" + }, + "Ignore List": { + "color": "#000000", + "url": "https://github.com/trending?l=Ignore-List" + }, + "IGOR Pro": { + "color": "#0000cc", + "url": "https://github.com/trending?l=IGOR-Pro" + }, + "ImageJ Macro": { + "color": "#99AAFF", + "url": "https://github.com/trending?l=ImageJ-Macro" + }, + "Imba": { + "color": "#16cec6", + "url": "https://github.com/trending?l=Imba" + }, + "Inform 7": { + "color": null, + "url": "https://github.com/trending?l=Inform-7" + }, + "INI": { + "color": "#d1dbe0", + "url": "https://github.com/trending?l=INI" + }, + "Ink": { + "color": null, + "url": "https://github.com/trending?l=Ink" + }, + "Inno Setup": { + "color": "#264b99", + "url": "https://github.com/trending?l=Inno-Setup" + }, + "Io": { + "color": "#a9188d", + "url": "https://github.com/trending?l=Io" + }, + "Ioke": { + "color": "#078193", + "url": "https://github.com/trending?l=Ioke" + }, + "Isabelle": { + "color": "#FEFE00", + "url": "https://github.com/trending?l=Isabelle" + }, + "Isabelle ROOT": { + "color": "#FEFE00", + "url": "https://github.com/trending?l=Isabelle-ROOT" + }, + "ISPC": { + "color": "#2D68B1", + "url": "https://github.com/trending?l=ISPC" + }, + "J": { + "color": "#9EEDFF", + "url": "https://github.com/trending?l=J" + }, + "Jac": { + "color": "#FC792D", + "url": "https://github.com/trending?l=Jac" + }, + "Jai": { + "color": "#ab8b4b", + "url": "https://github.com/trending?l=Jai" + }, + "Janet": { + "color": "#0886a5", + "url": "https://github.com/trending?l=Janet" + }, + "JAR Manifest": { + "color": "#b07219", + "url": "https://github.com/trending?l=JAR-Manifest" + }, + "Jasmin": { + "color": "#d03600", + "url": "https://github.com/trending?l=Jasmin" + }, + "Java": { + "color": "#b07219", + "url": "https://github.com/trending?l=Java" + }, + "Java Properties": { + "color": "#2A6277", + "url": "https://github.com/trending?l=Java-Properties" + }, + "Java Server Pages": { + "color": "#2A6277", + "url": "https://github.com/trending?l=Java-Server-Pages" + }, + "Java Template Engine": { + "color": "#2A6277", + "url": "https://github.com/trending?l=Java-Template-Engine" + }, + "JavaScript": { + "color": "#f1e05a", + "url": "https://github.com/trending?l=JavaScript" + }, + "JavaScript+ERB": { + "color": "#f1e05a", + "url": "https://github.com/trending?l=JavaScript+ERB" + }, + "JCL": { + "color": "#d90e09", + "url": "https://github.com/trending?l=JCL" + }, + "Jest Snapshot": { + "color": "#15c213", + "url": "https://github.com/trending?l=Jest-Snapshot" + }, + "JetBrains MPS": { + "color": "#21D789", + "url": "https://github.com/trending?l=JetBrains-MPS" + }, + "JFlex": { + "color": "#DBCA00", + "url": "https://github.com/trending?l=JFlex" + }, + "Jinja": { + "color": "#a52a22", + "url": "https://github.com/trending?l=Jinja" + }, + "Jison": { + "color": "#56b3cb", + "url": "https://github.com/trending?l=Jison" + }, + "Jison Lex": { + "color": "#56b3cb", + "url": "https://github.com/trending?l=Jison-Lex" + }, + "Jolie": { + "color": "#843179", + "url": "https://github.com/trending?l=Jolie" + }, + "jq": { + "color": "#c7254e", + "url": "https://github.com/trending?l=jq" + }, + "JSON": { + "color": "#292929", + "url": "https://github.com/trending?l=JSON" + }, + "JSON with Comments": { + "color": "#292929", + "url": "https://github.com/trending?l=JSON-with-Comments" + }, + "JSON5": { + "color": "#267CB9", + "url": "https://github.com/trending?l=JSON5" + }, + "JSONiq": { + "color": "#40d47e", + "url": "https://github.com/trending?l=JSONiq" + }, + "JSONLD": { + "color": "#0c479c", + "url": "https://github.com/trending?l=JSONLD" + }, + "Jsonnet": { + "color": "#0064bd", + "url": "https://github.com/trending?l=Jsonnet" + }, + "Julia": { + "color": "#a270ba", + "url": "https://github.com/trending?l=Julia" + }, + "Julia REPL": { + "color": "#a270ba", + "url": "https://github.com/trending?l=Julia-REPL" + }, + "Jupyter Notebook": { + "color": "#DA5B0B", + "url": "https://github.com/trending?l=Jupyter-Notebook" + }, + "Just": { + "color": "#384d54", + "url": "https://github.com/trending?l=Just" + }, + "Kaitai Struct": { + "color": "#773b37", + "url": "https://github.com/trending?l=Kaitai-Struct" + }, + "KakouneScript": { + "color": "#6f8042", + "url": "https://github.com/trending?l=KakouneScript" + }, + "KCL": { + "color": "#7ABABF", + "url": "https://github.com/trending?l=KCL" + }, + "KDL": { + "color": "#ffb3b3", + "url": "https://github.com/trending?l=KDL" + }, + "KerboScript": { + "color": "#41adf0", + "url": "https://github.com/trending?l=KerboScript" + }, + "KFramework": { + "color": "#4195c5", + "url": "https://github.com/trending?l=KFramework" + }, + "KiCad Layout": { + "color": "#2f4aab", + "url": "https://github.com/trending?l=KiCad-Layout" + }, + "KiCad Legacy Layout": { + "color": "#2f4aab", + "url": "https://github.com/trending?l=KiCad-Legacy-Layout" + }, + "KiCad Schematic": { + "color": "#2f4aab", + "url": "https://github.com/trending?l=KiCad-Schematic" + }, + "Koka": { + "color": "#215166", + "url": "https://github.com/trending?l=Koka" + }, + "KoLmafia ASH": { + "color": "#B9D9B9", + "url": "https://github.com/trending?l=KoLmafia-ASH" + }, + "Kotlin": { + "color": "#A97BFF", + "url": "https://github.com/trending?l=Kotlin" + }, + "KRL": { + "color": "#28430A", + "url": "https://github.com/trending?l=KRL" + }, + "kvlang": { + "color": "#1da6e0", + "url": "https://github.com/trending?l=kvlang" + }, + "LabVIEW": { + "color": "#fede06", + "url": "https://github.com/trending?l=LabVIEW" + }, + "Lambdapi": { + "color": "#8027a3", + "url": "https://github.com/trending?l=Lambdapi" + }, + "Langium": { + "color": "#2c8c87", + "url": "https://github.com/trending?l=Langium" + }, + "Lark": { + "color": "#2980B9", + "url": "https://github.com/trending?l=Lark" + }, + "Lasso": { + "color": "#999999", + "url": "https://github.com/trending?l=Lasso" + }, + "Latte": { + "color": "#f2a542", + "url": "https://github.com/trending?l=Latte" + }, + "Lean": { + "color": null, + "url": "https://github.com/trending?l=Lean" + }, + "Lean 4": { + "color": null, + "url": "https://github.com/trending?l=Lean-4" + }, + "Leo": { + "color": "#C4FFC2", + "url": "https://github.com/trending?l=Leo" + }, + "Less": { + "color": "#1d365d", + "url": "https://github.com/trending?l=Less" + }, + "Lex": { + "color": "#DBCA00", + "url": "https://github.com/trending?l=Lex" + }, + "LFE": { + "color": "#4C3023", + "url": "https://github.com/trending?l=LFE" + }, + "LigoLANG": { + "color": "#0e74ff", + "url": "https://github.com/trending?l=LigoLANG" + }, + "LilyPond": { + "color": "#9ccc7c", + "url": "https://github.com/trending?l=LilyPond" + }, + "Limbo": { + "color": null, + "url": "https://github.com/trending?l=Limbo" + }, + "Linear Programming": { + "color": null, + "url": "https://github.com/trending?l=Linear-Programming" + }, + "Linker Script": { + "color": null, + "url": "https://github.com/trending?l=Linker-Script" + }, + "Liquid": { + "color": "#67b8de", + "url": "https://github.com/trending?l=Liquid" + }, + "Liquidsoap": { + "color": "#990066", + "url": "https://github.com/trending?l=Liquidsoap" + }, + "Literate Agda": { + "color": "#315665", + "url": "https://github.com/trending?l=Literate-Agda" + }, + "Literate CoffeeScript": { + "color": "#244776", + "url": "https://github.com/trending?l=Literate-CoffeeScript" + }, + "Literate Haskell": { + "color": "#5e5086", + "url": "https://github.com/trending?l=Literate-Haskell" + }, + "LiveCode Script": { + "color": "#0c5ba5", + "url": "https://github.com/trending?l=LiveCode-Script" + }, + "LiveScript": { + "color": "#499886", + "url": "https://github.com/trending?l=LiveScript" + }, + "LLVM": { + "color": "#185619", + "url": "https://github.com/trending?l=LLVM" + }, + "Logos": { + "color": null, + "url": "https://github.com/trending?l=Logos" + }, + "Logtalk": { + "color": "#295b9a", + "url": "https://github.com/trending?l=Logtalk" + }, + "LOLCODE": { + "color": "#cc9900", + "url": "https://github.com/trending?l=LOLCODE" + }, + "LookML": { + "color": "#652B81", + "url": "https://github.com/trending?l=LookML" + }, + "LoomScript": { + "color": null, + "url": "https://github.com/trending?l=LoomScript" + }, + "LSL": { + "color": "#3d9970", + "url": "https://github.com/trending?l=LSL" + }, + "Lua": { + "color": "#000080", + "url": "https://github.com/trending?l=Lua" + }, + "Luau": { + "color": "#00A2FF", + "url": "https://github.com/trending?l=Luau" + }, + "M": { + "color": null, + "url": "https://github.com/trending?l=M" + }, + "M3U": { + "color": "#179C7D", + "url": "https://github.com/trending?l=M3U" + }, + "M4": { + "color": null, + "url": "https://github.com/trending?l=M4" + }, + "M4Sugar": { + "color": null, + "url": "https://github.com/trending?l=M4Sugar" + }, + "Macaulay2": { + "color": "#d8ffff", + "url": "https://github.com/trending?l=Macaulay2" + }, + "Makefile": { + "color": "#427819", + "url": "https://github.com/trending?l=Makefile" + }, + "Mako": { + "color": "#7e858d", + "url": "https://github.com/trending?l=Mako" + }, + "Markdown": { + "color": "#083fa1", + "url": "https://github.com/trending?l=Markdown" + }, + "Marko": { + "color": "#42bff2", + "url": "https://github.com/trending?l=Marko" + }, + "Mask": { + "color": "#f97732", + "url": "https://github.com/trending?l=Mask" + }, + "Mathematical Programming System": { + "color": "#0530ad", + "url": "https://github.com/trending?l=Mathematical-Programming-System" + }, + "MATLAB": { + "color": "#e16737", + "url": "https://github.com/trending?l=MATLAB" + }, + "Max": { + "color": "#c4a79c", + "url": "https://github.com/trending?l=Max" + }, + "MAXScript": { + "color": "#00a6a6", + "url": "https://github.com/trending?l=MAXScript" + }, + "mcfunction": { + "color": "#E22837", + "url": "https://github.com/trending?l=mcfunction" + }, + "mdsvex": { + "color": "#5f9ea0", + "url": "https://github.com/trending?l=mdsvex" + }, + "MDX": { + "color": "#fcb32c", + "url": "https://github.com/trending?l=MDX" + }, + "Mercury": { + "color": "#ff2b2b", + "url": "https://github.com/trending?l=Mercury" + }, + "Mermaid": { + "color": "#ff3670", + "url": "https://github.com/trending?l=Mermaid" + }, + "Meson": { + "color": "#007800", + "url": "https://github.com/trending?l=Meson" + }, + "Metal": { + "color": "#8f14e9", + "url": "https://github.com/trending?l=Metal" + }, + "MeTTa": { + "color": "#6a5acd", + "url": "https://github.com/trending?l=MeTTa" + }, + "MiniD": { + "color": null, + "url": "https://github.com/trending?l=MiniD" + }, + "MiniYAML": { + "color": "#ff1111", + "url": "https://github.com/trending?l=MiniYAML" + }, + "MiniZinc": { + "color": "#06a9e6", + "url": "https://github.com/trending?l=MiniZinc" + }, + "Mint": { + "color": "#02b046", + "url": "https://github.com/trending?l=Mint" + }, + "Mirah": { + "color": "#c7a938", + "url": "https://github.com/trending?l=Mirah" + }, + "mIRC Script": { + "color": "#3d57c3", + "url": "https://github.com/trending?l=mIRC-Script" + }, + "MLIR": { + "color": "#5EC8DB", + "url": "https://github.com/trending?l=MLIR" + }, + "Modelica": { + "color": "#de1d31", + "url": "https://github.com/trending?l=Modelica" + }, + "Modula-2": { + "color": "#10253f", + "url": "https://github.com/trending?l=Modula-2" + }, + "Modula-3": { + "color": "#223388", + "url": "https://github.com/trending?l=Modula-3" + }, + "Module Management System": { + "color": null, + "url": "https://github.com/trending?l=Module-Management-System" + }, + "Mojo": { + "color": "#ff4c1f", + "url": "https://github.com/trending?l=Mojo" + }, + "Monkey": { + "color": null, + "url": "https://github.com/trending?l=Monkey" + }, + "Monkey C": { + "color": "#8D6747", + "url": "https://github.com/trending?l=Monkey-C" + }, + "Moocode": { + "color": null, + "url": "https://github.com/trending?l=Moocode" + }, + "MoonBit": { + "color": "#b92381", + "url": "https://github.com/trending?l=MoonBit" + }, + "MoonScript": { + "color": "#ff4585", + "url": "https://github.com/trending?l=MoonScript" + }, + "Motoko": { + "color": "#fbb03b", + "url": "https://github.com/trending?l=Motoko" + }, + "Motorola 68K Assembly": { + "color": "#005daa", + "url": "https://github.com/trending?l=Motorola-68K-Assembly" + }, + "Move": { + "color": "#4a137a", + "url": "https://github.com/trending?l=Move" + }, + "MQL4": { + "color": "#62A8D6", + "url": "https://github.com/trending?l=MQL4" + }, + "MQL5": { + "color": "#4A76B8", + "url": "https://github.com/trending?l=MQL5" + }, + "MTML": { + "color": "#b7e1f4", + "url": "https://github.com/trending?l=MTML" + }, + "MUF": { + "color": null, + "url": "https://github.com/trending?l=MUF" + }, + "mupad": { + "color": "#244963", + "url": "https://github.com/trending?l=mupad" + }, + "Mustache": { + "color": "#724b3b", + "url": "https://github.com/trending?l=Mustache" + }, + "Myghty": { + "color": null, + "url": "https://github.com/trending?l=Myghty" + }, + "nanorc": { + "color": "#2d004d", + "url": "https://github.com/trending?l=nanorc" + }, + "Nasal": { + "color": "#1d2c4e", + "url": "https://github.com/trending?l=Nasal" + }, + "NASL": { + "color": null, + "url": "https://github.com/trending?l=NASL" + }, + "NCL": { + "color": "#28431f", + "url": "https://github.com/trending?l=NCL" + }, + "Nearley": { + "color": "#990000", + "url": "https://github.com/trending?l=Nearley" + }, + "Nemerle": { + "color": "#3d3c6e", + "url": "https://github.com/trending?l=Nemerle" + }, + "nesC": { + "color": "#94B0C7", + "url": "https://github.com/trending?l=nesC" + }, + "NetLinx": { + "color": "#0aa0ff", + "url": "https://github.com/trending?l=NetLinx" + }, + "NetLinx+ERB": { + "color": "#747faa", + "url": "https://github.com/trending?l=NetLinx+ERB" + }, + "NetLogo": { + "color": "#ff6375", + "url": "https://github.com/trending?l=NetLogo" + }, + "NewLisp": { + "color": "#87AED7", + "url": "https://github.com/trending?l=NewLisp" + }, + "Nextflow": { + "color": "#3ac486", + "url": "https://github.com/trending?l=Nextflow" + }, + "Nginx": { + "color": "#009639", + "url": "https://github.com/trending?l=Nginx" + }, + "Nickel": { + "color": "#E0C3FC", + "url": "https://github.com/trending?l=Nickel" + }, + "Nim": { + "color": "#ffc200", + "url": "https://github.com/trending?l=Nim" + }, + "Nit": { + "color": "#009917", + "url": "https://github.com/trending?l=Nit" + }, + "Nix": { + "color": "#7e7eff", + "url": "https://github.com/trending?l=Nix" + }, + "NMODL": { + "color": "#00356B", + "url": "https://github.com/trending?l=NMODL" + }, + "Noir": { + "color": "#2f1f49", + "url": "https://github.com/trending?l=Noir" + }, + "NPM Config": { + "color": "#cb3837", + "url": "https://github.com/trending?l=NPM-Config" + }, + "NSIS": { + "color": null, + "url": "https://github.com/trending?l=NSIS" + }, + "Nu": { + "color": "#c9df40", + "url": "https://github.com/trending?l=Nu" + }, + "NumPy": { + "color": "#9C8AF9", + "url": "https://github.com/trending?l=NumPy" + }, + "Nunjucks": { + "color": "#3d8137", + "url": "https://github.com/trending?l=Nunjucks" + }, + "Nushell": { + "color": "#4E9906", + "url": "https://github.com/trending?l=Nushell" + }, + "NWScript": { + "color": "#111522", + "url": "https://github.com/trending?l=NWScript" + }, + "OASv2-json": { + "color": "#85ea2d", + "url": "https://github.com/trending?l=OASv2-json" + }, + "OASv2-yaml": { + "color": "#85ea2d", + "url": "https://github.com/trending?l=OASv2-yaml" + }, + "OASv3-json": { + "color": "#85ea2d", + "url": "https://github.com/trending?l=OASv3-json" + }, + "OASv3-yaml": { + "color": "#85ea2d", + "url": "https://github.com/trending?l=OASv3-yaml" + }, + "Oberon": { + "color": null, + "url": "https://github.com/trending?l=Oberon" + }, + "Objective-C": { + "color": "#438eff", + "url": "https://github.com/trending?l=Objective-C" + }, + "Objective-C++": { + "color": "#6866fb", + "url": "https://github.com/trending?l=Objective-C++" + }, + "Objective-J": { + "color": "#ff0c5a", + "url": "https://github.com/trending?l=Objective-J" + }, + "ObjectScript": { + "color": "#424893", + "url": "https://github.com/trending?l=ObjectScript" + }, + "OCaml": { + "color": "#ef7a08", + "url": "https://github.com/trending?l=OCaml" + }, + "Odin": { + "color": "#60AFFE", + "url": "https://github.com/trending?l=Odin" + }, + "Omgrofl": { + "color": "#cabbff", + "url": "https://github.com/trending?l=Omgrofl" + }, + "OMNeT++ MSG": { + "color": "#a0e0a0", + "url": "https://github.com/trending?l=OMNeT++-MSG" + }, + "OMNeT++ NED": { + "color": "#08607c", + "url": "https://github.com/trending?l=OMNeT++-NED" + }, + "ooc": { + "color": "#b0b77e", + "url": "https://github.com/trending?l=ooc" + }, + "Opa": { + "color": null, + "url": "https://github.com/trending?l=Opa" + }, + "Opal": { + "color": "#f7ede0", + "url": "https://github.com/trending?l=Opal" + }, + "Open Policy Agent": { + "color": "#7d9199", + "url": "https://github.com/trending?l=Open-Policy-Agent" + }, + "OpenAPI Specification v2": { + "color": "#85ea2d", + "url": "https://github.com/trending?l=OpenAPI-Specification-v2" + }, + "OpenAPI Specification v3": { + "color": "#85ea2d", + "url": "https://github.com/trending?l=OpenAPI-Specification-v3" + }, + "OpenCL": { + "color": "#ed2e2d", + "url": "https://github.com/trending?l=OpenCL" + }, + "OpenEdge ABL": { + "color": "#5ce600", + "url": "https://github.com/trending?l=OpenEdge-ABL" + }, + "OpenQASM": { + "color": "#AA70FF", + "url": "https://github.com/trending?l=OpenQASM" + }, + "OpenRC runscript": { + "color": null, + "url": "https://github.com/trending?l=OpenRC-runscript" + }, + "OpenSCAD": { + "color": "#e5cd45", + "url": "https://github.com/trending?l=OpenSCAD" + }, + "Option List": { + "color": "#476732", + "url": "https://github.com/trending?l=Option-List" + }, + "Org": { + "color": "#77aa99", + "url": "https://github.com/trending?l=Org" + }, + "OverpassQL": { + "color": "#cce2aa", + "url": "https://github.com/trending?l=OverpassQL" + }, + "Ox": { + "color": null, + "url": "https://github.com/trending?l=Ox" + }, + "Oxygene": { + "color": "#cdd0e3", + "url": "https://github.com/trending?l=Oxygene" + }, + "Oz": { + "color": "#fab738", + "url": "https://github.com/trending?l=Oz" + }, + "P4": { + "color": "#7055b5", + "url": "https://github.com/trending?l=P4" + }, + "Pact": { + "color": "#F7A8B8", + "url": "https://github.com/trending?l=Pact" + }, + "Pan": { + "color": "#cc0000", + "url": "https://github.com/trending?l=Pan" + }, + "Papyrus": { + "color": "#6600cc", + "url": "https://github.com/trending?l=Papyrus" + }, + "Parrot": { + "color": "#f3ca0a", + "url": "https://github.com/trending?l=Parrot" + }, + "Parrot Assembly": { + "color": null, + "url": "https://github.com/trending?l=Parrot-Assembly" + }, + "Parrot Internal Representation": { + "color": null, + "url": "https://github.com/trending?l=Parrot-Internal-Representation" + }, + "Pascal": { + "color": "#E3F171", + "url": "https://github.com/trending?l=Pascal" + }, + "Pawn": { + "color": "#dbb284", + "url": "https://github.com/trending?l=Pawn" + }, + "PDDL": { + "color": "#0d00ff", + "url": "https://github.com/trending?l=PDDL" + }, + "PEG.js": { + "color": "#234d6b", + "url": "https://github.com/trending?l=PEG.js" + }, + "Pep8": { + "color": "#C76F5B", + "url": "https://github.com/trending?l=Pep8" + }, + "Perl": { + "color": "#0298c3", + "url": "https://github.com/trending?l=Perl" + }, + "PHP": { + "color": "#4F5D95", + "url": "https://github.com/trending?l=PHP" + }, + "PicoLisp": { + "color": "#6067af", + "url": "https://github.com/trending?l=PicoLisp" + }, + "PigLatin": { + "color": "#fcd7de", + "url": "https://github.com/trending?l=PigLatin" + }, + "Pike": { + "color": "#005390", + "url": "https://github.com/trending?l=Pike" + }, + "Pip Requirements": { + "color": "#FFD343", + "url": "https://github.com/trending?l=Pip-Requirements" + }, + "Pkl": { + "color": "#6b9543", + "url": "https://github.com/trending?l=Pkl" + }, + "PlantUML": { + "color": "#fbbd16", + "url": "https://github.com/trending?l=PlantUML" + }, + "PLpgSQL": { + "color": "#336790", + "url": "https://github.com/trending?l=PLpgSQL" + }, + "PLSQL": { + "color": "#dad8d8", + "url": "https://github.com/trending?l=PLSQL" + }, + "PogoScript": { + "color": "#d80074", + "url": "https://github.com/trending?l=PogoScript" + }, + "Polar": { + "color": "#ae81ff", + "url": "https://github.com/trending?l=Polar" + }, + "Pony": { + "color": null, + "url": "https://github.com/trending?l=Pony" + }, + "Portugol": { + "color": "#f8bd00", + "url": "https://github.com/trending?l=Portugol" + }, + "PostCSS": { + "color": "#dc3a0c", + "url": "https://github.com/trending?l=PostCSS" + }, + "PostScript": { + "color": "#da291c", + "url": "https://github.com/trending?l=PostScript" + }, + "POV-Ray SDL": { + "color": "#6bac65", + "url": "https://github.com/trending?l=POV-Ray-SDL" + }, + "PowerBuilder": { + "color": "#8f0f8d", + "url": "https://github.com/trending?l=PowerBuilder" + }, + "PowerShell": { + "color": "#012456", + "url": "https://github.com/trending?l=PowerShell" + }, + "Praat": { + "color": "#c8506d", + "url": "https://github.com/trending?l=Praat" + }, + "Prisma": { + "color": "#0c344b", + "url": "https://github.com/trending?l=Prisma" + }, + "Processing": { + "color": "#0096D8", + "url": "https://github.com/trending?l=Processing" + }, + "Procfile": { + "color": "#3B2F63", + "url": "https://github.com/trending?l=Procfile" + }, + "Prolog": { + "color": "#74283c", + "url": "https://github.com/trending?l=Prolog" + }, + "Promela": { + "color": "#de0000", + "url": "https://github.com/trending?l=Promela" + }, + "Propeller Spin": { + "color": "#7fa2a7", + "url": "https://github.com/trending?l=Propeller-Spin" + }, + "Pug": { + "color": "#a86454", + "url": "https://github.com/trending?l=Pug" + }, + "Puppet": { + "color": "#302B6D", + "url": "https://github.com/trending?l=Puppet" + }, + "PureBasic": { + "color": "#5a6986", + "url": "https://github.com/trending?l=PureBasic" + }, + "PureScript": { + "color": "#1D222D", + "url": "https://github.com/trending?l=PureScript" + }, + "Pyret": { + "color": "#ee1e10", + "url": "https://github.com/trending?l=Pyret" + }, + "Python": { + "color": "#3572A5", + "url": "https://github.com/trending?l=Python" + }, + "Python console": { + "color": "#3572A5", + "url": "https://github.com/trending?l=Python-console" + }, + "Python traceback": { + "color": "#3572A5", + "url": "https://github.com/trending?l=Python-traceback" + }, + "q": { + "color": "#0040cd", + "url": "https://github.com/trending?l=q" + }, + "Q#": { + "color": "#fed659", + "url": "https://github.com/trending?l=Qsharp" + }, + "QMake": { + "color": null, + "url": "https://github.com/trending?l=QMake" + }, + "QML": { + "color": "#44a51c", + "url": "https://github.com/trending?l=QML" + }, + "Qt Script": { + "color": "#00b841", + "url": "https://github.com/trending?l=Qt-Script" + }, + "Quake": { + "color": "#882233", + "url": "https://github.com/trending?l=Quake" + }, + "QuakeC": { + "color": "#975777", + "url": "https://github.com/trending?l=QuakeC" + }, + "QuickBASIC": { + "color": "#008080", + "url": "https://github.com/trending?l=QuickBASIC" + }, + "R": { + "color": "#198CE7", + "url": "https://github.com/trending?l=R" + }, + "Racket": { + "color": "#3c5caa", + "url": "https://github.com/trending?l=Racket" + }, + "Ragel": { + "color": "#9d5200", + "url": "https://github.com/trending?l=Ragel" + }, + "Raku": { + "color": "#0000fb", + "url": "https://github.com/trending?l=Raku" + }, + "RAML": { + "color": "#77d9fb", + "url": "https://github.com/trending?l=RAML" + }, + "Rascal": { + "color": "#fffaa0", + "url": "https://github.com/trending?l=Rascal" + }, + "RAScript": { + "color": "#2C97FA", + "url": "https://github.com/trending?l=RAScript" + }, + "RBS": { + "color": "#701516", + "url": "https://github.com/trending?l=RBS" + }, + "RDoc": { + "color": "#701516", + "url": "https://github.com/trending?l=RDoc" + }, + "REALbasic": { + "color": null, + "url": "https://github.com/trending?l=REALbasic" + }, + "Reason": { + "color": "#ff5847", + "url": "https://github.com/trending?l=Reason" + }, + "ReasonLIGO": { + "color": "#ff5847", + "url": "https://github.com/trending?l=ReasonLIGO" + }, + "Rebol": { + "color": "#358a5b", + "url": "https://github.com/trending?l=Rebol" + }, + "Record Jar": { + "color": "#0673ba", + "url": "https://github.com/trending?l=Record-Jar" + }, + "Red": { + "color": "#f50000", + "url": "https://github.com/trending?l=Red" + }, + "Redcode": { + "color": null, + "url": "https://github.com/trending?l=Redcode" + }, + "Regular Expression": { + "color": "#009a00", + "url": "https://github.com/trending?l=Regular-Expression" + }, + "Ren'Py": { + "color": "#ff7f7f", + "url": "https://github.com/trending?l=Ren'Py" + }, + "RenderScript": { + "color": null, + "url": "https://github.com/trending?l=RenderScript" + }, + "ReScript": { + "color": "#ed5051", + "url": "https://github.com/trending?l=ReScript" + }, + "reStructuredText": { + "color": "#141414", + "url": "https://github.com/trending?l=reStructuredText" + }, + "REXX": { + "color": "#d90e09", + "url": "https://github.com/trending?l=REXX" + }, + "Rez": { + "color": "#FFDAB3", + "url": "https://github.com/trending?l=Rez" + }, + "Ring": { + "color": "#2D54CB", + "url": "https://github.com/trending?l=Ring" + }, + "Riot": { + "color": "#A71E49", + "url": "https://github.com/trending?l=Riot" + }, + "RMarkdown": { + "color": "#198ce7", + "url": "https://github.com/trending?l=RMarkdown" + }, + "RobotFramework": { + "color": "#00c0b5", + "url": "https://github.com/trending?l=RobotFramework" + }, + "Roc": { + "color": "#7c38f5", + "url": "https://github.com/trending?l=Roc" + }, + "Rocq Prover": { + "color": "#d0b68c", + "url": "https://github.com/trending?l=Rocq-Prover" + }, + "Roff": { + "color": "#ecdebe", + "url": "https://github.com/trending?l=Roff" + }, + "Roff Manpage": { + "color": "#ecdebe", + "url": "https://github.com/trending?l=Roff-Manpage" + }, + "RON": { + "color": "#a62c00", + "url": "https://github.com/trending?l=RON" + }, + "ROS Interface": { + "color": "#22314e", + "url": "https://github.com/trending?l=ROS-Interface" + }, + "Rouge": { + "color": "#cc0088", + "url": "https://github.com/trending?l=Rouge" + }, + "RouterOS Script": { + "color": "#DE3941", + "url": "https://github.com/trending?l=RouterOS-Script" + }, + "RPC": { + "color": null, + "url": "https://github.com/trending?l=RPC" + }, + "RPGLE": { + "color": "#2BDE21", + "url": "https://github.com/trending?l=RPGLE" + }, + "Ruby": { + "color": "#701516", + "url": "https://github.com/trending?l=Ruby" + }, + "RUNOFF": { + "color": "#665a4e", + "url": "https://github.com/trending?l=RUNOFF" + }, + "Rust": { + "color": "#dea584", + "url": "https://github.com/trending?l=Rust" + }, + "Sage": { + "color": null, + "url": "https://github.com/trending?l=Sage" + }, + "Sail": { + "color": "#259dd5", + "url": "https://github.com/trending?l=Sail" + }, + "SaltStack": { + "color": "#646464", + "url": "https://github.com/trending?l=SaltStack" + }, + "SAS": { + "color": "#B34936", + "url": "https://github.com/trending?l=SAS" + }, + "Sass": { + "color": "#a53b70", + "url": "https://github.com/trending?l=Sass" + }, + "Scala": { + "color": "#c22d40", + "url": "https://github.com/trending?l=Scala" + }, + "Scaml": { + "color": "#bd181a", + "url": "https://github.com/trending?l=Scaml" + }, + "Scenic": { + "color": "#fdc700", + "url": "https://github.com/trending?l=Scenic" + }, + "Scheme": { + "color": "#1e4aec", + "url": "https://github.com/trending?l=Scheme" + }, + "Scilab": { + "color": "#ca0f21", + "url": "https://github.com/trending?l=Scilab" + }, + "SCSS": { + "color": "#c6538c", + "url": "https://github.com/trending?l=SCSS" + }, + "sed": { + "color": "#64b970", + "url": "https://github.com/trending?l=sed" + }, + "Self": { + "color": "#0579aa", + "url": "https://github.com/trending?l=Self" + }, + "ShaderLab": { + "color": "#222c37", + "url": "https://github.com/trending?l=ShaderLab" + }, + "Shell": { + "color": "#89e051", + "url": "https://github.com/trending?l=Shell" + }, + "ShellCheck Config": { + "color": "#cecfcb", + "url": "https://github.com/trending?l=ShellCheck-Config" + }, + "ShellSession": { + "color": null, + "url": "https://github.com/trending?l=ShellSession" + }, + "Shen": { + "color": "#120F14", + "url": "https://github.com/trending?l=Shen" + }, + "Sieve": { + "color": null, + "url": "https://github.com/trending?l=Sieve" + }, + "Simple File Verification": { + "color": "#C9BFED", + "url": "https://github.com/trending?l=Simple-File-Verification" + }, + "Singularity": { + "color": "#64E6AD", + "url": "https://github.com/trending?l=Singularity" + }, + "Slang": { + "color": "#1fbec9", + "url": "https://github.com/trending?l=Slang" + }, + "Slash": { + "color": "#007eff", + "url": "https://github.com/trending?l=Slash" + }, + "Slice": { + "color": "#003fa2", + "url": "https://github.com/trending?l=Slice" + }, + "Slim": { + "color": "#2b2b2b", + "url": "https://github.com/trending?l=Slim" + }, + "Slint": { + "color": "#2379F4", + "url": "https://github.com/trending?l=Slint" + }, + "Smali": { + "color": null, + "url": "https://github.com/trending?l=Smali" + }, + "Smalltalk": { + "color": "#596706", + "url": "https://github.com/trending?l=Smalltalk" + }, + "Smarty": { + "color": "#f0c040", + "url": "https://github.com/trending?l=Smarty" + }, + "Smithy": { + "color": "#c44536", + "url": "https://github.com/trending?l=Smithy" + }, + "SmPL": { + "color": "#c94949", + "url": "https://github.com/trending?l=SmPL" + }, + "SMT": { + "color": null, + "url": "https://github.com/trending?l=SMT" + }, + "Snakemake": { + "color": "#419179", + "url": "https://github.com/trending?l=Snakemake" + }, + "Solidity": { + "color": "#AA6746", + "url": "https://github.com/trending?l=Solidity" + }, + "SourcePawn": { + "color": "#f69e1d", + "url": "https://github.com/trending?l=SourcePawn" + }, + "SPARQL": { + "color": "#0C4597", + "url": "https://github.com/trending?l=SPARQL" + }, + "SQF": { + "color": "#3F3F3F", + "url": "https://github.com/trending?l=SQF" + }, + "SQL": { + "color": "#e38c00", + "url": "https://github.com/trending?l=SQL" + }, + "SQLPL": { + "color": "#e38c00", + "url": "https://github.com/trending?l=SQLPL" + }, + "Squirrel": { + "color": "#800000", + "url": "https://github.com/trending?l=Squirrel" + }, + "SRecode Template": { + "color": "#348a34", + "url": "https://github.com/trending?l=SRecode-Template" + }, + "Stan": { + "color": "#b2011d", + "url": "https://github.com/trending?l=Stan" + }, + "Standard ML": { + "color": "#dc566d", + "url": "https://github.com/trending?l=Standard-ML" + }, + "Starlark": { + "color": "#76d275", + "url": "https://github.com/trending?l=Starlark" + }, + "Stata": { + "color": "#1a5f91", + "url": "https://github.com/trending?l=Stata" + }, + "STL": { + "color": "#373b5e", + "url": "https://github.com/trending?l=STL" + }, + "StringTemplate": { + "color": "#3fb34f", + "url": "https://github.com/trending?l=StringTemplate" + }, + "Stylus": { + "color": "#ff6347", + "url": "https://github.com/trending?l=Stylus" + }, + "SubRip Text": { + "color": "#9e0101", + "url": "https://github.com/trending?l=SubRip-Text" + }, + "SugarSS": { + "color": "#2fcc9f", + "url": "https://github.com/trending?l=SugarSS" + }, + "SuperCollider": { + "color": "#46390b", + "url": "https://github.com/trending?l=SuperCollider" + }, + "SurrealQL": { + "color": "#ff00a0", + "url": "https://github.com/trending?l=SurrealQL" + }, + "Survex data": { + "color": "#ffcc99", + "url": "https://github.com/trending?l=Survex-data" + }, + "Svelte": { + "color": "#ff3e00", + "url": "https://github.com/trending?l=Svelte" + }, + "SVG": { + "color": "#ff9900", + "url": "https://github.com/trending?l=SVG" + }, + "Sway": { + "color": "#00F58C", + "url": "https://github.com/trending?l=Sway" + }, + "Sweave": { + "color": "#198ce7", + "url": "https://github.com/trending?l=Sweave" + }, + "Swift": { + "color": "#F05138", + "url": "https://github.com/trending?l=Swift" + }, + "SWIG": { + "color": null, + "url": "https://github.com/trending?l=SWIG" + }, + "SystemVerilog": { + "color": "#DAE1C2", + "url": "https://github.com/trending?l=SystemVerilog" + }, + "Tact": { + "color": "#48b5ff", + "url": "https://github.com/trending?l=Tact" + }, + "Talon": { + "color": "#333333", + "url": "https://github.com/trending?l=Talon" + }, + "Tcl": { + "color": "#e4cc98", + "url": "https://github.com/trending?l=Tcl" + }, + "Tcsh": { + "color": null, + "url": "https://github.com/trending?l=Tcsh" + }, + "Teal": { + "color": "#00B1BC", + "url": "https://github.com/trending?l=Teal" + }, + "templ": { + "color": "#66D0DD", + "url": "https://github.com/trending?l=templ" + }, + "Terra": { + "color": "#00004c", + "url": "https://github.com/trending?l=Terra" + }, + "Terraform Template": { + "color": "#7b42bb", + "url": "https://github.com/trending?l=Terraform-Template" + }, + "TeX": { + "color": "#3D6117", + "url": "https://github.com/trending?l=TeX" + }, + "TextGrid": { + "color": "#c8506d", + "url": "https://github.com/trending?l=TextGrid" + }, + "Textile": { + "color": "#ffe7ac", + "url": "https://github.com/trending?l=Textile" + }, + "TextMate Properties": { + "color": "#df66e4", + "url": "https://github.com/trending?l=TextMate-Properties" + }, + "Thrift": { + "color": "#D12127", + "url": "https://github.com/trending?l=Thrift" + }, + "TI Program": { + "color": "#A0AA87", + "url": "https://github.com/trending?l=TI-Program" + }, + "TL-Verilog": { + "color": "#C40023", + "url": "https://github.com/trending?l=TL-Verilog" + }, + "TLA": { + "color": "#4b0079", + "url": "https://github.com/trending?l=TLA" + }, + "TMDL": { + "color": "#f0c913", + "url": "https://github.com/trending?l=TMDL" + }, + "Toit": { + "color": "#c2c9fb", + "url": "https://github.com/trending?l=Toit" + }, + "TOML": { + "color": "#9c4221", + "url": "https://github.com/trending?l=TOML" + }, + "Tor Config": { + "color": "#59316b", + "url": "https://github.com/trending?l=Tor-Config" + }, + "Tree-sitter Query": { + "color": "#8ea64c", + "url": "https://github.com/trending?l=Tree-sitter-Query" + }, + "TSQL": { + "color": "#e38c00", + "url": "https://github.com/trending?l=TSQL" + }, + "TSV": { + "color": "#237346", + "url": "https://github.com/trending?l=TSV" + }, + "TSX": { + "color": "#3178c6", + "url": "https://github.com/trending?l=TSX" + }, + "Turing": { + "color": "#cf142b", + "url": "https://github.com/trending?l=Turing" + }, + "Twig": { + "color": "#c1d026", + "url": "https://github.com/trending?l=Twig" + }, + "TXL": { + "color": "#0178b8", + "url": "https://github.com/trending?l=TXL" + }, + "TypeScript": { + "color": "#3178c6", + "url": "https://github.com/trending?l=TypeScript" + }, + "TypeSpec": { + "color": "#4A3665", + "url": "https://github.com/trending?l=TypeSpec" + }, + "Typst": { + "color": "#239dad", + "url": "https://github.com/trending?l=Typst" + }, + "Unified Parallel C": { + "color": "#4e3617", + "url": "https://github.com/trending?l=Unified-Parallel-C" + }, + "Unity3D Asset": { + "color": "#222c37", + "url": "https://github.com/trending?l=Unity3D-Asset" + }, + "Unix Assembly": { + "color": null, + "url": "https://github.com/trending?l=Unix-Assembly" + }, + "Uno": { + "color": "#9933cc", + "url": "https://github.com/trending?l=Uno" + }, + "UnrealScript": { + "color": "#a54c4d", + "url": "https://github.com/trending?l=UnrealScript" + }, + "Untyped Plutus Core": { + "color": "#36adbd", + "url": "https://github.com/trending?l=Untyped-Plutus-Core" + }, + "UrWeb": { + "color": "#ccccee", + "url": "https://github.com/trending?l=UrWeb" + }, + "V": { + "color": "#4f87c4", + "url": "https://github.com/trending?l=V" + }, + "Vala": { + "color": "#a56de2", + "url": "https://github.com/trending?l=Vala" + }, + "Valve Data Format": { + "color": "#f26025", + "url": "https://github.com/trending?l=Valve-Data-Format" + }, + "VBA": { + "color": "#867db1", + "url": "https://github.com/trending?l=VBA" + }, + "VBScript": { + "color": "#15dcdc", + "url": "https://github.com/trending?l=VBScript" + }, + "vCard": { + "color": "#ee2647", + "url": "https://github.com/trending?l=vCard" + }, + "VCL": { + "color": "#148AA8", + "url": "https://github.com/trending?l=VCL" + }, + "Velocity Template Language": { + "color": "#507cff", + "url": "https://github.com/trending?l=Velocity-Template-Language" + }, + "Vento": { + "color": "#ff0080", + "url": "https://github.com/trending?l=Vento" + }, + "Verilog": { + "color": "#b2b7f8", + "url": "https://github.com/trending?l=Verilog" + }, + "VHDL": { + "color": "#adb2cb", + "url": "https://github.com/trending?l=VHDL" + }, + "Vim Help File": { + "color": "#199f4b", + "url": "https://github.com/trending?l=Vim-Help-File" + }, + "Vim Script": { + "color": "#199f4b", + "url": "https://github.com/trending?l=Vim-Script" + }, + "Vim Snippet": { + "color": "#199f4b", + "url": "https://github.com/trending?l=Vim-Snippet" + }, + "Visual Basic .NET": { + "color": "#945db7", + "url": "https://github.com/trending?l=Visual-Basic-.NET" + }, + "Visual Basic 6.0": { + "color": "#2c6353", + "url": "https://github.com/trending?l=Visual-Basic-6.0" + }, + "Volt": { + "color": "#1F1F1F", + "url": "https://github.com/trending?l=Volt" + }, + "Vue": { + "color": "#41b883", + "url": "https://github.com/trending?l=Vue" + }, + "Vyper": { + "color": "#9F4CF2", + "url": "https://github.com/trending?l=Vyper" + }, + "WDL": { + "color": "#42f1f4", + "url": "https://github.com/trending?l=WDL" + }, + "Web Ontology Language": { + "color": "#5b70bd", + "url": "https://github.com/trending?l=Web-Ontology-Language" + }, + "WebAssembly": { + "color": "#04133b", + "url": "https://github.com/trending?l=WebAssembly" + }, + "WebAssembly Interface Type": { + "color": "#6250e7", + "url": "https://github.com/trending?l=WebAssembly-Interface-Type" + }, + "WebIDL": { + "color": null, + "url": "https://github.com/trending?l=WebIDL" + }, + "WGSL": { + "color": "#1a5e9a", + "url": "https://github.com/trending?l=WGSL" + }, + "Whiley": { + "color": "#d5c397", + "url": "https://github.com/trending?l=Whiley" + }, + "Wikitext": { + "color": "#fc5757", + "url": "https://github.com/trending?l=Wikitext" + }, + "Windows Registry Entries": { + "color": "#52d5ff", + "url": "https://github.com/trending?l=Windows-Registry-Entries" + }, + "wisp": { + "color": "#7582D1", + "url": "https://github.com/trending?l=wisp" + }, + "Witcher Script": { + "color": "#ff0000", + "url": "https://github.com/trending?l=Witcher-Script" + }, + "Wolfram Language": { + "color": "#dd1100", + "url": "https://github.com/trending?l=Wolfram-Language" + }, + "Wollok": { + "color": "#a23738", + "url": "https://github.com/trending?l=Wollok" + }, + "World of Warcraft Addon Data": { + "color": "#f7e43f", + "url": "https://github.com/trending?l=World-of-Warcraft-Addon-Data" + }, + "Wren": { + "color": "#383838", + "url": "https://github.com/trending?l=Wren" + }, + "X10": { + "color": "#4B6BEF", + "url": "https://github.com/trending?l=X10" + }, + "xBase": { + "color": "#403a40", + "url": "https://github.com/trending?l=xBase" + }, + "XC": { + "color": "#99DA07", + "url": "https://github.com/trending?l=XC" + }, + "Xmake": { + "color": "#22a079", + "url": "https://github.com/trending?l=Xmake" + }, + "XML": { + "color": "#0060ac", + "url": "https://github.com/trending?l=XML" + }, + "XML Property List": { + "color": "#0060ac", + "url": "https://github.com/trending?l=XML-Property-List" + }, + "Xojo": { + "color": "#81bd41", + "url": "https://github.com/trending?l=Xojo" + }, + "Xonsh": { + "color": "#285EEF", + "url": "https://github.com/trending?l=Xonsh" + }, + "XProc": { + "color": null, + "url": "https://github.com/trending?l=XProc" + }, + "XQuery": { + "color": "#5232e7", + "url": "https://github.com/trending?l=XQuery" + }, + "XS": { + "color": null, + "url": "https://github.com/trending?l=XS" + }, + "XSLT": { + "color": "#EB8CEB", + "url": "https://github.com/trending?l=XSLT" + }, + "Xtend": { + "color": "#24255d", + "url": "https://github.com/trending?l=Xtend" + }, + "Yacc": { + "color": "#4B6C4B", + "url": "https://github.com/trending?l=Yacc" + }, + "YAML": { + "color": "#cb171e", + "url": "https://github.com/trending?l=YAML" + }, + "YARA": { + "color": "#220000", + "url": "https://github.com/trending?l=YARA" + }, + "YASnippet": { + "color": "#32AB90", + "url": "https://github.com/trending?l=YASnippet" + }, + "Yul": { + "color": "#794932", + "url": "https://github.com/trending?l=Yul" + }, + "ZAP": { + "color": "#0d665e", + "url": "https://github.com/trending?l=ZAP" + }, + "Zeek": { + "color": null, + "url": "https://github.com/trending?l=Zeek" + }, + "ZenScript": { + "color": "#00BCD1", + "url": "https://github.com/trending?l=ZenScript" + }, + "Zephir": { + "color": "#118f9e", + "url": "https://github.com/trending?l=Zephir" + }, + "Zig": { + "color": "#ec915c", + "url": "https://github.com/trending?l=Zig" + }, + "ZIL": { + "color": "#dc75e5", + "url": "https://github.com/trending?l=ZIL" + }, + "Zimpl": { + "color": "#d67711", + "url": "https://github.com/trending?l=Zimpl" + }, + "Zmodel": { + "color": "#ff7100", + "url": "https://github.com/trending?l=Zmodel" + } +} diff --git a/index.html b/index.html index cd9be55..a3c885b 100644 --- a/index.html +++ b/index.html @@ -14,41 +14,74 @@

Ngũ Hành tương sinh — code cho hợp tuổi, hợp mệnh.

-
-
- Sơ đồ phong thuỷ ngôn ngữ lập trình theo Ngũ Hành -
Sơ đồ ngôn ngữ lập trình xếp theo Ngũ Hành.
-
+
+ + +
+ +
+
+
+ Sơ đồ phong thuỷ ngôn ngữ lập trình theo Ngũ Hành +
Sơ đồ ngôn ngữ lập trình xếp theo Ngũ Hành.
+
+
+ +
+

Ngũ Hành & ngôn ngữ (theo bài gốc, 2018)

+
+
+

KIM

+

JavaScript, Objective-C, Python

+
+
+

THUỶ

+

C#, PHP

+
+
+

MỘC

+

Android, C#

+
+
+

HOẢ

+

Scala, HTML5, Java, Node.js

+
+
+

THỔ

+

JavaScript, Go, Ruby

+
+
+

* Bảng phân loại mang tính giải trí, lấy từ ảnh gốc.

+
-
-

Ngũ Hành & ngôn ngữ

-
-
-

KIM

-

JavaScript, Objective-C, Python

-
-
-

THUỶ

-

C#, PHP

-
-
-

MỘC

-

Android, C#

-
-
-

HOẢ

-

Scala, HTML5, Java, Node.js

-
-
-

THỔ

-

JavaScript, Go, Ruby

-
-
-

* Bảng phân loại mang tính giải trí, lấy từ ảnh gốc.

+
@@ -73,5 +106,7 @@

Trang này chỉ dùng cho mục đích trình bày lại nội dung, mọi quyền thuộc về tác giả gốc.

+ + diff --git a/js/classify-element.js b/js/classify-element.js new file mode 100644 index 0000000..3e176ba --- /dev/null +++ b/js/classify-element.js @@ -0,0 +1,58 @@ +// Algorithm: plans/reports/researcher-260427-0854-nguhanh-color-classifier.md §2 +// Pure HSL classifier mapping a hex color to one of the 5 Ngũ Hành elements. + +export const ELEMENTS = [ + { key: 'kim', label: 'KIM' }, + { key: 'moc', label: 'MỘC' }, + { key: 'thuy', label: 'THUỶ' }, + { key: 'hoa', label: 'HOẢ' }, + { key: 'tho', label: 'THỔ' }, +]; + +const HEX_RE = /^#[0-9a-fA-F]{6}$/; + +export function hexToHsl(hex) { + if (typeof hex !== 'string' || !HEX_RE.test(hex)) { + throw new TypeError(`hexToHsl: expected '#RRGGBB', got ${hex}`); + } + const r = parseInt(hex.slice(1, 3), 16) / 255; + const g = parseInt(hex.slice(3, 5), 16) / 255; + const b = parseInt(hex.slice(5, 7), 16) / 255; + + const max = Math.max(r, g, b); + const min = Math.min(r, g, b); + const d = max - min; + const l = (max + min) / 2; + + let h = 0; + let s = 0; + if (d !== 0) { + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + switch (max) { + case r: h = ((g - b) / d) + (g < b ? 6 : 0); break; + case g: h = ((b - r) / d) + 2; break; + case b: h = ((r - g) / d) + 4; break; + } + h *= 60; + } + return { h, s: s * 100, l: l * 100 }; +} + +export function classify(hex) { + const { h, s, l } = hexToHsl(hex); + + // Step 2: grayscale (very low saturation) + if (s < 5) { + if (l < 20) return 'thuy'; + if (l < 70) return 'tho'; + return 'kim'; + } + + // Step 3: hue ranges + if (h < 20) return 'hoa'; + if (h < 40) return (s >= 60 && l >= 50) ? 'hoa' : 'tho'; + if (h < 70) return 'tho'; + if (h < 200) return 'moc'; + if (h < 260) return 'thuy'; + return 'hoa'; +} diff --git a/js/classify-element.test.html b/js/classify-element.test.html new file mode 100644 index 0000000..cd43b4e --- /dev/null +++ b/js/classify-element.test.html @@ -0,0 +1,78 @@ + + + + + classify-element test harness + + + +

classify-element test harness

+
+
    + + + + diff --git a/js/main.js b/js/main.js new file mode 100644 index 0000000..898ffa1 --- /dev/null +++ b/js/main.js @@ -0,0 +1,51 @@ +import { classify } from './classify-element.js'; +import { renderGrid, renderError, renderDebugPanel, isBorderline } from './render-elements.js'; + +const HEX_RE = /^#[0-9a-fA-F]{6}$/; +const LEGEND_TEXT = + 'Phân loại theo tông màu HSL: đỏ/tím/cam đậm → HOẢ, xanh lá/cyan → MỘC, xanh dương → THUỶ, vàng/nâu → THỔ, trắng/xám sáng → KIM.'; + +async function init() { + const gridEl = document.getElementById('element-grid'); + const legendEl = document.querySelector('#panel-modern .legend'); + const elementsSection = document.querySelector('#panel-modern .elements'); + const debugEl = document.getElementById('debug-panel'); + + try { + const res = await fetch('./data/github-colors.json'); + if (!res.ok) throw new Error(`HTTP ${res.status}`); + const data = await res.json(); + + const buckets = { kim: [], moc: [], thuy: [], hoa: [], tho: [] }; + const skipped = []; + const borderline = []; + + for (const [name, entry] of Object.entries(data)) { + const color = entry && entry.color; + if (!color || !HEX_RE.test(color)) { + skipped.push({ name }); + continue; + } + const element = classify(color); + buckets[element].push({ name, color }); + if (isBorderline(color)) borderline.push({ name, color, element }); + } + + for (const key of Object.keys(buckets)) { + buckets[key].sort((a, b) => a.name.localeCompare(b.name, undefined, { sensitivity: 'base' })); + } + + renderGrid(buckets, gridEl); + if (legendEl) legendEl.textContent = LEGEND_TEXT; + renderDebugPanel({ skipped, borderline }, debugEl); + } catch (err) { + console.error('[programming-fengshui] failed to render modern grid:', err); + renderError(`Không tải được dữ liệu màu (${err.message}). Mở qua HTTP server thay vì file://.`, elementsSection); + } +} + +if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', init); +} else { + init(); +} diff --git a/js/mode-toggle.js b/js/mode-toggle.js new file mode 100644 index 0000000..1e12f39 --- /dev/null +++ b/js/mode-toggle.js @@ -0,0 +1,70 @@ +// Reserved hashes: #classic, #modern. Do not reuse for in-page anchors. + +const MODES = ['classic', 'modern']; +const DEFAULT_MODE = 'classic'; + +function readHash() { + const h = (location.hash || '').replace('#', ''); + return MODES.includes(h) ? h : DEFAULT_MODE; +} + +function setMode(mode, { writeHash = true, push = false } = {}) { + if (!MODES.includes(mode)) mode = DEFAULT_MODE; + + for (const m of MODES) { + const panel = document.getElementById(`panel-${m}`); + const tab = document.getElementById(`tab-${m}`); + if (panel) panel.hidden = m !== mode; + if (tab) { + tab.setAttribute('aria-selected', String(m === mode)); + tab.tabIndex = m === mode ? 0 : -1; + } + } + + if (writeHash) { + const target = '#' + mode; + if (push) { + location.hash = target; + } else if (location.hash !== target) { + history.replaceState(null, '', target); + } + } +} + +function onTabClick(e) { + setMode(e.currentTarget.dataset.mode, { push: true }); +} + +function onTabListKeydown(e) { + const keys = ['ArrowLeft', 'ArrowRight', 'Home', 'End']; + if (!keys.includes(e.key)) return; + e.preventDefault(); + const tabs = MODES.map((m) => document.getElementById(`tab-${m}`)); + const current = tabs.indexOf(document.activeElement); + let next; + if (e.key === 'Home') next = 0; + else if (e.key === 'End') next = tabs.length - 1; + else if (e.key === 'ArrowLeft') next = (current <= 0 ? tabs.length : current) - 1; + else next = (current + 1) % tabs.length; + const target = tabs[next]; + if (target) { + target.focus(); + setMode(target.dataset.mode, { push: true }); + } +} + +function onHashChange() { + setMode(readHash(), { writeHash: false }); +} + +document.addEventListener('DOMContentLoaded', () => { + for (const m of MODES) { + const tab = document.getElementById(`tab-${m}`); + if (tab) tab.addEventListener('click', onTabClick); + } + const list = document.querySelector('[role="tablist"]'); + if (list) list.addEventListener('keydown', onTabListKeydown); + setMode(readHash(), { writeHash: false }); +}); + +window.addEventListener('hashchange', onHashChange); diff --git a/js/render-elements.js b/js/render-elements.js new file mode 100644 index 0000000..8cf526d --- /dev/null +++ b/js/render-elements.js @@ -0,0 +1,96 @@ +import { ELEMENTS, hexToHsl } from './classify-element.js'; + +function pickTextColor(hex) { + const r = parseInt(hex.slice(1, 3), 16); + const g = parseInt(hex.slice(3, 5), 16); + const b = parseInt(hex.slice(5, 7), 16); + return (r * 299 + g * 587 + b * 114) / 1000 >= 128 ? 'black' : 'white'; +} + +function buildChip(name, color) { + const span = document.createElement('span'); + span.className = 'chip'; + span.textContent = name; + if (color) { + span.style.background = color; + span.style.color = pickTextColor(color); + span.title = color; + } + return span; +} + +export function renderGrid(buckets, mountEl) { + if (!mountEl) return; + const fragment = document.createDocumentFragment(); + for (const { key, label } of ELEMENTS) { + const langs = buckets[key] || []; + const card = document.createElement('article'); + card.className = `card ${key}`; + const h3 = document.createElement('h3'); + h3.textContent = label; + const count = document.createElement('small'); + count.className = 'card-count'; + count.textContent = `${langs.length} ngôn ngữ`; + const chips = document.createElement('div'); + chips.className = 'chips'; + for (const { name, color } of langs) chips.appendChild(buildChip(name, color)); + card.append(h3, count, chips); + fragment.appendChild(card); + } + mountEl.replaceChildren(fragment); +} + +export function renderError(message, mountEl) { + if (!mountEl) return; + const p = document.createElement('p'); + p.className = 'render-error'; + p.textContent = message; + mountEl.prepend(p); +} + +const HUE_BOUNDARIES = [20, 40, 70, 200, 260]; + +export function isBorderline(hex) { + const { h, s, l } = hexToHsl(hex); + if (s >= 4 && s < 6) return true; + if (s < 5) return (l >= 18 && l <= 22) || (l >= 68 && l <= 72); + return HUE_BOUNDARIES.some((b) => Math.abs(h - b) <= 2); +} + +export function renderDebugPanel({ skipped, borderline }, mountEl) { + if (!mountEl) return; + if (!skipped.length && !borderline.length) { + mountEl.hidden = true; + return; + } + + const fragment = document.createDocumentFragment(); + const summary = document.createElement('summary'); + summary.textContent = `Kiểm tra tự động (${skipped.length} skipped · ${borderline.length} borderline)`; + fragment.appendChild(summary); + + if (skipped.length) { + const h4 = document.createElement('h4'); + h4.textContent = 'Bỏ qua (không có màu)'; + const list = document.createElement('div'); + list.className = 'chips'; + for (const { name } of skipped) list.appendChild(buildChip(name, null)); + fragment.append(h4, list); + } + + if (borderline.length) { + const h4 = document.createElement('h4'); + h4.textContent = 'Trường hợp ranh giới'; + const list = document.createElement('div'); + list.className = 'chips'; + for (const { name, color, element } of borderline) { + const chip = buildChip(`${name} → ${element}`, color); + chip.title = `${color} → ${element}`; + list.appendChild(chip); + } + fragment.append(h4, list); + } + + mountEl.replaceChildren(fragment); + mountEl.hidden = false; +} diff --git a/plans/260427-0854-color-element-mapping/phase-01-data-and-classifier.md b/plans/260427-0854-color-element-mapping/phase-01-data-and-classifier.md new file mode 100644 index 0000000..7fb0be4 --- /dev/null +++ b/plans/260427-0854-color-element-mapping/phase-01-data-and-classifier.md @@ -0,0 +1,155 @@ +--- +title: "Phase 01 — Vendor color data + HSL classifier module" +status: pending +priority: P2 +effort: 60m +--- + +## Context Links + +- Plan overview: [plan.md](plan.md) +- Color data report: [../reports/researcher-260427-0855-github-language-colors.md](../reports/researcher-260427-0855-github-language-colors.md) +- Classifier algorithm report: [../reports/researcher-260427-0854-nguhanh-color-classifier.md](../reports/researcher-260427-0854-nguhanh-color-classifier.md) +- Existing files: `index.html`, `style.css` + +## Overview + +- **Priority:** P2 (foundation for phases 02–04) +- **Status:** pending +- **Description:** Vendor `ozh/github-colors` JSON locally and implement a pure-function HSL classifier (`hex → element`) with an in-browser sanity-check harness. + +## Key Insights + +- Report #1 confirms `ozh/github-colors` JSON is CORS-friendly + 78KB, but vendoring locally avoids any runtime third-party dependency and keeps the page working offline / on `file://`. +- Report #2 provides a deterministic HSL algorithm with explicit Step-2 grayscale handling and Step-4 edge-case refinements. Translate Python pseudocode to JS literally — do not invent variations. +- Report #2 §3 lists 12 sample languages with expected outputs; report §4 lists 10 canonical edge colors. These are the test fixtures. +- Element keys must be lowercase (`kim`, `moc`, `thuy`, `hoa`, `tho`) so they match the existing CSS class names in `style.css` (lines 124–133). Reports use uppercase Vietnamese — translate at module boundary. + +## Requirements + +### Functional +- Vendor `data/github-colors.json` (~78KB) at the documented schema: `{ "": { "color": "#hex"|null, "url": "..." } }`. +- Provide ES module `js/classify-element.js` exporting: + - `hexToHsl(hex: string): { h: number, s: number, l: number }` — H ∈ [0, 360), S/L ∈ [0, 100] + - `classify(hex: string): 'kim' | 'moc' | 'thuy' | 'hoa' | 'tho'` — implements report §2 Steps 2–4 verbatim + - `ELEMENTS` constant: ordered list `['kim', 'moc', 'thuy', 'hoa', 'tho']` with display labels (`KIM`, `MỘC`, `THUỶ`, `HOẢ`, `THỔ`) +- Provide `js/classify-element.test.html` — opens in any browser, runs assertions, prints green PASS / red FAIL list. No test framework. No build. + +### Non-functional +- File size budget: `classify-element.js` ≤ 120 lines, `classify-element.test.html` ≤ 100 lines (project rule: <200 lines/file). +- Pure functions: no I/O, no DOM, no globals. Importable from Node for future tooling without changes. +- Hex input tolerated: `#RRGGBB` and `#rrggbb`. Throw on malformed input (don't silently mis-classify). + +## Architecture + +### Data flow +``` +data/github-colors.json (static) + │ + ▼ (fetched in Phase 02) +{ "JavaScript": { color: "#f1e05a", url: "..." }, ... } + │ + ▼ (Phase 02 calls classify(entry.color)) +classify-element.js ──▶ 'thy' | 'kim' | ... +``` + +In Phase 01, the classifier is exercised only by the test harness — no integration yet. + +### Module contract (`js/classify-element.js`) + +```js +// Input: '#RRGGBB' or '#rrggbb' +// Output: 'kim' | 'moc' | 'thuy' | 'hoa' | 'tho' +// Throws: TypeError if input is null/undefined/not a 7-char hex string. +export function classify(hex) { ... } + +export function hexToHsl(hex) { ... } // exported for test visibility + +export const ELEMENTS = [ + { key: 'kim', label: 'KIM' }, + { key: 'moc', label: 'MỘC' }, + { key: 'thuy', label: 'THUỶ' }, + { key: 'hoa', label: 'HOẢ' }, + { key: 'tho', label: 'THỔ' }, +]; +``` + +### Classifier rules (mirror report #2 §2) + +1. Parse `#RRGGBB` → R, G, B ∈ [0, 255] → normalize → HSL. +2. Grayscale (`S < 5`): + - `L < 20` → `thuy` + - `20 ≤ L < 70` → `tho` + - `L ≥ 70` → `kim` +3. Hue ranges: + - `[0, 20)` → `hoa` + - `[20, 40)` → `hoa` if `S ≥ 60 && L ≥ 50` else `tho` + - `[40, 70)` → `tho` + - `[70, 200)` → `moc` (covers green + jade/cyan) + - `[200, 260)` → `thuy` + - `[260, 360)` → `hoa` + +## Related Code Files + +### Create +- `data/github-colors.json` (vendored, ~78KB) +- `js/classify-element.js` +- `js/classify-element.test.html` + +### Modify +- None. + +### Delete +- None. + +## Implementation Steps + +1. Fetch the JSON once: `curl -fsSL https://raw.githubusercontent.com/ozh/github-colors/master/colors.json -o data/github-colors.json`. Verify file is well-formed JSON (`python3 -m json.tool data/github-colors.json | head` is fine for a smoke check). +2. Create `js/classify-element.js`: + - Implement `hexToHsl(hex)` — port report #2 pseudocode line by line. Handle `max == min` achromatic case (S=0, H=0). + - Implement `classify(hex)` — call `hexToHsl`, then run Step 2 then Step 3, return lowercase string. + - Export `ELEMENTS` array. + - Add a leading file comment citing the algorithm source: `// Algorithm: plans/reports/researcher-260427-0854-nguhanh-color-classifier.md §2`. +3. Create `js/classify-element.test.html`: + - Plain HTML with `` before ``. +- `js/mode-toggle.js` responsibilities: + - On `DOMContentLoaded`: read `location.hash`, normalize (`#modern` → modern, anything else → classic), call `setMode(mode)`. + - `setMode(mode)` sets `hidden` on the inactive panel, removes from active, updates `aria-selected` + `tabindex` on the two ` + + + +
    + +
    +
    + ... +
    Sơ đồ ngôn ngữ lập trình xếp theo Ngũ Hành.
    +
    +
    + +
    +

    Ngũ Hành & ngôn ngữ (theo bài gốc, 2018)

    +
    +

    KIM

    JavaScript, Objective-C, Python

    +

    THUỶ

    C#, PHP

    +

    MỘC

    Android, C#

    +

    HOẢ

    Scala, HTML5, Java, Node.js

    +

    THỔ

    JavaScript, Go, Ruby

    +
    +

    * Bảng phân loại mang tính giải trí, lấy từ ảnh gốc.

    +
    +
    + + + +
    + + + +``` + +### Module contract (`js/mode-toggle.js`) + +```js +// Public surface: none (self-initialising entry point). +// Side effects: mutates DOM (hidden, aria-selected, tabindex), listens to clicks, keys, hashchange. + +const MODES = ['classic', 'modern']; +const DEFAULT_MODE = 'classic'; + +function readHash() { + const h = (location.hash || '').replace('#', ''); + return MODES.includes(h) ? h : DEFAULT_MODE; +} + +function setMode(mode, { writeHash = true, push = false } = {}) { + // toggle [hidden] on panels, aria-selected + tabindex on tabs, + // update hash via history.replaceState (push=false) or location.hash (push=true) +} + +function onTabClick(e) { setMode(e.currentTarget.dataset.mode, { push: true }); } +function onTabListKeydown(e) { /* ←/→ Home End cycle + setMode */ } +function onHashChange() { setMode(readHash(), { writeHash: false }); } + +document.addEventListener('DOMContentLoaded', () => { + // wire listeners; initial setMode(readHash(), { writeHash: false }) +}); +window.addEventListener('hashchange', onHashChange); +``` + +### Data flow + +``` +[page load] + │ + ▼ +mode-toggle.js DOMContentLoaded + ├── readHash() → 'classic' | 'modern' + └── setMode(mode, { writeHash:false }) + ├── #panel-classic [hidden=mode!=='classic'] + ├── #panel-modern [hidden=mode!=='modern'] + ├── #tab-classic aria-selected, tabindex=0|-1 + └── #tab-modern aria-selected, tabindex=0|-1 + +[tab click] → setMode(mode, { push:true }) → location.hash = '#mode' +[hashchange] → setMode(readHash(), { writeHash:false }) +[arrow key on tablist] → focus next tab + setMode(...) +``` + +## Related Code Files + +### Create +- `js/mode-toggle.js` + +### Modify +- `index.html` — restructure: insert toggle, wrap existing image+cards into `#panel-classic`, add scaffolded `#panel-modern`, add module script tag. **The 5 cards inside `#panel-classic` must be byte-identical copies of current `index.html` lines 30–49.** + +### Delete +- None. + +## Implementation Steps + +1. Open `index.html`. Capture the exact text of lines 17–52 (figure section + elements section) — these blocks move into `#panel-classic` unchanged except for the heading `` insertion. +2. Replace the body `
    ` content with the structure shown in the DOM contract above: + - Hero unchanged. + - Insert `
    ` with two buttons. + - Wrap the captured figure + elements blocks inside `
    `. Add `(theo bài gốc, 2018)` inside the existing `

    `. + - Add `