ccdeck 3.40.2 → 3.41.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (286) hide show
  1. package/README.md +9 -2
  2. package/THIRD_PARTY_NOTICES.md +29 -0
  3. package/dist/web/assets/BrowserWatchModal-xoHNkWWF.js +1 -0
  4. package/dist/web/assets/RadioPanel-Bii2jN0n.js +1 -0
  5. package/dist/web/assets/TrafficRadar-CXRcWYZ8.js +1 -0
  6. package/dist/web/assets/UsageHistoryModal-Ceg-2Dm9.js +1 -0
  7. package/dist/web/assets/ad-B18i8NGa.svg +150 -0
  8. package/dist/web/assets/ae-CZRtWSox.svg +6 -0
  9. package/dist/web/assets/af-C77Rf6cE.svg +81 -0
  10. package/dist/web/assets/ag-C8MykuG2.svg +14 -0
  11. package/dist/web/assets/ai-Dmedkf4v.svg +29 -0
  12. package/dist/web/assets/al-10QRkakw.svg +5 -0
  13. package/dist/web/assets/am-DMt4_dd4.svg +5 -0
  14. package/dist/web/assets/ao-tXuRa6vm.svg +13 -0
  15. package/dist/web/assets/aq-CF5jO-0h.svg +5 -0
  16. package/dist/web/assets/ar-Be8Ju1cG.svg +32 -0
  17. package/dist/web/assets/as-Dekqy8Of.svg +72 -0
  18. package/dist/web/assets/at-DGA_6m5E.svg +4 -0
  19. package/dist/web/assets/au-DAHDIuPI.svg +8 -0
  20. package/dist/web/assets/aw-W0PWLK5p.svg +186 -0
  21. package/dist/web/assets/ax-DvLIy84U.svg +18 -0
  22. package/dist/web/assets/az-Bk-bYNxy.svg +8 -0
  23. package/dist/web/assets/ba-WdDiSMvP.svg +12 -0
  24. package/dist/web/assets/bb-DJxbaxmT.svg +6 -0
  25. package/dist/web/assets/bd-BF9t1-60.svg +4 -0
  26. package/dist/web/assets/be-CLLkK3PN.svg +7 -0
  27. package/dist/web/assets/bf-YclsoDuF.svg +7 -0
  28. package/dist/web/assets/bg-GUQenraa.svg +5 -0
  29. package/dist/web/assets/bh-BQqEGq6F.svg +4 -0
  30. package/dist/web/assets/bi-CRmKY6RQ.svg +15 -0
  31. package/dist/web/assets/bj-14PhO9bM.svg +14 -0
  32. package/dist/web/assets/bl-4CI2YcwX.svg +5 -0
  33. package/dist/web/assets/bm-BeYgB2z9.svg +97 -0
  34. package/dist/web/assets/bn-B6T3O78g.svg +36 -0
  35. package/dist/web/assets/bo-CcUiMqkJ.svg +673 -0
  36. package/dist/web/assets/bq-BYpdxEeT.svg +5 -0
  37. package/dist/web/assets/br-Cu5YU29T.svg +45 -0
  38. package/dist/web/assets/bs-7Gd_oriM.svg +13 -0
  39. package/dist/web/assets/bt-BTo4qm10.svg +89 -0
  40. package/dist/web/assets/bv-wM9JLv4R.svg +13 -0
  41. package/dist/web/assets/bw-n5ZaAnGL.svg +7 -0
  42. package/dist/web/assets/by-C621sBpd.svg +18 -0
  43. package/dist/web/assets/bz-BCKHR4_q.svg +145 -0
  44. package/dist/web/assets/ca-PYUrLVUV.svg +4 -0
  45. package/dist/web/assets/cc-BNT6Xjzk.svg +19 -0
  46. package/dist/web/assets/cd-BGclsrP6.svg +5 -0
  47. package/dist/web/assets/cf-DRetLmp-.svg +15 -0
  48. package/dist/web/assets/cg-CwIyG6SE.svg +12 -0
  49. package/dist/web/assets/ch-sfriZoF1.svg +9 -0
  50. package/dist/web/assets/ci-C8Q8IYTn.svg +7 -0
  51. package/dist/web/assets/ck-DfXMUOTo.svg +9 -0
  52. package/dist/web/assets/cl-BgYYb4qP.svg +13 -0
  53. package/dist/web/assets/cm-D4yjdmKT.svg +15 -0
  54. package/dist/web/assets/cn-DifnnI3t.svg +11 -0
  55. package/dist/web/assets/co-DV591zMm.svg +7 -0
  56. package/dist/web/assets/cp-K_ay05Q_.svg +7 -0
  57. package/dist/web/assets/cr-BlYVN-_Q.svg +7 -0
  58. package/dist/web/assets/cu-L6XVZNgo.svg +13 -0
  59. package/dist/web/assets/cv-CPsfcOfk.svg +13 -0
  60. package/dist/web/assets/cw-BbrnximR.svg +14 -0
  61. package/dist/web/assets/cx-DpYD6n6U.svg +15 -0
  62. package/dist/web/assets/cy-bZuP8hmf.svg +6 -0
  63. package/dist/web/assets/cz-WWBC5Aeb.svg +5 -0
  64. package/dist/web/assets/de-B-2o-4Z9.svg +5 -0
  65. package/dist/web/assets/dg-CJPJrjiZ.svg +130 -0
  66. package/dist/web/assets/dj-hp_BwbmO.svg +13 -0
  67. package/dist/web/assets/dk-DmS9BCZB.svg +5 -0
  68. package/dist/web/assets/dm-Cbhezfe1.svg +152 -0
  69. package/dist/web/assets/do-B86d445t.svg +121 -0
  70. package/dist/web/assets/dz-Dytc1TFu.svg +5 -0
  71. package/dist/web/assets/ec-CaVOFQ3t.svg +138 -0
  72. package/dist/web/assets/ee-DufrxGIR.svg +5 -0
  73. package/dist/web/assets/eg-YC70hswZ.svg +38 -0
  74. package/dist/web/assets/eh-0awM4TVj.svg +16 -0
  75. package/dist/web/assets/er-X83uml6t.svg +8 -0
  76. package/dist/web/assets/es-d5m8M5h8.svg +544 -0
  77. package/dist/web/assets/et-DwdlzOIx.svg +14 -0
  78. package/dist/web/assets/eu-Brdgz8ab.svg +28 -0
  79. package/dist/web/assets/fi-DWUIkfjL.svg +5 -0
  80. package/dist/web/assets/fj-DEAVMg38.svg +120 -0
  81. package/dist/web/assets/fk-nuUF_Ak3.svg +90 -0
  82. package/dist/web/assets/fm-B4Z83GL0.svg +11 -0
  83. package/dist/web/assets/fo-DFjwyWur.svg +12 -0
  84. package/dist/web/assets/fr-DVvUyOqI.svg +5 -0
  85. package/dist/web/assets/ga-BklUhLH_.svg +7 -0
  86. package/dist/web/assets/gb-DTXiLQoe.svg +7 -0
  87. package/dist/web/assets/gd-CO-whzUe.svg +27 -0
  88. package/dist/web/assets/ge-B2RiL-Ih.svg +6 -0
  89. package/dist/web/assets/gf-DWl5zcw0.svg +5 -0
  90. package/dist/web/assets/gg-jdOQS2nU.svg +9 -0
  91. package/dist/web/assets/gh-r3LP_X7q.svg +6 -0
  92. package/dist/web/assets/gi-BJKE9SzW.svg +32 -0
  93. package/dist/web/assets/gl-CHaBnMib.svg +4 -0
  94. package/dist/web/assets/gm-Bu99atwn.svg +14 -0
  95. package/dist/web/assets/gn-1dJNy9oQ.svg +7 -0
  96. package/dist/web/assets/gp-DNyt_wTA.svg +5 -0
  97. package/dist/web/assets/gq-Cag8QTk2.svg +23 -0
  98. package/dist/web/assets/gr-C5PU0p9p.svg +16 -0
  99. package/dist/web/assets/gs-DiiNa0F5.svg +133 -0
  100. package/dist/web/assets/gt-CJo5DI-7.svg +204 -0
  101. package/dist/web/assets/gu-Di1JYREk.svg +19 -0
  102. package/dist/web/assets/gw-D249VY33.svg +13 -0
  103. package/dist/web/assets/gy-CcVYUM2E.svg +9 -0
  104. package/dist/web/assets/hk-CUNIaSX0.svg +8 -0
  105. package/dist/web/assets/hm-Dh6t_Tj3.svg +8 -0
  106. package/dist/web/assets/hn-CRjyS_bm.svg +18 -0
  107. package/dist/web/assets/hr-fzLfaANM.svg +58 -0
  108. package/dist/web/assets/ht-DIMg4gti.svg +116 -0
  109. package/dist/web/assets/hu-7Q5wwIIi.svg +7 -0
  110. package/dist/web/assets/ic-CSo4d8tH.svg +7 -0
  111. package/dist/web/assets/id-DiSP6Fmm.svg +4 -0
  112. package/dist/web/assets/ie-ChAXClx3.svg +7 -0
  113. package/dist/web/assets/il-_56OEGLa.svg +14 -0
  114. package/dist/web/assets/im--VPIqfkF.svg +36 -0
  115. package/dist/web/assets/in-Cdwu6Bq7.svg +25 -0
  116. package/dist/web/assets/index-2Z0Tr6cq.js +305 -0
  117. package/dist/web/assets/index-BgSnAnP6.css +1 -0
  118. package/dist/web/assets/io-13HOfeJD.svg +130 -0
  119. package/dist/web/assets/iq-Dp8HDzo2.svg +10 -0
  120. package/dist/web/assets/ir-cCIgaNf6.svg +219 -0
  121. package/dist/web/assets/is-CZjefTNV.svg +12 -0
  122. package/dist/web/assets/it-Br7q0Zh6.svg +7 -0
  123. package/dist/web/assets/je-DyWbhIiC.svg +62 -0
  124. package/dist/web/assets/jm-CItSr3iX.svg +8 -0
  125. package/dist/web/assets/jo-BAF1FGbm.svg +16 -0
  126. package/dist/web/assets/jp-BIMmfxpO.svg +11 -0
  127. package/dist/web/assets/ke-C8foqndp.svg +23 -0
  128. package/dist/web/assets/kg-B0FsxZiL.svg +4 -0
  129. package/dist/web/assets/kh-BeWfuE30.svg +61 -0
  130. package/dist/web/assets/ki-p_fAQGbS.svg +36 -0
  131. package/dist/web/assets/km-B5tqtGG7.svg +16 -0
  132. package/dist/web/assets/kn-DVPxDkNY.svg +14 -0
  133. package/dist/web/assets/kp-CrDKzoxe.svg +15 -0
  134. package/dist/web/assets/kr-BCXH1Hao.svg +24 -0
  135. package/dist/web/assets/kw-fSBzmd30.svg +13 -0
  136. package/dist/web/assets/ky-Dpsu1myA.svg +103 -0
  137. package/dist/web/assets/kz-CwKXYZ8s.svg +36 -0
  138. package/dist/web/assets/la-CuJflhIW.svg +12 -0
  139. package/dist/web/assets/lb-BSjpYEoo.svg +15 -0
  140. package/dist/web/assets/lc-CNvab8Ae.svg +8 -0
  141. package/dist/web/assets/li-CHdhvNcr.svg +43 -0
  142. package/dist/web/assets/lk-DUkgV9Tq.svg +22 -0
  143. package/dist/web/assets/lr-B84vu3Ds.svg +14 -0
  144. package/dist/web/assets/ls-5Xk3Mxq5.svg +8 -0
  145. package/dist/web/assets/lt-DoukV-Sm.svg +7 -0
  146. package/dist/web/assets/lu-DOI02Msy.svg +5 -0
  147. package/dist/web/assets/lv-C-KfY8Yc.svg +6 -0
  148. package/dist/web/assets/ly-BWpTK3ux.svg +13 -0
  149. package/dist/web/assets/ma-BTRNTRUj.svg +4 -0
  150. package/dist/web/assets/mc-PK078JHl.svg +6 -0
  151. package/dist/web/assets/md-DRlxvNwm.svg +70 -0
  152. package/dist/web/assets/me-Cv4Gwqah.svg +116 -0
  153. package/dist/web/assets/mf-BaAGWwAq.svg +5 -0
  154. package/dist/web/assets/mg-C168LHXW.svg +7 -0
  155. package/dist/web/assets/mh-gxuIp6Wk.svg +7 -0
  156. package/dist/web/assets/mk-D9SIMr-a.svg +5 -0
  157. package/dist/web/assets/ml-DVf6ujpi.svg +7 -0
  158. package/dist/web/assets/mm-lwT09MQ0.svg +12 -0
  159. package/dist/web/assets/mn-CgXyw0O9.svg +14 -0
  160. package/dist/web/assets/mo-BAtCjuYA.svg +9 -0
  161. package/dist/web/assets/mp-CrOApEqW.svg +86 -0
  162. package/dist/web/assets/mq-BFnJ22KI.svg +5 -0
  163. package/dist/web/assets/mr-D6G1wpeZ.svg +6 -0
  164. package/dist/web/assets/ms-DxciGbUu.svg +29 -0
  165. package/dist/web/assets/mt-YqzKx9xl.svg +58 -0
  166. package/dist/web/assets/mu-mcq7cUFl.svg +8 -0
  167. package/dist/web/assets/mv-BynAllfM.svg +6 -0
  168. package/dist/web/assets/mw-C15nc1xZ.svg +10 -0
  169. package/dist/web/assets/mx-Cc8Ccfe8.svg +382 -0
  170. package/dist/web/assets/my-Co4JeeyE.svg +26 -0
  171. package/dist/web/assets/mz-Drlr_USV.svg +21 -0
  172. package/dist/web/assets/na-D79ffb4Z.svg +16 -0
  173. package/dist/web/assets/nc-5j7wEmDR.svg +13 -0
  174. package/dist/web/assets/ne-B1jPOYkl.svg +6 -0
  175. package/dist/web/assets/nf-Dl00mlk2.svg +9 -0
  176. package/dist/web/assets/ng-su4NM9If.svg +6 -0
  177. package/dist/web/assets/ni-CcFCSQxm.svg +129 -0
  178. package/dist/web/assets/nl-BnOa6UiA.svg +5 -0
  179. package/dist/web/assets/no-qf2JPO73.svg +7 -0
  180. package/dist/web/assets/np-CIuq5GKd.svg +13 -0
  181. package/dist/web/assets/nr-DERIdzkN.svg +12 -0
  182. package/dist/web/assets/nu-BfgWvGcd.svg +10 -0
  183. package/dist/web/assets/nz-5vODdBjz.svg +36 -0
  184. package/dist/web/assets/om-DcqxRdQL.svg +115 -0
  185. package/dist/web/assets/pa-BLNN9G2-.svg +14 -0
  186. package/dist/web/assets/pc-BJpYiA9b.svg +33 -0
  187. package/dist/web/assets/pe-BLqhuu1C.svg +4 -0
  188. package/dist/web/assets/pf-C8ahG68q.svg +19 -0
  189. package/dist/web/assets/pg-BAYpbp9Z.svg +9 -0
  190. package/dist/web/assets/ph-BEzTn62K.svg +6 -0
  191. package/dist/web/assets/pk-CWMEc3ad.svg +15 -0
  192. package/dist/web/assets/pl-o38JROoc.svg +6 -0
  193. package/dist/web/assets/pm-CHiP5UmZ.svg +5 -0
  194. package/dist/web/assets/pn-DgxdtieE.svg +53 -0
  195. package/dist/web/assets/pr-B4tMV0xm.svg +13 -0
  196. package/dist/web/assets/ps-DO8YKYeS.svg +6 -0
  197. package/dist/web/assets/pt-DZ2ADgIR.svg +57 -0
  198. package/dist/web/assets/pw-CQP52WMX.svg +11 -0
  199. package/dist/web/assets/py-mNzh0mZC.svg +157 -0
  200. package/dist/web/assets/qa-Dkmpc78M.svg +4 -0
  201. package/dist/web/assets/re-Bk4ipYK1.svg +5 -0
  202. package/dist/web/assets/ro-CoSeqKY1.svg +7 -0
  203. package/dist/web/assets/rs-BfwKwXtn.svg +292 -0
  204. package/dist/web/assets/ru-D-4tNwXt.svg +5 -0
  205. package/dist/web/assets/rw-D7nbSYKI.svg +13 -0
  206. package/dist/web/assets/sa-Dh79zbT9.svg +25 -0
  207. package/dist/web/assets/sb-BDTYjcbk.svg +13 -0
  208. package/dist/web/assets/sc-CRNsSLg9.svg +7 -0
  209. package/dist/web/assets/sd-ClziNjGr.svg +13 -0
  210. package/dist/web/assets/se-8C923vhy.svg +4 -0
  211. package/dist/web/assets/sg-DGYIMG0G.svg +13 -0
  212. package/dist/web/assets/sh-DNImvbrE.svg +7 -0
  213. package/dist/web/assets/si-BMKT-Tec.svg +18 -0
  214. package/dist/web/assets/sj-BFFEGknm.svg +7 -0
  215. package/dist/web/assets/sk-K9BNIYAO.svg +9 -0
  216. package/dist/web/assets/sl-DxLJY5vJ.svg +7 -0
  217. package/dist/web/assets/sm-DGBIRFB_.svg +75 -0
  218. package/dist/web/assets/sn-S8ipNF1U.svg +8 -0
  219. package/dist/web/assets/so-DlzA2Fco.svg +11 -0
  220. package/dist/web/assets/sr-Co7OKBh3.svg +6 -0
  221. package/dist/web/assets/ss-CxVEpdPD.svg +8 -0
  222. package/dist/web/assets/st-C1Nd1c3V.svg +16 -0
  223. package/dist/web/assets/sv-CJIHhYwF.svg +593 -0
  224. package/dist/web/assets/sx-nDhIaDNb.svg +56 -0
  225. package/dist/web/assets/sy-DwSud114.svg +6 -0
  226. package/dist/web/assets/sz-qxMwa2gs.svg +34 -0
  227. package/dist/web/assets/tc-dtelpZmc.svg +50 -0
  228. package/dist/web/assets/td-BsuVhZpT.svg +7 -0
  229. package/dist/web/assets/tf-Co33RhQH.svg +15 -0
  230. package/dist/web/assets/tg-CP1-sc35.svg +14 -0
  231. package/dist/web/assets/th-tzq84hgd.svg +7 -0
  232. package/dist/web/assets/tj-b-aWfOTb.svg +22 -0
  233. package/dist/web/assets/tk-CDucsEss.svg +5 -0
  234. package/dist/web/assets/tl-wpo93AGk.svg +13 -0
  235. package/dist/web/assets/tm-C_WSgUcv.svg +204 -0
  236. package/dist/web/assets/tn-BcKCZULf.svg +4 -0
  237. package/dist/web/assets/to-D8uVsoxb.svg +10 -0
  238. package/dist/web/assets/tr-Cd6FO9Bg.svg +8 -0
  239. package/dist/web/assets/tt-CTnr7aY5.svg +5 -0
  240. package/dist/web/assets/tv-DDqkVT-n.svg +9 -0
  241. package/dist/web/assets/tw-d-Mf-0VT.svg +34 -0
  242. package/dist/web/assets/tz-BjLtHeil.svg +13 -0
  243. package/dist/web/assets/ua-Bq0XgQqK.svg +6 -0
  244. package/dist/web/assets/ug-ByL2ejGl.svg +30 -0
  245. package/dist/web/assets/um-Bhke9Eic.svg +9 -0
  246. package/dist/web/assets/un-Bqg4Cbbh.svg +16 -0
  247. package/dist/web/assets/us-C73uVeEr.svg +9 -0
  248. package/dist/web/assets/uy-DD6peej-.svg +28 -0
  249. package/dist/web/assets/uz-C2f-Cubn.svg +30 -0
  250. package/dist/web/assets/va-B9-hqIE-.svg +190 -0
  251. package/dist/web/assets/vc-COpmFovN.svg +8 -0
  252. package/dist/web/assets/ve-BSqnIB9l.svg +26 -0
  253. package/dist/web/assets/vg-C7xY6pic.svg +59 -0
  254. package/dist/web/assets/vi-BC_zcciE.svg +28 -0
  255. package/dist/web/assets/vn-BEAEijd0.svg +11 -0
  256. package/dist/web/assets/vu-D6k0NQlg.svg +21 -0
  257. package/dist/web/assets/wf-DrxpOO_G.svg +5 -0
  258. package/dist/web/assets/ws-vzJNwdVm.svg +7 -0
  259. package/dist/web/assets/xk-Bj15g7cp.svg +5 -0
  260. package/dist/web/assets/xx-zm_JmrXl.svg +4 -0
  261. package/dist/web/assets/ye-BwST9gXC.svg +7 -0
  262. package/dist/web/assets/yt-DIfEG0ex.svg +5 -0
  263. package/dist/web/assets/za-Jz40JTrv.svg +17 -0
  264. package/dist/web/assets/zm-BmsW91ne.svg +27 -0
  265. package/dist/web/assets/zw-U0m7oJ5e.svg +21 -0
  266. package/dist/web/index.html +2 -2
  267. package/package.json +1 -1
  268. package/release-notes.json +44 -0
  269. package/src/server/ccusage-session.mjs +17 -0
  270. package/src/server/claude-accounts.mjs +18 -10
  271. package/src/server/codex-quota.mjs +7 -1
  272. package/src/server/index.mjs +4 -1
  273. package/src/server/quota-history.mjs +149 -0
  274. package/src/server/quota-shape.mjs +23 -20
  275. package/src/server/quota.mjs +7 -2
  276. package/src/server/request-gates.mjs +1 -0
  277. package/src/server/traffic-radar-config.mjs +35 -3
  278. package/src/server/traffic-radar-routes.mjs +13 -0
  279. package/src/server/traffic-radar.mjs +12 -1
  280. package/src/server/usage-routes.mjs +12 -0
  281. package/dist/web/assets/BrowserWatchModal-CEWlounF.js +0 -1
  282. package/dist/web/assets/RadioPanel-B7qs4g1T.js +0 -1
  283. package/dist/web/assets/TrafficRadar-CGsJ5yOZ.js +0 -1
  284. package/dist/web/assets/UsageHistoryModal-DLExexb7.js +0 -1
  285. package/dist/web/assets/index-B_uYtqRM.css +0 -1
  286. package/dist/web/assets/index-BepyDfFS.js +0 -306
@@ -0,0 +1,28 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="flag-icons-vi" viewBox="0 0 640 480">
2
+ <path fill="#fff" d="M0 0h640v480H0z"/>
3
+ <path fill="#369443" stroke="#010002" stroke-miterlimit="10" stroke-width="1.5" d="M204.3 315s-.5-3.6 6.2-6.1c6.6-2.6 7.2-12.2 5.8-18.6 0 0-3.4 6-7.7 8.1 0 0-6.8 3.6-7.2 10.4 0 0 0 2.5-.5 4.5-.3 1-3.4-8.6 2.4-15.8 6-7.3 7.6-13.3 2.9-25 0 0-.5 7-5.1 11.1-4.7 4-5.3 4.4-5.2 14 0 0 0 3.4-1.7 4.5 0 0-3.6-5.3-4.6-8.8s-1.4-5 2.8-9c0 0 13.2-8.7 3.7-27.4 0 0-.3 6.4-5 10.2-4.5 3.9-4.2 6.4-4.4 13-.2 6.7-.6 6.2-1.1 7.2 0 0-8.5-15.6-2-23.8s10.2-10 3-25.4c0 0 .3 8-5.5 11.8-5.7 4-4.4 13-4.4 13s.4 3.5-.8 6c0 0-8.1-15.9-.4-24.4 6.6-7.3 7-12.4 3.5-22.6 0 0-.4 4.7-4 7.3-3.7 2.6-6.6 5.1-5.9 15 0 0 .3 7-.6 9 0 0-3.4-6.4-4.4-10.5-1-4.2-1.3-6.6 1.2-10.7s12.5-16 .6-33c0 0-.3 5.5-3.4 10.5-3 5-1.6 10.9-1 15.4s-1.5 8.9-1.5 8.9-5.2-9.5-4-20.4q1.6-16.6-13.5-26.4s-7.3 17 2.7 25.7c0 0 8.5 8.4 10.7 18.6 0 0-6.5-.6-12.3-12s-18-9.6-18.8-9.7c0 0 2 17.6 20.6 22.6 0 0 12 2 14.2 10.8 0 0 2 6 2.8 9.2 0 0-3.8-1.5-7.3-6.7-3.5-5-3-5.7-14.8-6.9 0 0-4.7-.5-7.2-3.9 0 0 5 18.6 17.7 18.5 0 0 11.6-1.3 18 14l-2.9-2c-1.7-1.1-6-3.3-14.5-2.3s-10.9-.4-13-1c0 0 8.6 15.7 20.7 11s18 12.4 18.2 12.7c0 0-1.7-1.2-3.8-3.3-2.2-2.1-6.6-4.7-15-2 0 0-6.1 2.3-12.3.4 0 0 6 11.5 19.8 9.5a15 15 0 0 1 17.3 10.2s-1.8-1-3-2c-1.3-1-6-3.7-16-.8s-13.6-.4-13.6-.4 5.5 10 16.2 11.3c0 0 6-.1 8.4-1s9.2-2.5 13.8 4.2c0 0-1.3.2-3.2-.7 0 0-7-2.5-12.5 2 0 0-4.8 4.9-11.6 4 0 0 8.8 8.5 22.8 1.3 0 0 4.7-3.4 8.2-.8 3.5 2.7 11.5-2.6 11.5-2.6z"/>
4
+ <g fill="#f4c53d" stroke="#010002" stroke-miterlimit="10" stroke-width="1.5">
5
+ <path d="M282.2 103.7s-1.6-14.5 10-16a38 38 0 0 1 18 1.2l5.5 10.6-2 7.2-7.4 3.4s1.3-11-8.8-11.2c-2.6 0-4 1-8.1.3s-6.3 3.8-7.2 4.5z"/>
6
+ <path d="M363.8 139.6c-1.8 2.2-8.7 3-8.7 3s7.1 5.5 10.2 13.3c3 7.7-82.4 0-82.4 0s3.8-2.6 6.3-7.6c0 0-3.8 1.4-7.6-2.4 0 0 2.8 1 6.5-4.6 0 0 5.5-7 9.4-9 0 0-1.8 1.2-6.1-1.2 0 0 7.4-1 10-13.5 0 0 .5-2.8 3.3-7 2.8-4 2.2.9 7.4-5.4 0 0 2.4-4.4.3-7-2-2.8-4.3-1.8-8.6-4.4-4.4-2.6-6.3-4-4.8-8s5.3-3.4 5.9-3.4.8-3.5 5.5-5.9 17.4-1.3 19.2-.3c2 1 9.5 3.3 14 14.5s-1.2 15.4 10.8 32.4c0 0-4.8 1-7.9 0 0 0 6.3 11.2 17.3 16.5z"/>
7
+ <path fill="none" d="M311 92.2c-10-.5-6.1-9.8-6.1-9.8"/>
8
+ <path d="M328 93.5s-1.7-.8-3.2-2.8c-2-2.7-6.7-4-9.1-1.4 0 0-2.5 2.8-4.8 3 0 0 2.6.7 4.3 2.3s3.5 2.8 6.1 2.4 3-1.7 4.2-2.5 2.5-1 2.5-1z"/>
9
+ </g>
10
+ <path fill="#369443" stroke="#010002" stroke-miterlimit="10" stroke-width="1.5" d="M202.8 336.5s-.2-6.4 7.8-6.8l23.5 32.7s-.9 2.1-11.5 1.9c0 0-1.2 0-1.8 1.2-.9 2-18-29-18-29z"/>
11
+ <g id="vi-a" fill="#f4c53d" stroke="#010002" stroke-width="10" transform="translate(3.6 26.2)scale(.15055)">
12
+ <path d="M1495 1807.9s-49.9 85.6-110.2 87c0 0-103.7-12.6-133 14.5-20.5 18.9-41.4 34.5-50 82.8-8.4 48.3 16.5 58.7 22.4 60.8 0 0 4.6 34.5 38.7 25.5 0 0 2 36 62.2 18.7s85.3-11.8 97-71.8c11.9-60.1 22.8-59.1 33.5-66.3 14.4-9.7 41.5-18.8 61.6-30.4 18-10.4 87.2-45.6 110.8-48.3 23.6-2.8 18.4-82.2 18.4-82.2h-61l-29.5-43.5zm192-429.4s-61 49.7-112.2 0c0 0-20.6 24.8-62 17.6-41.2-7.3-48.1-29-52-41.4 0 0-35.8 20.8-66 4.3-30-16.4-30-41.3-30-41.3s-52.5 10.4-79.4-25.2c-26.9-35.5-10.5-70.7 4-74.9 0 0-56.7 14.9-72.2-33.8a56 56 0 0 1 16.4-62.8s-119.4-.6-168.4-38c0 0-40.7-25.6-16.4-52.5 0 0-107.5-17.2-134.4-60 0 0-11.8-11.8-7.9-32.5 0 0 .7-11.7 12.5-12.4 0 0-122.6-19-158-59.4 0 0-17-18.6-8.5-43.5 0 0 1.8-6.5 4.7-11 0 0-111.6-23.5-166.6-73.2 0 0-31.8-28.3-15.4-66.3 0 0-186.5-51-143.3-133.2 0 0-87.2-28.3-59.6-107 0 0-72.1-36.6-40.7-94.6 30.1-55.5 122.6 9.7 232 40 0 0 296.4 93.2 442.3 118l414.6 617.3 241.9 93.2z"/>
13
+ <path d="M1689.9 923.9s-38.9-29.2-108.2 5.1c0 0-23.3 16.1-41.7-1.5a37.3 37.3 0 0 1 4.3-57.5c51.7-38.3 70.8-153.2-7.8-200.9 0 0-114-67.6-532.3-174 0 0-35-9.8-53.8-5.1a52 52 0 0 0-37.6 37.8S894 581.1 957 611.6c0 0 28.4 13 57.7 21.4 0 0-32.2-7-46 24.8-13 30.4 6 61.5 65 81.5 0 0 16 6.2 38.7 11.7 0 0-50.5 14.5-26.2 55.3 0 0 21.6 42.8 98 50.4 0 0-57 6.2-16.8 60.4 0 0 17.7 29.7 73.4 40.7 0 0-42.2 1.4-21 39.3 21.4 38 71.5 59.4 120.9 62.9 0 0 26.7 1.4 45.4-2.8 0 0-47 23.5-19.4 62.8 0 0 20.3 28 71.1 26.6 0 0-13.1 44 24.1 60.6 29 13 53.1-7.8 53.1-7.8s-9.8 47.1 32.5 63.7c0 0 21.1 10.9 52.6 0 0 0 24 53.9 109.6 16 85.6-37.7 20.2-355.1 20.2-355.1zm5 489.4s-12.5 67.4-112 152.2c0 0-76.8 67.7-74.9 145.7 2 79.5-13.7 88.4-43.9 115.3 0 0 62.3 4.9 92.4-36.6 0 0-1.3 69-10.5 75.3 0 0 19.6 1.2 47.9-29.7 0 0 17-18 32.8-24.9 0 0-18.4 47.7-4 91.9 0 0 4.6-17.3 28.9-24.9 0 0 44-9 61-72.5 0 0 11.1-42 80-79.4 0 0 78-29.4 76-67.8-2-38.5-173.6-244.6-173.6-244.6z"/>
14
+ <path stroke-miterlimit="10" d="M2056.5 2282.2s-17.9 78.8-80 72.5c0 0-43.9-4.2-40.6-77.4 0 0-64.9 34.6-75.4-51 0 0-59 13.7-58.3-66.3 0 0-55 9.6-48.5-61.5 0 0-59.7 16-59.7-51 0 0-139.6-23.2 151.4-288.6l259.6 154.6z"/>
15
+ <path d="M2085.4 1928.3s-43.3 38.4-74.1-19c0 0-42-2-48.5-33.8 0 0-34.1-3.4-40.7-35.9 0 0-46.5-4.8-45.2-44.1 0 0-84.6-6.6 0-102.4s228.1 159 228.1 159zm48.2-23.8c42 0 89.5 262 77.2 419.9-4.5 57.3-35.2 104.1-77.2 104.1s-72.6-46.8-77-104.1c-12.4-157.9 35.1-419.9 77-419.9"/>
16
+ <ellipse cx="2133.6" cy="1902.5" rx="58" ry="86"/>
17
+ <path fill="none" stroke-miterlimit="10" d="M1935.9 2277.3s6.6-138.7 126.8-337.6m-202.2 286.6s-18.7-80.1 150.8-317c0 0-19.7-56.5 40.6-92.8M1802.2 2160s-5.3-86.7 160.6-284.5c0 0-14.7-51 45.4-91.8m-254.5 314.8s6.2-87.6 168.4-258.9c0 0-8-52.4 50-84.9m-278 292.8s11.7-100.1 182.8-252c0 0-5.9-39.4 51.1-79.4"/>
18
+ <path fill="none" d="M372.3 432s134.3 77.8 552.9 155.6M431.9 539S795.6 657.6 965 672.2m-389.9 0s213.4 67 463.3 109.3m-281.2 30.3s241 57.9 356.2 67.5M919 925.6s203.9 42.5 255.5 47.6m-125.7 57.3s148.8 22.6 208 21.4m-23.2 69s60.2-2.8 89.1-7.6m-33.4 104.3s51.2-13.8 81.3-33.1m-5.9 133.2s39.4-15.2 58.4-56.6m37.7 93.6s30.4-27.3 32.4-57.7m81.6 81.5s-11.4-9.9-3.6-52.7m-11.1-62.8s-6-12.2-4-31.6m-211-581.3s68.8 27.6 91.7 65.6 7.9 74.9 0 96c-3.9 10.7-52.4 104.2 4.6 171.9M1346 1057s.4-.3 24.6-8m-169.8-91.4s41 8.2 81.3 8.6m-138-109.8s48.2 4.9 93.5 4.2m-165.2-109.8s69.5 13.8 106.8 14.5M1014.7 633s85.7 24.4 149.4 33.1m141.6 50.4s-61.6 57.3 12.5 110.5c0 0-30.8 48.3 30.8 98.7m-16.4 23.8s-9.2 92.2 103.6 92.2c0 0-21.7 82.1 87.2 79.4 0 0 12.4 65.6 91 52.4M1441.3 1895s-17.9 4-56.6 0m-108.8 48.3s-54.4-8.3-51.8 109.8m84.6-82.9s-49.2-6.2-46 108.4m520.7-384.5s-23.6 4.8-40 23.5-47.8 15.1-47.8 15.1 17-13.8 23-48.3c5.8-34.5 24.9-44.9 24.9-44.9m-56.3-32.6s-23.6 4.8-40 23.4c-16.4 18.7-47.9 15.2-47.9 15.2s17-13.8 23-48.3 24.9-44.9 24.9-44.9m23.7 188.5s-20.6 4.3-34.9 20.5c-14.3 16.3-41.8 13.3-41.8 13.3s15-12 20-42.2c5.2-30.1 21.8-39.2 21.8-39.2"/>
19
+ </g>
20
+ <use xlink:href="#vi-a" width="100%" height="100%" stroke="#010002" stroke-width="10" transform="matrix(-1 0 0 1 647.2 0)"/>
21
+ <path fill="#0081c6" stroke="#010002" stroke-miterlimit="10" stroke-width="1.5" d="m466 256-14.3 61.7-5.9-4.2 14-59.2-9.8.2 23.1-42.3 1.5 48.7zm37 13-43 50.8-4.6-5.2 42.8-50.2-8.7-4.6 39.2-26-20.3 43.8z"/>
22
+ <path fill="#0081c6" stroke="#010002" stroke-miterlimit="10" stroke-width="1.5" d="m492.6 242-38.5 74-5.9-3.5 38.7-73.8-9.4-2.4 32.7-34.6-10.5 47.5zm-48 96.6-2.9 11.7 8 8-11.2 47-10-13.3-14.6 6.8 11.1-47 10.4-3 2.6-11.7s3.2-1.2 6.6 1.5z"/>
23
+ <path fill="#0081c6" stroke="#010002" stroke-miterlimit="10" stroke-width="1.5" d="m447.3 330.8-5.7 10.6 5.7 9.7-22.4 42.5-6.3-15.6-15.9 2.6 22.4-42.4h10.7l5.5-10.6s4 0 6 3.2z"/>
24
+ <path fill="#0081c6" stroke="#010002" stroke-miterlimit="10" stroke-width="1.5" d="m448.2 333.9-15 19.2 3.4 10.8-30.9 36-2.8-16.6-16-1.2 30.8-36 10.4 2.5 16-20.4s4.4 2.2 4.1 5.7zm-382.7-45c3.6-1.5 6.2-2.9 6.2-6.7q0-1.5-1.5-6.1L46 202a59 59 0 0 0-3-7.9c-1.1-2-3.2-2.9-6.1-4h30.7c-3.3 1.5-6.4 2.7-6.3 6.3q0 2 1.1 5.7l18.6 58 18.5-58a20 20 0 0 0 1.1-5.7c0-3.7-3.2-5-6.3-6.4h29.8c-2.7 1.1-5 2-6 4.1a63 63 0 0 0-3.1 8L90.8 276a38 38 0 0 0-1.5 6.1s-1.1 4.7 6.2 6.7zm515.3-7.6v-83.7q0-2.1-.8-3.3c-.8-1.2-2.5-3-5.5-4.2h27.7a12 12 0 0 0-5.5 4.2q-.7 1.2-.7 3.3v83.7q0 2.2.7 3.4c.5.8 2.5 2.8 5.5 4.2h-27.7c3-1.4 5-3.4 5.5-4.2q.8-1.2.8-3.4z"/>
25
+ <path fill="#fff" stroke="#010002" stroke-width="1.5" d="M324.8 309.8S399 276.9 399.1 201H250.5c.2 76 74.3 108.8 74.3 108.8z"/>
26
+ <path fill="#a60032" stroke="#010002" stroke-width="1.5" d="M262 201v48.5s5.6 11.3 11.4 18.3V201zm22.8 0v80s7.2 7 11.4 10.4V201zm22.9 0v98.9s8.1 5.2 11.4 7v-106h-11.4zm80 0v48.5s-5.7 11.3-11.5 18.3V201zm-22.9 0v80s-7.1 7-11.4 10.4V201zm-22.8 0v98.9s-8.2 5.2-11.5 7v-106H342z"/>
27
+ <path fill="#162667" stroke="#010002" stroke-miterlimit="10" stroke-width="1.5" d="M399.1 145.8s-36.4 19-74.3-1.6c-37.9 20.6-74.3 1.6-74.3 1.6V201h148.6z"/>
28
+ </svg>
@@ -0,0 +1,11 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-vn" viewBox="0 0 640 480">
2
+ <defs>
3
+ <clipPath id="vn-a">
4
+ <path fill-opacity=".7" d="M-85.3 0h682.6v512H-85.3z"/>
5
+ </clipPath>
6
+ </defs>
7
+ <g fill-rule="evenodd" clip-path="url(#vn-a)" transform="translate(80)scale(.9375)">
8
+ <path fill="#da251d" d="M-128 0h768v512h-768z"/>
9
+ <path fill="#ff0" d="M349.6 381 260 314.3l-89 67.3L204 272l-89-67.7 110.1-1 34.2-109.4L294 203l110.1.1-88.5 68.4 33.9 109.6z"/>
10
+ </g>
11
+ </svg>
@@ -0,0 +1,21 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="flag-icons-vu" viewBox="0 0 640 480">
2
+ <defs>
3
+ <clipPath id="vu-a">
4
+ <path d="M0 0v475l420-195h480v-85H420Z"/>
5
+ </clipPath>
6
+ </defs>
7
+ <path fill="#009543" d="M0 0h640v480H0z"/>
8
+ <path fill="#d21034" d="M0 0h640v240H0z"/>
9
+ <g clip-path="url(#vu-a)" transform="scale(.71111 1.01053)">
10
+ <path stroke="#fdce12" stroke-width="110" d="m0 0 420 195h480v85H420L0 475"/>
11
+ <path fill="none" stroke="#000" stroke-width="60" d="m0 0 420 195h480m0 85H420L0 475"/>
12
+ </g>
13
+ <g fill="#fdce12" transform="translate(-22)scale(1.01053)">
14
+ <path d="M106.9 283v27c23.5 0 69.7-18 69.7-76.1s-49.3-68.9-64-68.9-60.3 10.6-60.3 58c0 47.6 44.7 52 53.5 52s41.8-8 38-43.6a35.5 35.5 0 0 1-35.4 31.5c-24 0-39-17.8-39-35.4s14.6-41.2 39.9-41.2 43.8 22.5 43.8 45.1-17.8 51.5-46.2 51.5z"/>
15
+ <g id="vu-b">
16
+ <path stroke="#fdce12" stroke-width=".8" d="m86.2 247.7 1.4 1s11.2-25.5 41.1-43.6c-3.8 2-23.8 12-42.5 42.6z"/>
17
+ <path d="M89.1 243.3s-3.4-7-.4-10.2 1.7 8.3 1.7 8.3l1.3-1.9s-2-8.6.2-10.4 1.2 8.3 1.2 8.3l1.4-1.8s-1.5-8.4.7-10 .9 8 .9 8l1.6-2s-1.2-8 1.5-9.9.3 7.6.3 7.6l1.8-2s-.8-7.3 1.5-9c2.3-1.6.4 7 .4 7l1.6-1.8s-.5-6.8 1.7-8.4.2 6.5.2 6.5l1.7-1.6s-.4-6.9 2.4-8.2-.5 6.4-.5 6.4l2-1.6s.5-8 2.9-8.7c2.4-.8-1 7-1 7l1.7-1.4s.9-6.8 3.5-7.6c2.7-.9-1.6 6.2-1.6 6.2l1.7-1.3s1.9-6.8 4.4-7.6c2.4-.7-2.6 6.5-2.6 6.5l1.7-1.2s2.7-6.2 5-6.6c2.1-.4-2.6 5.1-2.6 5.1l2.1-1.2s3.5-6.4 4.8-4.5-5 4.9-5 4.9l-2 1.2s7.5-3.6 8.4-1.8-10.3 3-10.3 3l-1.8 1.2s7.5-2 6.6-.1-8.4 1.5-8.4 1.5l-1.7 1.2s7.5-1.8 6.5 0c-1 1.6-8.3 1.5-8.3 1.5l-1.8 1.5s7.3-2 6.2.3-9.4 2.1-9.4 2.1l-2 2s7.7-2.7 7-.6c-.6 2-9.4 3-9.4 3l-2 2s8.3-2.7 5.8-.2c-2.4 2.6-8.5 3.2-8.5 3.2l-2.3 3s8.2-5 7-2.2-9.2 4.7-9.2 4.7l-1.6 2s7.4-4.3 6.6-2c-.7 2.5-8.6 5-8.6 5l-1.3 1.8s8.7-5.2 8-2.5c-.8 2.6-9.1 4.5-9.1 4.5l-1 1.7s8-4.7 8-2.4c.2 2.2-9.4 4.4-9.4 4.4z"/>
18
+ </g>
19
+ <use xlink:href="#vu-b" width="100%" height="100%" transform="matrix(-1 0 0 1 220 0)"/>
20
+ </g>
21
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-wf" viewBox="0 0 640 480">
2
+ <path fill="#fff" d="M0 0h640v480H0z"/>
3
+ <path fill="#000091" d="M0 0h213.3v480H0z"/>
4
+ <path fill="#e1000f" d="M426.7 0H640v480H426.7z"/>
5
+ </svg>
@@ -0,0 +1,7 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-ws" viewBox="0 0 640 480">
2
+ <g fill-rule="evenodd" stroke-width="1pt">
3
+ <path fill="#ce1126" d="M0 0h640v480H0z"/>
4
+ <path fill="#002b7f" d="M0 0h320v240H0z"/>
5
+ <path fill="#fff" d="m180 229.3-20.7-14-19.9 14.1 6.5-24.9-19-15.2 24.5-1.5 8.1-23.6 8.8 24 24 .7-19 16.3zm-3.6-165.6L159.8 53l-16 10.4 4.4-20-14.6-12.7 19.4-1.6 7.2-18.6 7.4 18.7 19.1 1.7L172 44.3zm-73 59.5-16-11-16.7 11 5.2-19.4L60.8 91 80 90l7-19 6.8 18.9 19.6 1.1-15 12.5zM250 110l-15.4-10-15 10 4.4-18.3-14-11.8 18.3-1.5 6.3-17.2 7 17.4 17.7 1-13.7 12.3zm-43.1 43.4-10.3-6.4-10.3 6.6 2.7-12.3-9.2-8.3 12-1 4.6-11.6 4.9 11.6 11.9 1-9.1 8.3z"/>
6
+ </g>
7
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-xk" viewBox="0 0 640 480">
2
+ <path fill="#244AA5" d="M0 0h640v480H0z"/>
3
+ <path fill="#D0A650" d="M253 224.8s1.2-.8 1.6-.9l2-.6s1-.5 1.5-.5 1.6.6 2 1.1 2 1.4 2 1.4 1.2.4 1.5 0q.4-.6 1.3-.7.7-.2.6-.9c-.1-.7.2-.9.6-1.4.5-.5 1.3-.8 1.3-.8s1.2-.5 1.3-1.2 1.3-1.2 2-1.3c.7 0 0-.4 1.8-.2 1.7.2 2-.4 2-.9.1-.5 0-1 1.1-1q1.6.4 1.6-.4c0-.6 1-1-.7-1.4-1.8-.5-1.6-.1-1.8-1 0-.7 0-.6-1.1-.7s-.6-.7-.7-1.3q-.2-.9-.6-1.3c-.3-.4-.9-.4-.9-1s-.1-1-.7-1q-1 .1-1-.5 0-1 .8-1 1-.2 1-1.2c-.2-.6-.2-1.9-.2-1.9l.9-1s2.6-2.1 2.8-2.5 1.1-.7 1.5.1.6 1 1 1.4c.3.4 1.3.1 1.5-.3s.3-1.9.9-2.7q1-.9 1.1-1.8.2-1.3 1.2-1.2c.6 0 1-.9 1-1.4q0-.8 1.2-1.2c.8-.1 1.3-.6 1.6.2s.6.7 1.1 1q1 .6 1.8.3c.5-.4.7-1 1.3-.7q.9.5 1.2-.7l.3-1.9s.1-.5 1.1-.5.3-.6.8-1 .6-.8 1.3-.6 1.8-.3 1.3-1-1.8-1.6-1.1-2.4 1-2 .3-2.2c-.7-.1-1.8.1-1.9-.6-.1-.8-.4-1.4.5-1.5s2.2-.1 2.7-.5 1.8-.7 1.8-1.8.4-1.3.6-2 .1-2-.5-2.6-1.4-1.6-1.5-2q-.3-.7-1.6-1.3c-.8-.2-1.6-.4-1.6-1s.6.1.6-1.6-1.1-2-1.1-2l-1.7-1s-3-.8-3.8-.8-1.8-.8-.9-1.4 1.2-1.5.9-2.2c-.4-.7-.6-1.3-1.9-1.6q-2-.3-1-1.4c.5-.7.7-1.3 1.4-.7.6.5 1.8.7 2.7.3s1.3-.8 1.8-.3 1 .8 1.7.2 2-.8 2.6-.5c.5.4 2 .3 2.4 0s1.4-1 1.4-1.3.6-1.2 1.1-1.5 1.3-1.4 1.9-1.4.8-.7.8-1c0-.5.5-1.4.6-1.7s1.2-.8 2 0c.9.5 2 .8 2 .8s1 .2 1.7 0a2 2 0 0 1 2.1 0c.9.6 2 .6 2 .6l.3-1.3c0-.4.2-1.2-.3-1.5s-1-.7-.1-1.4 1-.5 1.9-.5l2.2.1c.7 0 1.8.7 1.8 1.3q.1.8 1 1.4c.6.3 1.3.6 1 1.2q-.3 1 .6.8 1 0 .9.9-.1.7 1 1 1 .4 1 1.2c0 .8-.2.9 0 1.4l1 1.4s1.3 1.5-.4.7c-1.6-.7-2-1-2.5-1l-1 .5-1.3.2c-.6 0-1.2 1.2-.2 1.4q1.3.2 1.2 1.2c-.1 1-.3.5-.8 1s-.8.2-1.6.2-1 .7-1 1.3.3.6.6 1q.6 1 1.6.2c.5-.5 1-.9 1.3.1s.9 1 1.5 1q.9.1 1.6-.4 1-.5 1.3.9.4 1 1.3 1.3t1 1q.3 1 1.1.5 1.1-.7 1.9-.1l.9 1.2v1.1l2.3.8.2 1q0 .6 1 .4h1.6s.8-.3.8-1q0-.9 1-.8c.5 0 1.8.5 2.1-.2s1.4-.8 2.2-.5l3 1.2s-.3 0 .4 1.1 2 1.1 2 1.1 0 1 .3 1.4 1.3.6 1.8.2q1-.8 2.1-1c1.1-.2 1.2 0 1.2-.4s-.7-.7-.7-1.4.7-.6.8-1.3c.1-.6.8 0 1.3.4s1 .8 1 1.2c0 .5 1 2 1.5 2.2s2.1.3 2.6-.2 1.6-.8 1.5.5-.4 1.4.4 1.8 1 2 .3 2.4-1 .5-1 1.2-.2 1.6.4 2q1 .7 1 1.2c0 .5.6 2.4.6 2.4s.4 1.9.2 2.3c0 .5-.3 1.2.7 1.1q1.4-.3 1.3.7c-.1 1 .4 1.2-.2 1.5s-1 1.4-.4 1.6q.9.3 1.2 1c.1.4 1 1.2 1.6.7s.7-.6 1.2-.7.8-.4.3-1q-.7-.8-.1-1.4c.5-.3.7-1.3.7-1.3s.7-1 1.5 0 1 .6 1.5.6.8.5.8 1 1.2.5 1.2 1.3l.2 3s0 1.1.7 1.5q1 .6.2 1-.3 1-.2 2c.1 1 .2.5-.3 1q-1 .7-.5 1.6c.3.6.2 1 1.1 1.8 1 .7.9 1 .9 1.6 0 .5.9 1.3.9 1.8s.7 1.2 1.3 1.3 1.2 1 1.2 1.6l.1 1.9s0 .3.6.3 1.2.8 1.4 0c.2-1 1-1 1.4-1.3s1.4-.6 1.9-.3 1 .3 1.5.3l2.6.1s.6 0 1 .8c.3.8 1.3 1.8.8 2.2s-.6 1.3 0 1.3 1.5 0 1.5.5q-.2 1 .7.7.8-.5 1.1 0t1.3.7q.8.4 1.2-.3c.3-.4 1.7-.8 1.7-.8s1.8-.5 2.5-.3l1.7.7s.4 1 .2 1.7-.5.5-.2 1.5-.3 1-.7 1q-.9-.5-1 .7c0 .8-.4 1-.4 1.8s0 .6-.5 1q-.8.6.1 1c.7 0 .5.8.5 1.2l-.1 1.4s0 .5-.7.5-1.5 0-1.6.5-1 1.3-.3 1.9q1 .7.1 1c-.4.3-.8 1.3.2 1.6q1.2.5.2 1.1c-.6.4-1.7.8-1.7 1.4s-.3.6-1 .7q-1.2.3-.2 2c.8 1.1 1 1 1.6 1s.6-1 .6-1l2.5.2q1 0 1.9-.3c.5-.4 1.7-.9 1.7 0s.3 1 .8 1.3c.6.5.7.1 1.2.8.5.6.6 0 1-.7.3-.7 1-1.4 1.6-.6.5.9.5.6 1.2.6s1 .4 1 .9.6.5 1.5.4.9.5 1.2 1 .5.4 1 .4q.7.1 1.2-.4c.4-.4.8-1 1.3-.3s1.4.5 1.6-.2c.3-.8 1.3-1.4 1.9-.6.6.9 1 .9 1.6 1q1-.2 1.7.6c.4.6 1.5 1.4.7 2s-1.7 1.5-1 1.8a3 3 0 0 1 1.6 1c.5.4 2 .7 2.7.8.7 0 1.2.2 2-.5s1.7-.6 1.6.3.3 1.8.3 1.8.6 1.4.6 1.9-.1.6 1 1.3c1 .6.8 1 1.7.4q1.1-.8 1-1.5v-1.7s1.2-.2 1.6-.5c.5-.4 2.3-1.3 2.8-.9s1 .3 1.5.1l1.9-.2c.4 0 1.2.1 2.2-.6.9-.8.9-.6 1.5 0q.7.8.2 1.6c-.4.4 0 1.3.8 1.3s1 .5 1 1l.3 1.7c0 .4 0 .7 1.4 1 1.2.3 1 1 1.2 1.6q.6.9-.4 1c-1 .1-1 .3-1 .8-.2.5-1.2.7-1.2.7l-1-.2s-.8 0-1.1.4-1 1.3-.6 2q.7 1.1 0 1.6c-.4.3-.7 1.9-1.1 1.6-.5-.4-1 0-1.5.3s-.4 1.7.5 2.2q1.4 1.1 1.2 1.3l1 1.6s-.3.3-.5.9c-.3.5-1 1.6-.3 1.8s.4 1.4-.3 1.4-1.5-.4-1.6.5-.5.6-1.2.5-2.4-.5-2.9.3-.6 1.2-1.4 1.1-.5 1.3-.2 1.8l1 1.3s.7.5.7 1.6q-.1 1.4-1 .2c-.4-.7-1.3-.6-1.4.2s-.3 2.2-1 2.2q-1.2 0-1.6.6c-.3.4-.9 1.2-.9 1.6s-.1.9-.7 1-.7 1.2-.7 1.2-1.4.3-1.5.8.1 1.4-1 1.5a3 3 0 0 0-2.2 1.4q-.7.7 0 1.5c.7.8.8 2.2 1.4 2.5q.9.3.9 1.3c-.1.9-.8 1.5.1 1.5q1.6-.1 1.2 1c-.4.7-.4.8-1 1.1-.8.4-1.1.4-1.1 1.2s.2.9-.4 1.2-.6.7-.6 1.4-.2.4-.9 1.1q-1.2 1-2.2.6c-1-.4-.7-.2-.8-.9s-1.1-.6-1.7-.5-1.4.7-1.4.7-1 .7-.6 1.2.2 1.4-.6 1.3-2.6.8-3.2-.1-2.2-1.6-2.5-.3c-.2 1.2.7 1.1.6 2.4s-.3 1.3-.8 1.7q-.5.6-.6 1.3c0 .5-.2 1.7.6 2.1s1.2 1.6 1.2 2.3q-.2 1.1.8 1.3 1.5.2 1.6-.9c.1-.7 1.7-1.2 1.9.3q-.2 2.1.7 2.9c.5.6 1 1.5 1.5 1.8s1.2 3 1.2 3c-1.1.3-1.4 1.8-2.1 2-.4.2-.9 0-1.3.3q-.1.6-.6.8c-.9.4-.7-.9-1.8-.4-.9.4-1 1.5-2.3 1-.7-.2-1.1-3-1.3-3.6l-1.1-1.8c-.8-1.2-2.3 0-2.8-.4-.8-.5-.5-1.4-1.7-1.5-2.4-.2-.7 1.5-1.7 1.8-2 .7-2-1.8-3.4-.6-.5.4 1 .7.6 1.4-.3.6-1.7 1.6-1.7 2.3.2 1 1.2 1.3 1.5 2 1 2.3-.5 3.8-2.7 2-1.2-.9-1.5-2.7-3.3-2.5l-1 .5c-.5 0-.8-.4-1.3-.3-.7.3 0 .8-.2 1.2 0 0-1 .7-1 1-.6.6-.4 1.2-1.2 1.8-.6.5-1.1.2-1.8 1-.7.7-.8 1.9-1.7 2.6-.5.4-.8-1.1-1.4-.1l-.2.4q-.3.4 0 .7c1.2 2.4-1.4 3.2-2.2 4.9-.3.7.6 1.3.3 1.9l-1.5 1.7c0 .2-.2.8-.4 1s-1 0-1 .4.8.7 1 .9-.2.7 0 .8c1.2 1.3.5.9 1.1 2 .1.2.5-.1.7.3s-.4.4-.2.8c0 .2 1 1.4 1 1.4 0 .4-1.8 1.2-2.2 1.2-1.1 0 1-2.2-.8-2.2-.8 0-.9 1.7-1 2h-1c-1.2 0-2 1.4-2.4 1.5s-1-.2-1.5 0c-.4 0-1 .5-1.4.5q-.4 0-.7-.4c-.5-.3-1.5-.4-2-.6-.4 0-1 .4-1.2.3-.3-.2.3-1-.6-1.4l-.7-1.7q.6-1.5.5-3.1c-.2-1.1-2-2-2.4-3-.3-.6-.6-2.4-1.3-2.8a6 6 0 0 1-1.8-2.2c0-.2.3-.6 0-1q-.6-.4-1-1c-.1-.4 0-1.8-.5-2.1s-4-.8-5-.9q-.6 0-1-.3l-.6-.7-1 .2h-1c-1.1.7-1.4 1.7-2.5 2.6-1.1.8-2.3.8-3.4 1.7-.7.6-1.2 2.1-1.9 2.8-.3.3-.7 0-.8.1l-2 1.8q0 .3-.2.5l-1.3.4h-1.2c-.5.2-.5.8-2.5 1.2l-.5.3-.6.5h-.9c-.5 0-.8.5-1.2.5-1 .2-2.8-.5-3.6-.1-.5.1-1.8 1.7-2.3 1.8q-.4.1-1-.1l-.6 2.2-2.4 2.1-.8 1q-.5.5-1 .5l-1.6-.4c-.8-.2-3.3-.3-4-.1-.9.1-.6 2.4-2.6 2.6l-3.3.4c-.1 0-.8-.4-1.5-.3-.3.1-1.1 1-1.1 1.2v.5l.2.4c-.4.5-1.4 1.3-1.7 2l-.4.4c-.2.2-1.6.7-1.7.9-.3.8 1 1.6.8 1.9-.3 1-1.7 2-2.2 3-.1.4.5 1.7.5 2.1q-.5 2.1-.5 4.1l.2 1.7.7.5 1.8 3.6c.3 2.2-3 1.4-1 3.6q.2.6.8 1l2.8 2.3c0 .4-2 .7-2.3 1-1 1-1.7 2.6-2.6 3.6-.6.5-1-.1-1.8 1.3-.2.5 0 1.6-.3 2-.5.4-.8-.2-1.3 0-.2 0-.3.7-.5.8-.5.5-5.2 3-5.6 2.7-.2-.1-.5-.9-.5-1.1q-.1-.6-.6-1c-1.2-1-3-1.3-4.2 0l-.7 1-2 1.6-.5.5c-.5 0-1.6-1.3-2-1.7-.4-.6-2-2-2.1-2.7 0-2.4-1.9-4.9-2.6-7.2h1.1c1.3-.9 1-3 3.3-2.2.3-.4.3-.8.8-1l.7-.5c.8-1.2 1.7-5.8.9-7-.7-1-1.5-1-2-2.7q-.1-.7 0-1.6l-1-3.1-.7-.7-.2-3.1c-.7-2.2-3.4-3.5-3.5-3.8l-1-1.7-.6-1.6c-.1-.3-.6-.6-.6-.9 0-.6 1.6-1.7 1.5-2.7 0-.3-1-1.3-.8-1.8s1.2-1.8 1.2-2.5c0-.8-1.6-2.6-1.8-3.4-.1-.5.6-.8.4-1.1s-1.8-1.9-2-2.3c-.3-.3.5-.7 0-1.3-.6-.5-.1-.4-.3-.8l-1-1.5c-.2-.5-1.6-5.5-1.5-5.8q-.5-.4-.9-1l-.4-1.2s-1.6-.5-1.9-1c-.2-.3-.3-1.6-.7-2.2l-.7-.4-.3-.7c-.5-.6-1.4 0-2-2.4q-1.4-.8-2.4-1.8l-.4-.4q-1-.2-2-.7c-.3 0-1.8 0-2-.2l-.4-.8c-.8-.1-2.2 0-2.9-.6-.5-.5-.6-2.8-1.6-2.5h-.4c-.7-1-2.9-1-3.8-1.6-.2-.1-1 0-1-.2l.1-1.3-1.1-1.4c-.9-.2-.6-.3-1-.6-1.5 0-1.7.2-2.6 1q-.4.3-1 .4c-.5.3-.6 1.2-1.3.8l-.6-.5c-.4-.4-.6-.2-.8-.8-1.2-.7-4.5 1.5-5.2 0-.6-.3-1 0-1.5-.4-.2-.2.7-3-1.7-4l1.6-1.1q.2-.6 0-1c0-.5.3-1.4.2-1.7l-.5-1-.2-1.2-.8-.4q-1-.6-1.7-1.4l-.4-.5c-.4-.3-1.8-.8-1.8-1.4l.4-.5q0-.5.3-.8c.6-1 2.1-.5 1.9-2.2-.1-.8-.7-1.4-.8-2.2l-.5-.7c-1.5-.1-1.3-1.6-1.8-2-1.5-1-2.7-.4-1-2.4.2-.7-1.5-1.8-1.8-2.1-.6-.6-.3-1.9-.6-2.5 0-.3-1.1-.9-1.4-1.3l-.5-1v-.1q.4-.6 0-1c-.1-.3-.6-.2-.7-.4q-2-1.6-4.9-2.5c-.5-.2-.3-.6-.8-.8l-3-1.2c-.2 0-.4-1.1-.6-1.5l-.9-1c0-1-.6-1-1.4-1.6v-.6l.6-2.1c.1-.4.6-.8.5-1.2l-.4-2.3c-.8-2-1.7-1.8-1.2-4.5q-.2-.8.3-1.4l.2-.3 1.2-.9c.4-.6.7-1.9 1.2-2.3l1.8-1.2c.2-.2.4-.9.3-1.2l-1.2-.2-1.1-.4-.3-.5-.2-.2q-.8-.1-1.4-.5l-1.7-.5c-1-.5-2-2-2.9-2.2-1.2-.3-2 .1-3.2.2-.7 0-.7-.4-1.3-.6-.8-.3-.2.4-2-.2-.3-.2 0-.8 0-1h-1c-1.4-.4-.9-1.8-1.3-2.7-.1-.2-.8-.2-1-.2l-.2-.2.2-.1c.2-.4-.7-1.4-.7-1.6.1-.3 2-.6 2.2-.6q0-.4-.2-.7.1-.8.5-1.7v-.2c-.6-.3-.7-.7-1.2-1q.1-.4.4-.7c.9-2.5 2.3-.5 3.5-2.8l.6-1.1h.2q.4.1.8 0l.8-.3h.5c2.2-.4 1.7-1.2 3-2.1.4-.3 1.4-.4 1.8-.6q.7.6 2.1 1.4c.7.2 3 .7 3.4 1 .5.2.6.8 1 1 1.3.8.5-.4 1.8-.2s2.3 1.4 3.5 1.9l1-.1c.3-.1 2.3-.5 2.5-.4l.8.3c.3.1.5-.5.8-.5.8.2.8.5 2 .4 0 0 .6-3.3 1.2-3.4.3-.1 1.2.7 1.4.8.4.1 0-.7 0-.7-.2-.3-.8-2.3-.7-2.5l.8.1q1-.2 2-.9l1-1.5c.1-.2-.2-.8 0-1l.9-.6c.4-.4.4-1 1-1.3 2-.2 2.7-1.8 4.6-2h.6l.4.6c0 .1 1.3.9 1.5.8q.3-.1.5-.4c.3.1 1.4-.5 1.5-.9l-.1-.6 1.6-1.2h1.4q.2.4.5.6h1.2c.2 0 .3-.5.7-.5"/>
4
+ <path fill="#FFF" d="M351.9 73.4 368 123l-42.2-30.7H378L335.8 123zm62.8 11.1 16 49.6-42.1-30.7h52.1l-42.2 30.7zm59.9 21.8 16 49.6-42.1-30.7h52.1L458.4 156l16.2-49.6zM288.1 73.4 272 123l42.2-30.7H262l42.2 30.7zm-62.8 11.1-16 49.6 42.1-30.7h-52.1l42.2 30.7zm-59.6 21.8 16.2 49.6-42.2-30.7h52.1l-42.2 30.7z"/>
5
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-xx" viewBox="0 0 640 480">
2
+ <path fill="#fff" fill-rule="evenodd" stroke="#adb5bd" stroke-width="1.1" d="M.5.5h638.9v478.9H.5z"/>
3
+ <path fill="none" stroke="#adb5bd" stroke-width="1.1" d="m.5.5 639 479m0-479-639 479"/>
4
+ </svg>
@@ -0,0 +1,7 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-ye" viewBox="0 0 640 480">
2
+ <g fill-rule="evenodd" stroke-width="1pt">
3
+ <path fill="#fff" d="M0 0h640v472.8H0z"/>
4
+ <path fill="#f10600" d="M0 0h640v157.4H0z"/>
5
+ <path fill="#000001" d="M0 322.6h640V480H0z"/>
6
+ </g>
7
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-yt" viewBox="0 0 640 480">
2
+ <path fill="#fff" d="M0 0h640v480H0z"/>
3
+ <path fill="#000091" d="M0 0h213.3v480H0z"/>
4
+ <path fill="#e1000f" d="M426.7 0H640v480H426.7z"/>
5
+ </svg>
@@ -0,0 +1,17 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-za" viewBox="0 0 640 480">
2
+ <defs>
3
+ <clipPath id="za-a">
4
+ <path fill-opacity=".7" d="M-71.9 0h682.7v512H-71.9z"/>
5
+ </clipPath>
6
+ </defs>
7
+ <g clip-path="url(#za-a)" transform="translate(67.4)scale(.93748)">
8
+ <g fill-rule="evenodd" stroke-width="1pt">
9
+ <path fill="#000001" d="M-71.9 407.8V104.4L154 256.1z"/>
10
+ <path fill="#000c8a" d="m82.2 512.1 253.6-170.6H696V512H82.2z"/>
11
+ <path fill="#e1392d" d="M66 0h630v170.8H335.7S69.3-1.7 66 0"/>
12
+ <path fill="#ffb915" d="M-71.9 64v40.4L154 256-72 407.8v40.3l284.5-192z"/>
13
+ <path fill="#007847" d="M-71.9 64V0h95l301.2 204h371.8v104.2H324.3L23 512h-94.9v-63.9l284.4-192L-71.8 64z"/>
14
+ <path fill="#fff" d="M23 0h59.2l253.6 170.7H696V204H324.3zm0 512.1h59.2l253.6-170.6H696v-33.2H324.3L23 512z"/>
15
+ </g>
16
+ </g>
17
+ </svg>
@@ -0,0 +1,27 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-zm" viewBox="0 0 640 480">
2
+ <defs>
3
+ <clipPath id="zm-a">
4
+ <path fill-opacity=".7" d="M-170.7 0H512v512h-682.7z"/>
5
+ </clipPath>
6
+ </defs>
7
+ <g fill-rule="evenodd" clip-path="url(#zm-a)" transform="translate(160)scale(.9375)">
8
+ <path fill="#198a00" d="M-256 0h768v512h-768z"/>
9
+ <path fill="#ef7d00" d="M421.9 184H512v328h-90.1z"/>
10
+ <path fill="#000001" d="M331.9 183.8h90v328h-90z"/>
11
+ <path fill="#de2010" d="M240 184h91.9v328h-92z"/>
12
+ <g fill="#ef7d00" stroke="#000">
13
+ <path stroke-linejoin="round" d="M451.6 65.6s34-14.5 37.2-17.5c1.5 1.8-13.6 20-42.9 26.7 26.6-6.2 49.3-26 54-25.4 1.3.3 1 19.3-60 35.8 42.2-11 66.7-31.4 66.4-29.2.3.5-4.2 16-41.1 28.1 10.3-2.4 38.3-19.4 38-16.1.9 1.3-27 37.2-77.6 25.5 40.4 10.5 66.5-14.8 70.2-14.3.8.1-7.4 22-58.2 23.4 24.3-2.5 17.3-.1 17.3-.1s-14.3 11.2-31.7 3.6c13.6 3.7 15.1 3.9 15.4 5-.9 1.6-12 3.8-22.9-2 8.7 3.6 16.5 4.2 16.6 5.5-.1.4-5.6 3.6-10.6 1.3s-50.3-30.1-50.3-30.1l77.4-21.3 2.8 1zm-91 75.6c-6.8 0-7 6-7 6s-.5.5-.2 3.4l1.7-2.6c.8.1 3.9 1 8.8-2.8-4.5 4.7-1.8 6.4-1.8 6.4s-1 3.7 2.4 4.4c-1-1.5-.4-2.8-.4-2.8s4.8-.5 4.5-6.3c.1 5.3 3 6.6 3 6.6s0 2.9 3.1 3.2c-1.6-1.5-1.3-3.8-1.3-3.8s4-3 .7-8c2-1.2 3.7-4.5 3.7-4.5s-2.8-1.2-4.1-2.2c-.6-1.3 0-8.5 0-8.5l-1.8-9.3-4.8 14.5c.2-2 .3 6.3-6.5 6.3z"/>
14
+ <path stroke-linejoin="round" d="M394.2 120.3c.2.1 5.1 5.6 9.9 5.3 1.8-1.5-3.7-4.7-3.7-5.5 2 1.8 10.1 8.8 15.4 6.3 2-3-3.8-2.5-10.2-10.6 4.5 3 15.7 9.5 21 7 2.1-2.4-11.7-9.9-16.4-15.7l-12-6.1-16.2 13.3 12.3 6z"/>
15
+ <path stroke-linecap="round" stroke-linejoin="round" d="M375.9 74.8s5.5-3.2 27.6-1.6c2.4.3 15-4.3 19.1-5.7 6.4-1.2 27-5.6 32.4-9.8 4-.5-1 7.1-6 9-5.2 2.3-24.1 8.9-30.9 8 8.1.1 3.6 6.7-9.8 3.6 6.4 3.6 4 4.2 4 4.2s-11.3.6-14.3-2c7.6 2.9 4.4 4 4.4 4s-7.7.7-11.3-1c5.5 1.7 2.7 2.7 2.7 2.7s-4.5.8-8.2-.6c-3.8-1.3-9.4-10.7-9.7-10.7z"/>
16
+ <path stroke-linejoin="round" d="m384.7 123.4.8 14.6-.8 1.2c-.3.4-10.3-1.6-9 6 0 3.2 0 4 2.2 5.7-.5-2-.4-3.5-.4-3.5s2.9 1.7 5.6-3c-1.9 4.6-.6 6.3-.1 6.4.4.8-.8 4.5 3 4.4-1.5-1.4-.8-3.4-.8-3.4s4-.6 2.6-7.7c1.4-1.4 2 0 2 0s.4 4.2 3.9 3.3c1.5.9-.3 3.2-.3 3.2s2.5 0 3.3-2c.7-2.2 1.6-6-2.5-7.6-.5-1.5 1.6-1.6 1.6-1.6s2.6.9 3.4 2.2.5-3.4-2.8-4c-4 0-4.2-.9-4.2-1l-1-13.7z"/>
17
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.1" d="M398.6 135.8c0-.7-6.8-9.9-5-11 1.7.3 4.5 4.5 6.9 3.1-.7-1.6-2.8-.7-5.1-4.9-2.4-4.8-2.7-11.9-11-19.6 5.4 8.2 17.4 13 18 10.6s-10.7-11.4-10.1-13.6c2.2 4.4 13.4 14.4 21.6 13.6.6-2-6.7-5.8-8.6-9.4-5.3-3.6-19.4-15.7-19.6-18.5a33 33 0 0 0-9.9-10.6l-.8-1.7c-3.2-7.5 1-10 3.5-10.3 2-.3 2.6 0 4-.7l-5.1-2c2.3 1.7 8 .2 6.8 5 2.5-1 7.9-7.4-6.1-8.8-4.6-5.2-23.3-8.2-28 14.6.4.3.6.6 1.8 1.4-6-2.8-21.9-5-27.6-6-15.6-4.4-31.7-15.2-33.2-13.9-2 1 9.4 11.6 8.8 11.8a263 263 0 0 0-27.5-13.6c-6-2.2-11.9-7.4-12.5-6.4-2.2 4.5 9.5 15.9 11.7 17.2s19.3 9.3 19 9.4c-25.8-11.7-30-13.9-31.4-15.2-2.3-.5-7.8-8-9.3-7.5-.9.8.8 12.6 13.1 18 2 1.4 26.4 10.1 26.2 10.8 0 .2-28-11.5-29-12-5.4-2-12-9.4-13.2-8.6s3 8.8 8.4 11.3c2.9 1.2 13.8 6.6 23.6 10 .6.3-17.7-6.9-26.5-10.5-4-2.2-5.8-5-6.4-4.4-1 .6 1.4 12.4 29.7 19 .7.4 10-2.1 9.5-1.8a113 113 0 0 1-15.8 2.8c-.3.8 1.8 5 16.4 4.2 1.8-.1 12-3.7 11.1-3a174 174 0 0 1-14.8 4.9c-.9 0-5.6.6-5.8 1-.2.8 3.5 3.8 11.3 4.2 7 .4 20.2-4.2 20-3.9-.4.3-12.8 4.6-13.1 4.8-.5.3-5 .5-5.2.9-.4.9 6.6 7.4 27.1.4-2 2.8-12 4.7-12 5.2s2.2 2.5 5.7 3.3c1.7.4 4.1.3 6.3 0 4-.8 8-2.3 13.3-7.2.6 1.5-13.1 8.5-12.5 9.1 3 2.8 12.9-.3 13.5-.7.7-.3 19-10.7 19-12 .3 1.6-23.7 14.7-23.4 15.2 1.5 2.4 9.7-.1 10-.4l10.8-5.8c.3-.1-11.8 7-10.8 8.2-.5 4.7 19-3.2 20.5-4.2.7-.5-9.4 4.4-9.4 6.7 3.3 5.5 13.7 3.8 15.3 2.6.8-.6-1 4-.4 3.6a16 16 0 0 0 3-4.3c-.2 1.6-1.4 4-2 6.8s-.9 5.9-1.8 9.2c-.2 1.4 6.4-2.9 5.4-13.2.6 5.4-2 15.4-1.3 16 1.3 1 5.2-5 5.6-9.1 1.1 2 3.5 6.3 5.6 7.3-.2-3.1 0-3-1-6q.8-6.3.8-16.1c5.6 10.7 7.9 15.3 6.3 23.5 1.7.7 4.3-5.8 4.1-9a13 13 0 0 0 11.5 10.2"/>
18
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.1" d="M305.4 67.7s-3.9 2.9-8.6 2.7c1.2 4.8 11 1.1 11 1.1s-4.7 5.3-8.1 6.1c2 1.7 10.6 1.1 12 .3s4-4.2 4-4.2-8.8 10.2-10 10.1c-.3 1.2 9.1.8 11-1s7-4.4 7-4.4-13 9-13.5 9c4.8 1.2 14.5-1.6 20.7-5.4-9.2 6.1-10 7.2-14.7 9.3 4.2.9 6.3 3.7 20.3-2.4 8-3.8 12.6-10.8 12.6-10.8a82 82 0 0 1-21.6 18c-.5 1 9.4 5.2 21.9-7.9"/>
19
+ <path stroke-linecap="round" stroke-width="1.1" d="M373.4 96s.9 4 4.3 7 3.6 6 3.6 6m-9.5-39s1.1 3.7 4.6 6c3.6 2.2 9 9.4 9.3 10.7.4 1.5 2.5 12.6 2.3 13.8m-37.8-25c.2 1.5-5 8.3 2.2 16.4-6.6 8-6.6 9-6.6 9s3.7 2 10.2-3.6c10.8 13.2 7.2 19.2 7.2 19.2"/>
20
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.1" d="M362.3 107.2s-1-1.4.8-6.7c1.6 2 3.4 2.3 4.1 3 .8.9 9 2 9.4 7.5"/>
21
+ <path stroke-width="1.1" d="M371.9 57.5c0-.4-1.7-4-7.8.4 3.3.2 6.5 2.1 7.8-.4z"/>
22
+ <path stroke-linejoin="round" stroke-width="1.1" d="M430.1 73.5c.3.2 18.2 4 24.2 2.1-7.6 10.2-22.9 3.3-22.9 3.3 7.5 2.2 7.8 2 10.2 4.2.8 2-13.8 1-18.5-1.7 13.3 4.2 13.6 4 14 5.5.6 2.3-21.8-.6-23.7-3.5 6 4.6 9.2 5.5 12.5 7.6-4 1.8-11.5 3.6-25.2-6.1 18 16.4 34.3 15.4 36.9 18.3-6.3 9.3-30.7-5.5-41.9-13s24.5 18.1 27.8 17.7c-1.6 2.5-13.4.3-14.2-1"/>
23
+ <path stroke-linecap="round" stroke-width="1.1" d="M434.7 90.7c-2 .3-8.3.3-9.2.1"/>
24
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.1" d="M300.1 65s13.6 7.2 19.4 6.7a10 10 0 0 1-3.8 2c1.4.6 5.4 2.7 11.4 1.4l-3.3 3s5.2 2 11-1l-2.8 3.7 4.1.3"/>
25
+ </g>
26
+ </g>
27
+ </svg>
@@ -0,0 +1,21 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="flag-icons-zw" viewBox="0 0 640 480">
2
+ <defs>
3
+ <clipPath id="zw-a">
4
+ <rect width="546" height="420.1" x="1.9" y=".1" fill="#00f" fill-rule="evenodd" ry="0"/>
5
+ </clipPath>
6
+ </defs>
7
+ <g clip-path="url(#zw-a)" transform="matrix(1.1722 0 0 1.1426 -2.3 -.1)">
8
+ <path fill="#006400" d="M0 0h840v420H0z"/>
9
+ <path fill="#ffd200" d="M0 60h840v300H0z"/>
10
+ <path fill="#d40000" d="M0 120h840v180H0z"/>
11
+ <path fill="#000001" d="M0 180h840v60H0z"/>
12
+ <path stroke="#000" stroke-width="20" d="M0 0v420l280-210z"/>
13
+ <path fill="#fff" d="M0 0v420l280-210z"/>
14
+ <path fill="#d40000" d="M106.5 104.4 162 275.1 16.8 169.6h179.5L51 275.1z"/>
15
+ <path fill="#fc0" d="m82.8 253.7 9.8-1.8 18.1-.7 6.7.6 15 2.5 1.1-1.5V242l1.8-9.3 3-9.4 3.3-7.5 4.2-7.8 6.8 1.7h1.8l.2-1.3-14.4-12.3-15-11.5-21.7-16.2-2-.5-2.3-17-1.7-5.1-2.3-2-4.3-1.4-4.8.2-2.2 1.2-4.6 1-2.4.4-1.6 1.9-.2 2.4 6.7.2 1.7.7-.2.7-3.8.5-1.8.6 2.1 1.6 2.2.8 2.8 1 .6 2 .2 25.8-1.5 4-.5 7.5 2.2 9-5.6 6.4L77 216l-.6 3.5-1.7 3.5-.2 2.2 1.1 2.4 4.3 14.2 2.2 11.7z"/>
16
+ <path d="M88 142c-1.8 0-2.6.2-4.3 1.1a11 11 0 0 1-4.6 1.4c-2.5 0-4.5 1.8-4.5 4.1v1.5l3.6-.1c10.6.3 1 1.3.2 1.4-2.6.5.6 2.6 3.7 3.7 3.3 1 3.1.4 3.1 15 0 11.9 0 13.6-1 16.3-1.3 4-1.3 10 0 14 .6 1.6 1 3 1 3.3s-1.6 2.1-3.5 4.3c-3.5 4-5.6 8.1-5.6 11a6 6 0 0 1-1 2.6c-1.3 1.7-1.3 4.6-.1 5.7 1.3 1.2 6.6 21.8 6.7 25.7 0 1.4.2 1.4 8.3-.2 6.6-1.3 22.1-1.6 30-.6 3.6.5 7.8 1.3 9.3 1.6 4.8 1.3 4.6 1.5 4.6-4.3a74 74 0 0 1 5.1-26.7 95 95 0 0 1 6.9-14s1.8.2 4 .8c4.1 1 5.3.9 5.3-1 0-1-4.3-4.6-25.4-21a432 432 0 0 0-26.3-19.9q-1 0-1.3-.7l-1.5-9.5c-.7-4.9-1.7-9.7-2.1-10.7q-2-4.4-8.6-4.8zm.1 1h2c6.6.4 7.8 2.2 9.6 14l1.2 9.4q.1 1.1-3.2 3.3a47 47 0 0 0-10 9.5l-1.3 1.8-.3-4.2V165c.3-8.7 0-9.5-2.8-10.5-2.3-.8-5.3-1.6-4.5-2.1 1-.6 2-.2 4.4-.9 1-.2.9-.1.7-.9-.2-1.3-1.6-2-5.3-1.8-3 .2-3.3.1-3.1-.7q.7-2.4 4.5-2.9a13 13 0 0 0 4.4-1.3 7 7 0 0 1 3.7-1zm14.9 25.8h.4c1.7.3 50.8 38.7 50.8 39.8q0 .7-1 .7c-.4 0-12.9-3.5-27.7-7.8-23.6-7-27-8-28-9.3a5 5 0 0 1-.1-6.2 5 5 0 0 0 1-2c0-1.2-2.5 1.8-3 3.5-.5 2 .5 5.4 2 6.5.6.5 5.1 2 10 3.5 8.4 2.4 9 2.7 9.4 4.1 1 3.3-2.5 7.2-7.5 8.3a15 15 0 0 0-5.2 2.4 68 68 0 0 1-17.2 10.4c-.4.3-.9 1.9-1.2 3.4-.6 3.3-.8 3.8-1.8 3.8q-.8.1-.2-1.4c.7-2 .6-4.4-.1-4.4q-.7 0-.7 1.8c0 1-.3 2.2-.7 2.5-.5.6-.6.2-.4-2.3.2-1.7.1-3-.1-3-.5 0-1.4 2.5-1.7 4.7q-.2 2-.6-.3c-.3-1.2-.2-2 .7-3.5a9 9 0 0 0 1-3.5c0-1.3 1-2.6 5.7-7.3 3-3.1 6.7-7 8-8.7 2.3-2.8 2.4-3 2.3-5.9 0-1.6-.2-3.1-.4-3.3-.6-.6-1.4 2.6-1 4.3.2 1.6 0 2.1-3.3 6a113 113 0 0 1-7.5 7.8c-3.9 3.6-5.3 5.6-5.3 7.4 0 .6-.4 2-1 3.3s-.8 2.6-.6 2.9q.2.5-.3 0-.7-.6-.1-3a7 7 0 0 0 .2-2.6c-.5-1-1.2.2-1.5 2.7-.2 1.4-.5 2.5-.8 2.3-.7-.4-.5-3 .4-4.4.5-.7 1-2.3 1.3-3.6.7-3.7 2.3-6.7 5.8-10.7l3.2-3.8-1-3.3a25 25 0 0 1-.2-13.7q1.9-5.6 8-11.7c4-3.9 7.9-6.3 10-6.4m15 32.2a.9.6 0 0 1 1 .6.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.6m2.5.3a.9.6 0 0 1 1 .6.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.6m2.6.5a.9.6 0 0 1 1 .6.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.6m2.4.5a.9.6 0 0 1 1 .6.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.6m-6.3.6a.9.6 0 0 1 1 .6.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.6m2.4.4a.9.6 0 0 1 1 .6.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.6m5.2.2a.9.6 0 0 1 1 .6.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.6m-2.7 0a.9.6 0 0 1 1 .6.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.6m5 .6c.1 0 3.7.8 8 2l7.9 2.3-1.5 2.7-2.4 4.4c-1 2-1.2 2-6 .9-5.2-1.2-13.4-2.3-21.8-3l-8-.7 3-1.1 5.3-2.4c2-1.1 2.8-1.3 5.9-1q6.8.4 8.7-2.4l1-1.7zm-8.8.6a.9.6 0 0 1 1 .6.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.6m5.6 0a.9.6 0 0 1 1 .6.9.6 0 0 1-1.6 0 .9.6 0 0 1 .7-.6zm-8 0a.9.6 0 0 1 1 .6.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.5zm5.3.2a.9.6 0 0 1 1 .5.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.5m-6.6 1.1a.9.6 0 0 1 1 .6.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.6m2.5 0a.9.6 0 0 1 1 .7.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.6zm2.6.2a.9.6 0 0 1 1 .5.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.5m2.8 0a.9.6 0 0 1 1 .6.9.6 0 0 1-1.7 0 .9.6 0 0 1 .7-.6m-20.3 8.1a191 191 0 0 1 35.1 4.2c.1.1-.6 2.5-1.7 5.4l-2 6q0 .7-2.5.3c-8.3-1.3-32.3-1.2-41.5.2-5.3.8-6 .7-5.6-.4l1-3.5.6-2.7L93 221a63 63 0 0 0 10.2-6.5h.9zm-27 14.2q.5 0 1.6.8c1 .6 2.2 1.1 2.7 1.1 2.6 0 4 3.7 6.2 16l.8 4.4c.2 1 0 1.2-2.3 1.7-2.8.6-3.5.7-3.5.3 0-1-2.8-13.7-4-18.2l-1.6-6h.1zm28.6 2h2.9l-1 1c-1.7 2-2.5 2.1-3.7.8l-1-1.5c0-.2 1.3-.4 2.8-.4zm6.1 0h5.4l-1.2 1.2c-1.4 1.6-1.5 1.6-3 0l-1.2-1.3zm8.2 0h1.3c.7 0 2 0 2.8.2l1.5.3-1.4 1.3q-1.3 1.2-1.6 1.2l-1.4-1.6zm8.5.3 1.2.3c.7.2 2.2.3 3.3.4h2l-1.5 1.3-1.8 1.3c-.1 0-1-.8-1.7-1.7zm-30.2.1h.2q.1.5-1 1.7l-1 1.4-1.5-1.2-1.5-1.3 2.4-.3zm2.3.2 1.6 1.4 1.6 1.5-3 .2-3 .1 1.4-1.5zm18 0q.4 0 .8.3l1.3 1.7q.8 1.1-1 1l-2.5-.5-1.2-.3 1.3-1.3q.8-1 1.4-1zm-8.3 0q.7-.1 1.6 1.3c.7 1.1.7 1.1-2 1.1h-2.7l1.4-1.3q1-1 1.7-1zm17 .2 1.2 1.2q2.1 2 .6 2l-2.8-.3-2.2-.2 1.6-1.3zm-35.2.7q.5 0 1.6 1.2l1.2 1.3-2.5.4-3.5.5q-1.1.3 1-1.6 1.7-1.7 2.2-1.8m-3.7 0h.4c.8.2.8.4-.6 1.8l-1.5 1.5-.5-1.3c-.4-1-.3-1.3.6-1.7zm46 1.8q.3 0 0 .6c-.2.8-1.1 1-1.1.2q0-.3.7-.7zm-21.4 1.6c7.7 0 15.5.2 17.4.4 3.1.4 3.4.5 3.4 1.7 0 1.4-.4 1.5-4.6.8-1.2-.3-6.3-.7-11.2-1.1a150 150 0 0 0-28.5 1c-1.9.2-2.4 0-2.4-.6 0-1.3 10.2-2.2 25.9-2.2m-10.3 2.9h5.4l-1.2 1.3c-1.5 1.6-1.6 1.6-3 0zm7 0 1.4 1.4 1.4 1.6-2.9.1h-2.9l1.5-1.6zm2.1 0h5.4l-1.2 1.3c-1.4 1.6-1.5 1.6-3 0zm-12.8 0q.3 0-.7 1.5-1.2 1.5-1.5 1.6-.5-.1-1.5-1.3l-1.2-1.3H96a9 9 0 0 0 2.7-.4zm2 .5 1.3 1.2 1.5 1.3-2.6.2-2.9.2 1.4-1.5zm17.4 0 1.4 1.6c1.6 1.7 1.5 1.8-2.1 1.1l-1.7-.3 1.2-1.2zm2 0h2.4q3.8-.1 1.4 1.8c-1.2 1-1.2 1-2.6-.5zm-30.6.5c1.2 0 1.1.1-.4 1.6-1.1 1.1-1.2 1.1-1.6.3q-.3-1.6 2-1.9m38.8.2 2 .2 2.3.4-1.3 1.2-1.2 1.2-1.1-1.4-1-1.6zm-36 .5q.4 0 1.1.7c1 1 1 1 .2 1.4l-2.4.4H90l1.3-1.4q1-1 1.3-1.1zm34.1.3q.5-.1 1.2 1l.9 1.2h-2.1q-2 0-2-.6.3-.7 1.3-1.3zm6.4 1.3q.3 0 .2.5c0 1-.9 1.7-1.3 1q-.1-.5.5-1.1zm-25.9 1.2c8.7 0 18.3.6 24 1.6l1.6.3v4.4c0 3.3-.2 4.4-.7 4.4l-5-1a126 126 0 0 0-35-1l-2.3.3-.6-3.7-.4-3.8s2.3-.5 5-.8c3.3-.5 8.2-.7 13.4-.7"/>
17
+ <path id="zw-b" d="M124.8 217.8c-3 0-5.1 2.1-5.1 5.2 0 4.8 5.4 7.2 8.6 3.8s1-9-3.5-9m0 1.2a4 4 0 0 1 4 4c0 3-3.3 5-6 3.7-2.7-1.5-2.5-6.1.4-7.3z"/>
18
+ <use xlink:href="#zw-b" width="100%" height="100%" x="-20.1" y="-.6"/>
19
+ <path d="M88 145.3a1.7 1.8 0 0 0-1.6 1.7 1.7 1.8 0 1 0 3.5 0 1.7 1.8 0 0 0-1.9-1.7m.1.6a1.2 1.2 0 0 1 1.2 1.1 1.2 1.1 0 1 1-2.4 0 1.2 1.2 0 0 1 1.2-1.1"/>
20
+ </g>
21
+ </svg>
@@ -66,8 +66,8 @@
66
66
  document.documentElement.setAttribute("data-color-scheme", lightThemes.indexOf(theme) >= 0 ? "light" : "dark");
67
67
  })();
68
68
  </script>
69
- <script type="module" crossorigin src="/assets/index-BepyDfFS.js"></script>
70
- <link rel="stylesheet" crossorigin href="/assets/index-B_uYtqRM.css">
69
+ <script type="module" crossorigin src="/assets/index-2Z0Tr6cq.js"></script>
70
+ <link rel="stylesheet" crossorigin href="/assets/index-BgSnAnP6.css">
71
71
  </head>
72
72
  <body>
73
73
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccdeck",
3
- "version": "3.40.2",
3
+ "version": "3.41.1",
4
4
  "description": "Local dashboard for Claude Code and Codex CLI sessions: which Claude Code session needs input, every tool call and Claude Code subagent live, token cost and quota, several Claude accounts. Run npx ccdeck.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -77,6 +77,50 @@
77
77
  "3.39.4",
78
78
  "3.40.1", "3.40.2"
79
79
  ],
80
+ "3.41.1": [
81
+ {
82
+ "title": "🪟 More reliable Windows updates",
83
+ "body": "Restart to update stops the app’s background server before installation begins."
84
+ },
85
+ {
86
+ "title": "📊 More accurate account capacity",
87
+ "body": "Elapsed resets and older readings no longer imply newly available quota. Account refreshes keep the latest valid readings."
88
+ },
89
+ {
90
+ "title": "🖥️ Better layouts on portrait displays",
91
+ "body": "Sessions fill the right columns, and the canvas starts near the top. Usage history controls stay reachable in narrow windows."
92
+ },
93
+ {
94
+ "title": "✨ Clearer load history and consistent icons",
95
+ "body": "Load history includes the current core-capacity multiplier below the charts. Refresh and external-link icons look consistent across system fonts."
96
+ }
97
+ ],
98
+ "3.41.0": [
99
+ {
100
+ "title": "📅 Plan account resets",
101
+ "body": "See the next seven days of resets, account capacity and which readings need refreshing."
102
+ },
103
+ {
104
+ "title": "📊 Follow quota history",
105
+ "body": "Inspect recorded Claude and Codex quota readings to see how remaining capacity changes over time."
106
+ },
107
+ {
108
+ "title": "♻️ See cached input reuse",
109
+ "body": "Session usage details now show the percentage of measured input reused from cache."
110
+ },
111
+ {
112
+ "title": "📻 A more polished Radio Explorer",
113
+ "body": "Find radio stations with compact search and filters, explore workspace streams separately, and save favorites from either source. Playback and keyboard navigation are more reliable."
114
+ },
115
+ {
116
+ "title": "🌍 Radio flags on Windows",
117
+ "body": "Country flags now display correctly in the radio station list on Windows."
118
+ },
119
+ {
120
+ "title": "🔧 Clearer Telemetry Radar controls",
121
+ "body": "Change individual telemetry flags and use a simpler Monitor view."
122
+ }
123
+ ],
80
124
  "3.40.0": [
81
125
  {
82
126
  "title": "📻 Explore radio around the world",
@@ -9,6 +9,22 @@ const counters = value => ({
9
9
  const tokenTotal = row => row.inputTokens + row.outputTokens + row.cacheReadTokens + row.cacheCreationTokens;
10
10
  const date = value => typeof value === "string" && Number.isFinite(Date.parse(value)) ? value : null;
11
11
 
12
+ // Both ccusage providers normalize inputTokens to NON-cached input. Codex's
13
+ // raw input_tokens (which includes cache) must never be fed to this formula.
14
+ // ccusage/ccusage rust/adapters/codex/src/report.rs: non_cached_input_tokens.
15
+ export function sessionCacheReuse(rows, agent) {
16
+ let input = 0, cached = 0, measured = 0;
17
+ for (const row of rows) {
18
+ const values = [row?.inputTokens, row?.cacheReadTokens, row?.cacheCreationTokens];
19
+ if (!values.every(n => typeof n === "number" && Number.isFinite(n) && n >= 0)) continue;
20
+ input += values[0] + values[1] + values[2];
21
+ cached += values[1];
22
+ measured++;
23
+ }
24
+ return { pct: input > 0 ? cached / input * 100 : null, inputTokens: input, cachedTokens: cached,
25
+ measured, total: rows.length, unit: agent === "codex" ? "model groups" : "usage records" };
26
+ }
27
+
12
28
  export function validSessionLookup(agent, id, speed = "auto") {
13
29
  if (agent !== "claude" && agent !== "codex") return false;
14
30
  if (!["auto", "standard", "fast", "flex"].includes(speed) || (agent !== "codex" && speed !== "auto")) return false;
@@ -54,6 +70,7 @@ export function sessionDetail(raw, agent, sessionId, speed = "auto") {
54
70
  return {
55
71
  sessionId, agent, speed, totalCost: raw.totalCost, totalTokens: raw.totalTokens,
56
72
  ...usage, firstActivity, lastActivity, entries,
73
+ cacheReuse: sessionCacheReuse(agent === "claude" ? raw.entries : Object.values(raw.models), agent),
57
74
  models: [...models.values()].map(row => ({ ...row, totalTokens: tokenTotal(row) }))
58
75
  .sort((a, b) => b.totalTokens - a.totalTokens || a.model.localeCompare(b.model)),
59
76
  };
@@ -253,7 +253,7 @@ async function readUsageRows(root) {
253
253
  * trust a row the other two refuse. Exported for its test.
254
254
  */
255
255
  export function usageRows(usage) {
256
- return usage?.schemaVersion === 2 ? (usage.accounts ?? {}) : {};
256
+ return usage?.schemaVersion === 2 && usage.accounts && typeof usage.accounts === "object" && !Array.isArray(usage.accounts) ? usage.accounts : {};
257
257
  }
258
258
 
259
259
  /**
@@ -267,14 +267,14 @@ export function usageRows(usage) {
267
267
  * cannot disagree about whose row it is. Exported for its test.
268
268
  */
269
269
  export function rowIsFor(row, acct) {
270
- return Boolean(row)
270
+ return Boolean(row) && typeof acct?.email === "string" && acct.email.trim().length > 0
271
271
  && row.email === acct.email
272
272
  && (row.organizationUuid ?? "") === (acct.organizationUuid ?? "");
273
273
  }
274
274
 
275
275
  function pctOf(win) {
276
276
  const p = win?.pct;
277
- return typeof p === "number" && Number.isFinite(p) ? p : null;
277
+ return typeof p === "number" && Number.isFinite(p) ? Math.min(100, Math.max(0, p)) : null;
278
278
  }
279
279
 
280
280
  /** One lane, in the shape the panel's bars already speak. */
@@ -288,7 +288,7 @@ function lane(id, label, win) {
288
288
  pct,
289
289
  // claude-swap stores a countdown string too, but it was computed when the
290
290
  // row was written and drifts — the client recomputes from the timestamp.
291
- resetAt: isNaN(resetAt) ? null : Math.floor(resetAt / 1000),
291
+ resetAt: !Number.isFinite(resetAt) || resetAt <= 0 ? null : Math.floor(resetAt / 1000),
292
292
  };
293
293
  }
294
294
 
@@ -480,9 +480,12 @@ async function readRoster(now, gen) {
480
480
  ? await currentIdentity().catch(() => null)
481
481
  : null;
482
482
 
483
- const order = Array.isArray(seq.sequence) && seq.sequence.length
484
- ? seq.sequence.map(String)
485
- : Object.keys(seq.accounts).sort((a, b) => Number(a) - Number(b));
483
+ // Sequence is an ordering hint, not a second roster. Preserve all slots
484
+ // exactly once when an older or partially written order omits one.
485
+ const order = [...new Set([
486
+ ...(Array.isArray(seq.sequence) ? seq.sequence.map(String) : []),
487
+ ...Object.keys(seq.accounts).sort((a, b) => Number(a) - Number(b)),
488
+ ])].filter(num => Object.hasOwn(seq.accounts, num));
486
489
 
487
490
  const accounts = [];
488
491
  const recovered = [];
@@ -515,14 +518,19 @@ async function readRoster(now, gen) {
515
518
  * verdict cache, and asks the registered repair about a `stale-copy` row —
516
519
  * which is what starts that repair (see repairStaleCopyWith).
517
520
  */
521
+ function observedMs(seconds) {
522
+ const ms = typeof seconds === "number" ? seconds * 1000 : NaN;
523
+ return Number.isFinite(ms) && ms > 0 && Number.isFinite(new Date(ms).getTime()) ? ms : null;
524
+ }
525
+
518
526
  function rosterRow({ seq, num, acct, row, identity, now, key, origin = null }) {
519
527
  const matches = rowIsFor(row, acct);
520
528
  const good = matches ? row.lastGood : null;
521
529
 
522
- const fetchedAtMs = matches && typeof row.fetchedAt === "number" ? row.fetchedAt * 1000 : null;
530
+ const fetchedAtMs = matches ? observedMs(row.fetchedAt) : null;
523
531
  // When claude-swap last TRIED, well or not. A refusal counts against a login
524
532
  // only when it came after the deck last signed that login in (#1893).
525
- const attemptedAtMs = matches && typeof row.lastAttemptAt === "number" ? row.lastAttemptAt * 1000 : null;
533
+ const attemptedAtMs = matches ? observedMs(row.lastAttemptAt) : null;
526
534
  const isActive = String(seq.activeAccountNumber) === num;
527
535
  const trouble = authTrouble(row, {
528
536
  matches, isActive, identity, email: acct.email, fetchedAt: fetchedAtMs, now,
@@ -703,7 +711,7 @@ export async function activeAccountUsage() {
703
711
  const row = (await readUsageRows(root))[num];
704
712
  // Same identity guard the panel uses: rows are keyed by slot, and slots are
705
713
  // reused, so a row can outlive the account it was written for.
706
- if (!row?.lastGood || !rowIsFor(row, acct) || typeof row.fetchedAt !== "number") return null;
714
+ if (!row?.lastGood || !rowIsFor(row, acct) || observedMs(row.fetchedAt) == null) return null;
707
715
 
708
716
  return {
709
717
  num: Number(num),
@@ -1,3 +1,4 @@
1
+ import { noteQuotaHistory, forgetQuotaHistoryAccount } from "./quota-history.mjs";
1
2
  // Fetches Codex/ChatGPT quota from the same endpoint the Codex CLI uses.
2
3
  // Auth (including token refresh) lives in codex-auth.mjs.
3
4
  //
@@ -366,7 +367,12 @@ async function doFetchCodexQuota() {
366
367
  const finish = (r) => {
367
368
  _cache = r;
368
369
  _cacheAt = Date.now();
369
- if (r.ok && !r.stale) _lastGood = r;
370
+ if (r.ok && !r.stale) {
371
+ noteQuotaHistory("codex", _accountOfQuota.get(r), r);
372
+ _lastGood = r;
373
+ } else if (["no_token", "api_key_mode", "refresh_rejected"].includes(r.reason)) {
374
+ forgetQuotaHistoryAccount("codex");
375
+ }
370
376
  return r;
371
377
  };
372
378
  const fail = (reason) => finish({ ok: false, reason, fetchedAt: started });
@@ -164,7 +164,8 @@ import { handleBrowserWatch, handleBrowserWatchDismiss, handleBrowserWatchSettin
164
164
  // The music routes, every one behind AGENTS_DECK_NO_MUSIC — see music-routes.mjs.
165
165
  import { handleBestOfNostalgia, handleCafeMusicBgm, handleClaudeFm, handleFmStation, handleGoodLifeRadio, handleLiveRadioMix, handleLofiGirl, handleRadioStations, handleRadioClick, handleMusicConfig } from "./music-routes.mjs";
166
166
  // The usage panel's quota and history reads — see usage-routes.mjs.
167
- import { handleCcusage, handleCcusageSession, handleCodexQuota, handleCodexUsage, handleProviderStatus, handleQuota } from "./usage-routes.mjs";
167
+ import { startQuotaHistory } from "./quota-history.mjs";
168
+ import { handleCcusage, handleCcusageSession, handleCodexQuota, handleCodexUsage, handleProviderStatus, handleQuota, handleQuotaHistory } from "./usage-routes.mjs";
168
169
  // The port fallback, one listen attempt, and the words for a failed one — see
169
170
  // listen.mjs. The loop that uses them is startServer's.
170
171
  import { listenFailure, portRetryable, randomPort, tryListen } from "./listen.mjs";
@@ -190,6 +191,7 @@ export function requestUrl(rawUrl) {
190
191
  }
191
192
 
192
193
  export async function startServer({ port = 4317, host = "127.0.0.1", persist = null, portRange = [4318, 4400], workspace = "", codex = true, claude = true, onRestart = null, onStop = null, cswapQuiet = null } = {}) {
194
+ startQuotaHistory();
193
195
  armLifecycle({ onRestart, onStop, persist, onSelfUpdate: () => reporter.noteSelfUpdate() });
194
196
  // Which tree and which CLIs, normalised once — see setDeckScope.
195
197
  setDeckScope({ workspace, claude, codex });
@@ -316,6 +318,7 @@ export async function startServer({ port = 4317, host = "127.0.0.1", persist = n
316
318
  if (req.method === "POST" && url.pathname === "/api/restart") return guard(handleRestart(req, res), res);
317
319
  if (req.method === "POST" && url.pathname === "/api/presence") return guard(handlePresence(req, res), res);
318
320
  if (req.method === "POST" && url.pathname === "/api/shutdown") return guard(handleStop(req, res), res);
321
+ if (req.method === "GET" && url.pathname === "/api/quota/history") return guard(handleQuotaHistory(req, res), res);
319
322
  if (req.method === "GET" && url.pathname === "/api/quota") return guard(handleQuota(req, res), res);
320
323
  if (req.method === "GET" && url.pathname === "/api/codex-usage") return guard(handleCodexUsage(req, res), res);
321
324
  // Machine state, not session state: sampled on the server's own timer and
@@ -0,0 +1,149 @@
1
+ // Observed quota, never inferred from tokens or cost. Recording adds no polls.
2
+ import { createHash } from "node:crypto";
3
+ import { readFile, stat, mkdir } from "node:fs/promises";
4
+ import { dirname, join } from "node:path";
5
+ import { deckDataDir } from "./deck-home.mjs";
6
+ import { writeFileAtomic } from "./atomic-write.mjs";
7
+
8
+ export const HISTORY_LIMITS = Object.freeze({ series: 32, points: 2048, totalPoints: 16384, days: 35, bytes: 2 * 1024 * 1024 });
9
+ const finite = n => typeof n === "number" && Number.isFinite(n);
10
+ const providers = new Set(["claude", "codex"]);
11
+ const hash = (provider, identity) => createHash("sha256").update(`${provider}\0${identity}`).digest("hex");
12
+
13
+ export function historyAccount(provider, account) {
14
+ if (provider === "claude" && typeof account?.email === "string" && account.email.trim()
15
+ && typeof account?.organizationUuid === "string" && account.organizationUuid) {
16
+ return hash(provider, `${account.email.trim().toLowerCase()}\0${account.organizationUuid}`);
17
+ }
18
+ if (provider === "codex" && (typeof account?.accountId === "string" && account.accountId
19
+ || typeof account?.email === "string" && account.email.trim())) {
20
+ return hash(provider, `${typeof account.accountId === "string" ? account.accountId : ""}\0${typeof account.email === "string" ? account.email.trim().toLowerCase() : ""}`);
21
+ }
22
+ return null;
23
+ }
24
+
25
+ export function historyWindows(provider, r) {
26
+ if (!r?.ok || r.stale) return [];
27
+ if (provider === "codex") return [...(r.windows ?? []), ...(r.extraWindows ?? [])];
28
+ const out = [
29
+ { id: "five_hour", label: "5-hour window", pct: r.session5hPct, resetAt: r.session5hResetAt, windowSec: r.session5hWindowSec },
30
+ { id: "seven_day", label: "7-day window", pct: r.week7dPct, resetAt: r.week7dResetAt, windowSec: r.week7dWindowSec },
31
+ ];
32
+ // Store fallback can copy the weekly reading into the nominal session lane.
33
+ return out.filter((w, i) => i !== 0 || w.resetAt !== out[1].resetAt || w.pct !== out[1].pct);
34
+ }
35
+
36
+ function prune(series, now) {
37
+ const floor = now - HISTORY_LIMITS.days * 86400_000;
38
+ let rows = series.filter(s => s.points.length && s.points.at(-1).t >= floor)
39
+ .map(s => ({ ...s, points: s.points.filter(p => p.t >= floor).slice(-HISTORY_LIMITS.points) }))
40
+ .filter(s => s.points.length).sort((a, b) => b.points.at(-1).t - a.points.at(-1).t)
41
+ .slice(0, HISTORY_LIMITS.series);
42
+ let total = rows.reduce((n, s) => n + s.points.length, 0);
43
+ while (total > HISTORY_LIMITS.totalPoints) total -= rows.pop().points.length;
44
+ return rows;
45
+ }
46
+
47
+ export function normalizeHistory(raw, now) {
48
+ if (raw?.v !== 1 || !Array.isArray(raw.series)) return [];
49
+ const out = [];
50
+ for (const s of raw.series.slice(0, HISTORY_LIMITS.series)) {
51
+ if (!providers.has(s?.provider) || !/^[a-f0-9]{64}$/.test(s.account ?? "")
52
+ || typeof s.id !== "string" || s.id.length > 100 || typeof s.label !== "string"
53
+ || !finite(s.resetAt) || !finite(s.windowSec) || s.windowSec < 60 || s.windowSec > 40 * 86400
54
+ || !Array.isArray(s.points)) continue;
55
+ const points = s.points.slice(-HISTORY_LIMITS.points).filter(p => finite(p?.t) && finite(p?.pct)
56
+ && p.pct >= 0 && p.pct <= 100 && p.t <= now + 60_000
57
+ && p.t >= (s.resetAt - s.windowSec) * 1000 - 120_000 && p.t < s.resetAt * 1000)
58
+ .map(p => ({ t: p.t, pct: p.pct })).sort((a, b) => a.t - b.t)
59
+ .filter((p, i, all) => !i || p.t !== all[i - 1].t);
60
+ out.push({ provider: s.provider, account: s.account, id: s.id, label: s.label.slice(0, 100),
61
+ resetAt: s.resetAt, windowSec: s.windowSec, points });
62
+ }
63
+ return prune(out, now);
64
+ }
65
+
66
+ export function createQuotaHistory({ load = async () => null, save = async () => {}, now = Date.now } = {}) {
67
+ let series = [], loading = null, storageOk = true;
68
+ const active = new Map();
69
+ let queue = Promise.resolve();
70
+ const ready = () => loading ??= (async () => {
71
+ try { series = normalizeHistory(await load(), now()); }
72
+ catch { storageOk = false; }
73
+ })();
74
+ return {
75
+ activate(provider, account) {
76
+ if (!providers.has(provider)) return null;
77
+ const key = historyAccount(provider, account);
78
+ active.set(provider, key);
79
+ return key;
80
+ },
81
+ record(provider, account, reading) {
82
+ queue = queue.then(async () => {
83
+ await ready();
84
+ if (!providers.has(provider) || !/^[a-f0-9]{64}$/.test(account ?? "") || !reading?.ok || reading.stale
85
+ || !finite(reading.fetchedAt) || reading.fetchedAt > now() + 60_000) return;
86
+ let changed = false;
87
+ for (const w of historyWindows(provider, reading)) {
88
+ if (typeof w.id !== "string" || !finite(w.pct) || w.pct < 0 || w.pct > 100
89
+ || !finite(w.resetAt) || !finite(w.windowSec) || w.windowSec < 60 || w.windowSec > 40 * 86400
90
+ || reading.fetchedAt >= w.resetAt * 1000
91
+ || reading.fetchedAt < (w.resetAt - w.windowSec) * 1000 - 120_000) continue;
92
+ let s = series.find(s => s.provider === provider && s.account === account && s.id === w.id
93
+ && s.windowSec === w.windowSec && Math.abs(s.resetAt - w.resetAt) <= 120);
94
+ if (!s) {
95
+ s = { provider, account, id: w.id.slice(0, 100), label: String(w.label ?? w.id).slice(0, 100),
96
+ resetAt: w.resetAt, windowSec: w.windowSec, points: [] };
97
+ series.push(s);
98
+ }
99
+ if (s.points.length && reading.fetchedAt <= s.points.at(-1).t) continue;
100
+ // Small source jitter must not place a captured point beyond the
101
+ // persisted window's end, where the next load would discard it.
102
+ s.resetAt = Math.max(s.resetAt, w.resetAt);
103
+ s.points.push({ t: reading.fetchedAt, pct: w.pct });
104
+ changed = true;
105
+ }
106
+ series = prune(series, now());
107
+ if (changed) {
108
+ try { await save({ v: 1, series }); storageOk = true; }
109
+ catch { storageOk = false; } // history cannot fail a quota request
110
+ }
111
+ }).catch(() => { storageOk = false; });
112
+ return queue;
113
+ },
114
+ async report(provider, account) {
115
+ await queue;
116
+ await ready();
117
+ // A delayed request for an account that was switched away from cannot
118
+ // display its history beside the new account's current quota.
119
+ if (!account || active.get(provider) !== account) return { ok: true, account: null, series: [], storageOk };
120
+ series = prune(series, now());
121
+ return { ok: true, account, storageOk, series: series.filter(s => s.provider === provider && s.account === account)
122
+ .map(({ account: _account, provider: _provider, ...s }) => ({ ...s, points: s.points.map(p => ({ ...p })) })) };
123
+ },
124
+ };
125
+ }
126
+
127
+ let history = null;
128
+ export function startQuotaHistory() {
129
+ if (history) return;
130
+ const file = join(deckDataDir(), "quota-history.json");
131
+ history = createQuotaHistory({
132
+ load: async () => {
133
+ try {
134
+ if ((await stat(file)).size > HISTORY_LIMITS.bytes) throw new Error("History exceeds capacity");
135
+ return JSON.parse((await readFile(file, "utf8")).replace(/^\uFEFF/, ""));
136
+ } catch (e) { if (e?.code === "ENOENT") return null; throw e; }
137
+ },
138
+ save: async raw => { await mkdir(dirname(file), { recursive: true }); await writeFileAtomic(file, JSON.stringify(raw)); },
139
+ });
140
+ }
141
+ export function noteQuotaHistory(provider, account, reading) {
142
+ if (!history) return;
143
+ const key = history.activate(provider, account);
144
+ if (key) { reading.historyAccount = key; void history.record(provider, key, reading); }
145
+ }
146
+ export function forgetQuotaHistoryAccount(provider) { history?.activate(provider, null); }
147
+ export async function quotaHistoryReport(provider, account) {
148
+ return history ? history.report(provider, account) : { ok: true, account: null, series: [], storageOk: true };
149
+ }