diff --git a/assets/infrastructure-dark.svg b/assets/infrastructure-dark.svg new file mode 100644 index 000000000..398d1051c --- /dev/null +++ b/assets/infrastructure-dark.svg @@ -0,0 +1,13 @@ + + + + + + + + Main(MBP M3 Pro)Backup(Mac Mini M1)Synchronization(Syncthing)CloudflareServices:- ServerServices:- Parser- Serverbackup.kibo.moneykibo.moneyTunnel(cloudflared)Tunnel(cloudflared) \ No newline at end of file diff --git a/assets/infrastructure-light.svg b/assets/infrastructure-light.svg new file mode 100644 index 000000000..348145cc5 --- /dev/null +++ b/assets/infrastructure-light.svg @@ -0,0 +1,13 @@ + + + + + + + + Main(MBP M3 Pro)Backup(Mac Mini M1)Synchronization(Syncthing)CloudflareServices:- ServerServices:- Parser- Serverbackup.kibo.moneykibo.moneyTunnel(cloudflared)Tunnel(cloudflared) \ No newline at end of file diff --git a/assets/infrastructure.excalidraw b/assets/infrastructure.excalidraw new file mode 100644 index 000000000..07e9cc159 --- /dev/null +++ b/assets/infrastructure.excalidraw @@ -0,0 +1,1069 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "id": "4l5Cnq81N-N8HWbMPgOfm", + "type": "rectangle", + "x": 365.86486603966756, + "y": 534.9494905328866, + "width": 184.9297887916521, + "height": 85.19094049738938, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a1", + "roundness": { + "type": 3 + }, + "seed": 350356010, + "version": 351, + "versionNonce": 642218538, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "LfdDNULnkLxM4LrR-Ey2y" + }, + { + "id": "CbJ4u9h-uaIrTzsEExVo7", + "type": "arrow" + }, + { + "id": "-1w44Xvh1ZmtarGuufckU", + "type": "arrow" + } + ], + "updated": 1726489097527, + "link": null, + "locked": false + }, + { + "id": "LfdDNULnkLxM4LrR-Ey2y", + "type": "text", + "x": 388.80980193939985, + "y": 552.5449607815813, + "width": 139.0399169921875, + "height": 50, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a1V", + "roundness": null, + "seed": 218559926, + "version": 327, + "versionNonce": 614927414, + "isDeleted": false, + "boundElements": null, + "updated": 1726489097527, + "link": null, + "locked": false, + "text": "Main\n(MBP M3 Pro)", + "fontSize": 20, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "4l5Cnq81N-N8HWbMPgOfm", + "originalText": "Main\n(MBP M3 Pro)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 723, + "versionNonce": 1818928362, + "index": "a3", + "isDeleted": false, + "id": "9565AiaaW5P2onZJsxM5X", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 929.3589198932772, + "y": 533.3447074509686, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 187.13198652163655, + "height": 88.40050666122548, + "seed": 161587242, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "xEhd36k7qSdZORzI5BYDC" + }, + { + "id": "CbJ4u9h-uaIrTzsEExVo7", + "type": "arrow" + }, + { + "id": "gaJmg3DF-UOKWKTiDcUQS", + "type": "arrow" + } + ], + "updated": 1726489097527, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 736, + "versionNonce": 1604588918, + "index": "a4", + "isDeleted": false, + "id": "xEhd36k7qSdZORzI5BYDC", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 958.3049638132751, + "y": 552.5449607815814, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 129.23989868164062, + "height": 50, + "seed": 1838156522, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1726489097527, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 5, + "text": "Backup\n(Mac Mini M1)", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "9565AiaaW5P2onZJsxM5X", + "originalText": "Backup\n(Mac Mini M1)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "CbJ4u9h-uaIrTzsEExVo7", + "type": "arrow", + "x": 551.7946548313197, + "y": 577.8108949212098, + "width": 374.2744229755049, + "height": 0.5318682792568552, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a7", + "roundness": { + "type": 2 + }, + "seed": 1412467498, + "version": 554, + "versionNonce": 1113225130, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "-xyotiDxrIvGpHihaNTMw" + } + ], + "updated": 1726489097527, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 374.2744229755049, + -0.5318682792568552 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "4l5Cnq81N-N8HWbMPgOfm", + "focus": 0.053987925025335816, + "gap": 1, + "fixedPoint": null + }, + "endBinding": { + "elementId": "9565AiaaW5P2onZJsxM5X", + "focus": -0.06637645925445641, + "gap": 1.9594774360632248, + "fixedPoint": null + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "-xyotiDxrIvGpHihaNTMw", + "type": "text", + "x": 663.5995146712901, + "y": 553.6137138980424, + "width": 152.0398712158203, + "height": 50, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a7V", + "roundness": null, + "seed": 1240678698, + "version": 24, + "versionNonce": 1622013622, + "isDeleted": false, + "boundElements": null, + "updated": 1726489097527, + "link": null, + "locked": false, + "text": "Synchronization\n(Syncthing)", + "fontSize": 20, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "CbJ4u9h-uaIrTzsEExVo7", + "originalText": "Synchronization\n(Syncthing)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "4Kf-4nPmAC4H6JYuOWgKz", + "type": "ellipse", + "x": 674.688026887862, + "y": -113.87511038919328, + "width": 114.13321104184153, + "height": 83.7807552220783, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a9", + "roundness": { + "type": 2 + }, + "seed": 1864324918, + "version": 818, + "versionNonce": 2002389878, + "isDeleted": false, + "boundElements": null, + "updated": 1726489120258, + "link": null, + "locked": false + }, + { + "type": "ellipse", + "version": 885, + "versionNonce": 1270288106, + "index": "aA", + "isDeleted": false, + "id": "R4QUoIsp_Y1_gsH3uowyA", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 751.5605318882301, + "y": -89.26982658383659, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 114.13321104184153, + "height": 83.7807552220783, + "seed": 1029607658, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "id": "5dcU1IErPCDiUG3gflg8R", + "type": "arrow" + } + ], + "updated": 1726489120258, + "link": null, + "locked": false + }, + { + "type": "ellipse", + "version": 1074, + "versionNonce": 976563382, + "index": "aB", + "isDeleted": false, + "id": "sCBhvSDPsRkhW05eEeRy5", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 609.0037967435512, + "y": -83.9664057764262, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 164.9744518534024, + "height": 86.58639076795106, + "seed": 1345460918, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "id": "Xp-UFM8oBcOEj_8Scy4Ma", + "type": "arrow" + }, + { + "id": "5dcU1IErPCDiUG3gflg8R", + "type": "arrow" + } + ], + "updated": 1726489120258, + "link": null, + "locked": false + }, + { + "type": "ellipse", + "version": 1077, + "versionNonce": 277455274, + "index": "aC", + "isDeleted": false, + "id": "XkaKAKq7arG2a4-xuVxc_", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 755.5420699957402, + "y": -105.29203456400774, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 53.21063017191969, + "height": 42.38188857636974, + "seed": 1023165930, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1726489120258, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 1355, + "versionNonce": 401347318, + "index": "aE", + "isDeleted": false, + "id": "KDdwlG7bsCvMQxoGRy8Xc", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 289.55537150961595, + "y": 205.972242651008, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 901.105694871832, + "height": 144.9329694976395, + "seed": 1917949750, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "rqWH83jhOa4ihfEdsTYEt" + }, + { + "id": "h7FiB9aboy7Fv7NgvJ9pR", + "type": "arrow" + }, + { + "id": "NFH-Fk8W9vYhpSgVkY7Kq", + "type": "arrow" + }, + { + "id": "gaJmg3DF-UOKWKTiDcUQS", + "type": "arrow" + }, + { + "id": "-1w44Xvh1ZmtarGuufckU", + "type": "arrow" + } + ], + "updated": 1726487758729, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1306, + "versionNonce": 986398570, + "index": "aF", + "isDeleted": false, + "id": "rqWH83jhOa4ihfEdsTYEt", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 691.7582467123557, + "y": 265.93872739982777, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 96.69994446635246, + "height": 25, + "seed": 1304772726, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1726487758729, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 5, + "text": "Cloudflare", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "KDdwlG7bsCvMQxoGRy8Xc", + "originalText": "Cloudflare", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "Xp-UFM8oBcOEj_8Scy4Ma", + "type": "arrow", + "x": 459.16617750823536, + "y": 246.47593943435749, + "width": 199.39664159505958, + "height": 244.9843279773636, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aN", + "roundness": { + "type": 2 + }, + "seed": 1968881974, + "version": 887, + "versionNonce": 2022569782, + "isDeleted": false, + "boundElements": [], + "updated": 1726489120258, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 199.39664159505958, + -244.9843279773636 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "q5zgtaduyEFWvWtLqdo4u", + "focus": -0.29520668458161897, + "gap": 7.468651206465225, + "fixedPoint": null + }, + "endBinding": { + "elementId": "sCBhvSDPsRkhW05eEeRy5", + "focus": -0.015501021013443951, + "gap": 2.4489688039538677, + "fixedPoint": null + }, + "startArrowhead": "arrow", + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "5dcU1IErPCDiUG3gflg8R", + "type": "arrow", + "x": 830.1001802364694, + "y": -0.5385166255382927, + "width": 188.17952290562857, + "height": 239.22427486491006, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aO", + "roundness": { + "type": 2 + }, + "seed": 2106058986, + "version": 921, + "versionNonce": 1335502326, + "isDeleted": false, + "boundElements": null, + "updated": 1726489120258, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 188.17952290562857, + 239.22427486491006 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "R4QUoIsp_Y1_gsH3uowyA", + "focus": 0.23329021524550242, + "gap": 7.753664430702663, + "fixedPoint": null + }, + "endBinding": { + "elementId": "pglywLWx0DKRfK57PIrUI", + "focus": 0.17814510531398206, + "gap": 9.491520721779693, + "fixedPoint": null + }, + "startArrowhead": "arrow", + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "lS9tbqIzGDn_EHnkA1-z9", + "type": "text", + "x": 980.6673500907636, + "y": 625.9948603740997, + "width": 83.75991821289062, + "height": 50, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aP", + "roundness": null, + "seed": 1098959798, + "version": 201, + "versionNonce": 1806017514, + "isDeleted": false, + "boundElements": null, + "updated": 1726489102346, + "link": null, + "locked": false, + "text": "Services:\n- Server", + "fontSize": 20, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Services:\n- Server", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "text", + "version": 339, + "versionNonce": 874481386, + "index": "aR", + "isDeleted": false, + "id": "w8Pc4lZIzMJfQlLbzQX9w", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 416.4498013290483, + "y": 625.9510491610656, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 83.75991821289062, + "height": 75, + "seed": 1853359990, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1726489101018, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 5, + "text": "Services:\n- Parser\n- Server", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Services:\n- Parser\n- Server", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "pglywLWx0DKRfK57PIrUI", + "type": "ellipse", + "x": 880.0025282056731, + "y": 249.22675692415476, + "width": 285.84476989684487, + "height": 58.423940951345934, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aS", + "roundness": { + "type": 2 + }, + "seed": 1773150518, + "version": 793, + "versionNonce": 569869290, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "-iVMi_RkcWUQIt6Z2Mlrh" + }, + { + "id": "gaJmg3DF-UOKWKTiDcUQS", + "type": "arrow" + }, + { + "id": "5dcU1IErPCDiUG3gflg8R", + "type": "arrow" + } + ], + "updated": 1726489062551, + "link": null, + "locked": false + }, + { + "id": "-iVMi_RkcWUQIt6Z2Mlrh", + "type": "text", + "x": 936.4035939616971, + "y": 265.78274498465817, + "width": 172.91986322402954, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aSV", + "roundness": null, + "seed": 1414430634, + "version": 752, + "versionNonce": 748078710, + "isDeleted": false, + "boundElements": null, + "updated": 1726489062551, + "link": null, + "locked": false, + "text": "backup.kibo.money", + "fontSize": 20, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "pglywLWx0DKRfK57PIrUI", + "originalText": "backup.kibo.money", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "ellipse", + "version": 621, + "versionNonce": 284391082, + "index": "aU", + "isDeleted": false, + "id": "q5zgtaduyEFWvWtLqdo4u", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 361.7468186507642, + "y": 248.99504540515608, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 193.16588356945877, + "height": 58.88736398934328, + "seed": 1828238890, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "L2XYk3PmFoutUXTAiwF_e" + }, + { + "id": "-1w44Xvh1ZmtarGuufckU", + "type": "arrow" + }, + { + "id": "Xp-UFM8oBcOEj_8Scy4Ma", + "type": "arrow" + } + ], + "updated": 1726489062551, + "link": null, + "locked": false + }, + { + "id": "L2XYk3PmFoutUXTAiwF_e", + "type": "text", + "x": 407.4253380048505, + "y": 266.11890019829514, + "width": 102.21993869543076, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aUV", + "roundness": null, + "seed": 1196969142, + "version": 450, + "versionNonce": 1042450358, + "isDeleted": false, + "boundElements": null, + "updated": 1726489062551, + "link": null, + "locked": false, + "text": "kibo.money", + "fontSize": 20, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "q5zgtaduyEFWvWtLqdo4u", + "originalText": "kibo.money", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "-1w44Xvh1ZmtarGuufckU", + "type": "arrow", + "x": 457.4309139845321, + "y": 358.6114474878384, + "width": 0.71360804491934, + "height": 171.8383925156736, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aW", + "roundness": null, + "seed": 1204452650, + "version": 265, + "versionNonce": 617220342, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "6sYDgHoTWAbEIl_FWrDuW" + } + ], + "updated": 1726489093550, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0.71360804491934, + 171.8383925156736 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "KDdwlG7bsCvMQxoGRy8Xc", + "focus": 0.6301546827835128, + "gap": 7.706235339190897, + "fixedPoint": null + }, + "endBinding": { + "elementId": "4l5Cnq81N-N8HWbMPgOfm", + "focus": 0.000038110225611944457, + "gap": 2.8605229475869627, + "fixedPoint": null + }, + "startArrowhead": "arrow", + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "6sYDgHoTWAbEIl_FWrDuW", + "type": "text", + "x": 399.3979196785064, + "y": 417.0359387414294, + "width": 123.13990783691406, + "height": 50, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aX", + "roundness": null, + "seed": 655331882, + "version": 5, + "versionNonce": 412947894, + "isDeleted": false, + "boundElements": null, + "updated": 1726489073730, + "link": null, + "locked": false, + "text": "Tunnel\n(cloudflared)", + "fontSize": 20, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "-1w44Xvh1ZmtarGuufckU", + "originalText": "Tunnel\n(cloudflared)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "gaJmg3DF-UOKWKTiDcUQS", + "type": "arrow", + "x": 1023.1013869146059, + "y": 360.3721836771484, + "width": 0.3529475210207238, + "height": 156.29142731254342, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aY", + "roundness": null, + "seed": 818854890, + "version": 413, + "versionNonce": 1253093866, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "uTkD7W1DyHBhxilhBEtJv" + } + ], + "updated": 1726489079014, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -0.3529475210207238, + 156.29142731254342 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "KDdwlG7bsCvMQxoGRy8Xc", + "focus": -0.6340885693917432, + "gap": 9.46697152850092, + "fixedPoint": null + }, + "endBinding": { + "elementId": "9565AiaaW5P2onZJsxM5X", + "focus": 0.03896054889278365, + "gap": 16.71544096114612, + "fixedPoint": null + }, + "startArrowhead": "arrow", + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "uTkD7W1DyHBhxilhBEtJv", + "type": "text", + "x": 949.6087413031642, + "y": 419.85938650996854, + "width": 123.13990783691406, + "height": 50, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aZ", + "roundness": null, + "seed": 477996650, + "version": 5, + "versionNonce": 1065203830, + "isDeleted": false, + "boundElements": null, + "updated": 1726489079014, + "link": null, + "locked": false, + "text": "Tunnel\n(cloudflared)", + "fontSize": 20, + "fontFamily": 5, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "gaJmg3DF-UOKWKTiDcUQS", + "originalText": "Tunnel\n(cloudflared)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "l00BoaAvHhgy_wRaOndRf", + "type": "text", + "x": 698.1576166043603, + "y": 12.645887676558857, + "width": 83.77993774414062, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aa", + "roundness": null, + "seed": 1234467574, + "version": 95, + "versionNonce": 1587610794, + "isDeleted": false, + "boundElements": null, + "updated": 1726489133658, + "link": null, + "locked": false, + "text": "Internet", + "fontSize": 20, + "fontFamily": 5, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Internet", + "autoResize": true, + "lineHeight": 1.25 + } + ], + "appState": { + "gridSize": 20, + "gridStep": 5, + "gridModeEnabled": false, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/assets/latest.jpg b/assets/latest.jpg deleted file mode 100644 index 932dacc07..000000000 Binary files a/assets/latest.jpg and /dev/null differ diff --git a/website/index.html b/website/index.html index ef866f875..68e022d86 100644 --- a/website/index.html +++ b/website/index.html @@ -1,4 +1,4 @@ - + @@ -1298,7 +1298,7 @@ localStorage.getItem(settingsThemeLocalStorageKey) ); const preferredColorSchemeMatchMedia = window.matchMedia( - "(prefers-color-scheme: dark)", + "(prefers-color-scheme: dark)" ); if ( theme === "dark" || @@ -1310,7 +1310,7 @@ } const backgroundColor = getComputedStyle( - window.document.documentElement, + window.document.documentElement ).getPropertyValue("--background-color"); const meta = window.document.createElement("meta"); meta.name = "theme-color"; @@ -1320,6 +1320,10 @@ if ("standalone" in window.navigator && !!window.navigator.standalone) { window.document.documentElement.dataset.display = "standalone"; } + + if ("serviceWorker" in navigator) { + navigator.serviceWorker.register("/service-worker.js"); + } diff --git a/website/script.js b/website/script.js index 66d3ae678..5bb28a984 100644 --- a/website/script.js +++ b/website/script.js @@ -61,7 +61,7 @@ function dateToString(date) { */ function getNumberOfDaysBetweenTwoDates(oldest, youngest) { return Math.round( - Math.abs((youngest.getTime() - oldest.getTime()) / ONE_DAY_IN_MS), + Math.abs((youngest.getTime() - oldest.getTime()) / ONE_DAY_IN_MS) ); } @@ -104,7 +104,7 @@ const urlParamsHelpers = { window.history.replaceState( null, "", - `${pathname}?${urlParams.toString()}`, + `${pathname}?${urlParams.toString()}` ); }, /** @@ -304,7 +304,7 @@ const presetTitle = dom.getElementById("preset-title"); const presetDescription = dom.getElementById("preset-description"); const foldersFilterAllCount = dom.getElementById("folders-filter-all-count"); const foldersFilterFavoritesCount = dom.getElementById( - "folders-filter-favorites-count", + "folders-filter-favorites-count" ); const foldersFilterNewCount = dom.getElementById("folders-filter-new-count"); const chartListElement = dom.getElementById("chart-list"); @@ -1793,7 +1793,7 @@ lazySignals.then((importedSignals) => { name, title: `${name} Market Price Moving Average`, key, - }), + }) ), ], }; @@ -1855,7 +1855,7 @@ lazySignals.then((importedSignals) => { name, title: `${name} Total`, key: `${key}-total`, - }), + }) ), ], }, @@ -1868,7 +1868,7 @@ lazySignals.then((importedSignals) => { name, title: `${name} Compound`, key: `${key}-compound`, - }), + }) ), ], }, @@ -3789,7 +3789,7 @@ lazySignals.then((importedSignals) => { title: "Average", color, datasetPath: `${scale}-to-${datasetIdToPrefix( - datasetId, + datasetId )}realized-price`, }, ], @@ -3990,7 +3990,7 @@ lazySignals.then((importedSignals) => { name: legend, datasetId: id, title: name, - }), + }) ), { name: "Up To X", @@ -4001,7 +4001,7 @@ lazySignals.then((importedSignals) => { name, datasetId: id, title: name, - }), + }) ), }, { @@ -4013,7 +4013,7 @@ lazySignals.then((importedSignals) => { name, datasetId: id, title: name, - }), + }) ), }, { @@ -4025,7 +4025,7 @@ lazySignals.then((importedSignals) => { name, datasetId: id, title: name, - }), + }) ), }, { @@ -4037,7 +4037,7 @@ lazySignals.then((importedSignals) => { name, datasetId: id, title: name, - }), + }) ), }, ], @@ -4184,7 +4184,7 @@ lazySignals.then((importedSignals) => { name, filenameAddon: size, datasetId: key, - }), + }) ), }, { @@ -4196,7 +4196,7 @@ lazySignals.then((importedSignals) => { color: colors[key], name, datasetId: key, - }), + }) ), }, ], @@ -5115,7 +5115,7 @@ lazySignals.then((importedSignals) => { const filter = signals.createSignal( /** @type {FoldersFilter} */ ( localStorage.getItem(foldersFilterLocalStorageKey) || "all" - ), + ) ); const favoritesCount = signals.createSignal(0); @@ -5318,7 +5318,7 @@ lazySignals.then((importedSignals) => { return isFavorite; }, - false, + false ); } @@ -5430,7 +5430,7 @@ lazySignals.then((importedSignals) => { return null; } }, - null, + null ); partialTree.forEach((anyPartial, partialIndex) => { @@ -5452,14 +5452,14 @@ lazySignals.then((importedSignals) => { return null; } }, - undefined, + undefined ); if ("tree" in anyPartial) { const folderId = stringToId( `${(path || [])?.map(({ name }) => name).join(" ")} ${ anyPartial.name - } folder`, + } folder` ); /** @type {Omit} */ @@ -5477,13 +5477,13 @@ lazySignals.then((importedSignals) => { }; const passedDetails = signals.createSignal( - /** @type {HTMLDivElement | HTMLDetailsElement | null} */ (null), + /** @type {HTMLDivElement | HTMLDetailsElement | null} */ (null) ); const childPresetsCount = processPartialTree( anyPartial.tree, passedDetails, - [...(path || []), thisPath], + [...(path || []), thisPath] ); listForSum.push(childPresetsCount); @@ -5577,10 +5577,10 @@ lazySignals.then((importedSignals) => { } preset.isFavorite.set( - !!localStorage.getItem(presetToFavoriteLocalStorageKey(preset)), + !!localStorage.getItem(presetToFavoriteLocalStorageKey(preset)) ); preset.visited.set( - !!localStorage.getItem(presetToVisitedLocalStorageKey(preset)), + !!localStorage.getItem(presetToVisitedLocalStorageKey(preset)) ); createCountersEffects(preset); @@ -5647,7 +5647,7 @@ lazySignals.then((importedSignals) => { }); return signals.createMemo(() => - listForSum.reduce((acc, s) => acc + s(), 0), + listForSum.reduce((acc, s) => acc + s(), 0) ); } @@ -5668,7 +5668,7 @@ lazySignals.then((importedSignals) => { console.log( [...m.entries()] .filter(([_, value]) => value > 1) - .map(([key, _]) => key), + .map(([key, _]) => key) ); throw Error("ID duplicate"); @@ -5856,8 +5856,8 @@ lazySignals.then((importedSignals) => { return /** @type {TimeRange | null} */ ( JSON.parse( localStorage.getItem( - getVisibleTimeRangeLocalStorageKey(scale), - ) || "null", + getVisibleTimeRangeLocalStorageKey(scale) + ) || "null" ) ); } @@ -5917,23 +5917,23 @@ lazySignals.then((importedSignals) => { /** @type {Set>} */ (new Set()), { equals: false, - }, + } ); const visibleTimeRange = signals.createSignal( - getInitialVisibleTimeRange(scale()), + getInitialVisibleTimeRange(scale()) ); const visibleDatasetIds = signals.createSignal( /** @type {number[]} */ ([]), { equals: false, - }, + } ); const lastVisibleDatasetIndex = signals.createMemo(() => { const last = visibleDatasetIds().at(-1); return last !== undefined ? chunkIdToIndex(scale(), last) : undefined; }); const priceSeriesType = signals.createSignal( - /** @type {PriceSeriesType} */ ("Candlestick"), + /** @type {PriceSeriesType} */ ("Candlestick") ); function updateVisibleDatasetIds() { @@ -5949,7 +5949,7 @@ lazySignals.then((importedSignals) => { ids = Array.from( { length: to - from + 1 }, - (_, i) => i + from, + (_, i) => i + from ).filter((year) => year >= 2009 && year <= today.getUTCFullYear()); } else { const from = Math.floor(Number(rawFrom) / HEIGHT_CHUNK_SIZE); @@ -5959,7 +5959,7 @@ lazySignals.then((importedSignals) => { ids = Array.from( { length }, - (_, i) => (from + i) * HEIGHT_CHUNK_SIZE, + (_, i) => (from + i) * HEIGHT_CHUNK_SIZE ); } @@ -5979,7 +5979,7 @@ lazySignals.then((importedSignals) => { const debouncedUpdateVisibleDatasetIds = debounce( updateVisibleDatasetIds, - 100, + 100 ); function saveVisibleRange() { @@ -5987,17 +5987,17 @@ lazySignals.then((importedSignals) => { urlParamsHelpers.write( URL_PARAMS_TIME_RANGE_FROM_KEY, - String(range.from), + String(range.from) ); urlParamsHelpers.write( URL_PARAMS_TIME_RANGE_TO_KEY, - String(range.to), + String(range.to) ); localStorage.setItem( getVisibleTimeRangeLocalStorageKey(scale()), - JSON.stringify(range), + JSON.stringify(range) ); } const debouncedSaveVisibleRange = debounce(saveVisibleRange, 250); @@ -6057,17 +6057,17 @@ lazySignals.then((importedSignals) => { if (modulused === 0) { return `${numberToUSLocale( value / (1_000_000 * 1_000 ** letterIndex), - 3, + 3 )}${letter}`; } else if (modulused === 1) { return `${numberToUSLocale( value / (1_000_000 * 1_000 ** letterIndex), - 2, + 2 )}${letter}`; } else { return `${numberToUSLocale( value / (1_000_000 * 1_000 ** letterIndex), - 1, + 1 )}${letter}`; } } @@ -6144,7 +6144,7 @@ lazySignals.then((importedSignals) => { ++index ) { sortedTimePoints[index].timeWeight = this.computeHeightWeight( - sortedTimePoints[index].time, + sortedTimePoints[index].time ); } } @@ -6284,7 +6284,7 @@ lazySignals.then((importedSignals) => { function resetChartListElement() { while ( chartListElement.lastElementChild?.classList.contains( - "chart-wrapper", + "chart-wrapper" ) ) { chartListElement.lastElementChild?.remove(); @@ -6302,8 +6302,8 @@ lazySignals.then((importedSignals) => { new Array( getNumberOfDaysBetweenTwoDates( whitespaceStartDate, - whitespaceEndDate, - ), + whitespaceEndDate + ) ) ); // Hack to be able to scroll freely @@ -6312,7 +6312,7 @@ lazySignals.then((importedSignals) => { const date = new Date( whitespaceStartDateYear, whitespaceStartDateMonth, - whitespaceStartDateDate + i, + whitespaceStartDateDate + i ); const time = dateToString(date); @@ -6395,7 +6395,7 @@ lazySignals.then((importedSignals) => { /** @type {Lowercase} */ ( localStorage.getItem(id) || chartModes[chartIndex ? 0 : 1].toLowerCase() - ), + ) ); const field = createField({ @@ -6460,7 +6460,7 @@ lazySignals.then((importedSignals) => { ratio = getNumberOfDaysBetweenTwoDates( dateFromTime(from), - dateFromTime(to), + dateFromTime(to) ) / width; } else { const to = /** @type {number} */ (visibleTimeRange.to); @@ -6490,7 +6490,7 @@ lazySignals.then((importedSignals) => { const debouncedUpdateVisiblePriceSeriesType = debounce( updateVisiblePriceSeriesType, - 50, + 50 ); /** @@ -6543,12 +6543,12 @@ lazySignals.then((importedSignals) => { (new Date().getFullYear() - new Date("2009-01-01").getFullYear() + 2) * - (scale === "date" ? 1 : 6), + (scale === "date" ? 1 : 6) ) .fill(null) .map(() => { const json = signals.createSignal( - /** @type {FetchedJSON | null} */ (null), + /** @type {FetchedJSON | null} */ (null) ); /** @type {FetchedResult} */ @@ -6608,7 +6608,7 @@ lazySignals.then((importedSignals) => { ? NaN : /** @type {number} */ (value), }), - }), + }) ); } }), @@ -6672,8 +6672,9 @@ lazySignals.then((importedSignals) => { if (cachedResponse) { /** @type {FetchedJSON | null} */ - const json = - await convertResponseToJSON(cachedResponse); + const json = await convertResponseToJSON( + cachedResponse + ); if (json) { console.log(`cache: ${path}?chunk=${id}`); @@ -6707,7 +6708,7 @@ lazySignals.then((importedSignals) => { try { fetchedResponse = await fetch( backupUrlWithQuery, - fetchConfig, + fetchConfig ); } catch { fetched.loading = false; @@ -6745,7 +6746,7 @@ lazySignals.then((importedSignals) => { if (previousLength && previousLength === newLength) { const previousLastValue = Object.values( - previousMap || [], + previousMap || [] ).at(-1); const newLastValue = Object.values(newMap).at(-1); @@ -6852,12 +6853,12 @@ lazySignals.then((importedSignals) => { if (scale === "date") { date.set( /** @type {DatePath} */ (path), - /** @type {any} */ (dataset), + /** @type {any} */ (dataset) ); } else { height.set( /** @type {HeightPath} */ (path), - /** @type {any} */ (dataset), + /** @type {any} */ (dataset) ); } @@ -6985,7 +6986,7 @@ lazySignals.then((importedSignals) => { const hoveredLegend = signals.createSignal( /** @type {{label: HTMLLabelElement, series: Series} | undefined} */ ( undefined - ), + ) ); const notHoveredLegendTransparency = "66"; /** @@ -7094,8 +7095,9 @@ lazySignals.then((importedSignals) => { v = /** @type {string} */ (v).substring(0, 7); initialColors[i][k] = v; - darkenedColors[i][k] = - `${v}${notHoveredLegendTransparency}`; + darkenedColors[i][ + k + ] = `${v}${notHoveredLegendTransparency}`; } else if (k === "lastValueVisible" && v) { initialColors[i][k] = true; darkenedColors[i][k] = false; @@ -7112,7 +7114,7 @@ lazySignals.then((importedSignals) => { return hovered; }, - undefined, + undefined ); } createHoverEffect(); @@ -7158,14 +7160,14 @@ lazySignals.then((importedSignals) => { const id = stringToId(title); const storageId = presetAndSeriesToLocalStorageKey( preset, - seriesBlueprint, + seriesBlueprint ); const active = signals.createSignal( urlParamsHelpers.readBool(id) ?? localeStorageHelpers.readBool(storageId) ?? defaultActive ?? - true, + true ); const disabled = signals.createMemo(_disabled || (() => false)); @@ -7206,7 +7208,7 @@ lazySignals.then((importedSignals) => { dataset.fetchedJSONs.forEach((json, index) => { const chunk = signals.createSignal( - /** @type {ISeriesApi | undefined} */ (undefined), + /** @type {ISeriesApi | undefined} */ (undefined) ); chunks[index] = chunk; @@ -7304,11 +7306,11 @@ lazySignals.then((importedSignals) => { if (visibleDatasetIds().length) { const start = chunkIdToIndex( scale(), - /** @type {number} */ (visibleDatasetIds().at(0)), + /** @type {number} */ (visibleDatasetIds().at(0)) ); const end = chunkIdToIndex( scale(), - /** @type {number} */ (visibleDatasetIds().at(-1)), + /** @type {number} */ (visibleDatasetIds().at(-1)) ); if (index >= start && index <= end) { @@ -7441,7 +7443,7 @@ lazySignals.then((importedSignals) => { const blueprintCount = 1 + (preset.top?.length || 0) + (preset.bottom?.length || 0); const chartsBlueprints = [preset.top || [], preset.bottom].flatMap( - (list) => (list ? [list] : []), + (list) => (list ? [list] : []) ); resetLegendElement(); @@ -7453,7 +7455,7 @@ lazySignals.then((importedSignals) => { charts = chartsBlueprints.map((seriesBlueprints, chartIndex) => { const { chartDiv, unitName, chartMode } = createChartDiv( chartListElement, - chartIndex, + chartIndex ); const chart = @@ -7589,7 +7591,7 @@ lazySignals.then((importedSignals) => { maxMarker ) { min.seriesChunk.setMarkers( - [minMarker, maxMarker].sort((a, b) => a.weight - b.weight), + [minMarker, maxMarker].sort((a, b) => a.weight - b.weight) ); } else { if (min && minMarker) { @@ -7608,7 +7610,7 @@ lazySignals.then((importedSignals) => { () => { setMinMaxMarkers(); }, - blueprintCount * 10 + scale === "date" ? 50 : 100, + blueprintCount * 10 + scale === "date" ? 50 : 100 ); function createSetMinMaxMarkersWhenIdleEffect() { @@ -7666,7 +7668,7 @@ lazySignals.then((importedSignals) => { .forEach((seriesBlueprint, index) => { const dataset = datasets.getOrImport( scale, - seriesBlueprint.datasetPath, + seriesBlueprint.datasetPath ); // Don't trigger reactivity by design @@ -7698,7 +7700,7 @@ lazySignals.then((importedSignals) => { }); const chartVisible = signals.createMemo(() => - chartSeries.some((series) => series.visible()), + chartSeries.some((series) => series.visible()) ); function createChartVisibilityEffect() { @@ -7730,7 +7732,7 @@ lazySignals.then((importedSignals) => { signals.createEffect(() => chart.priceScale("right").applyOptions({ mode: chartMode() === "linear" ? 0 : 1, - }), + }) ); chart @@ -7775,7 +7777,7 @@ lazySignals.then((importedSignals) => { otherChart.setCrosshairPosition( NaN, time, - otherChart.whitespace, + otherChart.whitespace ); } else { // No time when mouse goes outside the chart @@ -7809,7 +7811,7 @@ lazySignals.then((importedSignals) => { return preset; }, - undefined, + undefined ); } createSelectedEffect(); @@ -7818,15 +7820,15 @@ lazySignals.then((importedSignals) => { function initScrollButtons() { const buttonBackward = dom.getElementById("button-backward"); const buttonBackwardIcon = dom.getElementById( - "button-backward-icon", + "button-backward-icon" ); const buttonBackwardPauseIcon = dom.getElementById( - "button-backward-pause-icon", + "button-backward-pause-icon" ); const buttonForward = dom.getElementById("button-forward"); const buttonForwardIcon = dom.getElementById("button-forward-icon"); const buttonForwardPauseIcon = dom.getElementById( - "button-forward-pause-icon", + "button-forward-pause-icon" ); let interval = /** @type {number | undefined} */ (undefined); @@ -7922,8 +7924,8 @@ lazySignals.then((importedSignals) => { Math.ceil( (to.getTime() - new Date(`${to.getUTCFullYear()}-01-01`).getTime()) / - ONE_DAY_IN_MS, - ), + ONE_DAY_IN_MS + ) ); } @@ -8031,7 +8033,7 @@ lazySignals.then((importedSignals) => { dom.getElementById("button-share").addEventListener("click", () => { const qrcode = generate( - /** @type {any} */ (window.document.location.href), + /** @type {any} */ (window.document.location.href) )?.toDataURL({ // @ts-ignore padX: 0, @@ -8044,8 +8046,8 @@ lazySignals.then((importedSignals) => { }); } initShareButton(); - }, - ), + } + ) ); function initResizeBar() { @@ -8065,7 +8067,7 @@ lazySignals.then((importedSignals) => { localStorage.setItem(barWidthLocalStorageKey, String(width)); } else { mainElement.style.width = bodyStyle.getPropertyValue( - "--default-main-width", + "--default-main-width" ); localStorage.removeItem(barWidthLocalStorageKey); } @@ -8122,7 +8124,7 @@ lazySignals.then((importedSignals) => { function initInput() { const haystack = presetsList.map( - (preset) => `${preset.title}\t${preset.serializedPath}`, + (preset) => `${preset.title}\t${preset.serializedPath}` ); const searchSmallOgInnerHTML = searchSmall.innerHTML; @@ -8146,7 +8148,7 @@ lazySignals.then((importedSignals) => { if (indexes?.length) { const maxIndex = Math.min( (order || indexes).length - 1, - minIndex + RESULTS_PER_PAGE - 1, + minIndex + RESULTS_PER_PAGE - 1 ); list = Array(maxIndex - minIndex + 1); @@ -8158,7 +8160,7 @@ lazySignals.then((importedSignals) => { const [title, path] = ufuzzy .highlight( haystack[info.idx[infoIdx]], - info.ranges[infoIdx], + info.ranges[infoIdx] ) .split("\t"); @@ -8243,7 +8245,7 @@ lazySignals.then((importedSignals) => { haystack, needle, undefined, - infoThresh, + infoThresh ); if (!result?.[0]?.length || !result?.[1]) { @@ -8251,7 +8253,7 @@ lazySignals.then((importedSignals) => { haystack, needle, outOfOrder, - infoThresh, + infoThresh ); } @@ -8260,7 +8262,7 @@ lazySignals.then((importedSignals) => { haystack, needle, outOfOrder, - infoThresh, + infoThresh ); } @@ -8269,7 +8271,7 @@ lazySignals.then((importedSignals) => { haystack, needle, outOfOrder, - infoThresh, + infoThresh ); } @@ -8278,7 +8280,7 @@ lazySignals.then((importedSignals) => { haystack, needle, undefined, - infoThresh, + infoThresh ); } @@ -8287,7 +8289,7 @@ lazySignals.then((importedSignals) => { haystack, needle, outOfOrder, - infoThresh, + infoThresh ); } @@ -8319,7 +8321,7 @@ lazySignals.then((importedSignals) => { } searchInput.addEventListener("input", inputEvent); - }, + } ); } @@ -8412,7 +8414,7 @@ lazySignals.then((importedSignals) => { id: date.valueOf().toString(), top: date.toLocaleTimeString(), owner, - }), + }) ); }); }); @@ -8450,7 +8452,7 @@ lazySignals.then((importedSignals) => { function updateHeading(id) { if (!id) return; dom.getElementById(id).innerHTML = dateToDisplayedString( - grouped[id][0].date, + grouped[id][0].date ); } @@ -8488,7 +8490,7 @@ lazySignals.then((importedSignals) => { localStorage.setItem( LOCAL_STORAGE_HISTORY_KEY, - JSON.stringify(serializedHistory), + JSON.stringify(serializedHistory) ); }); }); @@ -8535,7 +8537,7 @@ lazySignals.then((importedSignals) => { const theme = signals.createSignal(savedTheme); const preferredColorSchemeMatchMedia = window.matchMedia( - "(prefers-color-scheme: dark)", + "(prefers-color-scheme: dark)" ); /** @@ -8551,7 +8553,7 @@ lazySignals.then((importedSignals) => { } const backgroundColor = getComputedStyle( - window.document.documentElement, + window.document.documentElement ).getPropertyValue("--background-color"); const meta = dom.queryOrCreateMetaElement("theme-color"); meta.content = backgroundColor; @@ -8562,7 +8564,7 @@ lazySignals.then((importedSignals) => { localStorage.setItem(settingsThemeLocalStorageKey, theme()); updateTheme( theme() === "dark" || - (theme() === "system" && preferredColorSchemeMatchMedia.matches), + (theme() === "system" && preferredColorSchemeMatchMedia.matches) ); }); } @@ -8729,7 +8731,7 @@ lazySignals.then((importedSignals) => { donations.sort((a, b) => b.amount !== a.amount ? b.amount - a.amount - : a.name.localeCompare(b.name), + : a.name.localeCompare(b.name) ); donations.slice(0, 21).forEach(({ name, url, amount }) => { @@ -8760,7 +8762,7 @@ lazySignals.then((importedSignals) => { (env.macOS || env.ipad || env.iphone) ) { const installInstructionsElement = dom.getElementById( - "settings-install-instructions", + "settings-install-instructions" ); installInstructionsElement.hidden = false; @@ -8859,7 +8861,7 @@ lazySignals.then((importedSignals) => { window.document.addEventListener( "visibilitychange", - reinitWebSocketIfDocumentNotHidden, + reinitWebSocketIfDocumentNotHidden ); window.document.addEventListener("online", reinitWebSocket); @@ -8868,7 +8870,7 @@ lazySignals.then((importedSignals) => { ws?.close(); window.document.removeEventListener( "visibilitychange", - reinitWebSocketIfDocumentNotHidden, + reinitWebSocketIfDocumentNotHidden ); window.document.removeEventListener("online", reinitWebSocket); live.set(false); @@ -8895,7 +8897,7 @@ lazySignals.then((importedSignals) => { name: "ohlc", interval: 1440, }, - }), + }) ); }); @@ -8940,7 +8942,7 @@ lazySignals.then((importedSignals) => { console.log("close:", close); window.document.title = `${latest.close.toLocaleString( - "en-us", + "en-us" )} | kibō`; } }); diff --git a/website/service-worker.js b/website/service-worker.js new file mode 100644 index 000000000..1d0548766 --- /dev/null +++ b/website/service-worker.js @@ -0,0 +1,51 @@ +// @ts-check + +const version = "v1"; + +self.addEventListener("install", (_event) => { + const event = /** @type {any} */ (_event); + + event.waitUntil( + caches.open(version).then((cache) => { + return cache.addAll([ + "/", + "/index.html", + "/script.js", + "/packages/solid-signals/2024-04-17/script.js", + "/packages/ufuzzy/2024-02-21/script.js", + "/packages/lean-qr/v2.3.4/script.js", + "/packages/lightweight-charts/v4.2.0/script.js", + "/fonts/satoshi/2024-09/font.var.woff2", + ]); + }) + ); +}); + +self.addEventListener("fetch", (_event) => { + const event = /** @type {any} */ (_event); + + /** @type {Request} */ + const request = event.request; + const { url, method } = request; + + event.respondWith( + caches.match(request).then((cache) => { + return fetch(request) + .then((response) => { + // @ts-ignore + if (url.includes("/api/")) { + return response; + } + return caches.open(version).then((cache) => { + if (method === "GET" && response.status === 200) { + cache.put(request, response.clone()); + } + return response; + }); + }) + .catch(() => { + return cache; + }); + }) + ); +});