Compare commits

...
1275 Commits
Author SHA1 Message Date
KernelDeimos 203669a79f release: v2.4.2 2024-07-22 20:23:40 -04:00
Nariman Jelveh f8b39630ab Merge pull request #628 from HeyPuter/eric/fix-templates
Write contents from template when creating a file from a tempalte
2024-07-22 16:53:01 -07:00
Nariman Jelveh 5d58764316 Use join. to build target path 2024-07-22 16:38:45 -07:00
KernelDeimos 5d2a6fce30 fix: fix templates 2024-07-22 17:10:58 -04:00
Nariman Jelveh 1f7f094282 Merge pull request #627 from Koppeks/koppeks/templates_folder_contextmenu
Templates folder feature
2024-07-22 11:33:02 -07:00
Nariman Jelveh d8dd218089 Don't show No templates found for now. 2024-07-22 11:31:01 -07:00
Nariman Jelveh a9801fc10d place available_templates call in update_auth_data to guarantee that user object exists 2024-07-22 11:07:57 -07:00
Nariman Jelveh 2d5a0bb894 closes #614 2024-07-21 17:01:24 -07:00
Koppeks a0113788f9 remove extra comments 2024-07-21 17:32:33 -03:00
Nariman Jelveh 5cf74a0ad9 Merge pull request #624 from enweazudaniel/main
Update ig.js
2024-07-21 09:18:31 -07:00
enweazudaniel 382fb24dbb Update ig.js 2024-07-21 17:04:33 +01:00
KernelDeimos 8f87770ceb fix: popup login in co isolation mode 2024-07-20 20:46:03 -04:00
KernelDeimos 2a5cec7ee9 fix: add necessary iframe attributes for co isolation 2024-07-20 18:54:08 -04:00
Nariman Jelveh 1579cbccf0 Merge pull request #620 from pvhuwung/i18n/vietnamese-translation
Add Vietnamese Translation for i18n
2024-07-20 14:12:24 -07:00
pvhuwung 02e1b1e8f5 chore: fix confirm for type_confirm_to_delete_account 2024-07-21 04:03:37 +07:00
Pham Viet Hung *David f4a45d74e7 Merge branch 'HeyPuter:main' into i18n/vietnamese-translation 2024-07-21 04:53:48 +08:00
pvhuwung c2d3d69dbe feat: add vietnamese localization-a 2024-07-21 03:53:14 +07:00
Nariman Jelveh 71f4b4d71f When setting size/position of app window make sure it's not an empty string 2024-07-20 13:34:36 -07:00
Nariman Jelveh 452b7495b1 use app-request as label for app idea issues 2024-07-20 11:46:20 -07:00
Nariman Jelveh ace14e99fa Merge pull request #618 from secondtruth/issue-template-app-idea
Add issue template for app ideas
2024-07-20 11:41:50 -07:00
Christian Neff b3c1b128e2 Add issue template for app ideas 2024-07-20 18:09:37 +02:00
Nariman Jelveh b6a433ce0c Merge pull request #616 from stariver1862/patch-1
Complete Traditional Chinese translation based on English file #550
2024-07-20 08:06:07 -07:00
Nariman Jelveh 3a09e84838 fix: syntax error and formatting issue 2024-07-20 08:05:14 -07:00
Nariman Jelveh 4990ba01cc Merge branch 'main' into patch-1 2024-07-20 07:47:38 -07:00
Nariman Jelveh 6b5c31ddfe Merge pull request #615 from mlgzackfly/update-translations
fix(i18n): Complete Traditional Chinese translation based on English file #550
2024-07-20 07:33:49 -07:00
WHL b9e73b7288 Update zhtw.js, Complete Traditional Chinese translation based on English file #550 2024-07-20 22:18:05 +08:00
mlgzackfly 37fd666a9a fix(i18n): update zhtw.js to match en.js 2024-07-20 19:36:45 +08:00
Koppeks f897e84498 Temporal commit for issue #432 2024-07-19 19:42:47 -03:00
Nariman Jelveh eae51e945b Merge branch 'main' of https://github.com/HeyPuter/puter into main 2024-07-19 13:11:35 -07:00
Nariman Jelveh 98e69642d0 fix: launch_app not considering explorer as a special case 2024-07-19 13:11:26 -07:00
Nariman Jelveh 45c29b6220 Merge pull request #611 from Alfika07/main
Fixed Tamil translation
2024-07-19 08:52:58 -07:00
Nariman Jelveh f2bb551e75 Change english_name from English to Tamil 2024-07-19 08:52:19 -07:00
Alfika07 8a3d0430f3 Add Tamil translation to translations.js 2024-07-19 09:46:04 +02:00
Alfika07 333d6e3b65 Move Tamil translation to the rest of translations 2024-07-19 09:43:23 +02:00
KernelDeimos e58da265ba try cross-origin isolation only on sites 2024-07-18 20:58:09 -04:00
KernelDeimos 7043b9400c fix: well kinda (HOSTNAME in phoenix) 2024-07-18 20:16:08 -04:00
Nariman Jelveh eeda9fb568 close #409 2024-07-18 16:06:45 -07:00
KernelDeimos ae25711a13 update package.json for local testing 2024-07-18 17:02:31 -04:00
KernelDeimos 602a19895c fix: it was github actions the entire time 2024-07-18 16:58:36 -04:00
KernelDeimos 614f2c5061 fix: fix CI attempt #7 2024-07-18 16:44:11 -04:00
KernelDeimos 9d549b192d fix: fix CI attempt #6 2024-07-18 16:38:56 -04:00
KernelDeimos 74adcddc1d fix: fix CI attempt #5 2024-07-18 16:36:44 -04:00
Nariman Jelveh 5a4328e449 Update Dockerfile 2024-07-18 13:33:02 -07:00
Nariman Jelveh 8b5f58c156 Merge branch 'main' of https://github.com/HeyPuter/puter into main 2024-07-18 13:30:14 -07:00
Nariman Jelveh d9a90a67c1 let me try fixing mocha! 2024-07-18 13:30:05 -07:00
KernelDeimos 84b993bce9 fix: fix CI attempt #4 2024-07-18 16:27:36 -04:00
KernelDeimos 3bca973f5f fix: fix CI attempt #3 2024-07-18 16:20:57 -04:00
KernelDeimos aebe89a1ac fix: fix CI attempt #2 2024-07-18 16:16:31 -04:00
KernelDeimos 58c199c153 fix: run mocha within packages in monorepo 2024-07-18 16:10:45 -04:00
Nariman Jelveh 82fa2d0862 close #169 2024-07-18 13:01:14 -07:00
KernelDeimos ad3d318d07 fix: make webpack output not look like errors 2024-07-18 14:50:53 -04:00
KernelDeimos e539932070 feat: add cross_origin_isolation option 2024-07-18 14:23:03 -04:00
KernelDeimos 8c8904cb36 doc: update documentation for boot sequence 2024-07-18 14:23:03 -04:00
Nariman Jelveh f9333b3d1e feat: add option to disable temporary users 2024-07-18 12:59:42 -04:00
KernelDeimos ba50d0f96d feat: add some default groups 2024-07-18 01:08:49 -04:00
Nariman Jelveh 8e7306c23b Add support for dropping multiple Puter items onto Dev Center (close #311) 2024-07-17 20:56:36 -07:00
Nariman Jelveh e6833253c7 close #276 2024-07-17 20:14:07 -07:00
Nariman Jelveh 4d6edff169 Escape arguments passed to dev-center 2024-07-17 18:32:02 -07:00
KernelDeimos 29f919c98a sync: package-lock.json 2024-07-17 17:15:29 -04:00
Nariman Jelveh 45f131f8ea No scrollbar for session list 2024-07-17 14:05:49 -07:00
Nariman Jelveh d80f2fa847 fix: fix path issues under win32 platform 2024-07-17 13:36:22 -07:00
KernelDeimos 5c636d4fd2 fix: remove abnoxious debug file 2024-07-17 13:55:55 -04:00
Nariman Jelveh f28836180e Merge pull request #603 from ohm69/pl-trans
Translation improvements, mainly style and context-based
2024-07-17 08:06:30 -07:00
Michal Hobot 8bece96f62 Translation improvements, mainly style and context-based
After using a Polish-translated puter I found out several places for improvement
2024-07-17 15:43:23 +02:00
Nariman Jelveh 6c29427e16 close #174 2024-07-16 19:06:46 -07:00
Nariman Jelveh 9bfee0862f Merge pull request #600 from Koppeks/koppeks/translation-es
Translation to Spanish
2024-07-16 18:14:44 -07:00
Nariman Jelveh 9d8a46814d Merge pull request #597 from bryanthaboi/main
Directions for Windows / Docker Composer
2024-07-16 16:38:42 -07:00
Nariman Jelveh c19c18bfcf Bring both Windows and Linux/Mac instructions under Docker Compose 2024-07-16 16:32:42 -07:00
Koppeks 151527825f update translation file es.js to be up to date with the file en.js 2024-07-16 20:30:42 -03:00
Nariman Jelveh cc4c93b77f Update README.md 2024-07-16 15:56:59 -07:00
Nariman Jelveh 3ca92955cb Make the screenshot a little larger 2024-07-16 15:56:37 -07:00
Nariman Jelveh 9bc427ced2 Merge pull request #598 from ohm69/patch-1
Translate en.js as of 2024-07-10
2024-07-16 09:09:44 -07:00
Michal Hobot 8e297cd7e3 Translate en.js as of 2024-07-10 2024-07-16 17:55:34 +02:00
bryanthaboi 5833b391f1 Update README.md 2024-07-16 09:17:35 -04:00
bryanthaboi 64e4299ac0 Update README.md 2024-07-16 09:10:38 -04:00
KernelDeimos 747d7dea89 Update SECURITY-ACKNOWLEDGEMENTS.md 2024-07-15 20:03:14 -04:00
Nariman Jelveh c80526900b Merge pull request #594 from Szab54/patch-1
Update translations.js to Hungarian lang
2024-07-15 12:39:07 -07:00
Nariman Jelveh 1b12a413fe Merge pull request #595 from Szab54/patch-3
Create hu.js hungarian language
2024-07-15 12:38:33 -07:00
XYCert 69a80ab3d2 Create hu.js hungarian language 2024-07-15 21:04:38 +02:00
XYCert 56820cf6ee Update translations.js to Hungarian lang 2024-07-15 20:58:31 +02:00
KernelDeimos a259755fe5 Fix broken link 2024-07-15 13:22:15 -04:00
KernelDeimos 7a12e699de Update SECURITY-ACKNOWLEDGEMENTS.md 2024-07-15 13:21:05 -04:00
Nariman Jelveh 7f0365202e Merge pull request #593 from Varun710/tamil-translation
Tamil translation
2024-07-14 22:36:13 -07:00
Varun710 81781f80af Tamil translation 2024-07-15 00:27:35 -05:00
Nariman Jelveh 93f4e52983 Update README.md to add Mastodon link 2024-07-14 16:43:56 -07:00
Nariman Jelveh b52c31133e Merge pull request #591 from LNLenost/patch-1
Fixed grammar issues/untranslated stings in italian translation
2024-07-14 10:44:37 -07:00
LNLenost 84e31eff2f Update it.js 2024-07-14 19:34:09 +02:00
Nariman Jelveh 46cbe077bc Merge pull request #590 from narek-gh/armenian-translation
Update Armenian translation based on English file
2024-07-13 14:25:31 -07:00
Narek 3b8af7cc5c Update Armenian translation file 2024-07-14 00:11:15 +04:00
Nariman Jelveh 9afb1b78b8 Fix blackfortresslabs.com URL 2024-07-11 18:36:29 -07:00
Nariman Jelveh ae04a09c90 Take into account that godmode might be either integer or boolean 2024-07-11 18:07:09 -07:00
KernelDeimos e8f4c328bf fix: read_only fields in ES 2024-07-11 21:00:14 -04:00
Nariman Jelveh 7b4e95139f Shorten Reddit link 2024-07-11 17:24:57 -07:00
KernelDeimos 6a2fbc1925 fix(security): hoist acl check in ll_read 2024-07-11 20:09:39 -04:00
KernelDeimos ab74f1ee8d release: v2.4.1 2024-07-11 19:41:08 -04:00
Nariman Jelveh b790bab9c0 Merge pull request #585 from HeyPuter/eric/rename-traits-to-features
refactor(backend): rename traits to features
2024-07-11 14:37:12 -07:00
KernelDeimos f7d15bae41 refactor(backend): rename traits to features 2024-07-11 16:50:09 -04:00
Nariman Jelveh 01a248e96e Merge pull request #579 from Waheed4719/issue#530
Issue#530 - Update bengali translations
2024-07-10 17:55:59 -07:00
Waheed Uddin Ahmed cff488f4f4 Update bn.js file formatting 2024-07-11 06:46:34 +06:00
Waheed Uddin Ahmed 92abc9947f Issue#530 - Update bengali translations 2024-07-11 06:42:52 +06:00
KernelDeimos 7aadae58ce fix: remove flag that breaks puter-js webpack 2024-07-10 17:18:54 -04:00
KernelDeimos 5b1924f312 chore: remove duplicate headers 2024-07-10 16:53:54 -04:00
KernelDeimos e6e92dc7b2 dev(license-headers): add dupe detector 2024-07-10 16:50:41 -04:00
KernelDeimos 6728dd2571 dev(license-headers): fix excludes list 2024-07-10 16:25:14 -04:00
KernelDeimos 2bf9f60bb0 dev(license-headers): implement skip and replace 2024-07-10 16:12:09 -04:00
KernelDeimos d0a5a57c88 dev(tools): add conflict prompt to license-headers 2024-07-10 14:57:39 -04:00
Nariman Jelveh f006c9ed26 Rename #DoesItRunPuter?.md to #DoesItRunPuter.md 2024-07-10 11:53:11 -07:00
Nariman Jelveh 6013466bcb Rename DoesItRunPuter.md to #DoesItRunPuter?.md 2024-07-10 11:52:34 -07:00
Nariman Jelveh 435e1786a3 Rename doesitrunputer.md to DoesItRunPuter.md 2024-07-10 11:38:56 -07:00
Nariman Jelveh e96bba850f move #DoesItRunPuter from README.md to ./awesome 2024-07-10 11:38:03 -07:00
Nariman Jelveh 2378f1a833 Delete .vscode directory 2024-07-10 11:30:15 -07:00
KernelDeimos 713b1f5889 dev(tools): add missing header adding to license-headers 2024-07-10 14:10:31 -04:00
KernelDeimos fac08c4152 doc: remove extra log in doc snippet 2024-07-10 13:52:20 -04:00
Nariman Jelveh 059a1fe565 Merge pull request #576 from sbondor/fix/romanian-translations
Added missing Romanian translations.
2024-07-10 10:43:59 -07:00
Sergiu Bondor 8440f566b9 Added missing Romanian translations. 2024-07-10 19:49:45 +03:00
Nariman Jelveh adb0f9dc23 Merge pull request #575 from xslendix/main
Add Romanian translations
2024-07-10 06:25:05 -07:00
Slendi 473b6512c6 Add 2FA Romanian translations
Signed-off-by: Slendi <[email protected]>
2024-07-10 11:37:06 +03:00
KernelDeimos 67139ef91b dev(tools): add license header adder thingy 2024-07-10 00:41:08 -04:00
Nariman Jelveh c76af1ab21 Merge pull request #574 from askdkc/japanese-translation
Add Japanese translation
2024-07-09 19:29:31 -07:00
askdkc 31748506b7 Create ja.js for Japanese Translation 2024-07-10 11:22:16 +09:00
askdkc 47ec74f0aa Add Japanese Translation 2024-07-10 11:20:29 +09:00
Nariman Jelveh 5e4582dda6 Update README.md 2024-07-09 19:18:14 -07:00
Nariman Jelveh 3bd3be7dee Update README.md 2024-07-09 19:15:50 -07:00
Nariman Jelveh e5243ec560 Delete .github/ISSUE_TEMPLATE/driver-request.md 2024-07-09 19:05:04 -07:00
Nariman Jelveh e745f67273 Add 'Support' section to README.md 2024-07-09 19:04:09 -07:00
Nariman Jelveh 831b2e259e Add ladybird to #DIRP and move the license section to the bottom 2024-07-09 16:54:54 -07:00
Nariman Jelveh 069b5e0033 Merge pull request #573 from HeyPuter/fix-CI-network-issues
Move `.commit` to `/tools`
2024-07-09 16:18:10 -07:00
KernelDeimos fafa36c73f move: move dev-server.js back to gui
I'm not sure why it was here, I thought I moved it already.
2024-07-09 19:01:49 -04:00
Nariman Jelveh eebf379205 Move .commit to /tools 2024-07-09 15:58:55 -07:00
Nariman Jelveh 4e15c5fcf4 Merge pull request #572 from HeyPuter/fix-CI-network-issues
retry npm 3 times to account for the flakiness of the process
2024-07-09 15:14:21 -07:00
Nariman Jelveh 10d77f17aa retry npm 3 times to account for the flakiness of the process 2024-07-09 15:12:19 -07:00
Nariman Jelveh 4daa1f2c25 Merge pull request #571 from micheledinelli/main
Add documentation instructions to get started with My Websites
2024-07-09 14:56:40 -07:00
micheledinelli 6c4c73a9e8 Add documentation instructions to get started with My Websites 2024-07-09 23:33:11 +02:00
Nariman Jelveh 00eabd7b10 remove duplicate and/or incorrect license headers 2024-07-09 13:50:20 -07:00
Nariman Jelveh 3b59ecedd1 Merge pull request #567 from stronkexe/main
Completing Arabic translation based on English file.
2024-07-09 08:21:04 -07:00
Nariman Jelveh 871f4cab0c Merge branch 'main' into main 2024-07-09 08:16:28 -07:00
Nariman Jelveh 1d52a559ff Remove more duplicate license headers 2024-07-09 08:14:33 -07:00
Nariman Jelveh ab164c3a0a Merge pull request #570 from micheledinelli/main
Completing Italian translation based on English file
2024-07-09 07:59:11 -07:00
micheledinelli f5a8ee1c6a Completing Italian translation based on English file 2024-07-09 16:55:45 +02:00
Nariman Jelveh 7fa2dd535f remove all duplicated license headers 2024-07-09 07:51:54 -07:00
micheledinelli a96abb5793 Completing Italian translation based on English file. 2024-07-09 16:49:19 +02:00
Nariman Jelveh 1f4297f746 Remove extra license header from ar.js 2024-07-09 07:48:35 -07:00
stronkexe 78a0acea69 Completing Arabic translation based on English file 2024-07-09 09:35:07 +01:00
KernelDeimos 3a7221dba5 chore: cleanup root directory 2024-07-09 04:18:55 -04:00
KernelDeimos bda4aed2e8 chore: add missing license headers 2024-07-09 04:10:33 -04:00
KernelDeimos 365d795c3f doc: omit cp of .env.example in local build instructions
This command contradicts the statement that Puter will find the
next available port when port 4100 is in use.
2024-07-09 04:03:58 -04:00
KernelDeimos a1ff375931 doc: update comment_prefixes.md 2024-07-09 03:40:46 -04:00
KernelDeimos 50036e954d dev: add js-parse-and-output experiment 2024-07-09 03:40:34 -04:00
KernelDeimos 0b39c76c40 move: incubator to experiments
This name is easier to understand and more generalizable.
2024-07-09 03:19:31 -04:00
KernelDeimos 47f76ccc89 dev: add file walker 2024-07-09 03:15:51 -04:00
Nariman Jelveh d3a9ba847a Move icon credits to the GUI project directory 2024-07-08 22:23:02 -07:00
Nariman Jelveh 338004474f Add jsdoc-style comments for a number of functions 2024-07-08 17:52:43 -07:00
Nariman Jelveh 535475b3c3 Improve getMimeType to remove trailing dot in the extension if preset 2024-07-08 17:33:09 -07:00
Nariman Jelveh 073b501e41 Merge pull request #566 from matheussss1/update-br-translation
feat: update BR translation
2024-07-08 14:40:29 -07:00
Matheus Carvalho 42a6b3938a feat: update BR translation 2024-07-08 18:33:39 -03:00
KernelDeimos a9338b45c1 chore: update package.json 2024-07-08 17:31:50 -04:00
Nariman Jelveh 8b9d57dc88 Merge pull request #565 from medelm1/update-arabic-translations
Update Arabic translations in ar.js
2024-07-08 14:03:09 -07:00
Nariman Jelveh 7d92304e7f Update ar.js 2024-07-08 13:59:45 -07:00
Nariman Jelveh 7844965489 Merge branch 'update-arabic-translations' of https://github.com/medelm1/puter into pr/565 2024-07-08 13:59:18 -07:00
Nariman Jelveh 8bdd489eaf Add missing commas 2024-07-08 13:59:13 -07:00
Med Elm fe5be7f3cf Update Arabic translations in src/gui/src/i18n/translations/ar.js to match English version in src/gui/src/i18n/translations/en.js 2024-07-08 13:59:13 -07:00
Nariman Jelveh 42496f9319 Add missing commas 2024-07-08 13:58:50 -07:00
KernelDeimos 48f99fb807 dev: add script to replace release-please 2024-07-08 16:57:02 -04:00
Med Elm bffa192805 Update Arabic translations in src/gui/src/i18n/translations/ar.js to match English version in src/gui/src/i18n/translations/en.js 2024-07-08 21:44:19 +01:00
Nariman Jelveh 26e9b0b2de Merge pull request #564 from Speedyjet/Russian_and_Ukrainian
Russian and ukrainian
2024-07-08 13:18:33 -07:00
Nariman Jelveh e061b1f488 Merge pull request #560 from Speedyjet/translations_russian_and_ukrainian
Russian translation fixed
2024-07-08 13:14:45 -07:00
Nariman Jelveh d2c68308bb Merge branch 'main' into translations_russian_and_ukrainian 2024-07-08 13:08:55 -07:00
Oleh Brusentsov e61039faf4 Ukrainian updated 2024-07-08 21:44:42 +02:00
Nariman Jelveh a1dd354787 Merge pull request #561 from julijatol/main
Update ru.js issue #547
2024-07-08 12:29:54 -07:00
KernelDeimos 3ed7916856 feat: JSON support for kv driver 2024-07-08 15:27:54 -04:00
Yuliya Tolstikova 17145d0be6 Update ru.js issue #547 2024-07-08 15:12:48 -04:00
Oleh Brusentsov 8836011428 Russian translation fixed 2024-07-08 20:44:53 +02:00
KernelDeimos 1f659f7c01 chore: fix release-please version 2024-07-08 13:47:44 -04:00
github-actions[bot] c84e15ba20 chore(main): release 1.0.0 2024-07-08 13:47:44 -04:00
Nariman Jelveh 86fd2f4bc4 Delete src/dev-center/.eslintignore 2024-07-08 10:06:09 -07:00
KernelDeimos 1f3eb08a70 chore: remove eslint 2024-07-08 00:53:40 -04:00
Nariman Jelveh cb8f0aa359 wtf is wrong with eslint?! 2024-07-07 21:40:53 -07:00
Nariman Jelveh 58ff7c279d Update .eslintignore 2024-07-07 21:38:39 -07:00
Nariman Jelveh 1f8cd7f613 Create .eslintignore 2024-07-07 21:36:37 -07:00
KernelDeimos 94c0449437 fix: docker runtime fail because stdout columns 2024-07-08 00:31:18 -04:00
KernelDeimos 6603c45093 sync: update gui paths in Dockerfile 2024-07-08 00:31:02 -04:00
Nariman Jelveh 30f9f29982 Merge branch 'main' of https://github.com/HeyPuter/puter into main 2024-07-07 20:44:04 -07:00
Nariman Jelveh 594424444a make Dev Center aware of the origin of the host environment 2024-07-07 20:43:57 -07:00
KernelDeimos 4078a63fe1 tweak: maximize dev center on start 2024-07-07 23:16:19 -04:00
Nariman Jelveh ad56091c2f Merge pull request #559 from TianLangStudio/translation_zh
[translation] improve Chinese translation fix issue 549
2024-07-07 19:47:36 -07:00
Nariman Jelveh fd39f92ea6 get username and appID from puter.js rather than iframe URL in Dev Center 2024-07-07 19:44:28 -07:00
KernelDeimos 283f409a66 fix: fix owner ids for default apps 2024-07-07 22:35:45 -04:00
FusionZhu a8474054cc improve Chinese translation fix issue 549 2024-07-08 10:27:53 +08:00
KernelDeimos 10f4d7d50c feat: register dev center to apps 2024-07-07 22:26:32 -04:00
Nariman Jelveh e73d55b2c0 Perform getDeveloperProfile only when on puter.com 2024-07-07 19:22:26 -07:00
Nariman Jelveh f2b551d5be Initial commit for Dev Center 2024-07-07 18:52:37 -07:00
KernelDeimos af083b0800 cleanup: feat: support canonical puter.js url in dev 2024-07-07 20:47:01 -04:00
KernelDeimos fd41ae217c feat: support canonical puter.js url in dev 2024-07-07 20:45:02 -04:00
Nariman Jelveh fdea7907be Update screenshot in README.md 2024-07-07 16:45:59 -07:00
Nariman Jelveh 11cfa83193 Update README.md 2024-07-07 16:38:12 -07:00
Nariman Jelveh c88ce8e68c Delete test.txt 2024-07-07 16:31:46 -07:00
Nariman Jelveh c47556d1b7 Update README.md 2024-07-07 16:09:07 -07:00
Nariman Jelveh e6cdca09cc Remove the FAQ section from README.md 2024-07-07 15:58:17 -07:00
Nariman Jelveh 5e5a18565f Update README.md 2024-07-07 15:22:06 -07:00
Nariman Jelveh 2fbe6a6b26 Update README.md 2024-07-07 15:18:27 -07:00
Nariman Jelveh c5f4ff5a49 Update README.md 2024-07-07 15:15:19 -07:00
Nariman Jelveh 841c8bf9f2 Update README.md to add emojis to heading for easier reading 2024-07-07 15:09:49 -07:00
Nariman Jelveh 70b9b6f088 Update README.md 2024-07-07 15:03:09 -07:00
Nariman Jelveh 45840067f9 Update readme and put self-hosting instructions in a separate document 2024-07-07 15:01:01 -07:00
KernelDeimos 2a91edb965 chore: add Buffer to eslint 2024-07-07 17:12:55 -04:00
KernelDeimos edc5743a61 chore: add incubator/ to eslint ignores 2024-07-07 17:12:55 -04:00
KernelDeimos d3f3e089d3 sync: update check-translations.js 2024-07-07 17:12:55 -04:00
KernelDeimos 7c227ad967 chore: update eslint config 2024-07-07 17:12:55 -04:00
KernelDeimos a43cab0c93 refactor: move puter gui to workspace 2024-07-07 17:12:55 -04:00
Nariman Jelveh c23e8931ab Merge pull request #218 from lsileoni/main
WIP: Barebones x86emu skeleton
2024-07-07 11:25:18 -07:00
Nariman Jelveh d6dd04f195 Merge pull request #476 from HeyPuter/eric/more-reserved-words
tweak: add more reserved words
2024-07-07 11:22:35 -07:00
Nariman Jelveh 7811294f33 Add puter to reserved_words.js 2024-07-07 11:21:49 -07:00
Nariman Jelveh 016633cfbb Merge pull request #557 from Ramanmishra09/main
Issue no-551 hindi translation
2024-07-07 10:23:23 -07:00
Nariman Jelveh 4c26ebe3ac Fix key references for the Hindi language 2024-07-07 10:11:17 -07:00
ramanfloyeedee ce50718f84 Issue no-551 hindi translation
I have created hi.js file under src/i18n/translations in the main branch.
please review the file.
Thanks
2024-07-07 21:31:43 +05:30
Nariman Jelveh cb5184f2f1 Confirming to delete accoutn works with both English and the chosen locale of the user 2024-07-07 08:47:09 -07:00
Nariman Jelveh ce2b38c084 Merge pull request #556 from mklr19/translate-german
Updated german translation file
2024-07-07 08:22:46 -07:00
Nariman Jelveh 69332e14e7 Merge pull request #555 from etnms/#537-french-translation
Issue #537 - updated French translation based on English file
2024-07-07 08:07:44 -07:00
mklr19 37dca86506 Updated german translation file 2024-07-07 15:42:27 +02:00
etnms 812480bbd0 updated French translation based on English file per issue #513 2024-07-07 10:23:35 +02:00
Sam Atkins ef298ce3aa feat: Display app icon and description in embeds 2024-07-06 22:24:43 -04:00
KernelDeimos c8abe2380f dev: small changes 2024-07-06 22:12:49 -04:00
Nariman Jelveh d0cb0a96de Add english_name attribute for the Polish i18n file 2024-07-06 11:20:01 -07:00
Nariman Jelveh ac7fe1e436 Merge pull request #526 from brodbar/main
Update and revise Turkish translation
2024-07-06 08:45:33 -07:00
brodbar 28a9469914 Update locale 2024-07-06 16:47:50 +03:00
Nariman Jelveh bf27811167 Merge pull request #523 from sysnajar/th
Add Thai translation. https://github.com/HeyPuter/puter/issues/522
2024-07-05 21:27:40 -07:00
Nariman Jelveh 31bf69f10e add the two missing keys 2024-07-05 21:25:48 -07:00
Sysnajar 5e78690b97 Add Thai translation. 2024-07-06 10:46:58 +07:00
Nariman Jelveh d0758631ea Add more English translation keys 2024-07-05 15:35:16 -07:00
Nariman Jelveh c9e2427ad6 Merge pull request #521 from Zuhaib-Asif/update-urdu-translations
Updated Urdu translations, added missing entries, and corrected inacc… fix #520
2024-07-05 14:38:15 -07:00
Zuhaib Asif a9c33da151 Updated Urdu translations, added missing entries, and corrected inaccuracies 2024-07-06 02:21:49 +05:00
KernelDeimos 7d2f6d256f fix: group permission audit table 2024-07-04 19:37:52 -04:00
KernelDeimos 4af279a72f feat: rate-limit for excessive groups 2024-07-04 19:37:52 -04:00
KernelDeimos 0855f2b36e fix: property validation on some permission endpoints 2024-07-04 16:42:17 -04:00
Nariman Jelveh dcbca2f829 Add i18n keys for multiple terms 2024-07-03 13:05:39 -07:00
KernelDeimos de7e2adabd doc: document /group/list 2024-07-03 15:41:23 -04:00
KernelDeimos d55f38ca68 feat: add /group/list endpoint 2024-07-03 15:41:23 -04:00
Nariman Jelveh 3633349700 Merge pull request #516 from guicazaroto/feature/translate-br.js
feature: add (pt-br) translation for system settings.
2024-07-02 15:59:23 -07:00
Guilherme Guimarães Cazaroto 77211c4f71 feature: add (pt-br) translation for system settings. 2024-07-02 19:42:49 -03:00
KernelDeimos c0063a871f fix: handling of batch requests with zero files 2024-07-02 15:38:56 -04:00
Nariman Jelveh 80ea655d05 close #512 2024-07-01 15:44:48 -07:00
KernelDeimos d9c4fbbd1d fix: ui color input attributes 2024-07-01 14:23:49 -04:00
Sam Atkins 75a989a7b6 feat(phoenix): Make clear clear scrollback unless -x is given
From what I understand, we shouldn't need both `\x1B[2J` and `\x1B[3J`
sequences to clear everything, but xterm.js would not correctly clear
the visible region with only `\x1B[3J`. So, we have both.
2024-07-01 13:59:43 -04:00
Sam Atkins d76e7130cb fix(phoenix): Gracefully handle completing a non-existent path
filesystem.readdir() can throw, which previously would crash Phoenix and
leave the terminal unresponsive. This change makes it return no results
instead.
2024-07-01 13:52:46 -04:00
Sam Atkins 4539408a21 feat(phoenix): Show actual host name in prompt and neofetch 2024-07-01 12:46:15 -04:00
Sam Atkins e2ea57fcf9 tweak(phoenix): Only take auth params from config message
Having the parent app send us arbitrary config values was a holdover
from when phoenix was an embedded iframe and not a separate app. It led
to a security issue previously. Let's only take the auth parameters
since we can't get those otherwise, and they're safe to read.
Everything else should be available in our own URL params.
2024-07-01 12:46:15 -04:00
Sam Atkins b7133760df tweak: Ensure puter.domain is always set for launched apps 2024-07-01 12:46:15 -04:00
Nariman Jelveh 91e9fa7c25 improve the ux of "Show Desktop" toolbar button 2024-06-30 23:30:55 -07:00
KernelDeimos 2f5b9cc4ee chore: add temp user-app permission 2024-06-30 16:40:25 -04:00
KernelDeimos 2f163221bd fix: update PD alert custom details 2024-06-30 16:31:02 -04:00
KernelDeimos a0f4292072 test: add more test scenarios for sharing 2024-06-30 15:09:49 -04:00
KernelDeimos 1429d6f57c fix: column nullability blunder 2024-06-30 15:06:10 -04:00
KernelDeimos b10302ad74 fix: add missing columns for public directory update 2024-06-28 22:26:57 -04:00
KernelDeimos 88d6bee954 feat: get first test working on share-test service 2024-06-28 17:43:45 -04:00
KernelDeimos 9ad04cd33f prereq: make it possible to access storage without context init 2024-06-28 17:43:45 -04:00
KernelDeimos 332371fccb feat: add service to test file share logic 2024-06-28 17:43:45 -04:00
Nariman Jelveh 95e1268527 Make contextmenu smooth as butter 2024-06-28 12:48:55 -07:00
Sam Atkins d077504f9b doc(git): Expand documentation and add FIXMEs 2024-06-28 14:19:23 -04:00
Sam Atkins 711dbc0d2f feat(git): Understand references like HEAD^ and main~3
There are a lot of ways of specifying a revision, but these are a couple
of common ones.
2024-06-28 14:19:23 -04:00
Sam Atkins adcd3db0ed refactor: Move parsely into top-level packages directory
Parsely was missed by fa7bec3854 because
it got merged afterwards.
2024-06-28 14:19:23 -04:00
Sam Atkins 45cdfcb5bf feat(git): Display ref names in git log and git show 2024-06-28 14:19:23 -04:00
Sam Atkins 351d3f50ba tweak(git): List git subcommands in git help with no arguments 2024-06-28 14:19:23 -04:00
Sam Atkins 73d0f5a90c fix(git): Make git commit display detached HEAD correctly 2024-06-28 14:19:23 -04:00
Sam Atkins dd10a37749 feat(git): Make shorten_hash() guaranteed to produce a unique hash
Until now we just relied on it being very unlikely that there would be a
collision. This new method ensures that the returned hash is unique.
2024-06-28 14:19:23 -04:00
Sam Atkins fa3df72f6e feat(git): Add a --debug option, which sets the DEBUG global
I ended up removing the debugging code that used this, but it seems
useful anyway for future debug logs.
2024-06-28 14:19:23 -04:00
Sam Atkins 2e4259d267 feat(git): Implement git cherry-pick
This is quite manual, and only handles the simple cases where no merge
conflicts occur. Should be useful for basing a `rebase` command off of
though.
2024-06-28 14:19:23 -04:00
Sam Atkins bab5204209 feat(git): Color output for git status files
Matching canonical git, staged changes are green and unstaged/untracked
are red.
2024-06-28 14:19:23 -04:00
Sam Atkins 4ba8a32b45 feat(git): Implement git restore
I tried implementing --source=foo too, but was bumping into weird
behaviour with isomorphic-git, so I've removed that for now. Eventually
we'll want it, but it seems fairly niche.
2024-06-28 14:19:23 -04:00
Sam Atkins a68037111a feat(git): Display file contents as a string for git show FILE_OID 2024-06-28 14:19:23 -04:00
Sam Atkins b6906bbcaa feat(git): Resolve more forms of commit reference
Specifically, we previously didn't resolve short commit hashes into the
full ones.

These functions provide a single place to later add more ways of
selection a commit, such as `HEAD~1`.
2024-06-28 14:19:23 -04:00
Sam Atkins 60976b1ed6 feat(git): Format output closer to canonical git
Make some parts colored or bold, and indent commit messages.
2024-06-28 14:19:23 -04:00
Sam Atkins 955154468f feat(git): Make git add work for deleted files
Previously, this:

```sh
> rm deleted.txt
> git add deleted.txt
```

...would unhelpfully complain that deleted.txt cannot be found. Now, it
records the deleted file to the index, just as canonical git does.
2024-06-28 14:19:23 -04:00
Sam Atkins 057b3acf00 feat(git): Allow checking out a commit instead of a branch 2024-06-28 14:19:23 -04:00
Sam Atkins 2c9b1a3ffc feat(git): Handle detached HEAD in git status and git branch --list 2024-06-28 14:19:23 -04:00
Sam Atkins d6dd1a5bb0 feat(git): Add --color and --no-color options
These allow the user to force color on or off. The chalk library is used
for the output, because it's already used elsewhere in Puter and seems
like a good choice.

Ideally, the default will be based on whether stdout is a tty, but Puter
doesn't yet have that concept, so we just default to color.
2024-06-28 14:19:23 -04:00
Sam Atkins 364d580ff8 feat(git): Add authentication to clone, fetch, and pull. 2024-06-28 14:19:23 -04:00
Sam Atkins 8c70229a18 feat(git): Implement git push
For now, the authentication is by --username and --password options,
which obviously is not good because the password is visible. But doing
it in a nicer way requires features that Phoenix or Puter are currently
missing.
2024-06-28 14:19:23 -04:00
Sam Atkins 3cad1ec436 feat(git): Add diff display to show and log subcommands 2024-06-28 14:19:23 -04:00
Sam Atkins c436460b8c tweak(git): Move proxy url definition into config files
We'll likely want to host our own proxy. Self-hosters likewise may have
their own, but it's convenient to use isomorphic-git's for development.
2024-06-28 14:19:23 -04:00
Sam Atkins a68194090e tweak(git): Check for 'ENOENT' instead of ErrorCodes.ENOENT
This is functionally the same, but removes one place where we
unnecessarily relied on Puter code.
2024-06-28 14:19:23 -04:00
Sam Atkins c0562d78a2 docs(git): Document git client 2024-06-28 14:19:23 -04:00
Sam Atkins 622b6a9b92 feat(git): Implement git diff 2024-06-28 14:19:23 -04:00
Sam Atkins 49c2f16351 feat(git): Add start-revision and file arguments to git log 2024-06-28 14:19:23 -04:00
Sam Atkins eb2b6a08b0 feat(git): Implement git pull 2024-06-28 14:19:23 -04:00
Sam Atkins 1822ace296 refactor(git): Use dir/gitdir variable names like isogit does
I prefer the other names, but being able to type `{ dir, gitdir }` is
shorter and a lot less error-prone than `{ dir: repository_dir, gitdir:
git_dir }`.
2024-06-28 14:19:23 -04:00
Sam Atkins 35e4453930 feat(git): Implement git checkout
For now this only lets you check out branches, not files.
2024-06-28 14:19:23 -04:00
Sam Atkins 98a4b9ede3 feat(git): Implement git fetch
Sporadically we hang while trying to fetch. I haven't been able to
identify why but it seems like a race condition in isomorphic-git
somewhere.
2024-06-28 14:19:23 -04:00
Sam Atkins c86e4dfdce Remove unused imports from git subcommands 2024-06-28 14:19:23 -04:00
Sam Atkins ad4f13255d feat(git): Implement git branch
Create, delete, copy, rename, and list branches.
2024-06-28 14:19:23 -04:00
Sam Atkins 43ce0d5b45 feat(git): Implement git remote 2024-06-28 14:19:23 -04:00
Sam Atkins 95c8235a4a feat(git): Implement git clone 2024-06-28 14:19:23 -04:00
Sam Atkins fa81dca950 feat(backend): Add tab completion to server console command arguments
A command can optionally define a `completer(args)` function. It takes
an array of strings for the current arguments, and returns an array of
completion results for the last argument.

Includes a few completers:
- alarm:info/clear/inspect completes the first argument as an alarm id
  or short_id
- script:run completes the first argument as a script name
- params:get/set completes the first argument as a parameter name
2024-06-28 11:18:29 -04:00
Sam Atkins e1e76c6be7 feat(backend): Add tab-completion to server console command names 2024-06-28 11:18:29 -04:00
KernelDeimos ecb997885c fix: bug introduced when refactoring /share to Sequence 2024-06-27 18:27:20 -04:00
KernelDeimos 2faaeaedb3 chore: add write request to kdmod 2024-06-27 18:27:20 -04:00
KernelDeimos e9ee3191e9 doc: document group endpoints 2024-06-27 18:27:20 -04:00
KernelDeimos c374b0cbca feat: add group permission endpoints 2024-06-27 18:27:20 -04:00
KernelDeimos 4216346384 feat: add group management endpoints 2024-06-27 18:27:20 -04:00
KernelDeimos 00149402e0 feat: add user-group permission check 2024-06-27 18:27:20 -04:00
KernelDeimos b817a78efa sql: group permissions table 2024-06-27 18:27:20 -04:00
KernelDeimos 0ddb13e8ee sql: group table 2024-06-27 18:27:20 -04:00
KernelDeimos e132a203d1 refactor: move check-user-permission to Sequence 2024-06-27 18:27:20 -04:00
Nariman Jelveh fbc02a5f62 Fix the issue with re-opening submenus using keyboard 2024-06-26 09:41:57 -07:00
Nariman Jelveh 8a763eab6f fix multiple issues with ctx menu event delegation and keyboard navigation 2024-06-26 00:57:12 -07:00
KernelDeimos b78c83a4ab refactor: share endpoint 2024-06-25 16:59:50 -04:00
KernelDeimos 5551326c98 doc: add documentation for app shares 2024-06-24 20:13:40 -04:00
Sam Atkins d81f6e5ede chore: Mark globals as being part of the window object
Silences eslint
2024-06-24 19:15:02 -04:00
Sam Atkins 00765d0fce chore: Add mods/ directory to eslint 2024-06-24 19:15:02 -04:00
KernelDeimos 9033f6f8c7 fix: update email share object 2024-06-24 19:12:21 -04:00
KernelDeimos 9751fd92a5 feat: add appdata permission (if applicable) on app share 2024-06-24 19:12:21 -04:00
KernelDeimos 13e2f72c9f feat: add subdomain permission (if applicable) on app share 2024-06-24 19:12:21 -04:00
KernelDeimos 0cf90ee39a fix: fix issues with apps in /share endpoint 2024-06-24 19:12:21 -04:00
Sam Atkins 46eb4ed2b9 fix: Throw an error when readdir is called on a non-directory 2024-06-24 19:08:56 -04:00
KernelDeimos a136ee5edd fix: oops 2024-06-24 14:05:08 -04:00
KernelDeimos 15465bfc50 fix: improve console experience on mac 2024-06-24 14:01:00 -04:00
KernelDeimos c79f500364 tweak: improve dev console 2024-06-24 13:53:00 -04:00
Nariman Jelveh 266e41f95c Remove extra height for iframe when menu bar is in desktop mode 2024-06-24 10:24:30 -07:00
KernelDeimos 2839e74420 doc: /sharelink/request 2024-06-24 01:11:40 -04:00
KernelDeimos 742f625309 feat: add /sharelink/request endpoint 2024-06-24 01:11:40 -04:00
KernelDeimos b0e067e4ae doc: misc doc additions 2024-06-23 17:35:19 -04:00
KernelDeimos 16b1649ff6 feat: add debug mod 2024-06-23 17:35:05 -04:00
Nariman Jelveh a094ae5683 Update en.js 2024-06-23 10:01:16 -07:00
Nariman Jelveh a521ff3d7c Merge pull request #490 from HeyPuter/customizable-menubar
Customizable menubar
2024-06-22 22:10:01 -07:00
Nariman Jelveh a58aa3f2e6 Close #480 2024-06-22 22:09:19 -07:00
Nariman Jelveh 0bd0eaf890 add the ability to pick between desktop and winow menubars 2024-06-22 19:51:29 -07:00
KernelDeimos a72ec9799a fix: readdir on file 2024-06-22 19:10:25 -04:00
Nariman Jelveh 704a4ead17 Show register form when user receiving a file is not the correctone 2024-06-21 12:16:42 -07:00
Nariman Jelveh e31625d0da Update IPC.js 2024-06-21 00:06:01 -07:00
Nariman Jelveh d0e3da9b3e Merge branch 'main' of https://github.com/HeyPuter/puter into main 2024-06-20 23:47:43 -07:00
Nariman Jelveh 61961b565e Update initgui.js 2024-06-20 23:47:35 -07:00
KernelDeimos 265f4d9d64 doc: document testing Puter with email 2024-06-20 22:59:45 -04:00
Nariman Jelveh 27ec2d7f1c Update initgui.js 2024-06-20 19:43:32 -07:00
Nariman Jelveh 88ce871601 Update initgui.js 2024-06-20 19:38:47 -07:00
Nariman Jelveh 2d4f5778a2 Update initgui.js 2024-06-20 19:37:27 -07:00
Nariman Jelveh 5cb5a75455 Verify share_token when launched 2024-06-20 19:31:03 -07:00
KernelDeimos 5a49074f95 doc: sharelink endpoints 2024-06-20 22:15:57 -04:00
KernelDeimos 301ffaf61d feat: add endpoints for share tokens 2024-06-20 22:15:57 -04:00
KernelDeimos db5990a989 feat: add share service and share-by-email to /share 2024-06-20 22:15:57 -04:00
KernelDeimos fc4ae19d99 chore: cleanup share.js 2024-06-20 22:15:57 -04:00
KernelDeimos bf63144f7a fix: null email in request to /share 2024-06-20 19:41:41 -04:00
Nariman Jelveh 1c2ba76db2 If items are dropped on the home directory of another user, try to share the items rather than copy/move 2024-06-20 14:06:43 -07:00
Nariman Jelveh 6f0706ffc5 rename show_or_hide_empty_folder_message to toggle_empty_folder_message 2024-06-20 13:28:45 -07:00
Nariman Jelveh a834fbcc6c remove scroll bar from 2024-06-20 11:32:03 -07:00
KernelDeimos c0fb470719 tweak: update gui 2024-06-20 12:58:04 -04:00
KernelDeimos dd5fde5130 feat: update share endpoint to support more things 2024-06-20 12:58:04 -04:00
KernelDeimos 18f9959776 doc: type-tagged objects, update share doc 2024-06-20 12:58:04 -04:00
KernelDeimos 5f4b922b19 doc: document future share endpoint 2024-06-20 12:58:04 -04:00
Sam Atkins 2355a43efa tweak: Re-add mime.js import
This got removed in 7006dcc31c, but we do
need it.
2024-06-20 14:21:41 +01:00
Nariman Jelveh 1500f84d46 close #483 2024-06-19 22:30:42 -07:00
KernelDeimos 82f86ee4ab doc(backend): protected apps; function and permissions 2024-06-20 00:43:52 -04:00
KernelDeimos 16c4907be5 feat: add permission rewriter for app by name 2024-06-20 00:32:12 -04:00
Nariman Jelveh f6a4413411 Merge branch 'main' of https://github.com/HeyPuter/puter into main 2024-06-19 21:07:48 -07:00
Nariman Jelveh feabbaf564 close #430 2024-06-19 21:07:41 -07:00
KernelDeimos 3ae0081b41 tweak: update this too to avoid confusion 2024-06-20 00:01:22 -04:00
KernelDeimos 3b9a74c0cb doc: meta documentation and common pattern tracking 2024-06-20 00:00:59 -04:00
KernelDeimos f2f3d6ff46 feat: add protected apps 2024-06-19 23:44:42 -04:00
Nariman Jelveh 7006dcc31c refactor item_icon 2024-06-19 18:39:32 -07:00
Nariman Jelveh 219cb63b73 refactor open_item 2024-06-19 18:27:49 -07:00
Nariman Jelveh 0726a11d11 refactor get_html_element_from_options 2024-06-19 17:59:48 -07:00
KernelDeimos 55c609b3fe fix: update test kernel 2024-06-19 19:55:50 -04:00
KernelDeimos 7f5f6f83d7 doc: add this doc/planning folder so it stops being in my index 2024-06-19 18:40:05 -04:00
KernelDeimos ceba309dbd fix: add stream limit 2024-06-19 18:33:56 -04:00
KernelDeimos 2008db0852 fix: validate size metadata 2024-06-19 18:33:56 -04:00
Nariman Jelveh 44d340d429 Update UIWindowShare.js 2024-06-19 14:16:48 -07:00
Nariman Jelveh ad079cdcc5 Use razzle dazzle to display icons of items being shared 2024-06-19 14:06:25 -07:00
KernelDeimos d14a30e089 devex: add command to start/stop recording logs to a file 2024-06-19 15:49:58 -04:00
KernelDeimos eb17d61fc1 security: address 7018641 2024-06-19 15:17:58 -04:00
Nariman Jelveh bfd896041e Update UIWindow.js 2024-06-19 12:13:01 -07:00
Nariman Jelveh bd958b3820 show the share dialog when items are dropped on a username in the sidebar 2024-06-19 12:11:05 -07:00
Nariman Jelveh c67674c889 Add license headers 2024-06-19 00:01:12 -07:00
Nariman Jelveh 41e307bd5b cast selectable_body and multiselectable to Boolean 2024-06-18 23:37:28 -07:00
Nariman Jelveh 892750788b Merge branch 'main' of https://github.com/HeyPuter/puter into main 2024-06-18 23:21:16 -07:00
Nariman Jelveh 4bd62c02dc close #309 2024-06-18 23:21:07 -07:00
KernelDeimos 5cda51e184 tweak: add missing file for previous commit 2024-06-19 02:10:58 -04:00
KernelDeimos fb1e2f21fb feat: start directory index frame 2024-06-19 02:03:02 -04:00
Nariman Jelveh 581964b655 Make GUI open the relavant directory when URL is provided 2024-06-18 22:11:14 -07:00
Nariman Jelveh c1647a5982 wip: bad commit message, I know. 2024-06-18 21:57:34 -07:00
KernelDeimos a813fbbb88 feat: add cookie for site token 2024-06-19 00:51:16 -04:00
KernelDeimos 86fca17fb1 feat: add protected subdomains 2024-06-19 00:51:16 -04:00
KernelDeimos e7c0b8320a feat: add querystring-informed errors 2024-06-19 00:51:16 -04:00
KernelDeimos 616f28d1d4 tweak: change default static hosting domain 2024-06-19 00:51:16 -04:00
KernelDeimos 56e527d3ee db: add protected flag to app and subdomain 2024-06-19 00:51:16 -04:00
KernelDeimos 360ad2e252 refactor: move FilesystemService to BaseService 2024-06-19 00:51:16 -04:00
KernelDeimos 3e98f1a8a8 tweak: acl update 2024-06-19 00:10:40 -04:00
Nariman Jelveh 174e2b7781 Take user to shared directory when clicked on share notif 2024-06-18 21:04:09 -07:00
KernelDeimos cd65217f5c fix: switch share notif username to sender 2024-06-18 23:43:10 -04:00
Nariman Jelveh 1d083efb67 We officially have one of the best web-based Context Menus 2024-06-18 20:25:42 -07:00
Nariman Jelveh 1904b92a9d Update jquery.menu-aim.js 2024-06-18 18:15:53 -07:00
Nariman Jelveh 5dc640bec1 Add a list of sharing users in the sidebar of Explore 2024-06-18 17:15:46 -07:00
KernelDeimos d96f924cad fix: type error in puter-site 2024-06-18 13:03:40 -04:00
Sam Atkins 85c6798448 fix: Make polyfilled import.meta.filename getter a valid function 2024-06-18 13:17:04 +01:00
KernelDeimos 7eabb43bd4 fix: i forgot to test reloading 2024-06-18 05:09:29 -04:00
KernelDeimos de5886698e fix: fix permission cascade properly this time 2024-06-18 03:56:38 -04:00
KernelDeimos 10cbf08233 fix: peers array assumption 2024-06-18 02:44:20 -04:00
KernelDeimos b126b67094 fix: fix that fix 2024-06-18 01:40:27 -04:00
KernelDeimos e63ab3a67f fix: add permission implicator for file modes 2024-06-18 01:39:13 -04:00
Nariman Jelveh 4aa72eaf15 Update jQuery UI to 1.13.2 2024-06-17 22:35:17 -07:00
Nariman Jelveh 91b7f7db1e simplify UI for sharing 2024-06-17 21:50:30 -07:00
Nariman Jelveh e9af6358bb Merge branch 'main' of https://github.com/HeyPuter/puter into main 2024-06-17 21:26:09 -07:00
Nariman Jelveh 7f516896be Add the ability to share and revoke permission through UiWindowShare 2024-06-17 21:26:00 -07:00
KernelDeimos 34d4d606c3 tweak: add more information to errors 2024-06-17 22:45:05 -04:00
KernelDeimos 831c29f23b tweak: report permission for file shares 2024-06-17 22:13:06 -04:00
KernelDeimos bbf09eb74e doc: document path property items in /share 2024-06-17 20:35:49 -04:00
KernelDeimos 11a135c7b7 doc: add request example for /share 2024-06-17 18:44:21 -04:00
KernelDeimos 807addb4ef doc: document /share endpoint 2024-06-17 18:34:45 -04:00
KernelDeimos 6cdbc92ae3 tweak: add dry-run and tweak response for /share 2024-06-17 18:34:45 -04:00
KernelDeimos 846fdc20d4 feat: multi-recipient multi-file share endpoint 2024-06-17 18:34:45 -04:00
Nariman Jelveh afe37a69d6 Update IPC.js 2024-06-17 14:51:48 -07:00
KernelDeimos ce0eee3e29 tweak: add more reserved words 2024-06-17 17:45:33 -04:00
KernelDeimos f7a054956b fix: add app_uid param to kv interface 2024-06-17 17:33:37 -04:00
Nariman Jelveh 21c537fe22 Refactor to use KV exclusively 2024-06-17 14:33:24 -07:00
Nariman Jelveh 5f8b8a2147 Make sure an iframe is focused after app is loaded 2024-06-17 13:17:37 -07:00
Nariman Jelveh 2a748f1884 Close all other contextmenus when a new menu item is opened 2024-06-17 09:41:22 -07:00
Nariman Jelveh b2f2c557e9 Update UIWindowShare.js 2024-06-16 23:29:40 -07:00
Nariman Jelveh ccf6ebef4d Add support for disabled context menu items through puter.js 2024-06-16 20:18:11 -07:00
Nariman Jelveh 04adade80e Update launch_app.js 2024-06-16 19:25:06 -07:00
Nariman Jelveh fe2c8bc249 Merge branch 'main' of https://github.com/HeyPuter/puter into main 2024-06-16 19:24:58 -07:00
Nariman Jelveh f185c02f4c Update UIContextMenu.js 2024-06-16 19:00:53 -07:00
KernelDeimos 35cbec43e6 tweak: add full fsentry to share notification 2024-06-16 22:00:15 -04:00
Nariman Jelveh 4ef6fd6148 Make mouseMoved event take into account window head height 2024-06-16 18:48:34 -07:00
Nariman Jelveh 2a0fb8fe6d Merge branch 'main' of https://github.com/HeyPuter/puter into main 2024-06-16 18:35:50 -07:00
Nariman Jelveh b789bb7078 Refactor launch_app to add support for fullpage apps on landing 2024-06-16 18:10:37 -07:00
KernelDeimos 31d4eb090e feat: implicit access from apps to shared appdata dirs 2024-06-16 21:09:04 -04:00
KernelDeimos a2a10b94be fix: do not delegate to select on read like ever that is really dumb 2024-06-16 20:57:32 -04:00
KernelDeimos 9b39309e18 fix: database migration 2024-06-16 18:59:45 -04:00
Nariman Jelveh 6d1c1d3ed2 Add support for the metadata attribute for the App object in puter.js 2024-06-16 15:12:33 -07:00
KernelDeimos cb050b079a chore: update eslint config 2024-06-16 16:41:28 -04:00
KernelDeimos f7216b9567 feat: add app metadata 2024-06-16 16:41:28 -04:00
Nariman Jelveh 8ebf1cec3f Update UIContextMenu.js 2024-06-16 13:41:16 -07:00
Nariman Jelveh 0fea080ba9 Blur context menu items when mouse leaves 2024-06-16 13:25:46 -07:00
KernelDeimos 632c536616 fix: correct shown flag behavior 2024-06-16 02:19:37 -04:00
Nariman Jelveh c35ecec5a4 Focus back on the parent window when an item in context menu is clicked 2024-06-15 23:17:45 -07:00
Nariman Jelveh e466dc8057 Merge branch 'main' of https://github.com/HeyPuter/puter into main 2024-06-15 22:58:31 -07:00
Nariman Jelveh 476f408a13 Take into account the menubar height when positioning the contextmenu via puter.js 2024-06-15 22:58:24 -07:00
KernelDeimos 8c49ba2553 feat: add share list to stat 2024-06-16 01:54:25 -04:00
Nariman Jelveh 0dbc6aad0f Don't show 'Cut' and 'Delete' options on shared items 2024-06-15 22:14:14 -07:00
Nariman Jelveh 705b9de28c Add basic sharing UI 2024-06-15 20:36:40 -07:00
KernelDeimos b648817f27 fix: incorrect error from suggested_apps 2024-06-15 23:21:54 -04:00
KernelDeimos 1389298f8c doc: document share endpoints 2024-06-15 22:39:47 -04:00
KernelDeimos 2f6c428a40 feat: send notification when file gets shared 2024-06-15 22:39:47 -04:00
KernelDeimos f9d2a87d25 chore: choose end-user-facing name for fs nodes 2024-06-15 22:39:47 -04:00
KernelDeimos 0f05a41ea8 tweak: add improvements to share/file-by-username 2024-06-15 22:39:47 -04:00
KernelDeimos 9ac8535832 Add support for optional auth 2024-06-15 22:39:47 -04:00
Nariman Jelveh ea84c2f26d Fix issues with inconsistent path formats for owned files vs shared files 2024-06-15 22:39:47 -04:00
KernelDeimos f2c6e01296 fix: remove legacy permission check in stat 2024-06-15 22:39:47 -04:00
KernelDeimos d128ceed6f fix: handle subpaths under another user 2024-06-15 22:39:47 -04:00
KernelDeimos 19a5eb0076 feat: add readdir delegate for sharing user homedirs 2024-06-15 22:39:47 -04:00
KernelDeimos 8424d44609 feat: add readdir delegate for shares in a user directory 2024-06-15 22:39:47 -04:00
KernelDeimos 1166e69c76 fix: remove last component when share URL is file 2024-06-15 22:39:47 -04:00
KernelDeimos 079e25a9fe feat: add /show urls 2024-06-15 22:39:47 -04:00
KernelDeimos 5d214c7b52 feat: add /share/file-by-username endpoint 2024-06-15 22:39:47 -04:00
Nariman Jelveh 1859668257 Add proper handling of the close event handler in UINotification 2024-06-15 17:28:11 -07:00
KernelDeimos 7015cfcd31 chore: update doc too 2024-06-15 19:26:08 -04:00
KernelDeimos d5d987ead6 chore: fix typo because acknowledge is not spelled awknowledge in any variant of the english language 2024-06-15 19:25:09 -04:00
KernelDeimos 6f333bf262 doc: update notification doc 2024-06-15 19:13:11 -04:00
KernelDeimos 5f5bd6bd24 doc: add notification documentation 2024-06-15 18:59:32 -04:00
KernelDeimos 20542b0565 tweak: update notification format 2024-06-15 18:59:32 -04:00
KernelDeimos ef8f4de962 tweak: use timestamps to track notif awks 2024-06-15 18:59:32 -04:00
KernelDeimos f06cb30447 tweak: set limit to 200 for notification select 2024-06-15 18:59:32 -04:00
KernelDeimos c5334b0e19 feat: introduce notification selection via driver 2024-06-15 18:59:32 -04:00
KernelDeimos d5cbc24cfe chore: update lint config 2024-06-15 18:59:32 -04:00
KernelDeimos 0101f425d4 feat: add mark-read endpoint 2024-06-15 18:59:32 -04:00
KernelDeimos 02fc4d86b7 feat: re-send unreads on login 2024-06-15 18:59:32 -04:00
KernelDeimos a1e6887bf9 feat: add service for notifications 2024-06-15 18:59:32 -04:00
Nariman Jelveh 7e13ab16c9 Update style.css 2024-06-15 14:24:16 -07:00
KernelDeimos a623c94728 tweak: set app/subdomain query limit very high 2024-06-15 16:41:51 -04:00
KernelDeimos ba58c3fbeb Add a debug logger for backend 2024-06-15 16:02:07 -04:00
Nariman Jelveh 7b724ff1eb show the "Close All" button on multiple notifications 2024-06-15 13:01:33 -07:00
Nariman Jelveh b74315c7f5 add "fade up?!" animation to disappearing notifications 2024-06-15 12:31:14 -07:00
Nariman Jelveh e18766a651 Add support for value and click options to UINotification 2024-06-15 12:02:09 -07:00
Nariman Jelveh 9ecd5170e7 Merge branch 'main' of https://github.com/HeyPuter/puter into main 2024-06-15 11:31:39 -07:00
Nariman Jelveh 82c60414b9 Add support for icon, title, and text in notifications 2024-06-15 11:31:26 -07:00
KernelDeimos 502c9a36c7 chore: cleanup console log in BroadcastService 2024-06-15 13:53:53 -04:00
Nariman Jelveh 40c0ef4567 reimplement stacked notifications 2024-06-15 01:28:35 -07:00
Nariman Jelveh 5a47ba4110 Update UIDesktop.js 2024-06-15 01:02:14 -07:00
Nariman Jelveh f047c6b738 implement naive notification stacking 2024-06-15 01:01:29 -07:00
KernelDeimos e77c5f8bbc chore: update lint config 2024-06-14 23:22:23 -04:00
KernelDeimos 6c20ababfb chore: sync package.json 2024-06-14 23:17:58 -04:00
KernelDeimos 1207a158bd feat: add cross-server event broadcasting 2024-06-14 23:17:58 -04:00
KernelDeimos 3ae0773ce8 chore: revive static-assets (for now) 2024-06-14 23:06:38 -04:00
Eric Dubé d6d6fb0c37 Update build-and-test.yml 2024-06-14 22:42:19 -04:00
KernelDeimos 2cc1c5ac6c chore: fix linter errors 2024-06-14 22:01:31 -04:00
Nariman Jelveh 981066c4a1 Refactor helpers.js 2024-06-14 16:38:07 -07:00
Nariman Jelveh cb60759687 Fix html encode/decode issue in item rename 2024-06-13 11:46:54 -07:00
Nariman Jelveh cf08244b6f Enable keyboard navigation in the menubar 2024-06-13 00:05:48 -07:00
Nariman Jelveh 0c4728fbc1 Refactor 2024-06-12 21:41:02 -07:00
Nariman Jelveh 72641c66a2 Support the modification of individual items withing a menu bar 2024-06-12 19:18:24 -07:00
KernelDeimos cdff12e4e0 Remove repo links from Phoenix shell init 2024-06-12 01:50:13 -04:00
KernelDeimos dfdf1dd973 chore: appease linter so it stops ruining my index 2024-06-11 22:46:11 -04:00
KernelDeimos d38bf63f8e Get rid of old typo'd debug log 2024-06-11 13:57:25 -04:00
KernelDeimos 8e0f150fab Fix ESM-interop issue 2024-06-11 13:57:03 -04:00
KernelDeimos 684b0dc059 Support configurable mod locations 2024-06-10 03:02:17 -04:00
KernelDeimos 8d22276f13 fix(backend): remove a bad thing that really doesn't work 2024-06-09 14:21:07 -04:00
KernelDeimos b85cb50ea2 tweak: update eslint config 2024-06-09 13:14:48 -04:00
KernelDeimos 431b0da027 tweak: fix package-lock.json
Using npm install appears to have different results depending on whether
or not the parent directory of the puter repository happens to have a
package.json file (ex: nested workspaces).
2024-06-09 13:14:48 -04:00
KernelDeimos eb05fbd2dc feat: add external mod loading
A package called "useapi" is introduced to provide a dynamic import
system. This import system, rather than relying on the state of the
filesystem, is populated as modules are installed into Puter's kernel.

The "useapi" package is then used to add support for loading external
mod directories as Puter kernel modules, making it possible to mod puter
without any tooling.
2024-06-09 13:14:48 -04:00
Eric Dubé fa7bec3854 refactor: flatten the monorepo 2024-06-08 01:07:42 -04:00
KernelDeimos f88c4a5c9c doc(backend): document modules, services, and service-scripts 2024-06-06 20:10:23 -04:00
Ben Hählen 6ef283d7ef Docker CI - Update actions (#460)
* Update docker-image.yaml

* Update docker-image.yaml

* Update docker-image.yaml

* Update docker-image.yaml

* Update docker-image.yaml

* Create Docker on Tag and push on main
2024-06-06 16:41:19 -04:00
Nariman Jelveh 5e9617f6cc Add support for ContextMenu icons via Puter.js 2024-06-05 14:39:52 -07:00
KernelDeimos 30550fcddd feat(backend): add script service
The script service allows other services to register re-runnable tasks
called "scripts". These can be invoked via "script:run" in the console.
2024-06-05 16:17:03 -04:00
Nariman Jelveh 1416807c9d Merge pull request #454 from eltociear/patch-3
chore: update UI.js
2024-06-05 10:39:43 -07:00
KernelDeimos 41f378e403 Somehow this got lost earlier 2024-06-04 16:53:29 -04:00
KernelDeimos 0b0707363c Fix potential race condition 2024-06-04 16:28:53 -04:00
Nariman Jelveh 04fefc0761 Update README.md 2024-06-04 13:07:02 -07:00
Ikko Eltociear Ashimine de974f0551 chore: update UI.js
occured -> occurred
2024-06-05 01:17:23 +09:00
Eric Dubé aec5cd5148 Merge pull request #451 from HeyPuter/eric/drivers-1
refactor(backend): de-couple driver registration from DriverService
2024-06-03 18:11:53 -04:00
Eric Dubé 2a2a42c153 Merge pull request #424 from AtkinsSJ/sed
Actually parse sed scripts
2024-06-03 12:22:15 -04:00
Nariman Jelveh 66639ea110 Merge pull request #449 from wamynobe/main
fix: fix typo
2024-06-03 00:50:31 -07:00
Nariman Jelveh 1ae82b3210 turns out ESLint is garbage 2024-06-02 16:30:29 -07:00
Nariman Jelveh a81f461b54 Implement the contextMenu API for Puter.js 2024-06-02 16:15:35 -07:00
Nariman Jelveh cf8a07286a Fix typo sanitizeItems to sanitize_items 2024-06-02 10:23:41 -07:00
Nariman Jelveh 6efff83616 Support separator in the setMenubar API 2024-06-02 10:21:11 -07:00
Nariman Jelveh 233a2719c6 Add temp-email driver implementation to the SDK 2024-06-01 16:34:37 -07:00
Nariman Jelveh 49f61c4782 Update UIContextMenu.js 2024-06-01 15:56:32 -07:00
KernelDeimos 665b2d4e4e refactor(backend): de-couple driver registration from DriverService 2024-06-01 18:20:27 -04:00
Mason Nguyen ce328b7245 fix: fix typo 2024-06-01 11:00:03 +07:00
Eric Dubé 135b5eccc5 Merge pull request #448 from HeyPuter/eric/log-update
feat(backend): improve logger and reduce logs
2024-05-31 20:38:10 -04:00
KernelDeimos 2d8e6240c6 feat(backend): add tip of day 2024-05-31 20:36:14 -04:00
KernelDeimos 4bdad75766 feat(backend): improve logger and reduce logs 2024-05-31 19:40:13 -04:00
KernelDeimos 522664d415 feat(backend): allow services to provide user properties 2024-05-31 18:10:11 -04:00
KernelDeimos 71e2310fa4 tweak(ui): expose UIAlert to service scripts 2024-05-31 18:09:15 -04:00
KernelDeimos d2b37fc436 tweak(ui): fix NotifCard accessing on_click 2024-05-31 18:03:45 -04:00
Nariman Jelveh e6e058c0a0 Update UIContextMenu.js 2024-05-31 10:58:18 -07:00
Sam Atkins 6de4c89c25 refactor(phoenix): Combine similar sed command classes
These make more sense combined into one Command which is controlled by
constructor parameters:

- b, t and T
- d and D
- g and G
- h and H
- p and P
2024-05-31 15:49:32 +01:00
Sam Atkins 0d4f907b66 feat(phoenix): Implement parsing of sed scripts
Sed is now finally able to actually run scripts, instead of ignoring all
input and running a hard-coded test script!
2024-05-31 15:49:32 +01:00
Sam Atkins e047b0bf30 fix(phoenix): Add missing newlines to sed command output 2024-05-31 15:49:32 +01:00
Sam Atkins f250f86446 feat(phoenix): Add --dump and --file options to sed 2024-05-31 15:49:32 +01:00
Sam Atkins 4067c82486 feat(phoenix): Expose parsed arg tokens to apps that request them
Some shell apps care about what order the arguments appear in. When
`parseArgs()` is called with `tokens: true`, it produces this `tokens`
array which represents all the command line options and arguments, in
order, which is useful for these more advanced cases.
2024-05-31 15:49:32 +01:00
Sam Atkins 306014adc7 feat(phoenix): Add more commands to sed, including labels and branching
This is ported over from an old forgotten branch I'd deleted, then
thankfully managed to dig up again. 😅

Instead of making GroupCommand contain child commands, use a flat array
for commands and implement groups as GroupStartCommand and
GroupEndCommand. This makes it much simpler to iterate the commands
list in order to jump to labels.

Then implement those labels and the commands that use them: b, t, and T.

Also add the s SubstituteCommand, and combine the code for the q and Q
commands.
2024-05-31 15:49:32 +01:00
Sam Atkins 6aae8fc63b refactor(phoenix): Split up sed code
Let's organise this a bit.
2024-05-31 15:49:32 +01:00
Sam Atkins 9b4d16fbe9 fix(parsely): Make Repeat parser work when no separator is given 2024-05-31 15:49:32 +01:00
Sam Atkins d46b043c5d feat(parsely): Add stringUntil() parser
The counterpart of stringOf(), it reads characters until it matches its
parameter.
2024-05-31 15:49:32 +01:00
Sam Atkins 5656d9d42f feat(parsely): Add a fail() parser
I've found this useful for stubbing out parts of a grammar during
development.
2024-05-31 15:49:32 +01:00
Nariman Jelveh c9a43ce5c0 Update UIContextMenu.js 2024-05-30 18:16:32 -07:00
Nariman Jelveh 7c8492ba43 Fix the issue of checkmark's wrong color in ctx menu disabled items on hover 2024-05-30 17:09:18 -07:00
Nariman Jelveh 16d5ac6abb Delay opening the submenu for smoother mouse navigation on the menu 2024-05-30 15:24:50 -07:00
Nariman Jelveh a8515e0a41 Switch font to Inter 🎉 2024-05-30 15:14:25 -07:00
KernelDeimos fccabf1bc0 feat(backend): allow services to provide whoami values 2024-05-30 17:11:06 -04:00
Eric Dubé dd1d129693 Merge pull request #444 from HeyPuter/eric/ui-updates
UI Updates
2024-05-30 16:48:28 -04:00
KernelDeimos 124596058a feat(ui): allow component-based settings tabs 2024-05-30 16:14:32 -04:00
KernelDeimos be38df32ec tweak(ui): allow setting render more for JustHTML 2024-05-30 16:14:32 -04:00
KernelDeimos 577bd59b6c feat(ui): add new components
This commit adds the following components:
- ActionCard
- Frame
- NotifCard
2024-05-30 16:14:32 -04:00
KernelDeimos f8780d032b fix(ui): improve Component base class
The following improvements were made:
- do not require empty object in constructor
- allow components to override render mode based on constructor values
- improve error handling in get()
- allow array of property names in on_ready()->listen()
- allow components to be attached to shadow roots
2024-05-30 16:07:16 -04:00
KernelDeimos 38ba42575c feat(ui): add new components
This commit adds the following components:
- Glyph
2024-05-30 16:04:52 -04:00
Nariman Jelveh 60f0ade3c1 Improve the UX of the menubar and context menu 2024-05-30 13:02:00 -07:00
KernelDeimos 8e083d20d2 tweak(ui): allow size changing on spinner 2024-05-30 15:59:05 -04:00
Eric Dubé a62a56fd7b Merge pull request #413 from AtkinsSJ/extract-posix-error
refactor: Move PosixError class where it can be accessed outside of Phoenix
2024-05-30 12:43:41 -04:00
Eric Dubé 895358e6e5 Merge pull request #423 from AtkinsSJ/parsely
Tidy up "newparser" so it can be used properly
2024-05-30 12:42:03 -04:00
Eric Dubé d57980c6cb Merge pull request #421 from AtkinsSJ/exit-status
Add exit status codes to `puter.exit()`, and an `exit` builtin to Phoenix
2024-05-30 12:28:36 -04:00
Eric Dubé 0672562c8a Merge pull request #442 from HeyPuter/eric/extensibility
class registry for service scripts
2024-05-28 20:10:03 -04:00
KernelDeimos d047abf31c Update eslint 2024-05-28 19:06:00 -04:00
KernelDeimos e050506a05 Add class registry (second pass)
ExportService gets removed and instead a global class registry is added.
The `init.js` file is split into `init_sync.js` and `init_async.js`
so that synchronous code that isn't dependent on imports is guarenteed
to run before initgui.js. The globalThis scope and service-script API
now expose `def`, a function for registering class definitions, and
`use`, a function for obtaining registered classes.
2024-05-28 19:06:00 -04:00
KernelDeimos cd574c87ef Fix the previous fix 2024-05-28 16:10:43 -04:00
KernelDeimos 4e3a24e609 fix: check subdomain earlier for /apps 2024-05-28 15:51:22 -04:00
Eric Dubé c495ccff65 Merge pull request #408 from AtkinsSJ/git-client
Add a git client
2024-05-28 12:10:01 -04:00
KernelDeimos 51bac4486f Add class registry (first pass)
In the first pass I add a `register` method and update `defineComponent`
so it calls `register` as well. This made it possible to create a
proof-of-concept for registered classes. Additionally ExportService was
added to expose registered classes to service scripts. This first pass
works, but it would be better if all types of classes (components or
otherwise) were registered via the same method.
2024-05-27 21:16:50 -04:00
Eric Dubé 146ce659e2 Merge pull request #434 from HeyPuter/eric/get-user-service
refactor: add GetUserService
2024-05-26 00:44:03 -04:00
KernelDeimos c0cb1cd2b8 refactor: add GetUserService 2024-05-26 00:31:51 -04:00
Eric Dubé f4d41891d9 Merge pull request #426 from HeyPuter/eric/service-scripts
refactor(gui): add service scripts
2024-05-25 17:35:55 -04:00
KernelDeimos 06f41659f5 Add function to import UIWindow from service scripts 2024-05-25 17:20:22 -04:00
KernelDeimos cbfad2ef7a refactor(gui): add service scripts 2024-05-24 19:29:07 -04:00
Eric Dubé 8de94d3f1c Merge pull request #422 from HeyPuter/eric/gui-loading
GUI loading refactor + service-registered gui scripts
2024-05-24 17:42:14 -04:00
Eric Dubé f20870544d Update docker-image.yaml 2024-05-24 16:53:13 -04:00
Eric Dubé 4d91ef14f4 Update docker-image.yaml 2024-05-24 16:49:43 -04:00
Eric Dubé 6ed9f0a01d Update docker-image.yaml 2024-05-24 16:41:20 -04:00
Eric Dubé 94e9f8fd34 Update docker-image.yaml 2024-05-24 16:37:01 -04:00
Eric Dubé fc51424f86 Merge pull request #332 from HeyPuter/release-please--branches--main--components--puter.com
chore(main): release 1.0.0
2024-05-24 16:25:34 -04:00
github-actions[bot] 5146dc4981 chore(main): release 2.3.0 2024-05-24 16:22:55 -04:00
Sam Atkins 03123faa8a Finish concept JSON parser
This now can parse JSON correctly in various configurations.
2024-05-24 16:23:26 +01:00
Sam Atkins 7fccf79591 Make stringOf() take a callback instead of an array of accepted values
THe `a.stringOf(' \r\n\t'.split('')),` pattern works fine for small sets
of characters, but is horrible for situations like "any alphanumeric".
Instead, let's make it take a callback function that is run on each
character.
2024-05-24 16:23:26 +01:00
Sam Atkins d3dff8c20e Throw errors if parsing fails
Not consuming all input is now treated as an error, unless the
`must_consume_all_input` flag is set to false when parsing.
2024-05-24 16:23:26 +01:00
Sam Atkins 0bc4c3fde2 Move StringStream into Parsely 2024-05-24 16:23:26 +01:00
Sam Atkins 873dee7e51 Implement 'trailing' parameter for repeat() parser 2024-05-24 13:30:45 +01:00
Sam Atkins 837ec68371 Reorganize and document Parsely classes
- lib.js only holds Parser so rename it parser.js
- Move Symbol and None into terminals.js
- Briefly document all parser classes
2024-05-24 12:26:04 +01:00
Sam Atkins f8525c6f6c Rename newparser to Parsely
We're going to actually use this so let's give it a more permanent name.
2024-05-24 11:48:34 +01:00
KernelDeimos a1cfe7aef2 Allow services to register additional js files for gui 2024-05-23 18:41:34 -04:00
KernelDeimos 5042d49935 Simplify debugging runtime config object changes 2024-05-23 18:40:41 -04:00
KernelDeimos c89b50bf31 Refactor gui loading 2024-05-23 18:13:57 -04:00
Nariman Jelveh 103f9d209d Update README.md 2024-05-23 14:32:24 -07:00
KernelDeimos 4508bfac73 Fix cookie issue 2024-05-23 13:30:02 -04:00
Sam Atkins 3184d3482c feat(phoenix): Implement an exit builtin 2024-05-23 15:27:15 +01:00
Sam Atkins 5de3052026 feat(phoenix): Respond to exit status codes
- Detect exit status of Puter apps, now that that's available.
- Store the exit status of each pipeline.
- Display a message when the exit status was non-zero.

That message is temporary, until we have a better way of displaying or
querying it, such as the `$?` shell variable.
2024-05-23 15:26:43 +01:00
Sam Atkins 7674da4cd2 feat: Add exit status code to apps
`puter.exit()` now takes a status code, similar to the exit status on
desktop OSes. This is passed to the appClosed event, so that eg a
parent app can know whether its child app ran successfully.
2024-05-23 12:54:06 +01:00
Eric Dubé b15dc316d3 Merge pull request #406 from AtkinsSJ/fs-upload-data-type-error
Explicitly reject invalid types for puter.fs.upload() and .write() payloads
2024-05-22 12:13:24 -04:00
Sam Atkins 10f715f726 Implement git show 2024-05-22 16:00:42 +01:00
Sam Atkins 0377015190 Implement git config
This is also basic:

git config key             # To read a value
git config key value       # To set a value
git config --unset key     # To delete a value

As noted, --list is not possible to implement currently.
2024-05-22 16:00:42 +01:00
Sam Atkins 98c33fb3cc Implement git log
This is quite barebones for now.

Commit formatting is done in a separate file, as this is used by other
git commands, such as `show`.
2024-05-22 16:00:42 +01:00
Sam Atkins b4e2ba4544 Implement git commit 2024-05-22 16:00:42 +01:00
Sam Atkins 32c172d145 Implement git add 2024-05-22 16:00:42 +01:00
Sam Atkins 5a308a2a53 Implement git status 2024-05-22 16:00:42 +01:00
Sam Atkins 71873a9c27 Add a helper function for finding the git repo 2024-05-22 16:00:42 +01:00
Sam Atkins 5e3db870ec Implement git init 2024-05-22 16:00:42 +01:00
Sam Atkins 85b7587c42 Implement git help, git version, and subcommand infrastructure
Each subcommand is its own file, modeled after Phoenix's coreutils.
2024-05-22 16:00:42 +01:00
Sam Atkins b75c42b39f Implement Puter filesystem wrapper for git app 2024-05-22 08:56:50 +01:00
Sam Atkins 0d2ffdb380 Add boilerplate for empty git app
It does nothing but output a message to the console.
2024-05-22 08:56:50 +01:00
Sam Atkins 8f1c4fcda9 feat(Phoenix): Pass command line arguments and ENV when launching apps 2024-05-22 08:56:50 +01:00
Sam Atkins bf33fd752d Remove outdated FIXMEs about consuming extra stdin data 2024-05-22 08:56:50 +01:00
Sam Atkins c08c8bd073 Expose POSIX error name as PosixError.code
This matches the behaviour of Node.JS's errors, and some libraries
expect it.
2024-05-22 08:56:50 +01:00
Sam Atkins 8098dc9dcc Move error-conversion functions into PosixError
Specifically, this makes the Puter->PosixError conversion available to
the in-progress git client.
2024-05-22 08:56:50 +01:00
Sam Atkins e43b21387c Move PosixError into puter-js-common
The in-progress git client also needs to use this. puter-js-common uses
commonjs modules, so it had to be adjusted for that.
2024-05-22 08:56:50 +01:00
KernelDeimos 1f6a2093fb Disallow negative size values 2024-05-21 18:46:34 -04:00
KernelDeimos 90463a0732 Add support for webhook endpoints 2024-05-21 17:25:28 -04:00
Sam Atkins acf7eabef9 Expose POSIX error name as PosixError.code
This matches the behaviour of Node.JS's errors, and some libraries
expect it.
2024-05-20 12:14:22 +01:00
Sam Atkins 017077f8cb Move error-conversion functions into PosixError
Specifically, this makes the Puter->PosixError conversion available to
the in-progress git client.
2024-05-20 12:14:18 +01:00
Sam Atkins e798576a87 Move PosixError into puter-js-common
The in-progress git client also needs to use this. puter-js-common uses
commonjs modules, so it had to be adjusted for that.
2024-05-20 12:11:12 +01:00
Karan Parmar cc45a08388 updated the github links displayed in the Terminal welcome message 2024-05-19 11:52:26 +01:00
KernelDeimos 8cca067991 Fix 8688ha84v 2024-05-17 22:55:40 -04:00
Eric Dubé 80b763c47c Merge pull request #407 from AtkinsSJ/clean-suggested-apps
fix: Remove null or duplicate app entries from suggest_app_for_fsentry()
2024-05-17 15:46:06 -04:00
Eric Dubé 8786024559 Merge pull request #404 from secondtruth/patch-1
Update de.js
2024-05-17 15:42:02 -04:00
Eric Dubé bbb43f53d0 Merge pull request #403 from Zac0511/patch-3
Update fr.js
2024-05-17 15:39:06 -04:00
KernelDeimos 639e40d355 Phoenix shell deployment update 2024-05-17 13:26:44 -04:00
KernelDeimos f964f06f3f Fix 8688h4bwg 2024-05-17 13:05:13 -04:00
KernelDeimos e4543c5f35 Fix 8688ggu00 (2) 2024-05-17 12:32:16 -04:00
Sam Atkins 6900233c5a fix: Remove null or duplicate app entries from suggest_app_for_fsentry() 2024-05-17 15:34:36 +01:00
Sam Atkins 03fe3b6a0d Reject invalid types for puter.fs.upload() items or .write() data
Previously, this would crash in upload() when trying to iterate the
`entries` array, which is undefined when the `items` parameter is an
unsupported type.
2024-05-17 14:39:31 +01:00
Sam Atkins a9c89cef19 refactor: Reduce boilerplate for returning errors from puter.fs.upload() 2024-05-17 14:39:31 +01:00
Zac0511 340b9202c0 Update fr.js 2024-05-17 14:36:54 +02:00
Zac0511 99ca8755f3 Update fr.js 2024-05-17 14:22:22 +02:00
Zac0511 eaf1e96fa2 Update fr.js 2024-05-17 14:19:19 +02:00
Zac0511 f9b5353058 Update fr.js 2024-05-17 14:15:49 +02:00
Zac0511 e0af914c90 Update fr.js 2024-05-17 14:00:43 +02:00
Zac0511 8f19f4dc5b Update fr.js
Complete rework of the file, completly remade from en.js
2024-05-17 13:58:33 +02:00
Zac0511 5f47e7f0fa Update fr.js
Bug repairing... again
2024-05-17 09:55:25 +02:00
Zac0511 9c39b0453d Update fr.js
Little update for some bugs
2024-05-17 09:16:12 +02:00
Zac0511 545fc103b8 Update fr.js
Complete rework of the file for the latest updates
2024-05-17 09:10:55 +02:00
KernelDeimos c55b1e4680 Remove verification requirement on contact us form 2024-05-16 19:08:51 -04:00
Eric Dubé 297db58e68 Merge pull request #405 from HeyPuter/eric/path-builder
Add path builder
2024-05-16 19:08:56 -04:00
KernelDeimos e3f57ee20e Add path builder 2024-05-16 19:02:58 -04:00
KernelDeimos 5031cea040 Update _default.js for deployment purposes 2024-05-16 18:55:59 -04:00
Eric Dubé 6fe126ad5a Merge pull request #386 from HeyPuter/eric/socket-auth
fix(security): Move token for socket.io to request body
2024-05-16 18:02:12 -04:00
KernelDeimos 49b257ecff fix(security): Move token for socket.io to request body
Currently this commit breaks websocket events and needs to
be updated.
2024-05-16 17:58:44 -04:00
KernelDeimos f042b095f1 Fix 8688gxkuj 2024-05-16 17:25:41 -04:00
Christian Neff 43d0936533 Update de.js
Translated:
- 2FA strings
- Task Manager strings
- 2 other scattered strings
2024-05-16 19:51:42 +02:00
KernelDeimos b68873c5f4 Fix 8688grpf1 2024-05-16 12:48:57 -04:00
Zac0511 e1ae9241af Update fr.js 2024-05-16 18:27:12 +02:00
Zac0511 b6ea37c517 Update fr.js
Since there was a lot of text and menus added, and they were not translated, so i just translated them.
2024-05-16 18:06:21 +02:00
KernelDeimos bee0e19eaf Fix 8688ggu00 2024-05-15 20:59:20 -04:00
Eric Dubé f54657a569 Merge pull request #402 from HeyPuter/eric/email-lock
Add locking to save_account
2024-05-15 18:49:03 -04:00
Eric Dubé 1aa27084d0 Merge pull request #396 from AtkinsSJ/xterm-fix
fix(Terminal): Accept input from Chrome on Android
2024-05-15 18:24:02 -04:00
KernelDeimos 691c8f1436 Add locking to save_account 2024-05-15 18:22:54 -04:00
Eric Dubé b72e5b7e02 Merge pull request #401 from HeyPuter/eric/service-patches
Allow patching services
2024-05-15 15:47:14 -04:00
KernelDeimos c70e378973 Add error id for expired auth tokens 2024-05-15 15:42:00 -04:00
KernelDeimos 21444daefb Add jsdoc comments to registerService and patchService 2024-05-15 15:41:37 -04:00
KernelDeimos 2e0d7361cb Add method to patch services 2024-05-15 15:32:18 -04:00
Eric Dubé 6e0b6d84d2 Merge pull request #400 from AtkinsSJ/fix-apierror-includes
fix: Correct APIError imports
2024-05-15 13:51:04 -04:00
Eric Dubé ec59abe3ae Merge pull request #399 from AtkinsSJ/fix-db-scripts
fix: Add missing file extension to 0009_app-prefix-fix.sql in DB init
2024-05-15 13:45:30 -04:00
Sam Atkins 062e23b5c9 fix: Correct APIError imports
APIError is the only thing exported from its file, so we must not wrap
it in {}.
2024-05-15 17:47:15 +01:00
Sam Atkins a8160a8cdc fix: Add missing file extension to 0009_app-prefix-fix.sql in DB init 2024-05-15 10:18:28 +01:00
KernelDeimos 0b093dd57e Revoke other sessions when password is changed 2024-05-14 19:40:57 -04:00
KernelDeimos 923d5878c3 Prevent enable of 2FA without configure 2024-05-14 17:33:14 -04:00
Eric Dubé 9c5849fbce Merge pull request #397 from HeyPuter/eric/anti-csrf
Update for /logout
2024-05-14 14:08:35 -04:00
Sam Atkins 4ef3e53de3 fix(Terminal): Accept input from Chrome on Android
Xterm.js produces two kinds of events: onKey and onData. On a desktop,
these are effectively the same, but on mobile, IME inputs produce data
but not key presses. By listening to onData instead of onKey, we get
that input.

With some experimentation, I also found that we don't need the code to
handle enter, home, end, or Ctrl-Shift-V. All of these function as
expected without that code, so we can remove it and simplify this
further. :^)
2024-05-14 16:10:30 +01:00
Sam Atkins 2656b47640 chore: Update xterm
From version 5.4.0 onwards, xterm scopes its package names as
`@xterm/foo` instead of just `xterm-foo`.

We currently have a copy of xterm.css which we use instead of directly
including the one from the `@xterm/xterm` package, so I've updated the
contents of that too.
2024-05-14 16:10:30 +01:00
Sam Atkins fafbc292ca Remove xterm dependency from Phoenix
This is used by Terminal, not Phoenix.
2024-05-14 16:10:30 +01:00
KernelDeimos 800aef1942 Implement anti-CSRF for logout 2024-05-13 20:40:27 -04:00
KernelDeimos da7f73baa6 Add AntiCSRFService 2024-05-13 19:08:51 -04:00
KernelDeimos afb9d866b5 fix: Fix phoenix app prefix and TokenService test 2024-05-13 18:17:39 -04:00
Eric Dubé 7dc5929cfd Merge pull request #385 from HeyPuter/eric/dry-middleware
Add password requirement to: disable 2FA, change email
2024-05-13 16:38:59 -04:00
KernelDeimos c2f1694107 Require password entry to disable 2FA 2024-05-13 16:00:07 -04:00
KernelDeimos 23215bd6f7 Move change_email/start to password-protected endpoint 2024-05-13 16:00:07 -04:00
KernelDeimos 1493cacb69 Add rate-limiting to new password change endpoint 2024-05-13 16:00:07 -04:00
KernelDeimos 9076fddc0d Add new password change endpoint 2024-05-13 16:00:07 -04:00
KernelDeimos a89c9d59cf Add UserProtectedEndpointsService 2024-05-13 16:00:07 -04:00
KernelDeimos 15dec21118 doc(backend): Document the boot sequence
Now that the boot sequence is better formalized it may be documented.
2024-05-13 16:00:07 -04:00
KernelDeimos d800b12569 refactor(backend): Trigger webserver events in webserver
We were triggering webserver events in Kernel. This change improves
adherence to separation-of-concerns and ensures event cascading is
working as expected. This also better formalizes the boot sequence.
2024-05-13 01:05:49 -04:00
Eric Dubé 89ac491120 Merge pull request #391 from AtkinsSJ/truncate-filename
refactor: Put truncate_filename() helper in its own file
2024-05-10 12:54:46 -04:00
Eric Dubé 981a0f08fe Merge pull request #390 from AtkinsSJ/task-manager-components
refactor: Convert Task Manager to Components
2024-05-10 12:54:30 -04:00
Sam Atkins e53bfe6b62 refactor: Put truncate_filename() helper in its own file
Every user previously set the max_length as window.TRUNCATE_LENGTH, so
I've moved that constant into the truncate_filename file and set it as
the default if max_length is not specified.
2024-05-10 17:46:09 +01:00
Sam Atkins 9bb4570126 Re-use existing Task Manager rows if possible instead of recreating them
Most of the time, we'll already have a TaskManagerRow for the given
process, so we can just update its properties.

Iterating the results from #iter_tasks means we also insert the rows in
the correct order, regardless of their previous order.
2024-05-10 17:41:13 +01:00
Sam Atkins 5b43358219 fix: Only run Component initialization functions once
If the Component gets removed from the DOM and then re-added, it already
has contents, and we don't need to create them again. It also has
already had on_ready called, so that doesn't need to happen again
either.

This fix stops Components duplicating their content elements and
listener callbacks whenever they're moved around the document.
2024-05-10 17:41:01 +01:00
Sam Atkins cf605c8a38 refactor: Convert Task Manager to use Components
This currently behaves the same as it did before: It still recreates the
table contents every half a second. It should also look identical,
though it's possible I missed some small differences.

The component structure is:

TaskManagerTable
- Table
  - TaskManagerRow
  - TaskManagerRow
  - TaskManagerRow
  - ...

TaskManagerRow is implemented so that we can later move to modifying
them in place as the process tree changes, instead of having to replace
them all.

Otherwise, most of the code is just moved around, and not changed much.
2024-05-10 17:41:01 +01:00
Sam Atkins e304f6fc3a Add ability to look up a process by its uuid 2024-05-10 17:38:00 +01:00
Sam Atkins 09cee986f2 Add a Table component, based on the TaskManager table
For now, this is quite basic. The main feature is the sticky header.
2024-05-10 17:38:00 +01:00
Eric Dubé 3992fe1a45 Merge pull request #384 from AtkinsSJ/progress-dialogs
refactor: Replace several existing progress dialogs with one configurable one
2024-05-10 12:25:32 -04:00
Eric Dubé 17e08cafce Merge pull request #380 from AtkinsSJ/eslint-ci
Run ESLint on CI
2024-05-10 12:24:31 -04:00
Sam Atkins 7243ed718f Merge pull request #388 from AtkinsSJ/no-docker-images-for-prs
ci: Stop producing Docker images for PRs
2024-05-10 09:39:31 +01:00
Sam Atkins 387cfd758f Merge pull request #387 from ghostxbh/patch-1
fix: Eliminates duplicate translation keys
2024-05-10 09:31:52 +01:00
Sam Atkins c75a0bd311 ci: Wrap Docker images name with quotes
Not sure if this is required, but my IDE was complaining about it.
2024-05-10 09:29:49 +01:00
Sam Atkins 18633dcd88 ci: Stop producing Docker images for PRs 2024-05-10 09:28:55 +01:00
ghostxbh 5800350b25 fix: Eliminates duplicate translation keys 2024-05-10 10:41:21 +08:00
KernelDeimos cd2daa1910 Require email verification for contact form 2024-05-09 19:40:34 -04:00
KernelDeimos 8b6bbe003d fix(security) Disable 2FA configure if 2FA is enabled 2024-05-09 18:04:58 -04:00
Sam Atkins edebbee9e7 feat: Display upload errors in UIWindowProgress dialog
The object returned from UIWindowProgress() now has a `show_error()`
method, taking a title and message. Calling it will replace the content
of the window with those messages.

I've made use of this for file uploads. The only other place we
currently have errors we could show is for zipping and downloading
files, but we do not always have a progress dialog in that case, so I'll
leave that for now.

I think ideally, we would always create a progress dialog, and it would
then support being invisible initially, but appearing after a delay.
Then we'd always have an object to call `show_error()` on, and it could
then immediately show the dialog. But I'll get to that another day. :^)
2024-05-09 19:00:55 +01:00
Sam Atkins f3269693de Stop dumping binary data to the console
This was freaking out and freezing the Puter server, and my entire
terminal app. XD
2024-05-09 18:28:39 +01:00
Sam Atkins c2c87bf0ba refactor: Replace UIWindowDownloadDirProg with UIWindowProgress 2024-05-09 18:28:39 +01:00
Sam Atkins e525747002 refactor: Replace UIWindowCopyProgress with UIWindowProgress 2024-05-09 18:28:39 +01:00
Sam Atkins 6d8c709de8 Delete unused UIWindowDownloadProgress.js 2024-05-09 18:28:39 +01:00
Sam Atkins f07c13a50c feat: Show "Deleting /foo" in progress window when deleting files
Previously we showed "Moving /foo" which was confusing.

Also, make use of i18n replacements instead of gluing strings together,
because other languages might put the words in a different order. For
now, I've modified all the translations so that the "Moving foo" text
will appear as it did before, but these will require someone who
actually knows the different languages to check and correct them.
2024-05-09 18:19:05 +01:00
Sam Atkins c12312cbd3 refactor: Replace UIWindowMoveProgress with UIWindowProgress 2024-05-09 18:18:27 +01:00
Sam Atkins cb6c098f95 refactor: Replace UIWindowProgressEmptyTrash with UIWindowProgress
I noticed during this that emptying the trash from inside the Trash
window uses a different code path without a progress dialog, so I've
added a TODO to merge that in. I tried just using it directly but the
behaviour is a bit different. (The Trash one makes all the items fade
out.)
2024-05-09 18:17:15 +01:00
Sam Atkins 09ca82e1d8 refactor: Replace UIWindowNewFolderProgress with UIWindowProgress
This previously had code for the cancel button, but that cancel button
didn't exist. I've left the previous on-cancel code commented out with
a TODO.
2024-05-09 15:51:45 +01:00
Sam Atkins 5b565a69d7 refactor: Replace UIWindowUploadProgress with UIWindowProgress 2024-05-09 15:51:45 +01:00
Sam Atkins 52ddfc8801 Introduce a general-purpose progress window
We have 7 of these, which all have very similar code. Let's deduplicate
them! :^)
2024-05-09 15:51:45 +01:00
Sam Atkins df3f7e9a6e Allow Button component to not have button-block class
This needs a better solution for configuring the button's CSS classes,
but this works for now.
2024-05-09 12:38:29 +01:00
Sam Atkins 05aaa5b667 chore: Remove dead code from 2FA development
No `.qr-code-checkbox input`s now exist. Also, `.code-confirm-btn` is
only used by CodeEntryView, which doesn't use this Button component.
2024-05-09 12:12:33 +01:00
KernelDeimos df24c663df Invalidate email confirmation on password change 2024-05-08 22:28:41 -04:00
KernelDeimos 45e7f162a2 Add password change notification 2024-05-08 16:01:20 -04:00
Sam Atkins fbda8c8286 Run ESLint on CI
Run the ESLint static analysis tool on any code that is submitted, to
find possible bugs such as undefined functions and variables. We may
want to adjust the ESLint settings over time, but this seems like a
good start.

This is merged into the previous check-translations.yml action, because
that's also a form of linting. Possibly that could be reimplemented as
an ESLint plugin.
2024-05-08 18:53:37 +01:00
Sam Atkins 8c70efa058 Suppress remaining eslint errors
These two seem like bugs but are unclear to me how to fix, so I've added
FIXMEs.

/puter/packages/backend/src/routers/kvstore/clearItems.js
  41:32  error  'DB_MODE_WRITE' is not defined  no-undef

/puter/packages/backend/src/routers/whoami.js
  104:35  error  'db' is not defined  no-undef
2024-05-08 18:53:36 +01:00
Eric Dubé 65b489883d Merge pull request #381 from AtkinsSJ/web-components
Convert UIWindowThemeDialog to components
2024-05-08 12:15:23 -04:00
Sam Atkins 1b2608d6ee refactor: Replace component definition boilerplate with a function
Also, we can ask the CustomElementRegistry if it has an entry with a
given name, instead of polluting the window object.
2024-05-08 14:46:58 +01:00
Sam Atkins 9267b50666 Convert UIWindowThemeDialog to components
This also fixes the "Reset Colors" button not adjusting the sliders.
2024-05-08 14:46:58 +01:00
Sam Atkins 2604dae83c Resolve eslint issues in new 2FA code
/puter/src/UI/Settings/UITabSecurity.js
  13:13  error  'user' is not defined        no-undef
  31:13  error  'user' is not defined        no-undef
  32:70  error  'user' is not defined        no-undef
  36:30  error  'user' is not defined        no-undef
  40:82  error  'user' is not defined        no-undef
  41:83  error  'user' is not defined        no-undef
  87:41  error  'api_origin' is not defined  no-undef

/puter/src/UI/UIWindow2FASetup.js
  39:33  error  'api_origin' is not defined  no-undef
  51:37  error  'api_origin' is not defined  no-undef
  69:37  error  'api_origin' is not defined  no-undef

/puter/src/UI/UIWindowLogin.js
  202:73  error  'api_origin' is not defined  no-undef
  271:73  error  'api_origin' is not defined  no-undef
2024-05-08 09:49:58 +01:00
Sam Atkins 6778aa4343 Resolve eslint issues in Russian translation
/puter/src/i18n/translations/ru.js
  180:34  error  Irregular whitespace not allowed    no-irregular-whitespace
  257:9   error  Duplicate key 'storage_puter_used'  no-dupe-keys
2024-05-08 09:44:31 +01:00
KernelDeimos 5890b7e7bf Disable password reset token when email or password is changed 2024-05-07 20:18:11 -04:00
KernelDeimos d58aa33d2b Remove taskbar items from localstorage 2024-05-07 20:01:05 -04:00
KernelDeimos f62617a8bf Remove auth_token from /down call 2024-05-07 14:29:09 -04:00
KernelDeimos d20249f29a Send email notifications when 2FA state changes 2024-05-06 21:13:00 -04:00
Eric Dubé 0e16a3f3b4 Merge pull request #370 from HeyPuter/eric/2fa
2FA
2024-05-06 19:33:50 -04:00
Nariman Jelveh 5409547bba Make the 2fa disable prompt a child of the Settings window 2024-05-06 16:16:57 -07:00
KernelDeimos db8e2c3bf2 Address next batch of UX issues 2024-05-06 19:09:28 -04:00
KernelDeimos 4c53ec6dd3 Address UX issues 2024-05-06 18:53:43 -04:00
KernelDeimos b2d678ca95 Cleanup dead code 2024-05-06 16:45:03 -04:00
KernelDeimos adbefb4622 Cleanup log messages 2024-05-06 16:44:23 -04:00
KernelDeimos 429b7033a4 Improve error handling for 2FA rate limit 2024-05-06 16:35:35 -04:00
KernelDeimos 7f3e2852c6 Add rate limits 2024-05-06 16:12:54 -04:00
KernelDeimos 57d9c246c0 Fix css in firefox 2024-05-06 15:47:09 -04:00
KernelDeimos 7fce223a6d Fix OTP test endpoint 2024-05-06 15:40:34 -04:00
KernelDeimos abbbf0d030 Add confirmation for disabling 2FA 2024-05-06 15:36:38 -04:00
KernelDeimos a628358c9f Fix OTP time window 2024-05-06 15:02:14 -04:00
KernelDeimos 918eb3bb67 Put otpauth back on 9.2.4 2024-05-06 02:10:22 -04:00
KernelDeimos ecae1997aa Maybe this?? 2024-05-06 01:58:55 -04:00
KernelDeimos e4c7caa8ea Worth a try 2024-05-06 01:54:02 -04:00
KernelDeimos 54d1f05851 Install otpauth in root package.json because that... matters? 2024-05-06 01:48:25 -04:00
KernelDeimos 1592bc44fc Fix spinner getting stuck 2024-05-06 01:30:32 -04:00
KernelDeimos 77fedee58a Remove artifact 2024-05-06 00:13:24 -04:00
KernelDeimos 63e72a22e0 Fix settings card update 2024-05-06 00:02:46 -04:00
KernelDeimos 00c8ece07e Finish recovery codes 2024-05-06 00:02:46 -04:00
KernelDeimos 60a561c84c Re-use CodeEntryView for login 2024-05-06 00:02:46 -04:00
KernelDeimos 5cbe256120 Add missing part of previous commit 2024-05-06 00:02:46 -04:00
KernelDeimos 4ad50b14d6 Fix the duplicate loading issue 2024-05-06 00:02:46 -04:00
KernelDeimos df88373519 Remove test window open 2024-05-06 00:02:46 -04:00
KernelDeimos 099699198c Tweak QR code sizes 2024-05-06 00:02:46 -04:00
Nariman Jelveh 75bd1bc4c8 Update UIWindow2FASetup.js 2024-05-06 00:02:46 -04:00
Nariman Jelveh 12c883b6fd Remove the confirmation prompt when closing the 2FA setup winow
When exiting a window there should be a confirmation if exiting that window will irreversibly destroy work. For example, when you're working on a document and if you exit unsaved changes will be lost.
This doesn't seem to be the case. What work will be irreversibly lost?
2024-05-06 00:02:46 -04:00
Nariman Jelveh 144d647540 Improve styling 2024-05-06 00:02:46 -04:00
Nariman Jelveh c8a6d109ce Add icon for Security tab and warning/success styling for 2fa card 2024-05-06 00:02:46 -04:00
KernelDeimos 5fa3c6511f Fix padding and enable code 2024-05-06 00:02:46 -04:00
KernelDeimos a2a8f9de74 Fix cache state 2024-05-06 00:02:46 -04:00
KernelDeimos d72d83d0f3 Add i18n entries for 2FA setup 2024-05-06 00:02:46 -04:00
KernelDeimos c91c0afa71 Complete the 2FA setup flow 2024-05-06 00:02:46 -04:00
KernelDeimos a95fcc96be Add text components and styling 2024-05-06 00:02:46 -04:00
KernelDeimos f9c5a688b1 Fix code entry focus on init 2024-05-06 00:02:46 -04:00
KernelDeimos e9b8c452b9 Temporarily disable real check for testing 2024-05-06 00:02:46 -04:00
KernelDeimos 3e380ba844 Add otp test endpoint and next wizard step 2024-05-06 00:02:46 -04:00
KernelDeimos 22234ad1c1 Add the wizardy behaviour 2024-05-06 00:02:46 -04:00
KernelDeimos 662fd13548 Add code entry to 2FA wizard 2024-05-06 00:02:46 -04:00
KernelDeimos a672b8a58c Add UIWindow2FASetup 2024-05-06 00:02:46 -04:00
KernelDeimos 6e0cdb8a6b Document 2FA wizard structure 2024-05-06 00:02:46 -04:00
KernelDeimos 0baa678c8b Add Flexer 2024-05-06 00:02:46 -04:00
KernelDeimos c99747d7f2 Make using web components easier 2024-05-06 00:02:46 -04:00
KernelDeimos 2681a78501 Use username as otp label 2024-05-06 00:02:46 -04:00
KernelDeimos 3bf7737790 Add recovery codes 2024-05-06 00:02:46 -04:00
KernelDeimos 455d3946d6 Add checkboxes and cancel action for 2FA setup 2024-05-06 00:02:46 -04:00
KernelDeimos 2dfecb5287 Add 2fa setting and complete login flow 2024-05-06 00:02:46 -04:00
KernelDeimos abc12bd407 Add otp input at login 2024-05-06 00:02:46 -04:00
KernelDeimos bbf352caa4 Add missing package-lock.json changes 2024-05-06 00:02:46 -04:00
KernelDeimos d7c5c37cf8 Implement backend for 2FA 2024-05-06 00:02:46 -04:00
KernelDeimos 038373cbbc Fix filename inconsistency that breaks Linux support 2024-05-06 00:02:33 -04:00
Nariman Jelveh 321520741d Merge pull request #372 from nyedidikeke/naming-convention-patch-1
refactor: nomenclature, typo fixes, IDE and documentation enhancement 🔨
2024-05-05 19:46:16 -07:00
Didi Keke 2c75c636af docs: environment variable configuration 🌱 2024-05-06 01:21:59 +00:00
Didi Keke 01b7e523d0 chore: comment and fine tune .gitignore settings 🔨 2024-05-06 01:18:40 +00:00
Didi Keke 05d4a28adc chore: format content 📝 2024-05-06 01:14:36 +00:00
Didi Keke b89142c45c chore: include .vscode/extensions.json ⚓
- For recommendation of extensions or otherwise.
2024-05-05 20:31:08 +00:00
Didi Keke f9359bfb73 chore: ignore nested folders 🐜 2024-05-05 20:23:05 +00:00
Didi Keke 4d30740198 fix: typographical errors 🐛 2024-05-05 08:34:50 +00:00
Didi Keke 2d6dfd9002 chore: add word spelling dictionary 👼 2024-05-05 08:15:30 +00:00
Didi Keke 3914a14a2a chore: update .gitignore settings for VS Code 🚀
- All files within the `.vscode/` directory are ignored except for `settings.json`, `tasks.json`, and `launch.json`.
2024-05-05 08:11:13 +00:00
Didi Keke 2949f71691 fix: typographical error 🐛 2024-05-05 07:54:11 +00:00
Didi Keke 551121524c refactor: name from SelfhostedModule to SelfHostedModule 🔨 2024-05-05 07:53:55 +00:00
Nariman Jelveh 038c5e9a6e Merge pull request #371 from mafendi/main
Added Russian translation
2024-05-04 17:22:12 -07:00
Efendi 467aabe5ee Update translations.js
Added ru
2024-05-05 00:09:52 +03:00
Efendi 4f73641f46 Add files via upload 2024-05-05 00:07:07 +03:00
Nariman Jelveh 48e97b5ec2 Update UITaskbarItem.js 2024-05-04 12:34:28 -07:00
KernelDeimos a86106c0c1 Fix save_account token 2024-05-04 14:19:09 -04:00
Nariman Jelveh c9f3693785 Merge branch 'main' of https://github.com/HeyPuter/puter into main 2024-05-03 21:32:26 -07:00
Nariman Jelveh 5151863a94 disable context menu on settings sidebar 2024-05-03 21:32:23 -07:00
Nariman Jelveh 16a81cdc7f Merge pull request #369 from nyedidikeke/patch-1
fix: reliability issue 🐛
2024-05-03 21:10:21 -07:00
Nariman Jelveh ebb6cf2a91 clean up console messages and errors 2024-05-03 20:49:12 -07:00
Didi Keke 1d546d9ef7 fix: reliability issue 🐛 2024-05-04 03:23:28 +00:00
Nariman Jelveh 6bef35b406 Fix issue with passive event listeners via jQuery 2024-05-03 20:21:26 -07:00
Nariman Jelveh ecd9d5493f Fix issue with trash not opening from taskbar 2024-05-03 19:57:48 -07:00
Nariman Jelveh 33a6f4c49f quick fix 2024-05-03 16:56:27 -07:00
Nariman Jelveh 3c92cd3198 Update initgui.js 2024-05-03 12:04:38 -07:00
Eric Dubé 4d0e6b4772 Merge pull request #336 from AtkinsSJ/app-tab-completion
Phoenix: Add tab-completion for command names
2024-05-03 12:39:07 -04:00
Eric Dubé ebdf0d9148 Merge pull request #348 from AtkinsSJ/eslint
Set up eslint, and try to resolve the issues it finds
2024-05-03 12:28:21 -04:00
Sam Atkins 44aa4f1b0a chore: Remove debugger calls
/puter/packages/phoenix/src/ansi-shell/arg-parsers/simple-parser.js
  30:38  warning  Unexpected 'debugger' statement  no-debugger

/puter/packages/phoenix/src/ansi-shell/pipeline/Coupler.js
  71:32  warning  Unexpected 'debugger' statement  no-debugger
2024-05-02 17:41:14 +01:00
Sam Atkins fa7c6bee96 fix: Correct variables used in errors in sign.js
I couldn't figure out how to get a name for the no_suitable_app error
unfortunately, so that's just commented out.

/puter/packages/backend/src/routers/sign.js
   65:74  error  'subject' is not defined  no-undef
  114:59  error  'subject' is not defined  no-undef
2024-05-02 17:39:01 +01:00
Sam Atkins fa3b86fa7e chore: Amend empty blocks in upload.js
/puter/packages/puter-js/src/modules/FileSystem/operations/upload.js
   63:22  error  Empty block statement  no-empty
  173:22  error  Empty block statement  no-empty
2024-05-02 17:31:17 +01:00
Sam Atkins 52d5299374 fix: Use correct variable for version number
/puter/packages/backend/src/services/ComplainAboutVersionsService.js
  30:36  error  'current_version' is not defined  no-undef
2024-05-02 17:30:53 +01:00
Sam Atkins 23d959bf64 chore: Clarify usage of window fields in index.js
/puter/src/index.js
  58:15  error  'loadScript' is not defined  no-undef
  59:15  error  'loadScript' is not defined  no-undef
  65:13  error  'gui_env' is not defined     no-undef
  66:15  error  'loadScript' is not defined  no-undef
  68:15  error  'loadCSS' is not defined     no-undef
  69:15  error  'loadScript' is not defined  no-undef
  73:5   error  'initgui' is not defined     no-undef
2024-05-02 17:26:41 +01:00
Sam Atkins 5198081c2b chore: Fix eslint issues in initgui.js
Almost entirely clarifying use of window fields

/puter/src/initgui.js
    82:28   error  'api_origin' is not defined                                   no-undef
   118:34   error  'url_query_params' is not defined                             no-undef
   120:17   error  'app_query_params' is not defined                             no-undef
   136:8    error  'url_query_params' is not defined                             no-undef
   136:51   error  'url_query_params' is not defined                             no-undef
   136:105  error  'url_query_params' is not defined                             no-undef
   138:14   error  'url_query_params' is not defined                             no-undef
   138:57   error  'url_query_params' is not defined                             no-undef
   138:110  error  'url_query_params' is not defined                             no-undef
   154:8    error  'url_query_params' is not defined                             no-undef
   154:54   error  'url_query_params' is not defined                             no-undef
   154:110  error  'url_query_params' is not defined                             no-undef
   164:17   error  'openerOrigin' is not defined                                 no-undef
   171:30   error  'openerOrigin' is not defined                                 no-undef
   173:37   error  'is_auth' is not defined                                      no-undef
   184:23   error  'getUserAppToken' is not defined                              no-undef
   184:39   error  'openerOrigin' is not defined                                 no-undef
   186:41   error  'is_auth' is not defined                                      no-undef
   195:23   error  'getUserAppToken' is not defined                              no-undef
   195:39   error  'openerOrigin' is not defined                                 no-undef
   205:8    error  'url_query_params' is not defined                             no-undef
   206:32   error  'url_query_params' is not defined                             no-undef
   218:23   error  'url_query_params' is not defined                             no-undef
   219:22   error  'openerOrigin' is not defined                                 no-undef
   219:38   error  'url_query_params' is not defined                             no-undef
   220:26   error  'url_query_params' is not defined                             no-undef
   228:29   error  'embedded_in_popup' is not defined                            no-undef
   238:20   error  'url_query_params' is not defined                             no-undef
   239:21   error  'url_query_params' is not defined                             no-undef
   270:36   error  'openerOrigin' is not defined                                 no-undef
   271:30   error  'checkUserSiteRelationship' is not defined                    no-undef
   271:56   error  'openerOrigin' is not defined                                 no-undef
   274:44   error  'logged_in_users' is not defined                              no-undef
   274:76   error  'userAppToken' is not defined                                 no-undef
   274:92   error  'url_query_params' is not defined                             no-undef
   284:17   error  'userAppToken' is not defined                                 no-undef
   288:25   error  'is_auth' is not defined                                      no-undef
   302:13   error  'url_query_params' is not defined                             no-undef
   303:38   error  'url_query_params' is not defined                             no-undef
   309:17   error  'logout' is not defined                                       no-undef
   331:13   error  'update_auth_data' is not defined                             no-undef
   363:8    error  'is_auth' is not defined                                      no-undef
   388:13   error  'update_auth_data' is not defined                             no-undef
   394:23   error  'get_auto_arrange_data' is not defined                        no-undef
   395:31   error  'desktop_path' is not defined                                 no-undef
   403:30   error  'url_query_params' is not defined                             no-undef
   405:38   error  'getUserAppToken' is not defined                              no-undef
   405:62   error  'openerOrigin' is not defined                                 no-undef
   415:35   error  'user' is not defined                                         no-undef
   417:24   error  'openerOrigin' is not defined                                 no-undef
   430:24   error  'openerOrigin' is not defined                                 no-undef
   438:20   error  'openerOrigin' is not defined                                 no-undef
   439:37   error  'getAppUIDFromOrigin' is not defined                          no-undef
   439:57   error  'openerOrigin' is not defined                                 no-undef
   444:35   error  'url_query_params' is not defined                             no-undef
   508:46   error  'url_query_params' is not defined                             no-undef
   630:54   error  'busy_indicator_hide_delay' is not defined                    no-undef
   636:49   error  'busy_indicator_hide_delay' is not defined                    no-undef
   647:13   error  'update_sites_cache' is not defined                           no-undef
   656:9    error  'refresh_desktop_background' is not defined                   no-undef
   661:9    error  'is_auth' is not defined                                      no-undef
   661:23   error  'first_visit_ever' is not defined                             no-undef
   662:12   error  'logged_in_users' is not defined                              no-undef
   679:14   error  'is_auth' is not defined                                      no-undef
   679:27   error  'first_visit_ever' is not defined                             no-undef
   693:12   error  'url_query_params' is not defined                             no-undef
   696:47   error  'url_query_params' is not defined                             no-undef
   704:18   error  'gui_origin' is not defined                                   no-undef
   715:17   error  'update_auth_data' is not defined                             no-undef
   728:8    error  'feature_flags' is not defined                                no-undef
   746:19   error  'get_auto_arrange_data' is not defined                        no-undef
   747:27   error  'desktop_path' is not defined                                 no-undef
   755:26   error  'url_query_params' is not defined                             no-undef
   758:34   error  'getUserAppToken' is not defined                              no-undef
   758:58   error  'openerOrigin' is not defined                                 no-undef
   768:31   error  'user' is not defined                                         no-undef
   770:20   error  'openerOrigin' is not defined                                 no-undef
   783:20   error  'openerOrigin' is not defined                                 no-undef
   792:16   error  'openerOrigin' is not defined                                 no-undef
   793:33   error  'getAppUIDFromOrigin' is not defined                          no-undef
   793:53   error  'openerOrigin' is not defined                                 no-undef
   801:31   error  'url_query_params' is not defined                             no-undef
   864:42   error  'url_query_params' is not defined                             no-undef
   987:50   error  'busy_indicator_hide_delay' is not defined                    no-undef
   993:45   error  'busy_indicator_hide_delay' is not defined                    no-undef
  1021:13   error  'update_explorer_footer_selected_items_count' is not defined  no-undef
  1057:13   error  'active_item_container' is not defined                        no-undef
  1061:17   error  'active_item_container' is not defined                        no-undef
  1065:21   error  'active_item_container' is not defined                        no-undef
  1071:9    error  'active_element' is not defined                               no-undef
  1179:21   error  'select_ctxmenu_item' is not defined                          no-undef
  1185:21   error  'select_ctxmenu_item' is not defined                          no-undef
  1198:21   error  'select_ctxmenu_item' is not defined                          no-undef
  1211:21   error  'select_ctxmenu_item' is not defined                          no-undef
  1222:25   error  'select_ctxmenu_item' is not defined                          no-undef
  1255:22   error  'active_item_container' is not defined                        no-undef
  1256:39   error  'active_item_container' is not defined                        no-undef
  1257:21   error  'active_element' is not defined                               no-undef
  1258:23   error  'active_item_container' is not defined                        no-undef
  1263:27   error  'active_item_container' is not defined                        no-undef
  1264:39   error  'active_item_container' is not defined                        no-undef
  1267:27   error  'active_item_container' is not defined                        no-undef
  1268:39   error  'active_element' is not defined                               no-undef
  1268:74   error  'active_element' is not defined                               no-undef
  1268:93   error  'active_element' is not defined                               no-undef
  1271:27   error  'active_item_container' is not defined                        no-undef
  1272:39   error  'active_item_container' is not defined                        no-undef
  1275:39   error  'active_element' is not defined                               no-undef
  1275:74   error  'active_element' is not defined                               no-undef
  1275:93   error  'active_element' is not defined                               no-undef
  1323:114  error  'active_item_container' is not defined                        no-undef
  1331:21   error  'active_element' is not defined                               no-undef
  1334:27   error  'active_item_container' is not defined                        no-undef
  1390:37   error  'active_element' is not defined                               no-undef
  1407:31   error  'delete_item' is not defined                                  no-undef
  1419:37   error  'active_element' is not defined                               no-undef
  1419:115  error  'trash_path' is not defined                                   no-undef
  1436:31   error  'delete_item' is not defined                                  no-undef
  1438:55   error  'trash_path' is not defined                                   no-undef
  1445:59   error  'trash_path' is not defined                                   no-undef
  1446:61   error  'trash_path' is not defined                                   no-undef
  1452:37   error  'active_element' is not defined                               no-undef
  1456:25   error  'move_items' is not defined                                   no-undef
  1456:53   error  'trash_path' is not defined                                   no-undef
  1467:16   error  'keypress_item_seach_term' is not defined                     no-undef
  1468:30   error  'keypress_item_seach_buffer_timeout' is not defined           no-undef
  1470:13   error  'keypress_item_seach_buffer_timeout' is not defined           no-undef
  1471:17   error  'keypress_item_seach_term' is not defined                     no-undef
  1474:13   error  'keypress_item_seach_term' is not defined                     no-undef
  1477:38   error  'active_item_container' is not defined                        no-undef
  1480:108  error  'keypress_item_seach_term' is not defined                     no-undef
  1485:30   error  'active_item_container' is not defined                        no-undef
  1487:78   error  'keypress_item_seach_term' is not defined                     no-undef
  1505:19   error  'active_item_container' is not defined                        no-undef
  1509:17   error  'update_explorer_footer_selected_items_count' is not defined  no-undef
  1509:63   error  'active_element' is not defined                               no-undef
  1518:16   error  'keypress_item_seach_term' is not defined                     no-undef
  1519:30   error  'keypress_item_seach_buffer_timeout' is not defined           no-undef
  1521:13   error  'keypress_item_seach_buffer_timeout' is not defined           no-undef
  1522:17   error  'keypress_item_seach_term' is not defined                     no-undef
  1525:13   error  'keypress_item_seach_term' is not defined                     no-undef
  1531:97   error  'keypress_item_seach_term' is not defined                     no-undef
  1538:67   error  'keypress_item_seach_term' is not defined                     no-undef
  1581:39   error  'active_element' is not defined                               no-undef
  1583:39   error  'active_element' is not defined                               no-undef
  1590:17   error  'update_explorer_footer_selected_items_count' is not defined  no-undef
  1600:36   error  'active_element' is not defined                               no-undef
  1602:36   error  'active_element' is not defined                               no-undef
  1615:15   error  'mouseover_window' is not defined                             no-undef
  1616:15   error  'mouseover_window' is not defined                             no-undef
  1616:55   error  'trash_path' is not defined                                   no-undef
  1621:38   error  'active_element' is not defined                               no-undef
  1623:38   error  'active_element' is not defined                               no-undef
  1628:21   error  'clipboard' is not defined                                    no-undef
  1629:21   error  'clipboard_op' is not defined                                 no-undef
  1632:58   error  'trash_path' is not defined                                   no-undef
  1636:25   error  'clipboard' is not defined                                    no-undef
  1648:38   error  'active_element' is not defined                               no-undef
  1650:38   error  'active_element' is not defined                               no-undef
  1655:21   error  'clipboard' is not defined                                    no-undef
  1656:21   error  'clipboard_op' is not defined                                 no-undef
  1658:25   error  'clipboard' is not defined                                    no-undef
  1668:107  error  'last_enter_pressed_to_rename_ts' is not defined              no-undef
  1682:21   error  'launch_app' is not defined                                   no-undef
  1705:21   error  'select_ctxmenu_item' is not defined                          no-undef
  1713:21   error  'active_item_container' is not defined                        no-undef
  1714:37   error  'active_item_container' is not defined                        no-undef
  1717:25   error  'open_item' is not defined                                    no-undef
  1736:16   error  'clipboard' is not defined                                    no-undef
  1745:37   error  'trash_path' is not defined                                   no-undef
  1745:74   error  'trash_path' is not defined                                   no-undef
  1745:96   error  'clipboard_op' is not defined                                 no-undef
  1748:20   error  'clipboard_op' is not defined                                 no-undef
  1749:21   error  'copy_clipboard_items' is not defined                         no-undef
  1750:25   error  'clipboard_op' is not defined                                 no-undef
  1751:21   error  'move_clipboard_items' is not defined                         no-undef
  1760:13   error  'undo_last_action' is not defined                             no-undef
  1767:9    error  'mouseX' is not defined                                       no-undef
  1768:9    error  'mouseY' is not defined                                       no-undef
  1771:13   error  'mouseX' is not defined                                       no-undef
  1771:29   error  'mouseY' is not defined                                       no-undef
  1771:38   error  'toolbar_height' is not defined                               no-undef
  1771:63   error  'mouseX' is not defined                                       no-undef
  1771:78   error  'mouseY' is not defined                                       no-undef
  1772:13   error  'current_active_snap_zone' is not defined                     no-undef
  1774:17   error  'mouseX' is not defined                                       no-undef
  1774:32   error  'mouseY' is not defined                                       no-undef
  1774:49   error  'mouseY' is not defined                                       no-undef
  1774:58   error  'desktop_height' is not defined                               no-undef
  1775:13   error  'current_active_snap_zone' is not defined                     no-undef
  1777:17   error  'mouseX' is not defined                                       no-undef
  1777:32   error  'mouseY' is not defined                                       no-undef
  1777:41   error  'desktop_height' is not defined                               no-undef
  1778:13   error  'current_active_snap_zone' is not defined                     no-undef
  1780:17   error  'mouseX' is not defined                                       no-undef
  1780:26   error  'desktop_width' is not defined                                no-undef
  1780:48   error  'mouseY' is not defined                                       no-undef
  1780:65   error  'mouseY' is not defined                                       no-undef
  1780:74   error  'desktop_height' is not defined                               no-undef
  1781:13   error  'current_active_snap_zone' is not defined                     no-undef
  1783:18   error  'mouseX' is not defined                                       no-undef
  1783:27   error  'desktop_width' is not defined                                no-undef
  1783:50   error  'mouseY' is not defined                                       no-undef
  1783:59   error  'toolbar_height' is not defined                               no-undef
  1783:84   error  'mouseX' is not defined                                       no-undef
  1783:93   error  'desktop_width' is not defined                                no-undef
  1783:115  error  'mouseY' is not defined                                       no-undef
  1784:13   error  'current_active_snap_zone' is not defined                     no-undef
  1786:17   error  'mouseX' is not defined                                       no-undef
  1786:26   error  'desktop_width' is not defined                                no-undef
  1786:48   error  'mouseY' is not defined                                       no-undef
  1786:58   error  'desktop_height' is not defined                               no-undef
  1787:13   error  'current_active_snap_zone' is not defined                     no-undef
  1789:17   error  'mouseY' is not defined                                       no-undef
  1789:26   error  'toolbar_height' is not defined                               no-undef
  1789:49   error  'mouseX' is not defined                                       no-undef
  1789:66   error  'mouseX' is not defined                                       no-undef
  1789:75   error  'desktop_width' is not defined                                no-undef
  1790:13   error  'current_active_snap_zone' is not defined                     no-undef
  1793:13   error  'current_active_snap_zone' is not defined                     no-undef
  1802:21   error  'mouseX' is not defined                                       no-undef
  1802:41   error  'mouseX' is not defined                                       no-undef
  1802:75   error  'mouseY' is not defined                                       no-undef
  1802:95   error  'mouseY' is not defined                                       no-undef
  1819:21   error  'mouseX' is not defined                                       no-undef
  1819:41   error  'mouseX' is not defined                                       no-undef
  1819:75   error  'mouseY' is not defined                                       no-undef
  1819:95   error  'mouseY' is not defined                                       no-undef
  1840:12   error  'mouseover_window' is not defined                             no-undef
  1841:15   error  'mouseover_window' is not defined                             no-undef
  1876:17   error  'upload_items' is not defined                                 no-undef
  1934:21   error  'logout' is not defined                                       no-undef
  1936:17   error  'logout' is not defined                                       no-undef
  1946:22   error  'gui_origin' is not defined                                   no-undef
  1951:50   error  'auth_token' is not defined                                   no-undef
  1958:18   error  Empty block statement                                         no-empty
2024-05-02 17:23:20 +01:00
Sam Atkins b6c491171c chore: Fix eslint issues in helper/ files
/puter/src/helpers/determine_active_container_parent.js
  22:30  error  'active_element' is not defined         no-undef
  25:30  error  'active_element' is not defined         no-undef
  29:30  error  'active_element' is not defined         no-undef
  32:41  error  'active_element' is not defined         no-undef
  32:61  error  'active_element' is not defined         no-undef
  33:30  error  'active_element' is not defined         no-undef
  36:41  error  'active_item_container' is not defined  no-undef
  37:28  error  'active_item_container' is not defined  no-undef

/puter/src/helpers/download.js
  51:27  error  'api_origin' is not defined           no-undef
  52:59  error  'auth_token' is not defined           no-undef
  92:16  error  'operation_cancelled' is not defined  no-undef

/puter/src/helpers/new_context_menu_item.js
  38:21  error  'create_folder' is not defined  no-undef
  48:21  error  'create_file' is not defined    no-undef
  56:21  error  'create_file' is not defined    no-undef
  70:25  error  'create_file' is not defined    no-undef

/puter/src/helpers/refresh_item_container.js
   83:13  error  'update_window_layout' is not defined                no-undef
   86:13  error  'update_details_layout_sort_visuals' is not defined  no-undef
  124:35  error  'trash_path' is not defined                          no-undef
  162:29  error  Empty block statement                                no-empty
  166:51  error  'path' is not defined                                no-undef
  168:34  error  'trash_path' is not defined                          no-undef
  168:62  error  'appdata_path' is not defined                        no-undef
  171:38  error  'desktop_item_positions' is not defined              no-undef
  178:37  error  'item_icon' is not defined                           no-undef
  207:31  error  'trash_path' is not defined                          no-undef
  216:21  error  'sort_items' is not defined                          no-undef
  217:26  error  Empty block statement                                no-empty
  222:13  error  'sort_items' is not defined                          no-undef
  233:17  error  'update_explorer_footer_item_count' is not defined   no-undef

/puter/src/helpers/update_title_based_on_uploads.js
  21:41  error  'active_uploads' is not defined  no-undef
  22:59  error  'active_uploads' is not defined  no-undef
  23:51  error  'active_uploads' is not defined  no-undef
  27:51  error  'active_uploads' is not defined  no-undef
2024-05-02 17:02:53 +01:00
Sam Atkins eefc0d41e1 chore: Fix eslint issues in helpers.js
Most of these are window fields that wanted `window.` prepended, but a
couple of issues are code that was using undefined variables (`ht` and
`dir_uuid`) and some switch-cases that I believe are intentionally
falling through.

/puter/src/helpers.js
    39:55   error  'auth_token' is not defined                                                                                            no-undef
    47:14   error  'api_origin' is not defined                                                                                            no-undef
    55:40   error  'auth_token' is not defined                                                                                            no-undef
    59:17   error  'logout' is not defined                                                                                                no-undef
   199:14   error  'api_origin' is not defined                                                                                            no-undef
   208:40   error  'auth_token' is not defined                                                                                            no-undef
   212:17   error  'logout' is not defined                                                                                                no-undef
   224:14   error  'api_origin' is not defined                                                                                            no-undef
   234:40   error  'auth_token' is not defined                                                                                            no-undef
   238:17   error  'logout' is not defined                                                                                                no-undef
   316:13   error  Expected a 'break' statement before 'case'                                                                             no-fallthrough
   323:13   error  Expected a 'break' statement before 'case'                                                                             no-fallthrough
   330:13   error  Expected a 'break' statement before 'case'                                                                             no-fallthrough
   337:13   error  Expected a 'break' statement before 'case'                                                                             no-fallthrough
   367:47   error  Unnecessary escape character: \/                                                                                       no-useless-escape
   411:14   error  'isString' is not defined                                                                                              no-undef
   420:47   error  'config' is not defined                                                                                                no-undef
   519:21   error  'globToRegExp' is not defined                                                                                          no-undef
   651:14   error  Empty block statement                                                                                                  no-empty
   656:9    error  'update_auth_data' is not defined                                                                                      no-undef
   678:36   error  'api_origin' is not defined                                                                                            no-undef
   722:5    error  'update_user_preferences' is not defined                                                                               no-undef
   740:24   error  'uuidv4' is not defined                                                                                                no-undef
   746:9    error  'appCallbackFunctions' is not defined                                                                                  no-undef
   789:14   error  'api_origin' is not defined                                                                                            no-undef
   794:40   error  'auth_token' is not defined                                                                                            no-undef
   861:33   error  'trash_path' is not defined                                                                                            no-undef
   867:21   error  Empty block statement                                                                                                  no-empty
   889:70   error  'trash_path' is not defined                                                                                            no-undef
   891:59   error  'trash_path' is not defined                                                                                            no-undef
   894:49   error  'trash_path' is not defined                                                                                            no-undef
   907:29   error  'docs_path' is not defined                                                                                             no-undef
   909:35   error  'pictures_path' is not defined                                                                                         no-undef
   911:35   error  'home_path' is not defined                                                                                             no-undef
   913:35   error  'videos_path' is not defined                                                                                           no-undef
   915:35   error  'desktop_path' is not defined                                                                                          no-undef
  1037:5    error  'getItem' is not defined                                                                                               no-undef
  1041:17   error  'setItem' is not defined                                                                                               no-undef
  1070:54   error  Empty block statement                                                                                                  no-empty
  1089:51   error  'ht' is not defined                                                                                                    no-undef
  1091:20   error  'desktop_loading_fade_delay' is not defined                                                                            no-undef
  1150:27   error  'operation_id' is not defined                                                                                          no-undef
  1151:5    error  'operation_cancelled' is not defined                                                                                   no-undef
  1169:21   error  'activate_item_name_editor' is not defined                                                                             no-undef
  1172:21   error  'actions_history' is not defined                                                                                       no-undef
  1181:54   error  'copy_progress_hide_delay' is not defined                                                                              no-undef
  1187:37   error  'copy_progress_hide_delay' is not defined                                                                              no-undef
  1211:21   error  'activate_item_name_editor' is not defined                                                                             no-undef
  1214:21   error  'actions_history' is not defined                                                                                       no-undef
  1245:22   error  'operation_id' is not defined                                                                                          no-undef
  1246:5    error  'operation_cancelled' is not defined                                                                                   no-undef
  1249:5    error  'update_explorer_footer_selected_items_count' is not defined                                                           no-undef
  1263:24   error  'clipboard' is not defined                                                                                             no-undef
  1264:29   error  'clipboard' is not defined                                                                                             no-undef
  1273:20   error  'operation_cancelled' is not defined                                                                                   no-undef
  1302:38   error  'clipboard' is not defined                                                                                             no-undef
  1303:38   error  'clipboard' is not defined                                                                                             no-undef
  1327:9    error  'actions_history' is not defined                                                                                       no-undef
  1335:40   error  'copy_progress_hide_delay' is not defined                                                                              no-undef
  1341:29   error  'copy_progress_hide_delay' is not defined                                                                              no-undef
  1354:22   error  'operation_id' is not defined                                                                                          no-undef
  1377:20   error  'operation_cancelled' is not defined                                                                                   no-undef
  1432:9    error  'actions_history' is not defined                                                                                       no-undef
  1440:40   error  'copy_progress_hide_delay' is not defined                                                                              no-undef
  1446:29   error  'copy_progress_hide_delay' is not defined                                                                              no-undef
  1486:17   error  'update_explorer_footer_item_count' is not defined                                                                     no-undef
  1487:17   error  'update_explorer_footer_selected_items_count' is not defined                                                           no-undef
  1500:8    error  'clipboard' is not defined                                                                                             no-undef
  1501:24   error  'clipboard' is not defined                                                                                             no-undef
  1502:61   error  'clipboard' is not defined                                                                                             no-undef
  1505:13   error  'move_items' is not defined                                                                                            no-undef
  1508:5    error  'clipboard' is not defined                                                                                             no-undef
  1537:23   error  'api_origin' is not defined                                                                                            no-undef
  1537:84   error  'auth_token' is not defined                                                                                            no-undef
  1556:34   error  'uuidv4' is not defined                                                                                                no-undef
  1565:45   error  'get_apps' is not defined                                                                                              no-undef
  1572:13   error  This branch can never execute. Its condition is a duplicate or covered by previous conditions in the if-else-if chain  no-dupe-else-if
  1639:21   error  'root_dirname' is not defined                                                                                          no-undef
  1684:37   error  'gui_origin' is not defined                                                                                            no-undef
  1711:60   error  'app_domain' is not defined                                                                                            no-undef
  1723:64   error  'auth_token' is not defined                                                                                            no-undef
  1737:49   error  'auth_token' is not defined                                                                                            no-undef
  1748:12   error  'api_origin' is not defined                                                                                            no-undef
  1749:64   error  'api_origin' is not defined                                                                                            no-undef
  1800:13   error  'launch_apps' is not defined                                                                                           no-undef
  1803:13   error  'launch_apps' is not defined                                                                                           no-undef
  1803:43   error  'launch_apps' is not defined                                                                                           no-undef
  1806:13   error  'launch_apps' is not defined                                                                                           no-undef
  1806:34   error  'launch_apps' is not defined                                                                                           no-undef
  1810:22   error  'api_origin' is not defined                                                                                            no-undef
  1819:48   error  'auth_token' is not defined                                                                                            no-undef
  1867:56   error  'trash_path' is not defined                                                                                            no-undef
  1873:34   error  'trash_path' is not defined                                                                                            no-undef
  1942:30   error  'busy_indicator_hide_delay' is not defined                                                                             no-undef
  1948:25   error  'busy_indicator_hide_delay' is not defined                                                                             no-undef
  1954:48   error  'user_preferences' is not defined                                                                                      no-undef
  1955:9    error  'launch_app' is not defined                                                                                            no-undef
  1956:19   error  'user_preferences' is not defined                                                                                      no-undef
  1967:9    error  'launch_app' is not defined                                                                                            no-undef
  1978:25   error  'item_icon' is not defined                                                                                             no-undef
  1992:9    error  'window_nav_history' is not defined                                                                                    no-undef
  1992:45   error  'window_nav_history' is not defined                                                                                    no-undef
  1992:88   error  'window_nav_history_current_position' is not defined                                                                   no-undef
  1993:9    error  'window_nav_history' is not defined                                                                                    no-undef
  1994:9    error  'window_nav_history_current_position' is not defined                                                                   no-undef
  1996:9    error  'update_window_path' is not defined                                                                                    no-undef
  2009:22   error  'api_origin' is not defined                                                                                            no-undef
  2017:48   error  'auth_token' is not defined                                                                                            no-undef
  2021:25   error  'logout' is not defined                                                                                                no-undef
  2025:20   error  Empty block statement                                                                                                  no-empty
  2029:70   error  'suggest_apps_for_fsentry' is not defined                                                                              no-undef
  2040:17   error  'unzipItem' is not defined                                                                                             no-undef
  2057:17   error  'trigger_download' is not defined                                                                                      no-undef
  2065:13   error  'launch_app' is not defined                                                                                            no-undef
  2087:22   error  'operation_id' is not defined                                                                                          no-undef
  2088:5    error  'operation_cancelled' is not defined                                                                                   no-undef
  2129:12   error  'operation_cancelled' is not defined                                                                                   no-undef
  2166:30   error  Empty block statement                                                                                                  no-empty
  2173:20   error  'operation_cancelled' is not defined                                                                                   no-undef
  2182:34   error  'trash_path' is not defined                                                                                            no-undef
  2196:55   error  'trash_path' is not defined                                                                                            no-undef
  2196:116  error  'trash_path' is not defined                                                                                            no-undef
  2197:57   error  'trash_path' is not defined                                                                                            no-undef
  2201:46   error  'trash_path' is not defined                                                                                            no-undef
  2215:47   error  'trash_path' is not defined                                                                                            no-undef
  2254:25   error  'update_explorer_footer_item_count' is not defined                                                                     no-undef
  2255:25   error  'update_explorer_footer_selected_items_count' is not defined                                                           no-undef
  2260:34   error  'trash_path' is not defined                                                                                            no-undef
  2270:25   error  'update_window_path' is not defined                                                                                    no-undef
  2274:34   error  'trash_path' is not defined                                                                                            no-undef
  2279:46   error  'dir_uuid' is not defined                                                                                              no-undef
  2302:33   error  'item_icon' is not defined                                                                                             no-undef
  2303:42   error  'trash_path' is not defined                                                                                            no-undef
  2309:47   error  'trash_path' is not defined                                                                                            no-undef
  2331:41   error  'item_icon' is not defined                                                                                             no-undef
  2343:21   error  'sort_items' is not defined                                                                                            no-undef
  2348:21   error  'sort_items' is not defined                                                                                            no-undef
  2391:47   error  'trash_path' is not defined                                                                                            no-undef
  2397:51   error  'trash_path' is not defined                                                                                            no-undef
  2398:53   error  'trash_path' is not defined                                                                                            no-undef
  2413:34   error  'trash_path' is not defined                                                                                            no-undef
  2414:9    error  'actions_history' is not defined                                                                                       no-undef
  2418:40   error  'trash_path' is not defined                                                                                            no-undef
  2419:9    error  'actions_history' is not defined                                                                                       no-undef
  2428:12   error  'copy_progress_hide_delay' is not defined                                                                              no-undef
  2641:21   error  'upload_items' is not defined                                                                                          no-undef
  2659:21   error  'trash_path' is not defined                                                                                            no-undef
  2679:21   error  'show_save_account_notice_if_needed' is not defined                                                                    no-undef
  2683:17   error  'active_uploads' is not defined                                                                                        no-undef
  2695:17   error  'active_uploads' is not defined                                                                                        no-undef
  2714:17   error  'actions_history' is not defined                                                                                       no-undef
  2722:25   error  'show_save_account_notice_if_needed' is not defined                                                                    no-undef
  2723:33   error  'upload_progress_hide_delay' is not defined                                                                            no-undef
  2726:24   error  'active_uploads' is not defined                                                                                        no-undef
  2733:24   error  'active_uploads' is not defined                                                                                        no-undef
  2739:24   error  'active_uploads' is not defined                                                                                        no-undef
  2766:17   error  'uuidv4' is not defined                                                                                                no-undef
  2772:16   error  'trash_path' is not defined                                                                                            no-undef
  2782:47   error  'trash_path' is not defined                                                                                            no-undef
  2782:108  error  'trash_path' is not defined                                                                                            no-undef
  2783:37   error  'trash_path' is not defined                                                                                            no-undef
  2786:36   error  'trash_path' is not defined                                                                                            no-undef
  2788:13   error  'update_explorer_footer_item_count' is not defined                                                                     no-undef
  2788:71   error  'trash_path' is not defined                                                                                            no-undef
  2793:28   error  'copy_progress_hide_delay' is not defined                                                                              no-undef
  2799:28   error  'copy_progress_hide_delay' is not defined                                                                              no-undef
  2815:18   error  'api_origin' is not defined                                                                                            no-undef
  2818:42   error  'auth_token' is not defined                                                                                            no-undef
  2991:28   error  'copy_progress_hide_delay' is not defined                                                                              no-undef
  2998:28   error  'copy_progress_hide_delay' is not defined                                                                              no-undef
  3066:24   error  'copy_progress_hide_delay' is not defined                                                                              no-undef
  3074:24   error  'copy_progress_hide_delay' is not defined                                                                              no-undef
  3086:17   error  'actions_history' is not defined                                                                                       no-undef
  3095:17   error  'suggest_apps_for_fsentry' is not defined                                                                              no-undef
  3104:95   error  'truncate_filename' is not defined                                                                                     no-undef
  3104:123  error  'TRUNCATE_LENGTH' is not defined                                                                                       no-undef
  3111:84   error  'item_icon' is not defined                                                                                             no-undef
  3150:23   error  'update_sites_cache' is not defined                                                                                    no-undef
  3153:27   error  'determine_website_url' is not defined                                                                                 no-undef
  3158:17   error  'update_window_path' is not defined                                                                                    no-undef
  3166:17   error  'sort_items' is not defined                                                                                            no-undef
  3171:34   error  'truncate_filename' is not defined                                                                                     no-undef
  3171:66   error  'TRUNCATE_LENGTH' is not defined                                                                                       no-undef
  3205:9    error  'actions_history' is not defined                                                                                       no-undef
  3206:29   error  'actions_history' is not defined                                                                                       no-undef
  3211:13   error  'undo_create_file_or_folder' is not defined                                                                            no-undef
  3214:13   error  'rename_file' is not defined                                                                                           no-undef
  3217:13   error  'undo_upload' is not defined                                                                                           no-undef
  3220:13   error  'undo_copy' is not defined                                                                                             no-undef
  3223:13   error  'undo_move' is not defined                                                                                             no-undef
  3226:13   error  'undo_delete' is not defined                                                                                           no-undef
  3249:26   error  'get_html_element_from_options' is not defined                                                                         no-undef
  3251:9    error  'move_items' is not defined                                                                                            no-undef
  3257:26   error  'get_html_element_from_options' is not defined                                                                         no-undef
  3259:9    error  'move_items' is not defined                                                                                            no-undef
  3265:21   error  'global_element_id' is not defined                                                                                     no-undef
  3282:23   error  'determine_website_url' is not defined                                                                                 no-undef
  3324:42   error  'byte_format' is not defined                                                                                           no-undef
  3381:116  error  'truncate_filename' is not defined                                                                                     no-undef
  3381:148  error  'TRUNCATE_LENGTH' is not defined                                                                                       no-undef
  3396:5    error  'is_auto_arrange_enabled' is not defined                                                                               no-undef
  3398:5    error  'desktop_item_positions' is not defined                                                                                no-undef
  3408:8    error  'reset_item_positions' is not defined                                                                                  no-undef
  3409:9    error  'delete_desktop_item_positions' is not defined                                                                         no-undef
  3415:26   error  'desktop_item_positions' is not defined                                                                                no-undef
  3426:44   error  'desktop_item_positions' is not defined                                                                                no-undef
  3430:5    error  'desktop_item_positions' is not defined                                                                                no-undef
  3438:28   error  'is_fullscreen' is not defined                                                                                         no-undef
  3462:14   error  'window_for_app_instance' is not defined                                                                               no-undef
  3469:31   error  'iframe_for_app_instance' is not defined                                                                               no-undef
  3483:23   error  'window_for_app_instance' is not defined                                                                               no-undef
  3514:42   error  Unnecessary escape character: \[                                                                                       no-useless-escape
  3514:59   error  Unnecessary escape character: \/                                                                                       no-useless-escape
2024-05-02 16:54:17 +01:00
Sam Atkins e5cd2bed87 chore: Clarify usage of window fields in globals.js
/puter/src/globals.js
  124:65  error  'first_visit_animation' is not defined  no-undef
2024-05-02 11:21:51 +01:00
Sam Atkins 766da39138 chore: Clarify usage of window fields in UIWindowSignup.js
/puter/src/UI/UIWindowSignup.js
  154:22  error  'is_email' is not defined                 no-undef
  170:35  error  'check_password_strength' is not defined  no-undef
  188:22  error  'gui_origin' is not defined               no-undef
  203:21  error  'update_auth_data' is not defined         no-undef
2024-05-02 11:21:51 +01:00
Sam Atkins 72c0e118c3 chore: Clarify usage of window fields in UIWindowSessionList.js
/puter/src/UI/UIWindowSessionList.js
   33:117  error  'icons' is not defined             no-undef
   34:41   error  'logged_in_users' is not defined   no-undef
   35:32   error  'logged_in_users' is not defined   no-undef
  134:36   error  'logged_in_users' is not defined   no-undef
  141:17   error  'update_auth_data' is not defined  no-undef
2024-05-02 11:21:51 +01:00
Sam Atkins 66cdf98190 chore: Clarify usage of window fields in UIWindowSaveAccount.js
/puter/src/UI/UIWindowSaveAccount.js
  130:22  error  'api_origin' is not defined        no-undef
  142:48  error  'auth_token' is not defined        no-undef
  145:21  error  'update_auth_data' is not defined  no-undef
2024-05-02 11:21:51 +01:00
Sam Atkins e5d4be6250 chore: Clarify usage of window fields in UIWindowRefer.js
/puter/src/UI/UIWindowRefer.js
  25:20  error  'gui_origin' is not defined  no-undef
  25:37  error  'user' is not defined        no-undef
  73:30  error  'socialLink' is not defined  no-undef
2024-05-02 11:21:51 +01:00
Sam Atkins 130b57b986 chore: Clarify usage of window fields in UIWindowRecoverPassword.js
/puter/src/UI/UIWindowRecoverPassword.js
   84:16  error  'is_email' is not defined    no-undef
   91:22  error  'api_origin' is not defined  no-undef
  101:25  error  'logout' is not defined      no-undef
2024-05-02 11:21:51 +01:00
Sam Atkins 2f30ae7a82 fix: Make url variable accessible to all users of it
Line 107 tries to use `url` but can't see it.

Also, clarify usage of window fields.

/puter/src/UI/UIWindowPublishWebsite.js
   67:67  error  'generate_identifier' is not defined  no-undef
  107:54  error  'url' is not defined                  no-undef
  110:17  error  'update_sites_cache' is not defined   no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins e983e9e9b7 chore: Clarify usage of window fields in UIWindowNewPassword.js
/puter/src/UI/UIWindowNewPassword.js
   48:38  error  'api_origin' is not defined               no-undef
  153:35  error  'check_password_strength' is not defined  no-undef
  163:22  error  'api_origin' is not defined               no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins b042f3c738 chore: Clarify usage of window fields in UIWindowMyWebsites.js
/puter/src/UI/UIWindowMyWebsites.js
  156:30  error  'api_origin' is not defined  no-undef
  164:56  error  'auth_token' is not defined  no-undef
  168:33  error  'logout' is not defined      no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins ece37b62f2 chore: Clarify usage of window fields in progress dialogs
/puter/src/UI/UIWindowMoveProgress.js
  74:9  error  'operation_cancelled' is not defined  no-undef

/puter/src/UI/UIWindowNewFolderProgress.js
  67:9  error  'operation_cancelled' is not defined  no-undef

/puter/src/UI/UIWindowProgressEmptyTrash.js
  67:9  error  'operation_cancelled' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins abc70f2e92 chore: Clarify usage of window fields in UIWindowManageSessions.js
/puter/src/UI/UIWindowManageSessions.js
   91:41  error  'api_origin' is not defined  no-undef
  122:37  error  'api_origin' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 2ed258cb69 chore: Clarify usage of window fields in UIWindowLogin.js
/puter/src/UI/UIWindowLogin.js
  141:16  error  'is_email' is not defined          no-undef
  160:22  error  'gui_origin' is not defined        no-undef
  167:21  error  'update_auth_data' is not defined  no-undef
  180:59  error  'gui_origin' is not defined        no-undef
  186:29  error  'app_domain' is not defined        no-undef
  188:54  error  'gui_origin' is not defined        no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 6903ce0043 chore: Clarify usage of window fields in UIWindowItemProperties.js
/puter/src/UI/UIWindowItemProperties.js
  135:26   error  Empty block statement              no-empty
  147:120  error  'byte_format' is not defined       no-undef
  155:395  error  'extractSubdomain' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 0ebcbe516c chore: Clarify usage of window fields in UIWindowFontPicker.js
/puter/src/UI/UIWindowFontPicker.js
  45:12  error  'isString' is not defined             no-undef
  95:21  error  'scrollParentToChild' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins c44e0ca737 chore: Clarify usage of window fields in UIWindowFeedback.js
/puter/src/UI/UIWindowFeedback.js
  79:22  error  'api_origin' is not defined  no-undef
  84:48  error  'auth_token' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 7f050dc61a chore: Clarify usage of window fields in UIWindowDownloadProgress.js
/puter/src/UI/UIWindowDownloadProgress.js
  74:9  error  'operation_cancelled' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 93e13cdb06 chore: Clarify usage of window fields in UIWindowDesktopBGSettings.js
/puter/src/UI/UIWindowDesktopBGSettings.js
  168:26  error  'api_origin' is not defined  no-undef
  178:52  error  'auth_token' is not defined  no-undef
  182:29  error  'logout' is not defined      no-undef
  188:24  error  Empty block statement        no-empty
2024-05-02 11:21:50 +01:00
Sam Atkins dea3bc1a7f chore: Clarify use of window fields in UIWindowEmailConfirmationRequired
/puter/src/UI/UIWindowEmailConfirmationRequired.js
  113:26  error  'api_origin' is not defined         no-undef
  121:52  error  'auth_token' is not defined         no-undef
  125:29  error  'logout' is not defined             no-undef
  131:29  error  'refresh_user_data' is not defined  no-undef
  160:22  error  'api_origin' is not defined         no-undef
  165:48  error  'auth_token' is not defined         no-undef
  169:25  error  'logout' is not defined             no-undef
  188:13  error  'logout' is not defined             no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 2f6fcdb878 chore: Clarify usage of window fields in UIWindowDownloadProgress.js
/puter/src/UI/UIWindowDownloadProgress.js
  74:9  error  'operation_cancelled' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 3de32c2acc chore: Clarify usage of window fields in UIWindowColorPicker.js
/puter/src/UI/UIWindowColorPicker.js
  26:12  error  'isString' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins ff28d2919b chore: Clarify usage of window fields in UIWindowChangeUsername.js
/puter/src/UI/UIWindowChangeUsername.js
   97:18  error  'api_origin' is not defined  no-undef
  101:44  error  'auth_token' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins e3fb25cf45 chore: Clarify usage of window fields in UIWindowChangePassword.js
/puter/src/UI/UIWindowChangePassword.js
  107:31  error  'check_password_strength' is not defined  no-undef
  117:18  error  'api_origin' is not defined               no-undef
  121:44  error  'auth_token' is not defined               no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins d39fd8659e chore: Clarify usage of window fields in UIWindow.js
And also add some missing imports.

/puter/src/UI/UIWindow.js
    33:20   error  'global_element_id' is not defined                            no-undef
    34:5    error  'last_window_zindex' is not defined                           no-undef
    48:5    error  'window_stack' is not defined                                 no-undef
    69:52   error  'uuidv4' is not defined                                       no-undef
    90:9    error  'is_embedded' is not defined                                  no-undef
   174:52   error  'last_window_zindex' is not defined                           no-undef
   174:94   error  'last_window_zindex' is not defined                           no-undef
   244:77   error  'is_embedded' is not defined                                  no-undef
   289:57   error  'navbar_path' is not defined                                  no-undef
   436:25   error  'launch_app' is not defined                                   no-undef
   456:9    error  'window_nav_history' is not defined                           no-undef
   457:9    error  'window_nav_history_current_position' is not defined          no-undef
   524:9    error  'animate_window_opening' is not defined                       no-undef
   599:17   error  'validate_fsentry_name' is not defined                        no-undef
   790:9    error  'navbar_path_droppable' is not defined                        no-undef
   791:9    error  'sidebar_item_droppable' is not defined                       no-undef
   801:33   error  'window_nav_history' is not defined                           no-undef
   801:63   error  'window_nav_history_current_position' is not defined          no-undef
   804:46   error  'root_dirname' is not defined                                 no-undef
   812:17   error  'window_nav_history_current_position' is not defined          no-undef
   812:68   error  'window_nav_history_current_position' is not defined          no-undef
   813:34   error  'window_nav_history' is not defined                           no-undef
   813:64   error  'window_nav_history_current_position' is not defined          no-undef
   815:17   error  'update_window_path' is not defined                           no-undef
   825:29   error  'window_nav_history_current_position' is not defined          no-undef
   826:38   error  'window_nav_history' is not defined                           no-undef
   834:25   error  'window_nav_history_current_position' is not defined          no-undef
   835:42   error  'window_nav_history' is not defined                           no-undef
   835:72   error  'window_nav_history_current_position' is not defined          no-undef
   840:59   error  'root_dirname' is not defined                                 no-undef
   847:29   error  'update_window_path' is not defined                           no-undef
   869:33   error  'window_nav_history' is not defined                           no-undef
   869:63   error  'window_nav_history_current_position' is not defined          no-undef
   872:46   error  'root_dirname' is not defined                                 no-undef
   880:17   error  'window_nav_history_current_position' is not defined          no-undef
   882:37   error  'window_nav_history' is not defined                           no-undef
   882:67   error  'window_nav_history_current_position' is not defined          no-undef
   885:21   error  'update_window_path' is not defined                           no-undef
   896:29   error  'window_nav_history_current_position' is not defined          no-undef
   896:86   error  'window_nav_history' is not defined                           no-undef
   897:38   error  'window_nav_history' is not defined                           no-undef
   905:25   error  'window_nav_history_current_position' is not defined          no-undef
   906:42   error  'window_nav_history' is not defined                           no-undef
   906:72   error  'window_nav_history_current_position' is not defined          no-undef
   911:59   error  'root_dirname' is not defined                                 no-undef
   918:29   error  'update_window_path' is not defined                           no-undef
   941:50   error  'root_dirname' is not defined                                 no-undef
   950:17   error  'window_nav_history' is not defined                           no-undef
   950:46   error  'window_nav_history' is not defined                           no-undef
   950:82   error  'window_nav_history_current_position' is not defined          no-undef
   951:17   error  'window_nav_history' is not defined                           no-undef
   952:17   error  'window_nav_history_current_position' is not defined          no-undef
   954:17   error  'update_window_path' is not defined                           no-undef
   968:25   error  'update_window_layout' is not defined                         no-undef
   983:25   error  'update_window_layout' is not defined                         no-undef
   986:25   error  'update_window_layout' is not defined                         no-undef
   997:13   error  'is_auth' is not defined                                      no-undef
  1023:13   error  'update_explorer_footer_selected_items_count' is not defined  no-undef
  1106:21   error  'active_element' is not defined                               no-undef
  1117:13   error  'update_explorer_footer_selected_items_count' is not defined  no-undef
  1143:18   error  'mouseover_window' is not defined                             no-undef
  1205:82   error  'mouseX' is not defined                                       no-undef
  1205:107  error  'mouseY' is not defined                                       no-undef
  1219:83   error  'mouseover_window' is not defined                             no-undef
  1244:31   error  'mouseover_window' is not defined                             no-undef
  1246:17   error  'copy_items' is not defined                                   no-undef
  1246:45   error  'mouseover_window' is not defined                             no-undef
  1252:21   error  'create_shortcut' is not defined                              no-undef
  1255:27   error  'mouseover_window' is not defined                             no-undef
  1264:17   error  'move_items' is not defined                                   no-undef
  1264:45   error  'mouseover_window' is not defined                             no-undef
  1286:13   error  'scale_window' is not defined                                 no-undef
  1302:13   error  'scale_window' is not defined                                 no-undef
  1359:21   error  'upload_items' is not defined                                 no-undef
  1413:47   error  'window_width_threshold_for_sidebar' is not defined           no-undef
  1414:49   error  'window_width_threshold_for_sidebar' is not defined           no-undef
  1420:53   error  'window_width_threshold_for_sidebar' is not defined           no-undef
  1435:17   error  'last_window_zindex' is not defined                           no-undef
  1460:29   error  'current_active_snap_zone' is not defined                     no-undef
  1469:50   error  'current_active_snap_zone' is not defined                     no-undef
  1473:43   error  'desktop_height' is not defined                               no-undef
  1474:40   error  'toolbar_height' is not defined                               no-undef
  1476:44   error  'last_window_zindex' is not defined                           no-undef
  1480:55   error  'current_active_snap_zone' is not defined                     no-undef
  1484:43   error  'desktop_height' is not defined                               no-undef
  1485:40   error  'toolbar_height' is not defined                               no-undef
  1487:44   error  'last_window_zindex' is not defined                           no-undef
  1491:55   error  'current_active_snap_zone' is not defined                     no-undef
  1495:43   error  'desktop_height' is not defined                               no-undef
  1496:40   error  'toolbar_height' is not defined                               no-undef
  1497:41   error  'desktop_width' is not defined                                no-undef
  1498:44   error  'last_window_zindex' is not defined                           no-undef
  1502:55   error  'current_active_snap_zone' is not defined                     no-undef
  1506:43   error  'desktop_height' is not defined                               no-undef
  1507:40   error  'toolbar_height' is not defined                               no-undef
  1510:44   error  'last_window_zindex' is not defined                           no-undef
  1514:55   error  'current_active_snap_zone' is not defined                     no-undef
  1517:42   error  'desktop_width' is not defined                                no-undef
  1518:43   error  'desktop_height' is not defined                               no-undef
  1519:40   error  'toolbar_height' is not defined                               no-undef
  1521:44   error  'last_window_zindex' is not defined                           no-undef
  1525:55   error  'current_active_snap_zone' is not defined                     no-undef
  1528:40   error  'toolbar_height' is not defined                               no-undef
  1528:57   error  'desktop_height' is not defined                               no-undef
  1531:43   error  'desktop_height' is not defined                               no-undef
  1532:44   error  'last_window_zindex' is not defined                           no-undef
  1536:55   error  'current_active_snap_zone' is not defined                     no-undef
  1539:40   error  'toolbar_height' is not defined                               no-undef
  1539:57   error  'desktop_height' is not defined                               no-undef
  1540:41   error  'desktop_width' is not defined                                no-undef
  1542:43   error  'desktop_height' is not defined                               no-undef
  1543:44   error  'last_window_zindex' is not defined                           no-undef
  1559:52   error  'current_active_snap_zone' is not defined                     no-undef
  1590:28   error  'current_active_snap_zone' is not defined                     no-undef
  1592:40   error  'toolbar_height' is not defined                               no-undef
  1595:43   error  'desktop_height' is not defined                               no-undef
  1599:33   error  'current_active_snap_zone' is not defined                     no-undef
  1601:40   error  'toolbar_height' is not defined                               no-undef
  1604:43   error  'desktop_height' is not defined                               no-undef
  1608:33   error  'current_active_snap_zone' is not defined                     no-undef
  1610:40   error  'toolbar_height' is not defined                               no-undef
  1613:43   error  'desktop_height' is not defined                               no-undef
  1617:33   error  'current_active_snap_zone' is not defined                     no-undef
  1619:40   error  'toolbar_height' is not defined                               no-undef
  1619:57   error  'desktop_height' is not defined                               no-undef
  1622:43   error  'desktop_height' is not defined                               no-undef
  1626:33   error  'current_active_snap_zone' is not defined                     no-undef
  1628:40   error  'toolbar_height' is not defined                               no-undef
  1628:57   error  'desktop_height' is not defined                               no-undef
  1629:41   error  'desktop_width' is not defined                                no-undef
  1631:43   error  'desktop_height' is not defined                               no-undef
  1635:33   error  'current_active_snap_zone' is not defined                     no-undef
  1637:40   error  'toolbar_height' is not defined                               no-undef
  1640:43   error  'desktop_height' is not defined                               no-undef
  1644:33   error  'current_active_snap_zone' is not defined                     no-undef
  1645:29   error  'scale_window' is not defined                                 no-undef
  1656:51   error  'window_width_threshold_for_sidebar' is not defined           no-undef
  1657:53   error  'window_width_threshold_for_sidebar' is not defined           no-undef
  1663:57   error  'window_width_threshold_for_sidebar' is not defined           no-undef
  1674:71   error  'taskbar_height' is not defined                               no-undef
  1676:51   error  'taskbar_height' is not defined                               no-undef
  1703:35   error  'window_width_threshold_for_sidebar' is not defined           no-undef
  1718:36   error  'window_width_threshold_for_sidebar' is not defined           no-undef
  1719:49   error  'window_width_threshold_for_sidebar' is not defined           no-undef
  1725:42   error  'window_width_threshold_for_sidebar' is not defined           no-undef
  1733:50   error  'toolbar_height' is not defined                               no-undef
  1734:38   error  'toolbar_height' is not defined                               no-undef
  1736:32   error  'toolbar_height' is not defined                               no-undef
  1773:13   error  'setItem' is not defined                                      no-undef
  1820:21   error  'scale_window' is not defined                                 no-undef
  1867:51   error  'trash_path' is not defined                                   no-undef
  1881:41   error  'sort_items' is not defined                                   no-undef
  1882:41   error  'set_sort_by' is not defined                                  no-undef
  1889:41   error  'sort_items' is not defined                                   no-undef
  1890:41   error  'set_sort_by' is not defined                                  no-undef
  1897:41   error  'sort_items' is not defined                                   no-undef
  1898:41   error  'set_sort_by' is not defined                                  no-undef
  1905:41   error  'sort_items' is not defined                                   no-undef
  1906:41   error  'set_sort_by' is not defined                                  no-undef
  1918:41   error  'sort_items' is not defined                                   no-undef
  1919:41   error  'set_sort_by' is not defined                                  no-undef
  1927:41   error  'sort_items' is not defined                                   no-undef
  1928:41   error  'set_sort_by' is not defined                                  no-undef
  1973:40   error  'clipboard' is not defined                                    no-undef
  1975:36   error  'clipboard_op' is not defined                                 no-undef
  1976:37   error  'copy_clipboard_items' is not defined                         no-undef
  1977:41   error  'clipboard_op' is not defined                                 no-undef
  1978:37   error  'move_clipboard_items' is not defined                         no-undef
  1986:39   error  'actions_history' is not defined                              no-undef
  1988:33   error  'undo_last_action' is not defined                             no-undef
  1998:33   error  'init_upload_using_dialog' is not defined                     no-undef
  2014:48   error  'UIWindowSaveAccount' is not defined                          no-undef
  2023:85   error  'UIWindowEmailConfirmationRequired' is not defined            no-undef
  2036:33   error  'launch_app' is not defined                                   no-undef
  2059:44   error  'mouseX' is not defined                                       no-undef
  2063:43   error  'mouseY' is not defined                                       no-undef
  2102:68   error  'trash_path' is not defined                                   no-undef
  2103:37   error  'delete_item' is not defined                                  no-undef
  2110:67   error  'trash_path' is not defined                                   no-undef
  2110:128  error  'trash_path' is not defined                                   no-undef
  2146:21   error  'upload_items' is not defined                                 no-undef
  2163:13   error  'enter_fullpage_mode' is not defined                          no-undef
  2173:8    error  'active_element' is not defined                               no-undef
  2174:9    error  'active_element' is not defined                               no-undef
  2195:25   error  'item_icon' is not defined                                    no-undef
  2210:9    error  'window_nav_history' is not defined                           no-undef
  2210:45   error  'window_nav_history' is not defined                           no-undef
  2210:88   error  'window_nav_history_current_position' is not defined          no-undef
  2211:9    error  'window_nav_history' is not defined                           no-undef
  2212:9    error  'window_nav_history_current_position' is not defined          no-undef
  2214:9    error  'update_window_path' is not defined                           no-undef
  2257:37   error  'item_icon' is not defined                                    no-undef
  2364:9    error  'update_window_path' is not defined                           no-undef
  2380:38   error  'root_dirname' is not defined                                 no-undef
  2389:9    error  'window_nav_history' is not defined                           no-undef
  2389:45   error  'window_nav_history' is not defined                           no-undef
  2389:88   error  'window_nav_history_current_position' is not defined          no-undef
  2390:9    error  'window_nav_history' is not defined                           no-undef
  2391:9    error  'window_nav_history_current_position' is not defined          no-undef
  2391:62   error  'window_nav_history' is not defined                           no-undef
  2392:9    error  'update_window_path' is not defined                           no-undef
  2436:59   error  'root_dirname' is not defined                                 no-undef
  2453:19   error  'clipboard' is not defined                                    no-undef
  2455:16   error  'clipboard_op' is not defined                                 no-undef
  2456:17   error  'copy_clipboard_items' is not defined                         no-undef
  2457:21   error  'clipboard_op' is not defined                                 no-undef
  2458:17   error  'move_clipboard_items' is not defined                         no-undef
  2484:18   error  'mouseover_window' is not defined                             no-undef
  2503:21   error  'create_shortcut' is not defined                              no-undef
  2515:17   error  'move_items' is not defined                                   no-undef
  2525:18   error  'mouseover_window' is not defined                             no-undef
  2605:12   error  'window_nav_history' is not defined                           no-undef
  2605:42   error  'window_nav_history' is not defined                           no-undef
  2605:84   error  'window_nav_history_current_position' is not defined          no-undef
  2612:12   error  'window_nav_history_current_position' is not defined          no-undef
  2626:55   error  'navbar_path' is not defined                                  no-undef
  2687:17   error  'update_window_layout' is not defined                         no-undef
  2690:21   error  'update_details_layout_sort_visuals' is not defined           no-undef
  2698:13   error  'update_window_path' is not defined                           no-undef
  2707:54   error  'root_dirname' is not defined                                 no-undef
  2712:9    error  'navbar_path_droppable' is not defined                        no-undef
  2715:5    error  'update_explorer_footer_selected_items_count' is not defined  no-undef
  2727:18   error  'mouseover_window' is not defined                             no-undef
  2746:21   error  'create_shortcut' is not defined                              no-undef
  2758:17   error  'move_items' is not defined                                   no-undef
  2768:18   error  'mouseover_window' is not defined                             no-undef
  2807:36   error  'sendWindowWillCloseMsg' is not defined                       no-undef
  2819:23   error  'window_stack' is not defined                                 no-undef
  2829:17   error  'remove_taskbar_item' is not defined                          no-undef
  2836:17   error  'exit_fullpage_mode' is not defined                           no-undef
  2853:31   error  'window_stack' is not defined                                 no-undef
  2854:73   error  'window_stack' is not defined                                 no-undef
  2854:86   error  'window_stack' is not defined                                 no-undef
  2857:47   error  'window_stack' is not defined                                 no-undef
  2857:60   error  'window_stack' is not defined                                 no-undef
  2916:22   error  'window_stack' is not defined                                 no-undef
  2924:13   error  'active_item_container' is not defined                        no-undef
  2949:20   error  'toolbar_height' is not defined                               no-undef
  3007:14   error  'api_origin' is not defined                                   no-undef
  3017:40   error  'auth_token' is not defined                                   no-undef
  3021:17   error  'logout' is not defined                                       no-undef
  3083:43   error  'last_window_zindex' is not defined                           no-undef
  3123:38   error  'last_window_zindex' is not defined                           no-undef
  3127:98   error  'last_window_zindex' is not defined                           no-undef
  3131:100  error  'last_window_zindex' is not defined                           no-undef
  3147:81   error  'mouseX' is not defined                                       no-undef
  3147:106  error  'mouseY' is not defined                                       no-undef
  3151:9    error  'active_item_container' is not defined                        no-undef
  3153:34   error  'active_item_container' is not defined                        no-undef
  3155:9    error  'window_stack' is not defined                                 no-undef
  3157:11   error  'active_item_container' is not defined                        no-undef
  3252:5    error  'sort_items' is not defined                                   no-undef
  3253:5    error  'set_sort_by' is not defined                                  no-undef
  3258:14   error  'api_origin' is not defined                                   no-undef
  3267:40   error  'auth_token' is not defined                                   no-undef
  3271:17   error  'logout' is not defined                                       no-undef
  3280:21   error  'update_details_layout_sort_visuals' is not defined           no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 126b00b35c chore: Clarify usage of window fields in UITaskbarItem.js
/puter/src/UI/UITaskbarItem.js
   31:24  error  'global_element_id' is not defined    no-undef
  124:21  error  'launch_app' is not defined           no-undef
  143:21  error  'empty_trash' is not defined          no-undef
  158:25  error  'remove_taskbar_item' is not defined  no-undef
  160:21  error  'update_taskbar' is not defined       no-undef
  174:21  error  'update_taskbar' is not defined       no-undef
  250:73  error  'mouseover_window' is not defined     no-undef
  254:33  error  'path' is not defined                 no-undef
  297:21  error  'launch_app' is not defined           no-undef
  328:89  error  'mouseover_window' is not defined     no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 94291c4968 chore: Clarify usage of window fields in UITaskbar.js
/puter/src/UI/UITaskbar.js
   24:5    error  'global_element_id' is not defined      no-undef
   31:14   error  'api_origin' is not defined             no-undef
   36:40   error  'auth_token' is not defined             no-undef
   44:33   error  'global_element_id' is not defined      no-undef
   77:17   error  'launch_apps' is not defined            no-undef
   77:33   error  'launch_apps' is not defined            no-undef
   77:55   error  'launch_apps' is not defined            no-undef
   79:17   error  'launch_apps' is not defined            no-undef
   80:26   error  'api_origin' is not defined             no-undef
   85:52   error  'auth_token' is not defined             no-undef
   99:16   error  'launch_apps' is not defined            no-undef
  105:88   error  'launch_apps' is not defined            no-undef
  106:38   error  'launch_apps' is not defined            no-undef
  119:16   error  'launch_apps' is not defined            no-undef
  121:107  error  'launch_apps' is not defined            no-undef
  125:45   error  'launch_apps' is not defined            no-undef
  126:38   error  'launch_apps' is not defined            no-undef
  179:17   error  'launch_app' is not defined             no-undef
  201:25   error  'launch_app' is not defined             no-undef
  215:39   error  'trash_path' is not defined             no-undef
  228:68   error  'trash_path' is not defined             no-undef
  230:17   error  'launch_app' is not defined             no-undef
  236:13   error  'move_items' is not defined             no-undef
  236:31   error  'trash_path' is not defined             no-undef
  240:5    error  'make_taskbar_sortable' is not defined  no-undef
  262:22   error  Empty block statement                   no-empty
  284:29   error  'launch_app' is not defined             no-undef
  297:17   error  'update_taskbar' is not defined         no-undef
  301:17   error  'update_taskbar' is not defined         no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins a5821815bf chore: Clarify usage of window fields in UIPrompt.js
/puter/src/UI/UIPrompt.js
  26:12  error  'isString' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins c5612beff9 chore: Clarify usage of window fields in UIPopover.js
/puter/src/UI/UIPopover.js
  28:5   error  'global_element_id' is not defined  no-undef
  33:30  error  'global_element_id' is not defined  no-undef
  40:59  error  'global_element_id' is not defined  no-undef
  76:59  error  'taskbar_height' is not defined     no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins eecaf759ea chore: Clarify usage of window fields in UINotification.js
The click handler also makes use of the `options` parameter from
UINotification(), which isn't available there, so I've commented that
out. This needs more work.

/puter/src/UI/UINotification.js
  21:5   error  'global_element_id' is not defined  no-undef
  26:39  error  'global_element_id' is not defined  no-undef
  34:73  error  'global_element_id' is not defined  no-undef
  47:14  error  'toolbar_height' is not defined     no-undef
  55:12  error  'options' is not defined            no-undef
  55:36  error  'options' is not defined            no-undef
  56:13  error  'options' is not defined            no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 620a1a1334 chore: Clarify usage of window fields in UIItem.js
/puter/src/UI/UIItem.js
    42:21   error  'global_element_id' is not defined                            no-undef
    62:23   error  'determine_website_url' is not defined                        no-undef
   100:58   error  'timeago' is not defined                                      no-undef
   104:42   error  'byte_format' is not defined                                  no-undef
   161:151  error  'truncate_filename' is not defined                            no-undef
   161:183  error  'TRUNCATE_LENGTH' is not defined                              no-undef
   171:5    error  'show_or_hide_empty_folder_message' is not defined            no-undef
   178:64   error  'trash_path' is not defined                                   no-undef
   186:9    error  'update_explorer_footer_item_count' is not defined            no-undef
   190:10   error  'is_auto_arrange_enabled' is not defined                      no-undef
   217:21   error  'upload_items' is not defined                                 no-undef
   336:16   error  'mouseover_window' is not defined                             no-undef
   337:39   error  'mouseover_window' is not defined                             no-undef
   338:23   error  'mouseover_window' is not defined                             no-undef
   341:24   error  'mouseX' is not defined                                       no-undef
   341:46   error  'mouseX' is not defined                                       no-undef
   341:69   error  'mouseY' is not defined                                       no-undef
   341:90   error  'mouseY' is not defined                                       no-undef
   342:88   error  'mouseX' is not defined                                       no-undef
   342:113  error  'mouseY' is not defined                                       no-undef
   350:18   error  'is_auto_arrange_enabled' is not defined                      no-undef
   350:78   error  'trash_path' is not defined                                   no-undef
   352:17   error  'mouseover_window' is not defined                             no-undef
   358:17   error  'desktop_item_positions' is not defined                       no-undef
   359:17   error  'save_desktop_item_positions' is not defined                  no-undef
   383:73   error  'mouseover_window' is not defined                             no-undef
   427:21   error  'launch_app' is not defined                                   no-undef
   448:25   error  'copy_items' is not defined                                   no-undef
   450:25   error  'copy_items' is not defined                                   no-undef
   455:25   error  'create_shortcut' is not defined                              no-undef
   468:32   error  'desktop_item_positions' is not defined                       no-undef
   469:25   error  'save_desktop_item_positions' is not defined                  no-undef
   471:21   error  'move_items' is not defined                                   no-undef
   483:89   error  'mouseover_window' is not defined                             no-undef
   525:13   error  'open_item' is not defined                                    no-undef
   540:13   error  'open_item' is not defined                                    no-undef
   579:9    error  'update_explorer_footer_selected_items_count' is not defined  no-undef
   596:13   error  'update_explorer_footer_selected_items_count' is not defined  no-undef
   651:34   error  'truncate_filename' is not defined                            no-undef
   651:66   error  'TRUNCATE_LENGTH' is not defined                              no-undef
   661:9    error  'rename_file' is not defined                                  no-undef
   678:13   error  'last_enter_pressed_to_rename_ts' is not defined              no-undef
   679:13   error  'update_explorer_footer_selected_items_count' is not defined  no-undef
   718:25   error  'activate_item_name_editor' is not defined                    no-undef
   763:78   error  'trash_path' is not defined                                   no-undef
   775:29   error  'move_items' is not defined                                   no-undef
   796:25   error  'zipItems' is not defined                                     no-undef
   810:25   error  'zipItems' is not defined                                     no-undef
   875:39   error  'delete_item' is not defined                                  no-undef
   877:63   error  'trash_path' is not defined                                   no-undef
   885:67   error  'trash_path' is not defined                                   no-undef
   885:116  error  'trash_path' is not defined                                   no-undef
   886:69   error  'trash_path' is not defined                                   no-undef
   906:29   error  'create_shortcut' is not defined                              no-undef
   925:25   error  'move_items' is not defined                                   no-undef
   925:53   error  'trash_path' is not defined                                   no-undef
   936:63   error  'trash_path' is not defined                                   no-undef
   936:122  error  'trash_path' is not defined                                   no-undef
   945:25   error  'open_item' is not defined                                    no-undef
   962:49   error  'suggest_apps_for_fsentry' is not defined                     no-undef
   984:37   error  'user_preferences' is not defined                             no-undef
   987:43   error  'user_preferences' is not defined                             no-undef
   989:42   error  'user_preferences' is not defined                             no-undef
  1007:41   error  'user_preferences' is not defined                             no-undef
  1008:72   error  'user_preferences' is not defined                             no-undef
  1011:33   error  'launch_app' is not defined                                   no-undef
  1047:29   error  'open_item' is not defined                                    no-undef
  1093:25   error  'launch_app' is not defined                                   no-undef
  1114:25   error  'empty_trash' is not defined                                  no-undef
  1127:29   error  'zipItems' is not defined                                     no-undef
  1129:29   error  'trigger_download' is not defined                             no-undef
  1140:25   error  'zipItems' is not defined                                     no-undef
  1151:41   error  'JSZip' is not defined                                        no-undef
  1180:25   error  'move_items' is not defined                                   no-undef
  1219:31   error  'clipboard' is not defined                                    no-undef
  1221:28   error  'clipboard_op' is not defined                                 no-undef
  1222:29   error  'copy_clipboard_items' is not defined                         no-undef
  1223:33   error  'clipboard_op' is not defined                                 no-undef
  1224:29   error  'move_clipboard_items' is not defined                         no-undef
  1247:25   error  'create_shortcut' is not defined                              no-undef
  1265:25   error  'move_items' is not defined                                   no-undef
  1265:47   error  'trash_path' is not defined                                   no-undef
  1290:35   error  'delete_item' is not defined                                  no-undef
  1292:63   error  'trash_path' is not defined                                   no-undef
  1299:67   error  'trash_path' is not defined                                   no-undef
  1299:128  error  'trash_path' is not defined                                   no-undef
  1300:57   error  'trash_path' is not defined                                   no-undef
  1313:25   error  'activate_item_name_editor' is not defined                    no-undef
  1373:9    error  'sort_items' is not defined                                   no-undef
  1376:9    error  'activate_item_name_editor' is not defined                    no-undef
  1433:31   error  'copy_to_clipboard' is not defined                            no-undef
  1517:9    error  'show_or_hide_empty_folder_message' is not defined            no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 9fc983f54a chore: Clarify usage of window fields in UIDesktop.js
/puter/src/UI/UIDesktop.js
    44:24   error  'gui_origin' is not defined                                   no-undef
    46:25   error  'auth_token' is not defined                                   no-undef
    86:5    error  'socket' is not defined                                       no-undef
    95:5    error  'socket' is not defined                                       no-undef
   104:5    error  'socket' is not defined                                       no-undef
   105:43   error  'trash_path' is not defined                                   no-undef
   106:45   error  'trash_path' is not defined                                   no-undef
   109:49   error  'trash_path' is not defined                                   no-undef
   112:5    error  'socket' is not defined                                       no-undef
   118:9    error  'launch_apps' is not defined                                  no-undef
   121:9    error  'launch_apps' is not defined                                  no-undef
   121:39   error  'launch_apps' is not defined                                  no-undef
   124:9    error  'launch_apps' is not defined                                  no-undef
   124:30   error  'launch_apps' is not defined                                  no-undef
   127:5    error  'socket' is not defined                                       no-undef
   146:5    error  'socket' is not defined                                       no-undef
   153:85   error  'truncate_filename' is not defined                            no-undef
   153:114  error  'TRUNCATE_LENGTH' is not defined                              no-undef
   156:77   error  'item_icon' is not defined                                    no-undef
   192:13   error  'update_window_path' is not defined                           no-undef
   199:13   error  'sort_items' is not defined                                   no-undef
   203:5    error  'socket' is not defined                                       no-undef
   206:9    error  'sendItemChangeEventToWatchingApps' is not defined            no-undef
   220:25   error  'fsentry.path' is assigned to itself                          no-self-assign
   233:17   error  'update_explorer_footer_item_count' is not defined            no-undef
   234:17   error  'update_explorer_footer_selected_items_count' is not defined  no-undef
   239:26   error  'trash_path' is not defined                                   no-undef
   249:17   error  'update_window_path' is not defined                           no-undef
   253:26   error  'trash_path' is not defined                                   no-undef
   280:25   error  'item_icon' is not defined                                    no-undef
   281:34   error  'trash_path' is not defined                                   no-undef
   287:39   error  'trash_path' is not defined                                   no-undef
   308:37   error  'item_icon' is not defined                                    no-undef
   319:17   error  'sort_items' is not defined                                   no-undef
   324:13   error  'sort_items' is not defined                                   no-undef
   328:5    error  'socket' is not defined                                       no-undef
   333:9    error  'refresh_user_data' is not defined                            no-undef
   336:5    error  'socket' is not defined                                       no-undef
   341:9    error  'refresh_user_data' is not defined                            no-undef
   344:5    error  'socket' is not defined                                       no-undef
   346:9    error  'sendItemChangeEventToWatchingApps' is not defined            no-undef
   360:85   error  'truncate_filename' is not defined                            no-undef
   360:114  error  'TRUNCATE_LENGTH' is not defined                              no-undef
   363:77   error  'item_icon' is not defined                                    no-undef
   398:13   error  'update_window_path' is not defined                           no-undef
   405:13   error  'sort_items' is not defined                                   no-undef
   409:5    error  'socket' is not defined                                       no-undef
   415:9    error  'sendItemChangeEventToWatchingApps' is not defined            no-undef
   440:81   error  'item_icon' is not defined                                    no-undef
   445:17   error  'sort_items' is not defined                                   no-undef
   455:29   error  'item_icon' is not defined                                    no-undef
   463:17   error  Duplicate key 'associated_app_name'                           no-dupe-keys
   470:17   error  'sort_items' is not defined                                   no-undef
   491:42   error  'desktop_path' is not defined                                 no-undef
   496:5    error  'getItem' is not defined                                      no-undef
   508:8    error  'url_query_params' is not defined                             no-undef
   525:9    error  'update_user_preferences' is not defined                      no-undef
   560:17   error  'upload_items' is not defined                                 no-undef
   560:52   error  'desktop_path' is not defined                                 no-undef
   577:16   error  'mouseover_window' is not defined                             no-undef
   585:69   error  'desktop_path' is not defined                                 no-undef
   613:17   error  'copy_items' is not defined                                   no-undef
   613:43   error  'desktop_path' is not defined                                 no-undef
   617:17   error  'move_items' is not defined                                   no-undef
   617:43   error  'desktop_path' is not defined                                 no-undef
   649:39   error  'is_auto_arrange_enabled' is not defined                      no-undef
   651:37   error  'is_auto_arrange_enabled' is not defined                      no-undef
   651:64   error  'is_auto_arrange_enabled' is not defined                      no-undef
   652:37   error  'store_auto_arrange_preference' is not defined                no-undef
   652:67   error  'is_auto_arrange_enabled' is not defined                      no-undef
   653:40   error  'is_auto_arrange_enabled' is not defined                      no-undef
   654:41   error  'sort_items' is not defined                                   no-undef
   655:41   error  'set_sort_by' is not defined                                  no-undef
   656:41   error  'clear_desktop_item_positions' is not defined                 no-undef
   658:41   error  'set_desktop_item_positions' is not defined                   no-undef
   668:44   error  'is_auto_arrange_enabled' is not defined                      no-undef
   671:37   error  'sort_items' is not defined                                   no-undef
   672:37   error  'set_sort_by' is not defined                                  no-undef
   677:44   error  'is_auto_arrange_enabled' is not defined                      no-undef
   680:37   error  'sort_items' is not defined                                   no-undef
   681:37   error  'set_sort_by' is not defined                                  no-undef
   686:44   error  'is_auto_arrange_enabled' is not defined                      no-undef
   689:37   error  'sort_items' is not defined                                   no-undef
   690:37   error  'set_sort_by' is not defined                                  no-undef
   695:44   error  'is_auto_arrange_enabled' is not defined                      no-undef
   698:37   error  'sort_items' is not defined                                   no-undef
   699:37   error  'set_sort_by' is not defined                                  no-undef
   708:44   error  'is_auto_arrange_enabled' is not defined                      no-undef
   712:37   error  'sort_items' is not defined                                   no-undef
   713:37   error  'set_sort_by' is not defined                                  no-undef
   718:44   error  'is_auto_arrange_enabled' is not defined                      no-undef
   722:37   error  'sort_items' is not defined                                   no-undef
   723:37   error  'set_sort_by' is not defined                                  no-undef
   757:43   error  'desktop_path' is not defined                                 no-undef
   767:35   error  'clipboard' is not defined                                    no-undef
   769:32   error  'clipboard_op' is not defined                                 no-undef
   770:33   error  'copy_clipboard_items' is not defined                         no-undef
   770:54   error  'desktop_path' is not defined                                 no-undef
   771:37   error  'clipboard_op' is not defined                                 no-undef
   772:33   error  'move_clipboard_items' is not defined                         no-undef
   780:35   error  'actions_history' is not defined                              no-undef
   782:29   error  'undo_last_action' is not defined                             no-undef
   791:29   error  'init_upload_using_dialog' is not defined                     no-undef
   818:9    error  'is_embedded' is not defined                                  no-undef
   911:12   error  'user' is not defined                                         no-undef
   922:13   error  'is_embedded' is not defined                                  no-undef
   940:8    error  'url_query_params' is not defined                             no-undef
   941:28   error  'url_query_params' is not defined                             no-undef
   943:35   error  'home_path' is not defined                                    no-undef
   944:16   error  'url_query_params' is not defined                             no-undef
   945:34   error  'url_query_params' is not defined                             no-undef
   950:29   error  'item_icon' is not defined                                    no-undef
   966:13   error  'launch_app' is not defined                                   no-undef
   967:23   error  'app_launched_from_url' is not defined                        no-undef
   970:25   error  'app_query_params' is not defined                             no-undef
  1017:40   error  'taskbar_height' is not defined                               no-undef
  1023:40   error  'user' is not defined                                         no-undef
  1024:9    error  'getItem' is not defined                                      no-undef
  1031:21   error  'setItem' is not defined                                      no-undef
  1125:47   error  'user' is not defined                                         no-undef
  1128:48   error  'user' is not defined                                         no-undef
  1131:25   error  'update_auth_data' is not defined                             no-undef
  1170:37   error  'listSupportedLanguages' is not defined                       no-undef
  1249:29   error  'logout' is not defined                                       no-undef
  1253:25   error  'logout' is not defined                                       no-undef
  1261:9    error  'is_fullscreen' is not defined                                no-undef
  1308:5    error  'launch_app' is not defined                                   no-undef
  1381:9    error  'launch_apps' is not defined                                  no-undef
  1460:14   error  'api_origin' is not defined                                   no-undef
  1468:40   error  'auth_token' is not defined                                   no-undef
  1488:14   error  'toolbar_height' is not defined                               no-undef
  1502:9    error  'reset_window_size_and_position' is not defined               no-undef
  1513:5    error  'refresh_desktop_background' is not defined                   no-undef
  1520:26   error  'window_border_radius' is not defined                         no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins dd7361441d chore: Clarify usage of window fields in UIContextMenu.js
/puter/src/UI/UIContextMenu.js
   23:21  error  'global_element_id' is not defined      no-undef
  117:57  error  'taskbar_height' is not defined         no-undef
  118:52  error  'taskbar_height' is not defined         no-undef
  260:17  error  'make_taskbar_sortable' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 63347843cb chore: Clarify usage of window fields in UIAlert.js
/puter/src/UI/UIAlert.js
  26:12  error  'isString' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins c2ef0a9578 chore: Clarify usage of window fields in Settings app
Solves these eslint issues:

/puter/src/UI/Settings/UITabAccount.js
  34:13   error  'user' is not defined  no-undef
  47:99   error  'user' is not defined  no-undef
  55:12   error  'user' is not defined  no-undef
  59:105  error  'user' is not defined  no-undef

/puter/src/UI/Settings/UITabLanguage.js
  35:37  error  'listSupportedLanguages' is not defined  no-undef

/puter/src/UI/Settings/UITabUsage.js
   45:18  error  'api_origin' is not defined   no-undef
   50:46  error  'auth_token' is not defined   no-undef
   54:21  error  'logout' is not defined       no-undef
   96:18  error  'api_origin' is not defined   no-undef
  101:46  error  'auth_token' is not defined   no-undef
  105:21  error  'logout' is not defined       no-undef
  116:51  error  'byte_format' is not defined  no-undef
  123:41  error  'byte_format' is not defined  no-undef
  124:45  error  'byte_format' is not defined  no-undef

/puter/src/UI/Settings/UIWindowChangeEmail.js
   96:18  error  'api_origin' is not defined  no-undef
  100:44  error  'auth_token' is not defined  no-undef

/puter/src/UI/Settings/UIWindowFinalizeUserDeletion.js
   29:12  error  'user' is not defined        no-undef
   97:16  error  'user' is not defined        no-undef
  115:22  error  'api_origin' is not defined  no-undef
  120:50  error  'auth_token' is not defined  no-undef
  127:25  error  'logout' is not defined      no-undef
  139:25  error  'logout' is not defined      no-undef

/puter/src/UI/Settings/UIWindowSettings.js
  48:162  error  'icons' is not defined  no-undef
  86:13   error  Duplicate key 'height'  no-dupe-keys
2024-05-02 11:21:50 +01:00
Sam Atkins d17e0b80b3 chore: Add missing import for node:console
Solves these eslint issues:

/puter/run-selfhosted.js
   49:9  error  'console' is not defined  no-undef
   64:5  error  'console' is not defined  no-undef
  127:5  error  'console' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 8d4a1e0ed3 fix: Add missing TextEncoder to PTT
Solves this eslint issue:

/puter/packages/terminal/src/pty/PTT.js
  35:29  error  'encoder' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 280479c0c6 chore: Clarify usage of window fields in IPC.js
Resolves these eslint errors:

/puter/src/IPC.js
    53:69  error  'appCallbackFunctions' is not defined                no-undef
    55:9   error  'appCallbackFunctions' is not defined                no-undef
    57:16  error  'appCallbackFunctions' is not defined                no-undef
    81:33  error  'window_for_app_instance' is not defined             no-undef
    84:27  error  'iframe_for_app_instance' is not defined             no-undef
   105:48  error  Empty block statement                                no-empty
   180:18  error  'api_origin' is not defined                          no-undef
   190:44  error  'auth_token' is not defined                          no-undef
   194:21  error  'logout' is not defined                              no-undef
   207:18  error  'api_origin' is not defined                          no-undef
   216:44  error  'auth_token' is not defined                          no-undef
   220:21  error  'logout' is not defined                              no-undef
   239:18  error  'api_origin' is not defined                          no-undef
   248:44  error  'auth_token' is not defined                          no-undef
   252:21  error  'logout' is not defined                              no-undef
   268:13  error  'is_auth' is not defined                             no-undef
   309:13  error  'is_auth' is not defined                             no-undef
   348:27  error  'window_for_app_instance' is not defined             no-undef
   360:27  error  'window_for_app_instance' is not defined             no-undef
   576:35  error  'uuidv4' is not defined                              no-undef
   582:9   error  'launch_app' is not defined                          no-undef
   597:37  error  'appdata_path' is not defined                        no-undef
   629:12  error  'appdata_signatures' is not defined                  no-undef
   633:23  error  'appdata_signatures' is not defined                  no-undef
   638:30  error  'appdata_path' is not defined                        no-undef
   647:25  error  'appdata_signatures' is not defined                  no-undef
   664:29  error  'appdata_signatures' is not defined                  no-undef
   682:13  error  'is_auth' is not defined                             no-undef
   717:13  error  'is_auth' is not defined                             no-undef
   745:13  error  'is_auth' is not defined                             no-undef
   773:13  error  'is_auth' is not defined                             no-undef
   783:22  error  'api_origin' is not defined                          no-undef
   793:48  error  'auth_token' is not defined                          no-undef
   797:25  error  'logout' is not defined                              no-undef
   825:13  error  'is_auth' is not defined                             no-undef
   857:36  error  'operation_id' is not defined                        no-undef
   872:41  error  'auth_token' is not defined                          no-undef
   873:41  error  'api_origin' is not defined                          no-undef
   939:45  error  'item_icon' is not defined                           no-undef
   951:33  error  'sort_items' is not defined                          no-undef
   954:29  error  'show_save_account_notice_if_needed' is not defined  no-undef
   998:38  error  'busy_indicator_hide_delay' is not defined           no-undef
  1004:33  error  'busy_indicator_hide_delay' is not defined           no-undef
  1018:37  error  'pictures_path' is not defined                       no-undef
  1020:37  error  'desktop_path' is not defined                        no-undef
  1022:37  error  'documents_path' is not defined                      no-undef
  1024:37  error  'videos_path' is not defined                         no-undef
  1026:37  error  'audio_path' is not defined                          no-undef
  1028:37  error  'appdata_path' is not defined                        no-undef
  1032:13  error  'is_auth' is not defined                             no-undef
  1044:28  error  'operation_id' is not defined                        no-undef
  1059:33  error  'auth_token' is not defined                          no-undef
  1060:33  error  'api_origin' is not defined                          no-undef
  1145:31  error  'iframe_for_app_instance' is not defined             no-undef
  1163:31  error  'window_for_app_instance' is not defined             no-undef
  1178:36  error  'get_apps' is not defined                            no-undef
  1199:11  error  'window_for_app_instance' is not defined             no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins ca65ed1258 chore: Use this to refer to itemWatchCallbackFunctions field
Solves these eslint issues:

/puter/packages/puter-js/src/modules/UI.js
  418:20  error  'itemWatchCallbackFunctions' is not defined  no-undef
  418:74  error  'itemWatchCallbackFunctions' is not defined  no-undef
  419:21  error  'itemWatchCallbackFunctions' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 33785b3786 chore: Add missing imports for node:process 2024-05-02 11:21:50 +01:00
Sam Atkins 96e9c154bd chore: Fix a couple of regex related eslint issues
/puter/packages/phoenix/src/puter-shell/providers/ScriptCommandProvider.js
  27:38  error  Unnecessary escape character: \/  no-useless-escape

/puter/packages/phoenix/src/util/wrap-text.js
  24:33  error  Unexpected control character(s) in regular expression: \x1b  no-control-regex
2024-05-02 11:21:50 +01:00
Sam Atkins c8a20cadbf fix: Correct grep output when asking for line numbers
A couple of issues here:
- We didn't pass the line number to do_grep_line() so `i` was undefined
- Operator precedence messed with the ternary so when line numbers were
  requested, the line wouldn't be output.

Found thanks to this now-solved eslint issue:

/puter/packages/phoenix/src/puter-shell/coreutils/grep.js
  100:60  error  'i' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 71f8afab9a chore: Adjust comment for eslint
This was confusing its fallthrough detection:

/puter/packages/phoenix/src/puter-shell/coreutils/date.js
  132:21  error  Expected a 'break' statement before 'case'  no-fallthrough
2024-05-02 11:21:50 +01:00
Sam Atkins 6ad8f5e06a fix: Parse octal echo escapes
Found by this eslint issue:

/puter/packages/phoenix/src/puter-shell/coreutils/coreutil_lib/echo_escapes.js
  107:59  error  'hexchars' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 50d75cd2f9 refactor: Make loop condition non-constant
Resolves this eslint issue:

/puter/packages/phoenix/src/ansi-shell/readline/readline.js
  154:33  error  Unexpected constant condition  no-constant-condition
2024-05-02 11:21:50 +01:00
Sam Atkins 6d895dff42 chore: Remove empty block statement
Resolves this eslint issue:

/puter/packages/phoenix/src/ansi-shell/parsing/PuterShellParser.js
  25:9  error  Empty block statement  no-empty
2024-05-02 11:21:50 +01:00
Sam Atkins d4c2b492ef fix: Correct inverted instanceof check in SignalReader.read()
Also make tmp_value non-const because it gets modified later.

Solves these eslint issues:

/puter/packages/phoenix/src/ansi-shell/ioutil/SignalReader.js
  45:14  error  Unexpected negating the left operand of 'instanceof' operator  no-unsafe-negation
  46:13  error  'tmp_value' is constant                                        no-const-assign
2024-05-02 11:21:50 +01:00
Sam Atkins 64c886bfeb chore: Clarify setter to not return a value
Solves this eslint issue:

/puter/packages/phoenix/src/ansi-shell/ANSIShell.js
  86:23  error  Setter cannot return a value  no-setter-return
2024-05-02 11:21:50 +01:00
Sam Atkins 2094e05a2e chore: Comment out unreachable code in ExpectationService
The `return` looks temporary but I don't know this code well enough.

Solves this eslint issue:

/puter/packages/backend/src/services/runtime-analysis/ExpectationService.js
  94:9  error  Unreachable code  no-unreachable
2024-05-02 11:21:50 +01:00
Sam Atkins 0df0de6507 chore: Define def() and defv() using const
Fixes these eslint issues:

/puter/packages/backend/src/services/auth/TokenService.js
   3:1   error  'def' is not defined   no-undef
  18:1   error  'defv' is not defined  no-undef
  61:11  error  'def' is not defined   no-undef
  69:21  error  'defv' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 01ab6b88ea chore: Remove unused uses of uuid_user in save_account.js
The variable doesn't exist, and we never use it after this. Seems like a
copy-paste error.

Solves these eslint errors:

/puter/packages/backend/src/routers/save_account.js
  90:9   error  'uuid_user' is not defined  no-undef
  91:9   error  'uuid_user' is not defined  no-undef
  91:21  error  'uuid_user' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 9b3dd6b753 chore: Fix eslint issues in backend util
/puter/packages/backend/src/util/stdioutil.js
  26:24  error  Unexpected control character(s) in regular expression: \x1b  no-control-regex

/puter/packages/backend/src/util/streamutil.js
  368:1  error  'string_to_stream' is not defined  no-undef
  463:5  error  'string_to_stream' is not defined  no-undef

/puter/packages/backend/src/util/strutil.js
  42:1  error  'format_as_usd' is not defined  no-undef
  56:5  error  'format_as_usd' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 60523dc7a7 chore: Fix some eslint issues in services
/puter/packages/backend/src/services/ContextInitService.js
  57:18  error  'async_factory' is not defined  no-undef

/puter/packages/backend/src/services/StorageService.js
  22:5  error  Expected to call 'super()'  constructor-super

/puter/packages/backend/src/services/WebServerService.js
  258:35  error  'services' is not defined  no-undef

/puter/packages/backend/src/services/auth/AuthService.js
  52:13  error  Unreachable code  no-unreachable

/puter/packages/backend/src/services/drivers/implementations/BaseImplementation.js
   64:25  error  'services' is not defined  no-undef
   75:39  error  'services' is not defined  no-undef
  117:39  error  'services' is not defined  no-undef
  123:42  error  'services' is not defined  no-undef
  149:42  error  'services' is not defined  no-undef
  168:38  error  'services' is not defined  no-undef

/puter/packages/backend/src/services/drivers/implementations/PuterDriverProxy.js
  43:5  error  Expected to call 'super()'              constructor-super
  44:9  error  'this' is not allowed before 'super()'  no-this-before-super

/puter/packages/backend/src/services/drivers/meta/Construct.js
  125:9  error  Unreachable code  no-unreachable

/puter/packages/backend/src/services/runtime-analysis/PagerService.js
  49:41  error  'util' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins ca3f9a823d chore: Fix some eslint issues in routers
/puter/packages/backend/src/routers/open_item.js
  48:10  error  Unexpected negating the left operand of 'instanceof' operator  no-unsafe-negation

/puter/packages/backend/src/routers/save_account.js
  106:34  error  'get_user' is not defined   no-undef

/puter/packages/backend/src/routers/sign.js
  37:10  error  Unexpected negating the left operand of 'instanceof' operator  no-unsafe-negation
2024-05-02 11:21:50 +01:00
Sam Atkins 0c0846eef9 chore: Fix some backend router eslint issues
/puter/packages/backend/src/routers/auth/list-permissions.js
  36:15  error  'APIError' is not defined  no-undef

/puter/packages/backend/src/routers/auth/list-sessions.js
  17:15  error  'APIError' is not defined  no-undef

/puter/packages/backend/src/routers/auth/revoke-user-app.js
  34:15  error  'APIError' is not defined  no-undef
  43:15  error  'APIError' is not defined  no-undef

/puter/packages/backend/src/routers/delete-site.js
  43:11  error  Unexpected empty object pattern  no-empty-pattern

/puter/packages/backend/src/routers/drivers/usage.js
  146:11  error  'k' is not defined  no-undef
  147:21  error  'k' is not defined  no-undef
  147:52  error  'k' is not defined  no-undef

/puter/packages/backend/src/routers/drivers/xd.js
  68:5  error  'window' is not defined  no-undef
  69:21  error  Parsing error: The keyword 'interface' is reserved

/puter/packages/backend/src/routers/filesystem_api/batch/all.js
   51:21  error  'get_app' is not defined       no-undef
  224:13  error  Unexpected constant condition  no-constant-condition

/puter/packages/backend/src/routers/filesystem_api/copy.js
   70:10  error  Unexpected constant condition  no-constant-condition
  106:13  error  Duplicate key 'new_name'       no-dupe-keys

/puter/packages/backend/src/routers/filesystem_api/read.js
  80:5  error  Unreachable code  no-unreachable

/puter/packages/backend/src/routers/filesystem_api/token-read.js
   53:9  error  Unreachable code  no-unreachable
   58:9  error  Unreachable code  no-unreachable
  104:5  error  Unreachable code  no-unreachable

/puter/packages/backend/src/routers/hosting/puter-site.js
  65:21  error  Unexpected constant nullishness on the left-hand side of a `??` expression  no-constant-binary-expression
2024-05-02 11:21:50 +01:00
Sam Atkins b4af28a91b chore: Miscellaneous eslint fixes
/puter/packages/backend/src/om/entitystorage/ValidationES.js
  89:25  error  Do not assign to the exception parameter  no-ex-assign

/puter/packages/backend/src/om/proptypes/__all__.js
  166:17  warning  Unexpected 'debugger' statement  no-debugger

/puter/packages/backend/src/routers/_default.js
  405:31  error  'err' is not defined  no-undef
2024-05-02 11:21:50 +01:00
Sam Atkins 4879ee93bf chore: Fix eslint errors in backend/src/helpers.js
/puter/packages/backend/src/helpers.js
   682:9   error  'sharing_users' is not defined     no-undef
   689:12  error  'sharing_users' is not defined     no-undef
   690:28  error  'sharing_users' is not defined     no-undef
   695:28  error  'sharing_users' is not defined     no-undef
   720:9   error  'shared_fsentries' is not defined  no-undef
   733:12  error  'shared_fsentries' is not defined  no-undef
   734:28  error  'shared_fsentries' is not defined  no-undef
   735:17  error  'shared_fsentries' is not defined  no-undef
   735:58  error  'shared_fsentries' is not defined  no-undef
   736:31  error  'shared_fsentries' is not defined  no-undef
   900:57  error  'e' is not defined                 no-undef
  1849:18  error  Empty block statement              no-empty
2024-05-02 11:21:50 +01:00
Sam Atkins 8ab1cd0ca8 chore: Remove unused 'connective' source files 2024-05-02 11:21:50 +01:00
Sam Atkins 11f3e29604 chore: Disable eslint checks on puter-js tests
These currently work in a way that's different from what eslint expects,
so disable it. At some point it would be good if it could check them
(and if the tests could run on CI) but right now they just make a lot of
noise.
2024-05-02 11:21:50 +01:00
Sam Atkins 8cf6379de3 chore: Correct eslint errors in backend filesystem
Removes or disables the following eslint errors/warnings:

/puter/packages/backend/src/api/filesystem/FlagParam.js
  33:19  error  'APIError' is not defined  no-undef
  47:19  error  'APIError' is not defined  no-undef
  58:15  error  'APIError' is not defined  no-undef

/puter/packages/backend/src/api/filesystem/StringParam.js
  32:19  error  'APIError' is not defined  no-undef
  39:13  error  'APIError' is not defined  no-undef
  46:19  error  'APIError' is not defined  no-undef

/puter/packages/backend/src/filesystem/FilesystemService.js
  141:17  warning  Unexpected 'debugger' statement  no-debugger
  366:21  error    'services' is not defined        no-undef

/puter/packages/backend/src/filesystem/batch/BatchExecutor.js
  121:21  error  Do not assign to the exception parameter  no-ex-assign

/puter/packages/backend/src/filesystem/hl_operations/hl_data_read.js
  44:19  error  'APIError' is not defined     no-undef
  47:22  error  'chkperm' is not defined      no-undef
  48:19  error  'APIError' is not defined     no-undef
  51:29  error  'LLRead' is not defined       no-undef
  54:13  error  'version_id' is not defined   no-undef
  88:35  error  'PassThrough' is not defined  no-undef

/puter/packages/backend/src/filesystem/hl_operations/hl_mkdir.js
  68:49  error  'fs' is not defined  no-undef

/puter/packages/backend/src/filesystem/hl_operations/hl_move.js
  102:33  error  'get_user' is not defined  no-undef
  104:35  error  'get_user' is not defined  no-undef
  110:33  error  'df' is not defined        no-undef

/puter/packages/backend/src/filesystem/hl_operations/hl_read.js
  54:13  error  'stream' is constant  no-const-assign

/puter/packages/backend/src/filesystem/hl_operations/hl_stat.js
  40:37  error  'APIError' is not defined  no-undef

/puter/packages/backend/src/filesystem/lib/PuterPath.js
  67:5  error  Expected to return a value in getter 'hasRelativePortion'  getter-return

/puter/packages/backend/src/filesystem/ll_operations/ll_copy_idea.js
   53:21  error  'UploadProgressTracker' is not defined   no-undef
   73:17  error  'PuterS3StorageStrategy' is not defined  no-undef
  137:22  error  'LLFilesystemOperation' is not defined   no-undef

/puter/packages/backend/src/filesystem/ll_operations/ll_read.js
  102:65  error  'offset' is not defined  no-undef
  102:73  error  'offset' is not defined  no-undef
  102:80  error  'length' is not defined  no-undef

/puter/packages/backend/src/filesystem/ll_operations/ll_rmnode.js
  43:23  error  'APIError' is not defined  no-undef

/puter/packages/backend/src/filesystem/storage/SystemFSEntryService.js
  101:26  error  '_path' is not defined  no-undef

/puter/packages/backend/src/filesystem/validation.js
  27:29  error  Unexpected control character(s) in regular expression: \x00, \x1f  no-control-regex
  28:29  error  Unexpected control character(s) in regular expression: \x00, \x1f  no-control-regex
  28:31  error  Unnecessary escape character: \/                                   no-useless-escape
2024-05-02 11:21:50 +01:00
Sam Atkins 4a426ce045 chore: Remove duplicate translation keys 2024-05-02 11:21:50 +01:00
Sam Atkins 25b35769c5 chore: Set-up eslint
eslint is a static analysis tool that tries to identify bugs and
mistakes in the code. We have quite a variety of code in this repo so
the config is a little complicated, but I've tried to make it clear.
It's found a *lot* of issues (over 1700), and while many of which will
not be actual problems, (it doesn't like us using window properties
without `window.`,) but some definitely are.
2024-05-02 11:21:50 +01:00
Nariman Jelveh 4b0c474537 Merge pull request #363 from AtkinsSJ/document-selfhost-limitations
docs: Explain self-host differences
2024-05-01 11:09:37 -07:00
Sam Atkins a74b8e32fa docs: Explain self-host differences 2024-04-30 16:29:57 +01:00
Sam Atkins 251368e749 docs: Link to sections in README 2024-04-30 16:29:47 +01:00
Nariman Jelveh 0b1f963f0b Add fun HN badges! 2024-04-30 00:01:36 -07:00
Nariman Jelveh 4ea54823b0 Merge pull request #360 from Bashamega/bashamega-patch
Fixes the scroll bar
2024-04-29 22:20:33 -07:00
Bashamega c6ffa6e9e1 fix 2024-04-30 06:48:11 +03:00
KernelDeimos 8e6ee9ea79 Fix oversight in token compression 2024-04-29 22:48:10 -04:00
KernelDeimos e7e7363fa7 Drop useless header 2024-04-29 22:34:19 -04:00
KernelDeimos 5a76bad28d fix: reduce token lengths 2024-04-29 21:46:02 -04:00
KernelDeimos c1e4eeec32 Add TokenService and test utility 2024-04-29 21:11:31 -04:00
KernelDeimos d2de46edfb fix: increase QR code size 2024-04-29 19:48:01 -04:00
KernelDeimos 04432df554 feat: improve password recovery experience 2024-04-29 19:26:29 -04:00
KernelDeimos c44028f413 refactor: normalize email calls 2024-04-29 17:34:24 -04:00
Nariman Jelveh 8cad610a54 more sanitization, just in case 2024-04-29 14:09:54 -07:00
Nariman Jelveh f807a28e95 bugfix 2024-04-29 12:05:41 -07:00
KernelDeimos 4c1d5a4b6d fix: fix error handling for outdated node versions 2024-04-29 02:42:04 -04:00
Nariman Jelveh ecfbc44a20 safely escape settings strings 2024-04-28 16:02:54 -07:00
Nariman Jelveh 63c81d6fff Update UITabAccount.js 2024-04-27 19:29:44 -07:00
Nariman Jelveh 42d85abfc2 Update WebServerService.js 2024-04-27 19:10:10 -07:00
Nariman Jelveh fd4e2f59dc Update WebServerService.js 2024-04-27 19:03:48 -07:00
Nariman Jelveh 053728a03f Validate the Host header before responding to requests 2024-04-27 18:52:01 -07:00
Nariman Jelveh 92f6c8003b Merge pull request #352 from enweazudaniel/main
Language: Add Igbo translations
2024-04-27 14:49:28 -07:00
Nariman Jelveh 826afd7653 change en to ig for object name 2024-04-27 14:38:18 -07:00
enweazudaniel 0df9519f76 Language: Add Igbo 2024-04-27 12:06:29 +01:00
enweazudaniel d5d0f67797 Language: Add (Igbo) ig.js 2024-04-27 12:03:18 +01:00
Nariman Jelveh 219cc94fbf Merge branch 'main' of https://github.com/HeyPuter/puter into main 2024-04-26 19:13:34 -07:00
Nariman Jelveh bfa6419070 Update helpers.js 2024-04-26 19:13:22 -07:00
KernelDeimos d7d6ff0cca Rate limit updates 2024-04-26 21:02:01 -04:00
KernelDeimos 79d6f64451 Notify old email when email change is initiated 2024-04-26 21:02:01 -04:00
Nariman Jelveh fd59a6c994 Merge branch 'main' of https://github.com/HeyPuter/puter into main 2024-04-26 15:36:22 -07:00
Nariman Jelveh cb4776cc0e do not append question mark to app URL if there is no query params to append 2024-04-26 15:36:15 -07:00
Eric Dubé 2ee00ca8e6 Revert "fix(security): Prevent email enumeration" (#351) 2024-04-26 18:22:14 -04:00
Nariman Jelveh a3ec7bb5ad Fix the issue with context submenu not closing parent menu when clicked 2024-04-25 23:14:39 -07:00
Nariman Jelveh faa72fd97c Update UIWindow.js 2024-04-25 23:10:03 -07:00
Nariman Jelveh 378b87459a Add robust hostname comparison for when declaring an environment as GUI 2024-04-25 17:51:20 -07:00
KernelDeimos 30f17ade3a fix: use primary read in signup 2024-04-25 19:46:39 -04:00
KernelDeimos ecec8bf75d Use pread for signup page 2024-04-25 19:44:06 -04:00
KernelDeimos 736ebb6f28 Improve server health service 2024-04-25 19:39:18 -04:00
Nariman Jelveh 928dd90f61 Merge pull request #346 from youngsiiimba/main
fix(security): Prevent email enumeration
2024-04-25 14:59:56 -07:00
KernelDeimos eb166a67a9 fix(security): Fix session revocation 2024-04-25 16:19:46 -04:00
Nariman Jelveh 51a6d1ea1d Allow the <p> tag in UIAlert body 2024-04-25 13:19:03 -07:00
Nariman Jelveh 3cce0e88df Revert "Allow the <p> tag in UIAlert body"
This reverts commit e2dcc813ec.
2024-04-25 13:18:37 -07:00
Nariman Jelveh e2dcc813ec Allow the <p> tag in UIAlert body 2024-04-25 13:18:28 -07:00
Nariman Jelveh a572a0a640 Merge pull request #341 from Xiayucheng1212/pass_locale
Pass locale to the iframe url whenever accessing an app
2024-04-25 13:14:16 -07:00
Nariman Jelveh c4b2d9861f Clean up some of the unnecessary console warnings 2024-04-25 13:11:11 -07:00
Simba Chawanda ed70314686 fix(security): Prevent email enumeration 2024-04-25 09:27:37 +02:00
Nariman Jelveh f5f35f2c37 Phase out openItem in IPC
also fix the issue with directories being opened with notepad after setting notepad as default app for files without extensions.
2024-04-24 23:12:57 -07:00
KernelDeimos ccf1afc93c feat(security): add ip rate limiting 2024-04-24 22:35:40 -04:00
KernelDeimos 7800ef6102 fix(security): skip cache when checking old passwd 2024-04-24 22:28:27 -04:00
Nariman Jelveh 25eea41f60 Keep track of app_instance_ids 2024-04-24 17:57:30 -07:00
Nariman Jelveh c21c16026b Update ko.js 2024-04-24 14:43:07 -07:00
KernelDeimos 74e9270d58 Fix 2024-04-24 16:16:31 -04:00
KernelDeimos b2e72adba9 Add ratelimit for /confirm-email 2024-04-24 16:12:09 -04:00
KernelDeimos 1eac147918 Add ratelimit for /contactUs 2024-04-24 16:09:04 -04:00
スーチ・ファトマワティ 3f6f4bb4c0 fix(security): update follow-redirects
When using axios, its dependency follow-redirects only clears authorization header during cross-domain redirect, but allows the proxy-authentication header which contains credentials too.

## Steps To Reproduce & PoC
```js
const axios = require('axios');

axios.get('http://127.0.0.1:10081/', {
 headers: {
 'AuThorization': 'Rear Test',
 'ProXy-AuthoriZation': 'Rear Test',
 'coOkie': 't=1'
 }
})
 .then((response) => {
 console.log(response);
 })
```
When I meet the cross-domain redirect, the sensitive headers like authorization and cookie are cleared, but proxy-authentication header is kept.

```diff
- removeMatchingHeaders(/^(?:authorization|cookie)$/i, this._options.headers);
+ removeMatchingHeaders(/^(?:authorization|proxy-authorization|cookie)$/i, this._options.headers);
```
CWE-200
`CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N`
CVE-2024-28849
2024-04-24 15:23:47 -04:00
Sam Atkins a8d1d3b87a docs: Add help text to dcall utility (#335) 2024-04-24 15:21:31 -04:00
Nariman Jelveh fb3dfc5672 Merge branch 'main' of https://github.com/HeyPuter/puter into main 2024-04-24 12:06:16 -07:00
Nariman Jelveh cdd0231a76 translation fix 2024-04-24 12:06:05 -07:00
Eric Dubé e9e43c059a Merge pull request #342 from brhahlen/docker-ci-improvements
Update Docker CI
2024-04-24 15:04:29 -04:00
Nariman Jelveh 548e975cac remove unused imports, sanitization, and validation of input 2024-04-24 10:05:53 -07:00
Sam Atkins cf0eee1fa3 feat: Add command names to phoenix tab-completion
Gives CommandProviders a `complete(query, {ctx})` method where they can provide completed command names, and then make use of this in CommandCompleter.

Supported CommandProvider sources:
- Shell built-ins (was supported previously)
- PATH executables (when running under Node)
- Puter app names (when running in Puter)

Script filenames are not yet supported.
2024-04-24 15:08:54 +01:00
Sam Atkins dc5b010d09 feat: Allow querying puter-apps driver by partial app names 2024-04-24 15:08:54 +01:00
Sam Atkins a854a0dc0a feat: Implement 'Like' predicate in entity storage
This acts like the SQL 'LIKE' keyword, allowing partial string matches.
2024-04-24 15:08:54 +01:00
Sam Atkins d733119456 fix: Make PathCommandProvider reject queries with path separators
`../bin/foo` should only find `foo` relative to the current working
directory, not to directories in PATH.

Also switch to using the Node path library since PathCommandProvider is
Node-only, and this means getting the correct path separator and
delimiter values on Windows.
2024-04-24 11:45:21 +01:00
Sam Atkins 670673ab8d Rename FooCompleter js files to match FooCommandProvider file names 2024-04-24 11:19:25 +01:00
Ben Hählen 028b37b9d4 Update Docker CI 2024-04-24 11:29:44 +02:00
Xiayucheng1212 916e1bb95c Add local to url 2024-04-24 16:40:42 +08:00
Nariman Jelveh c9e8207e4b Clean up the console warninf message 2024-04-23 23:53:15 -07:00
Nariman Jelveh aef6df048c allow the <strong> tag in UIAlert 2024-04-23 23:06:04 -07:00
Nariman Jelveh f8b2b18185 Update en.js 2024-04-23 22:49:16 -07:00
Nariman Jelveh ce411ed728 Perform more advanced input and string sanitization and validation for performance and security 2024-04-23 22:46:33 -07:00
Nariman Jelveh 9859a32e15 Deprecate and remove UIWindowConfirmDownload 2024-04-23 16:35:28 -07:00
Nariman Jelveh 3be7af8fb8 Merge branch 'main' of https://github.com/HeyPuter/puter into main 2024-04-23 16:26:07 -07:00
Nariman Jelveh 5538649125 Update UIAlert.js 2024-04-23 16:25:57 -07:00
Eric Dubé 97ee951b1f Merge pull request #339 from HeyPuter/eric/rate-limits
Add ip rate limiting to some endpoints
2024-04-23 19:24:17 -04:00
KernelDeimos 44aac16991 Add ip rate limiting 2024-04-23 19:13:37 -04:00
Nariman Jelveh ab5fee1562 deprecate UIWindowGetCopyLink as it's not supported by the backend 2024-04-23 15:43:55 -07:00
KernelDeimos 65a73b5b45 Rename workspace modules to avoid confusion 2024-04-23 04:06:15 -04:00
KernelDeimos 74e213a534 fix(security): always use application/octet-stream 2024-04-22 23:54:03 -04:00
KernelDeimos f9d561d40b docs: document purpose of scary-looking token 2024-04-22 23:48:45 -04:00
Nariman Jelveh 5066128c72 Merge pull request #329 from Eric-Lighthall/desktop-bg-revert
feat: add option to change desktop background to default
2024-04-22 20:26:39 -07:00
Eric Dubé a2de5e3da2 Merge pull request #328 from HeyPuter/release-please--branches--main--components--puter.com
chore(main): release 2.2.0
2024-04-22 22:05:35 -04:00
github-actions[bot] 458f2eae4c chore(main): release 2.2.0 2024-04-23 02:03:34 +00:00
KernelDeimos c166560ff4 feat: add /healthcheck endpoint 2024-04-22 22:02:40 -04:00
Eric Lighthall 03f05f316f feat: add option to change desktop background to default
users can now select 'default' as their desktop background
2024-04-22 18:26:15 -07:00
Eric DubéandNariman Jelveh 331d9e7542 feat: allow apps to add a menubar via puter.js
* Begin work on menubar and dropdowns

* Improve menubar

* Fix pointer event behavior

* Fix labels

* Fix active button

* Eliminate flicker

* Update _default.js

---------

Co-authored-by: Nariman Jelveh <[email protected]>
2024-04-22 20:38:16 -04:00
Eric Dubé ec31007c4b Update main.yml 2024-04-22 19:23:03 -04:00
Eric Dubé e615c7ee7f Update main.yml 2024-04-22 19:15:59 -04:00
Eric Dubé 35d4d4f755 Update main.yml 2024-04-22 19:14:21 -04:00
Eric Dubé 195468c4e1 Update main.yml 2024-04-22 19:11:51 -04:00
Eric Dubé 15f274e662 Create main.yml 2024-04-22 19:06:59 -04:00
Eric Dubé 7cb898457c Merge pull request #323 from HeyPuter/release-please--branches--main--components--puter.com
chore(main): release 2.1.1
2024-04-22 18:50:43 -04:00
github-actions[bot] aa4050ee32 chore(main): release 2.1.1 2024-04-22 22:42:20 +00:00
KernelDeimos f392de722a fix: test release-please action #4 2024-04-22 18:40:49 -04:00
Eric Dubé 07d95d5d3c Update release-please.yml 2024-04-22 18:34:13 -04:00
Eric Dubé 22c61d8221 Update release-please.yml 2024-04-22 18:18:35 -04:00
KernelDeimos 8fb0a66ef2 fix: test release-please action #3 2024-04-22 18:16:08 -04:00
KernelDeimos d5cd828cba chore: test release-please action #2 2024-04-22 18:12:35 -04:00
KernelDeimos 0119ae36a8 chore: test release-please action #1 2024-04-22 17:51:03 -04:00
Eric Dubé 87852d125f Only deploy docker image on release branch 2024-04-22 17:47:47 -04:00
Eric Dubé d3969b0122 Create release-please.yml 2024-04-22 17:46:40 -04:00
Nariman Jelveh 3cba4cab1e Disable iframing of the main domain using meta tags as well 2024-04-22 14:14:20 -07:00
Nariman Jelveh ef35a04c4a Disable iframing of the main domain 2024-04-22 14:09:32 -07:00
Eric Dubé 874928e845 Update bug_report.md 2024-04-22 16:39:47 -04:00
Eric Dubé c3d1574f8c Merge pull request #321 from HeyPuter/eric/batch-error-handling
Make errors in /batch more preemptive
2024-04-22 16:37:31 -04:00
KernelDeimos eee5c9e48b Cleanup 2024-04-22 16:29:12 -04:00
KernelDeimos 2f5780d1d1 Cleanup 2024-04-22 16:28:22 -04:00
Nariman Jelveh fa60f66057 Update helpers.js 2024-04-22 13:13:49 -07:00
KernelDeimos a741bd5419 Make errors in /batch more preemptive 2024-04-22 04:35:01 -04:00
KernelDeimos 4d2d4a7ca3 Fix 86888h53w 2024-04-21 22:06:36 -04:00
KernelDeimos 5c1e6ab16b Fix false-positive password recovery response 2024-04-21 18:28:58 -04:00
Nariman Jelveh f5f75dbef8 Add link to Bug Bounty program 2024-04-21 15:04:49 -07:00
Nariman Jelveh 6577051d64 Add Steam Deck to DiRP 2024-04-21 14:46:45 -07:00
KernelDeimos b2f5cc11b5 Fix dbrr reference 2024-04-21 17:10:18 -04:00
Nariman Jelveh a1252f66cc Update README.md 2024-04-21 12:50:58 -07:00
Nariman Jelveh e8d9e8b42b Update README.md 2024-04-20 20:34:52 -07:00
Nariman Jelveh ced7265eb0 Merge pull request #306 from zinreq/main
Do not show the "Change Password" option when user is temporary
2024-04-20 19:46:54 -07:00
zinreq 14098b2ff2 Do not show the "Change Password" option when user is temporary 2024-04-20 19:42:30 -07:00
Eric Dubé fb93a0863b Merge pull request #305 from HeyPuter/eric/support-levels
Document scope for fixes
2024-04-20 20:02:52 -04:00
KernelDeimos 4088bff216 Document scope for fixes 2024-04-20 19:57:40 -04:00
Nariman Jelveh 915152d3b9 Merge pull request #296 from Xiayucheng1212/keep_params
Keep the query params in the url started with '/app/*'
2024-04-20 16:45:05 -07:00
Nariman Jelveh 2ecea9a7b0 Prevent XSS by escaping user_set_url_params 2024-04-20 16:34:15 -07:00
Eric Dubé dc2a620b4e Merge pull request #304 from HeyPuter/eric/stdio-bridge/2
stdio-bridge 2
2024-04-20 19:29:15 -04:00
Nariman Jelveh 8648a303f1 use puter.js to retrieve server info 2024-04-20 15:29:33 -07:00
Nariman Jelveh 6a65ca4ebd Merge pull request #303 from Eric-Lighthall/login-server-info
Add server info to the login page for issue #257
2024-04-20 10:12:31 -07:00
KernelDeimos 58b83c27f2 Remove large log 2024-04-20 07:23:32 -04:00
Eric Lighthall 338d925bcc Fetch server info from versionservice.js module
Instead of directly fetching for the version info in UITabAbout.js, the module is now used for it
2024-04-20 02:24:45 -07:00
Eric Lighthall 7e2c4a0a1c Add server/version info on login page
The server/version info is under the forgot password section of the login page
2024-04-20 02:22:13 -07:00
Eric Lighthall 9822be5df4 Add version service module for fetching server information
this centralizes the handling of requests to get the server information
2024-04-20 01:58:12 -07:00
Nariman Jelveh cf5c62bcfc Update README.md to add more DiRPs 2024-04-19 23:52:41 -07:00
KernelDeimos 27553ef926 Cleanup 2024-04-19 23:35:56 -04:00
KernelDeimos 3f249fcc89 Fix pipes 2024-04-19 23:31:23 -04:00
KernelDeimos c3654ab148 Add more streaming fixes 2024-04-19 23:24:32 -04:00
KernelDeimos 0e9e8d41d9 Fix authorizer not defined 2024-04-19 17:12:15 -04:00
Sam Atkins 2f49c1c9b0 Remove a whole load of noisy log messages
These can be added back if and when we need them, but right now, it's
hard to follow console output with all this chatter. 😅
2024-04-19 17:29:26 +01:00
Sam AtkinsandKernelDeimos 072dbe8db5 Make BetterReader buffer and cancel, to fix stdin data loss
BetterReader.read_with_cancel() returns both the read promise, and a
function that can be used to cancel the read. A cancelled read is
placed back into the BetterReader's chunk buffer, to be consumed by the
next user that requests a read.

This is used by Coupler so that when the coupler is closed, its pending
read() call does not consume the next batch of input.

This fixes the problem we were having with child applications consuming
one chunk of stdin after they are closed, meaning the first key you
press after an app exits would disappear.

Co-authored-by: KernelDeimos <[email protected]>
2024-04-19 15:52:59 +01:00
KernelDeimos da208e23f5 Add a valve and internal pipe to commands 2024-04-19 15:52:59 +01:00
Sam Atkins 222a617c44 Phoenix: Use regular code path to run built-in apps
Now launchApp() can always be awaited, we can run built-in apps using
the same code path for other apps, and eventually have SIGINT close
them.
2024-04-19 15:52:59 +01:00
Sam Atkins e355c77a4a Phoenix: Wait for apps to finish executing, and connect stdio to them
After launching an app, if successful, we connect stdio streams to it,
and wait for it to exit before we return to the prompt.

stdio is implemented as regular AppConnection messages:
- stdin:  `{ $: 'stdin',  data: Uint8Array }` from phoenix -> child
- stdout: `{ $: 'stdout', data: Uint8Array }` from child -> phoenix

Terminal and Phoenix now communicate with each other using the same
style, instead of 'input' and 'output' messages. This will help with
eventually running subshells.

SIGINT currently is not sent. We also suffer from the same "one more
read from stdin happens after app exits" bug that's in
PathCommandProvider where I copied the stdin code from.
2024-04-19 15:52:59 +01:00
Sam Atkins 639653dac2 Report when a non-SDK app closes
puter.ui.launchApp() returns a Promise that needs to resolve whether the
app uses the Puter SDK or not. Non-SDK apps are tricky because they
don't send a READY message on startup, and we don't know in advance
whether an app will use the SDK or not.

This is a workaround to ensure that launchApp() always resolves. When an
app is closed, if it wasn't using the SDK, we send an artificial
notification that it launched, followed by an extra notification that
it has closed (because the original close notification was sent before
this point). This means any users of launchApp() can await it, and get
an AppConnection, and listen to the close event. They can't otherwise
interact with a non-SDK app because it will have closed already, but we
can improve this in the future without breaking the API.
2024-04-19 15:52:59 +01:00
Sam Atkins 0aa5543397 Let AppConnection know if its target app uses the Puter SDK
Apps are not required to use the Puter SDK. If they don't, then we can
still launch them, close them, and listen to their close event, but are
unable to send messages to them.
2024-04-19 15:52:59 +01:00
Sam Atkins dfdda4f3b9 Extract some helper functions for accessing a window/iframe by uuid 2024-04-19 15:52:59 +01:00
Eric Dubé 8cf58d7fc6 Merge pull request #299 from Eric-Lighthall/reduce-console-flicker
Optimize console redraw by tracking widget changes
2024-04-19 07:47:41 -04:00
Eric Lighthall 4783e3eae4 Optimize console redraw by tracking widget changes
Instead of redrawing the widget area every 2 seconds, only auto redraw when the widget area has changed, reducing unecessary redraw operations.
2024-04-19 00:48:36 -07:00
Eric Dubé 4931ad3960 Merge pull request #297 from AtkinsSJ/test-minimum-version
Make tests work in Node 16.x
2024-04-18 14:41:20 -04:00
Sam Atkins 5ad78a5ebb Expand supported versions that we test in CI
Phoenix now only requires 16.x or above, and so does Puter itself, so
let's include that, and also 18.x as the other LTS version.
2024-04-18 14:41:06 +01:00
Sam Atkins dc95f2e065 Phoenix: Support older Node versions in test harness
This brings Phoenix's minimum required version from 20.x down to 16.x.

ReadableStream.from() is deemed experimental, and requires Node 20.x
(or at least, something higher than 18.x). This was the only code that
made us require version 20.x.

ReadableStream and WritableStream are available from Node 16.5, but
require that they be explicitly imported.
2024-04-18 14:41:06 +01:00
KernelDeimos 0361ceba6c Normalize session objects to have both user_uid and user_id 2024-04-17 23:22:10 -04:00
KernelDeimos 4ecc7372f9 Fix issue with use_bundled_gui flag 2024-04-17 22:59:22 -04:00
KernelDeimos dbcd627815 Apply various small fixes 2024-04-17 20:57:59 -04:00
Nariman Jelveh 6061c81c36 Update get-launch-apps.js 2024-04-17 17:58:11 -07:00
Nariman Jelveh c1aee61da1 Update README.md 2024-04-17 10:14:10 -07:00
KernelDeimos f0d3346ca7 Update session.last_touch always 2024-04-17 13:03:32 -04:00
KernelDeimos e8ca6376be Avoid logging sensitive query params 2024-04-17 12:51:30 -04:00
KernelDeimos c48c134869 Remove verbose log 2024-04-17 12:42:12 -04:00
KernelDeimos 49e334521d Update timers 2024-04-17 12:41:43 -04:00
Eric Dubé 04a641adc2 Merge pull request #291 from AtkinsSJ/test-submodules
Re-enable Phoenix tests
2024-04-17 10:08:43 -04:00
Eric Dubé 2210652643 Merge pull request #295 from AtkinsSJ/remove-phoenix-css
Phoenix: Remove unwanted CSS includes
2024-04-17 10:07:33 -04:00
Xiayucheng1212 8713db3d55 Fix params lost 2024-04-17 19:45:01 +08:00
Sam Atkins f2e8b5ee3e Phoenix: Remove unwanted CSS includes 2024-04-17 11:05:03 +01:00
KernelDeimos 7e0c6c6470 Fix last_activity_ts 2024-04-16 19:30:30 -04:00
KernelDeimos 19c49db538 Improve sessions 2024-04-16 18:57:02 -04:00
Sam Atkins ea40ac1e53 Re-enable Phoenix tests
This also runs the tests for contextlink, which I think we previously
never ran. I don't see any other packages that define an `npm test`
command. Having to manually list all the sub-package test directories in
the top-level package.json is a bit unfortunate, but it works.

For Puter itself we support Node 16.x IIRC, but Phoenix requires at
least 20.x currently.
2024-04-16 13:57:02 +01:00
KernelDeimos 653898b463 Report proper error when an operation is invalid 2024-04-15 22:27:03 -04:00
KernelDeimos c07d0a2bc7 Set NO_VAR_RUNTIME in Dockerfile 2024-04-15 20:47:27 -04:00
KernelDeimos 9bb221a0d7 Fix Dockerfile 2024-04-15 19:03:00 -04:00
Eric Dubé e4f2c4a28b Merge pull request #280 from vineeth-vk11/#206
fixing on conflict issue in sqlite kv write
2024-04-15 17:55:52 -04:00
Eric Dubé 3a4858b83c Merge pull request #286 from AtkinsSJ/background-settings
Settings: Organise code to be grouped by tab, and add desktop background picker
2024-04-15 17:55:09 -04:00
KernelDeimos 826ea36502 Add use_bundled_gui option 2024-04-15 17:50:44 -04:00
KernelDeimos 397819d45e Add missing endpoint /down 2024-04-15 16:38:03 -04:00
KernelDeimos 66fecf88ef Fix funny context menu on task manager 2024-04-15 15:58:07 -04:00
KernelDeimos e8dc220981 This is 2.1.0 I decided 2024-04-15 15:37:13 -04:00
KernelDeimos 1c2b05d8f6 Fix phoenix for auto ports 2024-04-15 15:34:58 -04:00
KernelDeimos f3495f3098 Fix xterm.css not loading 2024-04-15 14:46:16 -04:00
KernelDeimos 081b093e7e Add missing asset for xterm, fix SDK url 2024-04-15 14:43:15 -04:00
KernelDeimos 4d30753958 Fix more phoenix dev issues 2024-04-15 14:25:40 -04:00
KernelDeimos c72e0cb0e0 Fix phoenix watcher 2024-04-15 14:08:50 -04:00
KernelDeimos 25f8dbf120 Add postinstall for phoenix 2024-04-15 14:02:49 -04:00
Sam Atkins 868202ba41 Settings: Add desktop-background setting to 'Personalization' tab 2024-04-15 17:41:19 +01:00
Sam Atkins c6b0ed32bf Settings: Move 'Clock' tab into its own file 2024-04-15 17:41:19 +01:00
Sam Atkins 17adef11a6 Settings: Move 'Language' tab into its own file
Also implement an optional `on_show` callback for settings tabs, to
support the "select and clear the search field" behaviour we had before.
2024-04-15 17:41:19 +01:00
Sam Atkins 6d1c807879 Settings: Move 'Personalization' tab into its own file 2024-04-15 17:41:19 +01:00
Sam Atkins 0ed5b20627 Settings: Move 'Account' tab into its own file 2024-04-15 17:41:19 +01:00
Sam Atkins f5175941d9 Settings: Move 'Usage' tab into its own file 2024-04-15 17:41:19 +01:00
Sam Atkins e2f048ec2d Settings: Move 'About'-specific logic and data into UITabAbout.js
Keeping all the logic and data for the tab together should make it
easier to modify.
2024-04-15 17:41:19 +01:00
KernelDeimos 2717444c29 Oops 2024-04-15 12:17:09 -04:00
KernelDeimos b21755b5a3 Fix casualty of phoenix due to Docker naming conventions 2024-04-15 12:12:28 -04:00
KernelDeimos 37ff97b52f Thanks minify 2024-04-15 03:59:39 -04:00
Eric Dubé b897598fac Merge pull request #282 from HeyPuter/eric/task-manager
Add a task manager
2024-04-15 03:53:51 -04:00
Eric Dubé 95cb92abed Remove outdated information 2024-04-15 03:50:46 -04:00
KernelDeimos 5730dc642a Add process ending and i18n 2024-04-15 03:37:04 -04:00
KernelDeimos 7c2a3b4612 Portal shows up as 'app' 2024-04-15 02:12:39 -04:00
Nariman Jelveh dbf796d698 Update index.js 2024-04-14 21:27:25 -07:00
Nariman Jelveh 7f739a53f8 Merge pull request #281 from HeyPuter/change-email-feature
Change email feature
2024-04-14 21:10:57 -07:00
Nariman Jelveh 2dbde52338 live-update email address after change 2024-04-14 21:09:41 -07:00
KernelDeimos 61f1caa122 Add type column 2024-04-14 23:58:14 -04:00
Nariman Jelveh 695d7b8654 Update UIDesktop.js 2024-04-14 20:53:31 -07:00
KernelDeimos 6e7fd2ca95 Add polling 2024-04-14 23:52:53 -04:00
KernelDeimos 79bfcf226b Integrate ProcessService with task manager 2024-04-14 23:52:53 -04:00
KernelDeimos 9d9e091a7a Add process management 2024-04-14 23:52:53 -04:00
KernelDeimos be1bb6bc06 Improve task manager style 2024-04-14 23:52:53 -04:00
KernelDeimos d39bb412f3 Begin work on task manager 2024-04-14 23:52:53 -04:00
KernelDeimos e71b586fe5 Invalidate cached user when the user's email address is changed 2024-04-14 23:50:39 -04:00
KernelDeimos 2fcac12340 Fixg 2024-04-14 23:24:47 -04:00
KernelDeimos 0847395c92 Socket 2024-04-14 23:10:23 -04:00
Nariman Jelveh 49c3df2328 allow child windows to center relative to parent window 2024-04-14 20:04:27 -07:00
KernelDeimos 58192cacb3 Try again 2024-04-14 23:00:07 -04:00
KernelDeimos b81284e2c6 Pass the RIGHT token to email 2024-04-14 22:49:51 -04:00
KernelDeimos 5b39e39e1f Use jwt for email change confirmation 2024-04-14 22:44:04 -04:00
KernelDeimos b944217410 Fix 2024-04-14 22:29:54 -04:00
KernelDeimos dca7304be9 Remove requirement of auth from email confirm 2024-04-14 22:23:42 -04:00
Nariman Jelveh 61a4b10adf add i18n text 2024-04-14 19:14:33 -07:00
KernelDeimos 231878266c Fix 2024-04-14 22:08:31 -04:00
KernelDeimos 51bf8fdde6 Fix 2024-04-14 21:41:08 -04:00
KernelDeimos 18134629d2 Move 2024-04-14 21:37:12 -04:00
KernelDeimos f6b737e45d Add confirmation email for email change 2024-04-14 21:33:15 -04:00
KernelDeimos 3b7be8a719 Add delete-own-user 2024-04-14 21:32:43 -04:00
Nariman Jelveh aae1d194c7 wip 2024-04-14 17:43:20 -07:00
KernelDeimos ef0da306a8 Fix change_email 2024-04-14 20:35:34 -04:00
Nariman Jelveh bfaaa914f1 wip 2024-04-14 17:30:22 -07:00
Nariman Jelveh 2f101c4a39 close #271 2024-04-14 17:10:46 -07:00
Nariman Jelveh 765eb43568 Disable manual arrangement in Explore 2024-04-14 12:50:28 -07:00
Nariman Jelveh aa61e005e5 Merge pull request #279 from hasanbeder/main
Translated Turkish language file
2024-04-14 09:53:59 -07:00
Nariman Jelveh 5b2e2b037b Update tr.js 2024-04-14 09:50:21 -07:00
Nariman Jelveh bcfd685826 Update translations.js 2024-04-14 09:48:43 -07:00
vineethvk11 5d8d25f370 fixing on conflict issue in sqlite kv write 2024-04-14 16:39:29 +05:30
hasanbeder 6679318207 Translated Turkish language file
This commit includes the Turkish language file with the translations. 🇹🇷
2024-04-14 13:12:56 +03:00
Nariman Jelveh 255e80d077 Make Puter.js verbosity optional via debug flag. 2024-04-13 17:31:29 -07:00
KernelDeimos 965d99d137 Fix socket auth 2024-04-13 17:19:12 -04:00
Nariman Jelveh 3b65523da9 separate refresh_item_container into a module 2024-04-13 13:41:15 -07:00
Nariman Jelveh 3cfee32ae0 Update helpers.js 2024-04-13 12:28:28 -07:00
Eric Dubé 497c633b8a Merge pull request #227 from MohamedElashri/main
Add requirements for multi-platform docker build to the CI
2024-04-13 14:58:45 -04:00
KernelDeimos df45e22813 Make node-pty not required 2024-04-13 13:56:57 -04:00
KernelDeimos 199b68a964 Highlight current session 2024-04-13 02:30:48 -04:00
Nariman Jelveh 8db8ec3574 Update Apps.js 2024-04-12 22:04:28 -07:00
KernelDeimos 4a36670417 Update README.md files for monorepo'd projects 2024-04-12 23:54:41 -04:00
KernelDeimos 77ac503bfc Edit phoenix README.md 2024-04-12 23:49:43 -04:00
Nariman Jelveh be55e447bb fix issue with two session managers on top of each other 2024-04-12 20:43:15 -07:00
KernelDeimos 00e9f922c0 Fix target version 2024-04-12 23:16:49 -04:00
KernelDeimos 361e51060a Update apps 2024-04-12 22:03:40 -04:00
Eric Dubé fbbc73308e Merge pull request #274 from HeyPuter/eric/builtin-apps
Move terminal and phoenix into main repo
2024-04-12 21:54:47 -04:00
KernelDeimos a31e4c19cb Update package-lock.json 2024-04-12 21:51:49 -04:00
Nariman Jelveh b69a85f10e Merge pull request #273 from Hiya-its-Aya/dark-mode
White text for themes
2024-04-12 18:30:15 -07:00
KernelDeimos d919b1f312 Register terminal and phoenix builtins 2024-04-12 20:56:16 -04:00
KernelDeimos cb81579c53 Copy over phoenix 2024-04-12 20:53:44 -04:00
KernelDeimos 0306a395a2 Copy over terminal 2024-04-12 20:53:32 -04:00
KernelDeimos 5fbbfb4c18 Enable background and builtin apps 2024-04-12 20:52:57 -04:00
Aya Moosa b725c4c7b4 removed commented code causing translation error 2024-04-12 14:39:46 -07:00
Aya Moosa 24e3ec89f3 added white text to brodacast 2024-04-12 14:28:15 -07:00
Aya Moosa f8d3fdbefb merge 2024-04-12 14:16:26 -07:00
Nariman Jelveh 352f1bc23e Update README.md to add link to fridge running Puter. 2024-04-12 13:59:59 -07:00
Nariman Jelveh 413cb79683 Merge pull request #269 from secondtruth/patch/translation-de
Update German translation
2024-04-12 13:26:35 -07:00
Christian Neff d06f856e46 Update German translation 2024-04-12 22:00:42 +02:00
KernelDeimos 09c3cc6db1 Fix error when session not found 2024-04-12 01:22:33 -04:00
Eric Dubé eb96dd952b Merge pull request #267 from HeyPuter/eric/session-fixes
session management fixes
2024-04-12 00:29:26 -04:00
KernelDeimos 1da3a769c4 Use localstorage instead of cookie for list-sessions 2024-04-12 00:19:07 -04:00
KernelDeimos 356a3284fa Fix mysql incompatibility 2024-04-12 00:10:56 -04:00
KernelDeimos 0eedcf567e Apply some fixes 2024-04-11 23:48:17 -04:00
KernelDeimos f4f58dbfb9 Fix destructuring 2024-04-11 23:28:40 -04:00
Eric Dubé 8135e076c2 Merge pull request #266 from HeyPuter/eric/session-updates
session management
2024-04-11 22:04:07 -04:00
Eric Dubé 22b3415866 Merge pull request #265 from HeyPuter/eric/puter-dot-js
puter.js
2024-04-11 21:59:46 -04:00
KernelDeimos 5effca4bbc Add missing i18n key 2024-04-11 21:57:26 -04:00
KernelDeimos aa14541e50 Update package-lock.json for npm ci 2024-04-11 21:54:50 -04:00
KernelDeimos 13525c85a0 -dot- 2024-04-11 21:46:43 -04:00
KernelDeimos 2f6f7e39bb Add timestamp 2024-04-11 21:41:19 -04:00
KernelDeimos 2d76025c9c Send cookie on token upgrade 2024-04-11 21:40:10 -04:00
KernelDeimos bb9edc4f65 Add automatic token migration 2024-04-11 21:33:44 -04:00
KernelDeimos afcd821f50 Update README.md 2024-04-11 19:40:50 -04:00
KernelDeimos b8e66cada9 Add puter.js 2024-04-11 19:07:00 -04:00
lsileoni f1dedf5a74 Proper order for moving the compressed file into the static directory 2024-04-11 21:39:07 +03:00
lsileoni 2ebda29f02 Don't bind manager to window for now 2024-04-11 21:38:36 +03:00
KernelDeimos fc5025a2a8 Simplify PuterVersionService 2024-04-11 14:37:34 -04:00
KernelDeimos e3d238f897 Do not use git to get version number 2024-04-11 13:57:40 -04:00
lsileoni fa841582a9 Added temporary package.json, so node doens't refer to the repo root package.json 2024-04-11 20:54:21 +03:00
lsileoni 2b28388fa7 Changes to module imports for parity between the browser and node, fixed browser and node examples 2024-04-11 20:53:48 +03:00
lsileoni a6b7ec5c66 Clean up index.html usage example 2024-04-11 20:52:47 +03:00
Nariman Jelveh 9ab3e3ccd8 Merge pull request #244 from HeyPuter/eric/host-storage
Display storage use of host/puter separately
2024-04-11 10:14:45 -07:00
Nariman Jelveh 7abf5faa3c fix missing translations 2024-04-11 10:13:52 -07:00
Nariman Jelveh 4052c7995c Merge pull request #260 from AtkinsSJ/fix-silly-mistakes
Fix permission check for closeApp message
2024-04-11 09:48:02 -07:00
Sam Atkins 776b6831f3 Fix permission check for closeApp message
Firstly, I was missing an `async` here, which somehow still worked for
me then, but produced errors for me when I tried it today.

Then, actually await the promise.

Finally, actually check the target's parent is us, and not just that it
has the attribute!

I don't know what was going on in my head that day. 🤦‍♂️
2024-04-11 17:21:23 +01:00
lsileoni 902a242f6b Rebuilding logic and zstd compression for v86starter 2024-04-11 19:15:58 +03:00
Nariman Jelveh a2d231dc23 Merge pull request #259 from PeterDaveHelloKitchen/zhtw
Add a simple Traditional Chinese translation
2024-04-11 09:02:20 -07:00
lsileoni d6a327ea86 Changed vm build target directory to /tmp because of package.json issue 2024-04-11 15:51:50 +03:00
lsileoni 21ef0598f9 Also ignore wasm blobs 2024-04-11 15:49:46 +03:00
lsileoni 2405ee90e9 Ignore generated .bin files 2024-04-11 15:48:31 +03:00
Peter Dave Hello 1aeedd8696 Add a simple Traditional Chinese translation 2024-04-11 20:03:13 +08:00
lsileoni 4815eb10a9 Don't bind to all interfaces by default in web server 2024-04-11 12:41:17 +03:00
lsileoni d13efbbe23 Changed vm dir to make_container in starter script 2024-04-11 12:25:21 +03:00
Luis 9b1fbea7e1 Merge branch 'HeyPuter:main' into main 2024-04-11 12:23:16 +03:00
KernelDeimos 09bf422686 Add session manager ui 2024-04-11 00:29:39 -04:00
KernelDeimos 18b3e06fe8 Add session listing and revocation 2024-04-10 23:00:37 -04:00
KernelDeimos e436693d3e Improve session mgmt (part 1) 2024-04-10 21:54:16 -04:00
KernelDeimos eb66848aee Update database version when creating a new one 2024-04-10 12:25:44 -04:00
KernelDeimos 0eded34c8c Add indented logs and fix a bug 2024-04-10 12:22:21 -04:00
KernelDeimos 367c18bfc5 Add endpoint to list permissions 2024-04-10 12:16:08 -04:00
Eric Dubé 92dc0a7671 Merge pull request #255 from AtkinsSJ/appconnection-close
Notify apps when a child app closes, and let them close their children manually
2024-04-09 21:31:48 -04:00
Eric Dubé 8e553b4ee0 Merge pull request #252 from AtkinsSJ/broadcasts
Add a message broadcasting system
2024-04-09 21:29:46 -04:00
Sam Atkins 21c64e827b Add closeApp message
Sending a 'closeApp' message allows an app to close a target app, if it
has permission to do so. Currently, permission is granted if the
requesting app is the parent of the target app, or has godmode set.
2024-04-09 16:09:12 +01:00
Sam Atkins c69a0abfa9 Extract a window_for_app_instance() helper function 2024-04-09 15:55:14 +01:00
Sam Atkins cce6531d45 Notify parents/children when an app closes
Send an appClosed message with the instance ID of the app that was
closed. This will be picked up by Puter.js's AppConnection and reported
as a 'close' event.

To make this work, a `data-parent_instance_id` attribute is set on child
app windows. This is very similar to the `data-parent_uuid` attribute,
which tracks parent windows instead of parent app instances. (Dialogs
have a parent window, but are not apps, so don't have a parent app
instance.) The difference is subtle, and we may want to combine these in
the future, but currently closing an app will close any child windows,
which is not behaviour we want for child apps.
2024-04-09 15:55:14 +01:00
Sam Atkins 84a31b3520 Broadcast when the language changes
This is left open to future additions, by naming it 'locale', and having
the language just be an object field.

Side note, maybe we should have a LocaleService for this?
2024-04-09 10:44:51 +01:00
Sam Atkins 59cdb6e8c6 Broadcast when theme changes 2024-04-09 10:44:51 +01:00
Sam Atkins 068e620249 Add a message broadcasting service
A broadcast is a message sent to every running app that uses Puter.js.
Broadcasts have a name and a data payload, and are sent as a 'broadcast'
message.

Send a broadcast using:
`globalThis.services.get('broadcast').sendBroadcast(...)`

When doing so, you have the option to keep the broadcast message around,
so that it can be sent to any newly-launched apps. Sending another
broadcast with the same name will overwrite the previous one, so you
don't have to worry about flooding a new app with duplicates.
2024-04-09 10:44:51 +01:00
Aya Moosa 80aa87023e working white text, not perfect with all colors 2024-04-08 22:01:00 -07:00
Aya Moosa 626d63c91d working white text, not perfect with all colors 2024-04-08 22:00:12 -07:00
Aya Moosa 5bf0411015 got white text working, restets when other silders are used 2024-04-08 21:24:24 -07:00
Aya Moosa b2fcb8d104 started light text for color 2024-04-08 15:59:12 -07:00
KernelDeimos 79f98795c7 Fix version checker using later javascript features 2024-04-08 17:05:47 -04:00
Eric Dubé 24ad365047 Merge pull request #253 from AtkinsSJ/bad-config-login-error
Add an error message when login fails because of domain misconfiguration
2024-04-08 12:23:31 -04:00
Eric Dubé 72286fd642 Merge pull request #249 from AtkinsSJ/service-copyrights
Add some missing copyright notices
2024-04-08 12:22:15 -04:00
Mohamed Elashri a0f46c326a Add build stage and remove linux/arm/v7 2024-04-08 17:12:26 +02:00
Sam Atkins b1f2750cdb Add an error message when login fails because of domain misconfiguration
Previously, we just output whatever err.responseText was. However, that
has some downsides:

- If there's no responseText (as for when we can't find the domain) then
  the user gets a blank message.
- If it's a 404 error, the responseText includes the full HTML for
  Puter's 404 page, which we don't want to dump in the error box! This
  is unlikely to happen in practice, but was easy enough to cater for.

So, add a nicer message in those cases.

The misconfiguration message is taken from here:
https://github.com/HeyPuter/puter/issues/185#issuecomment-2037977592

Resolves #235.
2024-04-08 15:49:00 +01:00
Sam Atkins 8aee3f8174 Add some missing copyright notices 2024-04-08 11:10:39 +01:00
Nariman Jelveh ea61799b3d Merge pull request #240 from HeyPuter/eric/gui-personalization
Puter Theme Color Setting
2024-04-07 14:35:24 -07:00
KernelDeimos b1e6e0c25a Fix i18n 2024-04-07 17:27:09 -04:00
KernelDeimos f7916cfa74 Add option to reset colors 2024-04-07 17:19:47 -04:00
KernelDeimos 3f37ef2fad Fix i18n 2024-04-07 16:18:59 -04:00
KernelDeimos 3297940bab Improve dialog 2024-04-07 04:53:49 -04:00
KernelDeimos 821d33b8d8 Make opacity differences match prod 2024-04-07 04:39:08 -04:00
KernelDeimos 72129ca16f Make defaults consistent with original 2024-04-07 03:21:32 -04:00
KernelDeimos 12fa88b149 Save color settings 2024-04-07 03:15:45 -04:00
KernelDeimos c83069bd03 Add i18n items 2024-04-07 02:53:33 -04:00
KernelDeimos 5661605884 Add ui colors to settings window 2024-04-07 02:53:05 -04:00
KernelDeimos d1bbbb8e93 Use CSS variables 2024-04-07 02:34:04 -04:00
KernelDeimos 178f851684 Fix previous fix 2024-04-07 00:28:23 -04:00
KernelDeimos cb4b8c5914 Add minor fixes 2024-04-07 00:06:11 -04:00
KernelDeimos 8018a607a8 Add CSS 2024-04-07 00:05:54 -04:00
KernelDeimos dc5a7ca431 Display storage use of host/puter separately 2024-04-06 23:26:18 -04:00
Eric Dubé 95d33eab94 Merge pull request #238 from AtkinsSJ/app-ipc
Implement support for launching child apps, and IPC between a parent and its children
2024-04-06 07:51:17 -04:00
Sam Atkins 725cbf2e20 Add support for launching child apps
Calling `puter.ui.launchApp()` now treats the new app as a child of the
one that launched it.

A child app is given a `puter.parent_instance_id` URL param, containing
its parent's instance ID.

Previously, `launchApp()` would resolve as soon as the app was launched.
This commit changes that, so that it is notified after the child app
sends its READY event to Puter. This means that as soon as `launchApp()`
has completed, the child app is ready to receive messages. The downside
is that launching an app that does not include Puter.js will now not
cause a notification, so `await puter.ui.launchApp()` will not resolve
in that case.
2024-04-06 12:27:36 +01:00
KernelDeimos 674cebd9e1 Add Linux support to HostDiskUsageService 2024-04-06 05:33:46 -04:00
Eric Dubé 0dd66463df Merge pull request #241 from vineeth-vk11/#233
Implementing HostDiskUsageService removing diskusage dependency
2024-04-06 05:29:21 -04:00
KernelDeimos beeeb7bcbf Tiny fix 2024-04-06 05:08:38 -04:00
vineethvk11 bf4bc214b2 Implementing HostDiskUsageService removing diskusage dependency 2024-04-06 13:03:09 +05:30
KernelDeimos b99534ebdf Add WIP color sliders 2024-04-06 02:35:06 -04:00
Eric Dubé c6fb75c65f Merge pull request #231 from HeyPuter/eric/user-to-user-permissions
User-to-User Permission Granting
2024-04-05 23:11:32 -04:00
KernelDeimos 38e8b19b50 Cleanup 2024-04-05 23:05:20 -04:00
KernelDeimos 90ce840234 Add revoke-user-user endpoint 2024-04-05 23:01:50 -04:00
KernelDeimos fc6eda392b Allow granting user-to-user permissions 2024-04-05 22:11:36 -04:00
KernelDeimos 343edbff51 Use weak CORS policy for experimental_no_subdomain 2024-04-05 16:51:57 -04:00
KernelDeimos fe88880486 Add experimental_no_subdomain flag 2024-04-05 16:21:19 -04:00
KernelDeimos 1c2e4968e2 Remove console log 2024-04-05 14:38:50 -04:00
KernelDeimos f9b375a39b Fix case when main domain is a subdomain 2024-04-05 14:38:33 -04:00
KernelDeimos eb18e74e88 Add error when someone forgets npm install 2024-04-05 14:09:34 -04:00
Eric Dubé 487553a00c Merge pull request #237 from eltociear/patch-2
Update download.js
2024-04-05 13:32:05 -04:00
Sam Atkins c78927d5db Add messageToApp message
This lets apps communicate with each other, via Puter.

We probably want to limit this in some way, but for now, all apps are
allowed to send messages to any other apps.

The message is:
- `targetAppInstanceID`: The instance ID to send the message to
- `targetAppOrigin`: targetOrigin passed to postMessage(), in case we
  want to restrict which URL can receive the message
- `contents`: The message to send to the target
2024-04-05 16:38:12 +01:00
Ikko Eltociear Ashimine 26e9822344 Update download.js
minor fix
2024-04-06 00:22:22 +09:00
KernelDeimos 207fa139d4 Add user-to-user permissions table 2024-04-05 03:23:31 -04:00
Eric Dubé e2236d43fd Merge pull request #234 from vineeth-vk11/#80
fixing issues in copy while overwriting
2024-04-05 03:21:22 -04:00
vineethvk11 6006767a9f fixing issues in copy while overwriting 2024-04-05 09:11:39 +05:30
KernelDeimos 35abf9a6bc Stop printing default password in logs 2024-04-04 22:17:00 -04:00
KernelDeimos c3a4223bbf Add service to check EOL date of node 2024-04-04 22:10:56 -04:00
KernelDeimos 4a2fa5a29f Friendly node version errors 2024-04-04 21:39:32 -04:00
Mohamed Elashri 17ae6668b4 Add linux/arm/v7 again
We need to test if this is what causes the problem of the GitHub action getting stuck or `linux/arm/v6`
2024-04-05 01:10:47 +00:00
Mohamed Elashri 06a31fd67b Fix typo in arm64 namespace 2024-04-05 00:59:05 +00:00
Mohamed Elashri 1a13ef6921 remove linux/arm/v7,linux/arm/v6 emporarily 2024-04-05 00:55:44 +00:00
KernelDeimos 17a323298c Make dismiss command print what was dismissed 2024-04-04 20:46:03 -04:00
KernelDeimos 27c99fd90a Use OR IGNORE when sqlite 2024-04-04 20:02:35 -04:00
KernelDeimos 6c7175c109 NOOP legacy share fetch 2024-04-04 19:26:29 -04:00
KernelDeimos cdd9dbf748 Add quick doc about https 2024-04-04 19:08:45 -04:00
Eric Dubé 1b72b80241 Merge branch 'main' into main 2024-04-04 18:43:39 -04:00
Eric Dubé be53a9472a Update docker-image.yaml 2024-04-04 18:39:53 -04:00
Mohamed Elashri accdec3af4 handle linking to python binary gracefully 2024-04-04 21:51:39 +00:00
Mohamed Elashri 95b6dbd140 Add python3 to use node-gyp to allow native cross platform build
python3 would be required by node-gyp to natively build node add-on. This is required if we build for multi-platform
2024-04-04 21:47:29 +00:00
KernelDeimos 08838c989e Fix fragmented if..else seq (fix app tokens) 2024-04-04 17:44:54 -04:00
Mohamed Elashri 74bff84226 Remove unpopular archs
For now, we need to stick to the most used archs for resources and build time reasons.
2024-04-04 21:35:22 +00:00
Mohamed Elashri b1a3124fcc Add requirements for multi-platform docker build to the CI 2024-04-04 22:58:00 +02:00
Eric Dubé 3e1c7eb434 Merge pull request #223 from vineeth-vk11/#211
removing storage limit for self hosters
2024-04-04 16:12:31 -04:00
KernelDeimos 2125367683 Avoid predicate.values not iterable error 2024-04-04 14:20:30 -04:00
KernelDeimos 809e33b053 Remove unused code 2024-04-04 14:18:34 -04:00
KernelDeimos 0efe163591 Update README.md 2024-04-04 13:56:33 -04:00
Eric Dubé e8935f5582 Add many platforms arbitrarily
Related to #214; added additional architectures which may or may not work. I'd rather someone find out it doesn't work then for them to be blocked from even trying.
2024-04-04 13:47:24 -04:00
vineethvk11 0da9e1fab3 removing storage limit for self hosters 2024-04-04 22:31:37 +05:30
Eric Dubé 802370eb9d Fix heading level 2024-04-04 02:14:36 -04:00
KernelDeimos 4e722b47b5 Document pub_port, which wasn't documented before 2024-04-03 22:11:52 -04:00
KernelDeimos b055c5cdad Fix change_username 2024-04-03 22:06:06 -04:00
KernelDeimos b7a1f21e31 Fix puter sites errors 2024-04-03 22:05:33 -04:00
KernelDeimos a04cac60e6 Fix db migration error in SQLES 2024-04-03 17:38:42 -04:00
KernelDeimos 274b69d017 Fix /file and /setItem 2024-04-03 17:21:25 -04:00
Nariman Jelveh 5fab338ba1 Merge pull request #219 from HeyPuter/eric/2024-04-02/display-directory-load-error
Display error in directory when readdir fails
2024-04-02 15:44:44 -07:00
KernelDeimos 6cd77384a5 Update default text for explorer-error-message 2024-04-02 16:50:22 -04:00
KernelDeimos 5290d78e20 Display error in directory when readdir fails 2024-04-02 16:46:34 -04:00
lsileoni 4054e822ed Barebones x86emu skeleton 2024-04-02 18:25:21 +03:00
Eric Dubé 2ce02db1b5 Update issue templates 2024-04-02 05:03:39 -04:00
Eric Dubé fff46a6b63 Update issue templates 2024-04-02 04:54:33 -04:00
KernelDeimos 369037e269 Fix incorrect asset urls 2024-04-02 04:19:22 -04:00
KernelDeimos 6f7264b60b Fix logout for invalid sessions 2024-04-02 04:19:12 -04:00
KernelDeimos 9881fecacd Fix error caused by fixing kv 2024-04-02 03:40:58 -04:00
KernelDeimos cf9338c35f Document different configuration locations 2024-04-02 02:14:59 -04:00
KernelDeimos a9947ad97f Update README.md 2024-04-02 02:09:36 -04:00
Eric Dubé ac2e3e2873 Merge pull request #212 from shuguet/main
fix: Fix permission errors when running Docker. Update Docker Compose & Docker instructions
2024-04-02 02:02:46 -04:00
Sylvain Huguet 8f4eb5627b Update instructions & docker-compose to reflect production paths 2024-04-02 07:45:14 +02:00
Sylvain Huguet e4bd62b84c Fix README instructions following path changes 2024-04-02 07:34:55 +02:00
Sylvain Huguet 0e033348f0 Fix permission errors when running Docker. Update Docker Compose & Docker instructions 2024-04-02 07:26:44 +02:00
KernelDeimos 0651aab1be Fix DBKVStore value format 2024-04-02 00:47:14 -04:00
KernelDeimos f8a7f1c1f9 Update README.md 2024-04-02 00:33:02 -04:00
KernelDeimos c90931d004 Fix docker-compose.yml 2024-04-02 00:25:29 -04:00
KernelDeimos a973f66092 Only load from source in dev environment 2024-04-01 22:26:09 -04:00
KernelDeimos 5d81ff4cbe Fix dev console bar when columns has small value 2024-04-01 22:01:34 -04:00
KernelDeimos 7442b48157 Fix undefined instead of null in db query 2024-04-01 19:41:16 -04:00
KernelDeimos 59003a9ab9 Make dev-console use in WebServerService optional 2024-04-01 19:40:59 -04:00
KernelDeimos 40c2e3f442 Add April-1st-appropriate commit message guidelines 2024-04-01 19:33:11 -04:00
KernelDeimos 65b61fc90d Remove unused variable 2024-04-01 17:24:48 -04:00
KernelDeimos 05c6cd6c3d Separate default user into SelfhostedModule 2024-04-01 17:24:07 -04:00
Eric Dubé 15fcc5680f Merge pull request #195 from shuguet/main
feat: Add support for running Puter self-hosted using the automatically built Docker image
2024-04-01 15:06:23 -04:00
Eric Dubé fdd9f30c39 Merge branch 'main' into main 2024-04-01 15:06:16 -04:00
Nariman Jelveh 0049c9ef00 Merge pull request #205 from AtkinsSJ/fix-i18n-typo
Fix issues with translation keys, and check these in CI
2024-04-01 11:18:43 -07:00
Nariman Jelveh f097f2e10a Merge pull request #164 from vineeth-vk11/#141
removing html inside translation strings
2024-04-01 11:03:55 -07:00
Nariman Jelveh 4009f4f331 Merge branch 'main' into #141 2024-04-01 11:02:37 -07:00
Sam Atkins 8f8b7f0fbf Check that all uses of i18n() use keys that exist
If code uses `i18n('foo')` and 'foo' is not in the dictionary for the en
translation, then this script will now report it as an error. This has
already helped catch a few mistakes.
2024-04-01 12:12:31 +01:00
Sam Atkins 29b3b4ecba Add or correct missing i18n keys
'save_account_to_publish' isn't used anywhere, so I assume that
'save_account_to_publish_website' is supposed to use that.
2024-04-01 12:10:31 +01:00
Sam Atkins b111e05ef7 Fix typo in 'change_always_open_with' i18n key 2024-04-01 12:00:58 +01:00
Sam Atkins c2f73c37c5 Correct capitalisation of i18n() keys
Found by searching for `i18n\(\'[^\']*[A-Z]+[^\']*\'\)`
2024-04-01 11:26:07 +01:00
Sylvain Huguet cc648be854 Re-enable healthchecks, adjusted intervals & start-time 2024-04-01 02:07:44 +02:00
Sylvain Huguet 483e2835c4 Disable healthcheck in Dockerfile as well 2024-03-31 11:34:03 +02:00
Sylvain Huguet daa90286d3 Update README instruction to run either with pure Docker, or with Docker Compose 2024-03-31 11:30:12 +02:00
Sylvain Huguet 5e1d6a7db3 Disable healthcheck until we know the proper URL to call/check 2024-03-31 11:19:35 +02:00
Sylvain Huguet ab4f222e92 Add support for self-hosting in Docker 2024-03-31 11:18:03 +02:00
vineeth kumar 5da46a15fb Merge branch 'main' into #141 2024-03-31 13:02:11 +05:30
vineethvk11 9438355a36 removing html inside translation strings 2024-03-31 12:53:53 +05:30
1290 changed files with 98073 additions and 13924 deletions

No files matched your search

+1
View File
@@ -1,3 +1,4 @@
.dockerignore
Dockerfile
node_modules
/puter
+1 -1
View File
@@ -1 +1 @@
PORT=4000
PORT=4000
+11
View File
@@ -0,0 +1,11 @@
---
name: App idea
about: Suggest a potential app for Puter
title: ''
labels:
- app-request
assignees: ''
---
+25
View File
@@ -0,0 +1,25 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Issue Description**
**Steps to Reproduce**
**Expected & Actual Behavior**
**Addition Information or Screenshots (if applicable)**
**Deployment**
- [ ] Production (puter.com)
- [ ] Development (`npm run start`)
- [ ] Docker (via `docker run`)
- [ ] Docker (via `docker-compose`)
**Puter version (if accessible)**
> Click the profile button on the top-right, then "Settings". The version number will be printed at the bottom
+10
View File
@@ -0,0 +1,10 @@
---
name: Feature request
about: Suggest an idea for Puter
title: ''
labels: idea
assignees: ''
---
@@ -0,0 +1,10 @@
---
name: Idea for Improvement
about: An enhancement for an existing feature on Puter
title: ''
labels: enhancement
assignees: ''
---
-28
View File
@@ -1,28 +0,0 @@
# This workflow runs the tools/check-translations.js script to make sure that the translation data is valid.
name: Check Translations
env:
NODE_VERSION: 21.x
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ env.NODE_VERSION }}
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
cache-dependency-path: ./package-lock.json
- run: npm ci
- run: npm run check-translations
+16 -11
View File
@@ -5,8 +5,10 @@ name: Docker Image CI
# branch called `main`.
on:
push:
branches: ['main']
tags:
- '*.*.*'
branches:
- 'main'
# Defines two custom environment variables for the workflow. These are used
# for the Container registry domain, and a name for the Docker image that
@@ -41,6 +43,12 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about)
# to extract tags and labels that will be applied to the specified image.
# The `id` "meta" allows the output of this step to be referenced in
@@ -50,16 +58,10 @@ jobs:
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
images: "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}"
tags: |
type=schedule
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}},enable=${{ !startsWith(github.ref, 'refs/tags/v0.') }}
type=sha
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }}
type=ref,event=branch
# This step uses the `docker/build-push-action` action to build the
# image, based on your repository's `Dockerfile`. If the build succeeds,
@@ -73,7 +75,10 @@ jobs:
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
platforms: linux/amd64,linux/arm64
context: .
push: true
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
+40
View File
@@ -0,0 +1,40 @@
name: Maintain Release Merge PR
on:
push:
branches:
- main
jobs:
update-release-pr:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Git
run: |
git config user.name github-actions
git config user.email [email protected]
- name: Check for existing PR
id: find-pr
uses: juliangruber/find-pull-request-action@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
branch: release
- uses: actions/checkout@v4
if: steps.find-pr.outputs.number == ''
with:
ref: release
- name: Reset release branch
if: steps.find-pr.outputs.number == ''
run: |
git fetch origin main:main
git reset --hard main
- name: Create/Update PR
if: steps.find-pr.outputs.number == ''
uses: peter-evans/create-pull-request@v6
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: Update release branch
title: Merge Release Auto-PR
body: Merging this PR will invoke release actions
branch: auto-update/release
+18
View File
@@ -0,0 +1,18 @@
on:
push:
branches:
- main
permissions:
contents: write
pull-requests: write
name: release-please
jobs:
release-please:
runs-on: ubuntu-latest
steps:
- uses: google-github-actions/release-please-action@v4
with:
release-type: node
+19 -2
View File
@@ -1,11 +1,28 @@
# Misc
.DS_Store
# Dependencies
node_modules/
*.zip
*.tgz
license.config.json
license-header.txt
# Build Outputs
dist/
.vscode/
# VS Code IDE
.vscode/**/*
!.vscode/extensions.json
!.vscode/launch.json
!.vscode/settings.json
!.vscode/tasks.json
# Local env files
.env
!.env.example
# this is for jetbrain IDEs
.idea/
.idea/
/puter
+304
View File
@@ -0,0 +1,304 @@
# Changelog
## v2.4.2 (2024-07-22)
### Puter
#### Features
- add new file templates ([1f7f094](https://github.com/HeyPuter/puter/commit/1f7f094282fae915a2436701cfb756444cd3f781))
- add cross_origin_isolation option ([e539932](https://github.com/HeyPuter/puter/commit/e53993207077aecd2c01712519251993bb2562bc))
- add option to disable temporary users ([f9333b3](https://github.com/HeyPuter/puter/commit/f9333b3d1e05bd0dffaecd2e29afd08ea61559fc))
- add some default groups ([ba50d0f](https://github.com/HeyPuter/puter/commit/ba50d0f96d58075abec067d24e6532bd874093f0))
- Add support for dropping multiple Puter items onto Dev Center (close #311) ([8e7306c](https://github.com/HeyPuter/puter/commit/8e7306c23be01ee6c31cdb4c99f2fb1f71a2247f))
#### Translations
- Update ig.js ([382fb24](https://github.com/HeyPuter/puter/commit/382fb24dbb1737a8a54ed2491f80b2e2276cde61))
- feat: add vietnamese localization-a ([c2d3d69](https://github.com/HeyPuter/puter/commit/c2d3d69dbe33f36fcae13bcbc8e2a31a86025af9))
- Update zhtw.js, Complete Traditional Chinese translation based on English file #550 ([b9e73b7](https://github.com/HeyPuter/puter/commit/b9e73b7288aebb14e6bbf1915743e9157fc950b1))
- update zhtw.js to match en.js ([37fd666](https://github.com/HeyPuter/puter/commit/37fd666a9a6788d5f0c59311499f29896b48bc82))
- Add Tamil translation to translations.js ([8a3d043](https://github.com/HeyPuter/puter/commit/8a3d0430f39f872b8a460c344cce652c340b700b))
- Move Tamil translation to the rest of translations ([333d6e3](https://github.com/HeyPuter/puter/commit/333d6e3b651e460caca04a896cbc8c175555b79b))
- Translation improvements, mainly style and context-based ([8bece96](https://github.com/HeyPuter/puter/commit/8bece96f6224a060d5b408e08c58865fadb8b79c))
- update translation file es.js to be up to date with the file en.js ([1515278](https://github.com/HeyPuter/puter/commit/151527825f1eb4b060aaf97feb7d18af4fcddbf2))
- Translate en.js as of 2024-07-10 ([8e297cd](https://github.com/HeyPuter/puter/commit/8e297cd7e30757073e2f96593c363a273b639466))
- Create hu.js hungarian language ([69a80ab](https://github.com/HeyPuter/puter/commit/69a80ab3d2c94ee43d96021c3bcbdab04a4b5dc6))
- Update translations.js to Hungarian lang ([56820cf](https://github.com/HeyPuter/puter/commit/56820cf6ee56ff810a6b495a281ccbb2e7f9d8fb))
- Tamil translation ([81781f8](https://github.com/HeyPuter/puter/commit/81781f80afc07cd1e6278906cdc68c8092fbfedf))
- Update it.js ([84e31ef](https://github.com/HeyPuter/puter/commit/84e31eff2f58584d8fab7dd10606f2f6ced933a2))
- Update Armenian translation file ([3b8af7c](https://github.com/HeyPuter/puter/commit/3b8af7cc5c1be8ed67be827360bbfe0f0b5027e9))
#### Bug Fixes
- fix templates ([5d2a6fc](https://github.com/HeyPuter/puter/commit/5d2a6fce305a3dcd4857f52ebb75f529dffe4790))
- popup login in co isolation mode ([8f87770](https://github.com/HeyPuter/puter/commit/8f87770cebab32c00cb10133979d426306685292))
- add necessary iframe attributes for co isolation ([2a5cec7](https://github.com/HeyPuter/puter/commit/2a5cec7ee914c9c97ae90b85464f9fc5332ad2fb))
- chore: fix confirm for type_confirm_to_delete_account ([02e1b1e](https://github.com/HeyPuter/puter/commit/02e1b1e8f5f8e22d7ab39ebff99f7dd8e08a4221))
- syntax error and formatting issue ([3a09e84](https://github.com/HeyPuter/puter/commit/3a09e84838fe8b74bd050641620eec87d9f59dfc))
- #432 ([f897e84](https://github.com/HeyPuter/puter/commit/f897e844989083b0b369ba0ce4d2c5a9f3db5ad8))
- `launch_app` not considering `explorer` as a special case ([98e6964](https://github.com/HeyPuter/puter/commit/98e69642d027a83975a0b2b825317213098bb689))
- well kinda (HOSTNAME in phoenix) ([7043b94](https://github.com/HeyPuter/puter/commit/7043b9400c63842c4c54d82724167666708d3119))
- it was github actions the entire time ([602a198](https://github.com/HeyPuter/puter/commit/602a19895c05b45a7d283470e7af3ae786be1bf2))
- fix CI attempt #7 ([614f2c5](https://github.com/HeyPuter/puter/commit/614f2c5061525f230ccd879bfb047434ac46a9ba))
- fix CI attempt #6 ([9d549b1](https://github.com/HeyPuter/puter/commit/9d549b192d149eac96c316ded645bf7c2e96153d))
- fix CI attempt #5 ([74adcdd](https://github.com/HeyPuter/puter/commit/74adcddc1d60e0a513408a0716ed2b301126225d))
- fix CI attempt #4 ([84b993b](https://github.com/HeyPuter/puter/commit/84b993bce913c3ad99127063bcfaae19331b199c))
- fix CI attempt #3 ([3bca973](https://github.com/HeyPuter/puter/commit/3bca973f5f4e65a2bd24c634c347fbd681a7458b))
- fix CI attempt #2 ([aebe89a](https://github.com/HeyPuter/puter/commit/aebe89a1acb070764551e8e89e325325ffbed8f9))
- run mocha within packages in monorepo ([58c199c](https://github.com/HeyPuter/puter/commit/58c199c15356ac087a04b16dd18e8fe0f1aea359))
- make webpack output not look like errors ([ad3d318](https://github.com/HeyPuter/puter/commit/ad3d318d07377c78c0429247225655e489b68be4))
- No scrollbar for session list ([45f131f](https://github.com/HeyPuter/puter/commit/45f131f8eaf94cf3951ca7ffeb6f311590233b8a))
- fix path issues under win32 platform ([d80f2fa](https://github.com/HeyPuter/puter/commit/d80f2fa847bfaef98dc8d482898f5c15f268e4bd))
- remove abnoxious debug file ([5c636d4](https://github.com/HeyPuter/puter/commit/5c636d4fd25e14ba3813f7fca3b70ff7bd6860e7))
- read_only fields in ES ([e8f4c32](https://github.com/HeyPuter/puter/commit/e8f4c328bff5c36b95fe460b80803e12e619f8ee))
### Security
#### Bug Fixes
- hoist acl check in ll_read ([6a2fbc1](https://github.com/HeyPuter/puter/commit/6a2fbc1925952ecceed741afe138270d1eeda7b7))
## v2.4.1 (2024-07-11)
### Puter
#### Features
- update BR translation ([42a6b39](https://github.com/HeyPuter/puter/commit/42a6b3938a588b8b4d1bd976c37e9c6e58408c75))
- JSON support for kv driver ([3ed7916](https://github.com/HeyPuter/puter/commit/3ed7916856f03eafbe0891f2ab39c34d20d2bd24))
#### Translations
- Update bn.js file formatting ([cff488f](https://github.com/HeyPuter/puter/commit/cff488f4f4378ca6c7568a585a665f2a3b87b89c))
- Issue#530 - Update bengali translations ([92abc99](https://github.com/HeyPuter/puter/commit/92abc9947f811f94f17a5ee5a4b73ee2b210900a))
- Added missing Romanian translations. ([8440f56](https://github.com/HeyPuter/puter/commit/8440f566b91c9eb4f01addcb850061e3fbe3afc7))
- Add 2FA Romanian translations ([473b651](https://github.com/HeyPuter/puter/commit/473b6512c697854e3f3badae1eb7b87742954da5))
- Add Japanese Translation ([47ec74f](https://github.com/HeyPuter/puter/commit/47ec74f0aa6adb3952e6460909029a4acb0c3039))
- Completing Italian translation based on English file ([f5a8ee1](https://github.com/HeyPuter/puter/commit/f5a8ee1c6ab950d62c90b6257791f026a508b4e4))
- Completing Italian translation based on English file. ([a96abb5](https://github.com/HeyPuter/puter/commit/a96abb5793528d0dc56d75f95d771e1dcf5960d1))
- Completing Arabic translation based on English file ([78a0ace](https://github.com/HeyPuter/puter/commit/78a0acea6980b6d491da4874edbd98e17c0d9577))
- Update Arabic translations in src/gui/src/i18n/translations/ar.js to match English version in src/gui/src/i18n/translations/en.js ([fe5be7f](https://github.com/HeyPuter/puter/commit/fe5be7f3cf7f336730137293ba86a637e8d8591d))
- Update Arabic translations in src/gui/src/i18n/translations/ar.js to match English version in src/gui/src/i18n/translations/en.js ([bffa192](https://github.com/HeyPuter/puter/commit/bffa192805216fc17045cd8d629f34784dca7f3f))
- Ukrainian updated ([e61039f](https://github.com/HeyPuter/puter/commit/e61039faf409b0ad85c7513b0123f3f2e92ebe32))
- Update ru.js issue #547 ([17145d0](https://github.com/HeyPuter/puter/commit/17145d0be6a9a1445947cc0c4bec8f16a475144c))
- Russian translation fixed ([8836011](https://github.com/HeyPuter/puter/commit/883601142873f10d69c84874499065a7d29af054))
#### Bug Fixes
- remove flag that breaks puter-js webpack ([7aadae5](https://github.com/HeyPuter/puter/commit/7aadae58ce1a51f925bf64c3d65ac1fa6971b164))
- Improve `getMimeType` to remove trailing dot in the extension if preset ([535475b](https://github.com/HeyPuter/puter/commit/535475b3c36a37e3319ed067a24fb671790dcda3))
## 2.4.0 (2024-07-08)
### Features
* add (pt-br) translation for system settings. ([77211c4](https://github.com/HeyPuter/puter/commit/77211c4f71b0285fb3060f7e5c8d493b4d7c4f0c))
* add /group/list endpoint ([d55f38c](https://github.com/HeyPuter/puter/commit/d55f38ca68899c3574cfe328d2b206b1143ff0d4))
* add /share/file-by-username endpoint ([5d214c7](https://github.com/HeyPuter/puter/commit/5d214c7b52887b594af6be497f1892baf7d77679))
* add /sharelink/request endpoint ([742f625](https://github.com/HeyPuter/puter/commit/742f625309f9f4cfa70cf7d2fe5b03fd164913ea))
* add /show urls ([079e25a](https://github.com/HeyPuter/puter/commit/079e25a9fe8e179f26d72378856058eb656e2314))
* add app metadata ([f7216b9](https://github.com/HeyPuter/puter/commit/f7216b95672b38802b288ef5b022e947017ff311))
* add appdata permission (if applicable) on app share ([9751fd9](https://github.com/HeyPuter/puter/commit/9751fd92a50e75385cffed0ca847d5076ba98c92))
* add cookie for site token ([a813fbb](https://github.com/HeyPuter/puter/commit/a813fbbb88bcfb8b9a61976e2a4fc4aab943fc88))
* add cross-server event broadcasting ([1207a15](https://github.com/HeyPuter/puter/commit/1207a158bdc88a90b14d31d03387ce353c176a9c))
* add debug mod ([16b1649](https://github.com/HeyPuter/puter/commit/16b1649ff62fd87a4dda5d2e1c68941c864c5da4))
* add endpoints for share tokens ([301ffaf](https://github.com/HeyPuter/puter/commit/301ffaf61dbb4fca1a855650ab80707ae6d9f602))
* Add exit status code to apps ([7674da4](https://github.com/HeyPuter/puter/commit/7674da4cd225bcad34079251c5600fc32e32248b))
* add external mod loading ([eb05fbd](https://github.com/HeyPuter/puter/commit/eb05fbd2dc4877553b5118a069a9afdc32bea137))
* add group management endpoints ([4216346](https://github.com/HeyPuter/puter/commit/4216346384d90dcba429dbcb175e6f86482d19f4))
* add group permission endpoints ([c374b0c](https://github.com/HeyPuter/puter/commit/c374b0cbca761e7c8a47d56a09551f2e9378066a))
* add mark-read endpoint ([0101f42](https://github.com/HeyPuter/puter/commit/0101f425d480705c20df4919a76f66e987f5790f))
* add permission rewriter for app by name ([16c4907](https://github.com/HeyPuter/puter/commit/16c4907be592dae31ed3c1aa3fac3b9655255d6f))
* add protected apps ([f2f3d6f](https://github.com/HeyPuter/puter/commit/f2f3d6ff460932698fb8da7309fbce3e96132950))
* add protected subdomains ([86fca17](https://github.com/HeyPuter/puter/commit/86fca17fb17c0c24397c29b49b133deadea1de8b))
* add querystring-informed errors ([e7c0b83](https://github.com/HeyPuter/puter/commit/e7c0b8320a6829315d9154d6d513bab4491c47ea))
* add readdir delegate for shares in a user directory ([8424d44](https://github.com/HeyPuter/puter/commit/8424d446099ac30ccf829c57d43eef1f235618e4))
* add readdir delegate for sharing user homedirs ([19a5eb0](https://github.com/HeyPuter/puter/commit/19a5eb00763f3ac31df8483fb59cb7a96c448745))
* add service for notifications ([a1e6887](https://github.com/HeyPuter/puter/commit/a1e6887bf93da21b9482040b3e30ee083fb23477))
* add service to test file share logic ([332371f](https://github.com/HeyPuter/puter/commit/332371fccb198462948a440419adc7a26d671a23))
* add share list to stat ([8c49ba2](https://github.com/HeyPuter/puter/commit/8c49ba2553ce6bee20eb5b6f2721bc80f639e98a))
* add share service and share-by-email to /share ([db5990a](https://github.com/HeyPuter/puter/commit/db5990a98935817c0e16d30e921bb99c57a98fc8))
* add subdomain permission (if applicable) on app share ([13e2f72](https://github.com/HeyPuter/puter/commit/13e2f72c9f33f485570f13f45341246b1a05879f))
* add user-group permission check ([0014940](https://github.com/HeyPuter/puter/commit/00149402e041443aa3ac571fbe97a9a85f95564b))
* **backend:** add script service ([30550fc](https://github.com/HeyPuter/puter/commit/30550fcddda18469735499546de502d29b85e2ad))
* **backend:** Add tab completion to server console command arguments ([fa81dca](https://github.com/HeyPuter/puter/commit/fa81dca9507b7fa0f82099b75f2ab89c865626ac))
* **backend:** Add tab-completion to server console command names ([e1e76c6](https://github.com/HeyPuter/puter/commit/e1e76c6be71fdeb3b6246307b626734d8dc26f86))
* **backend:** add tip of day ([2d8e624](https://github.com/HeyPuter/puter/commit/2d8e6240c61dc6301f49cbdcd1c3b04736f9ca93))
* **backend:** allow services to provide user properties ([522664d](https://github.com/HeyPuter/puter/commit/522664d415c33342500defec309c2ff15bc94804))
* **backend:** allow services to provide whoami values ([fccabf1](https://github.com/HeyPuter/puter/commit/fccabf1bc0c4418f3599222616dd63bf98c14fe1))
* **backend:** improve logger and reduce logs ([4bdad75](https://github.com/HeyPuter/puter/commit/4bdad75766d0617a164024b39b79bf5373c495a6))
* Display app icon and description in embeds ([ef298ce](https://github.com/HeyPuter/puter/commit/ef298ce3aa3ce90224e883fb0ba33f9cd3a3da44))
* get first test working on share-test service ([88d6bee](https://github.com/HeyPuter/puter/commit/88d6bee9546f36d689c53ec7fe95f01f772f5211))
* **git:** Add --color and --no-color options ([d6dd1a5](https://github.com/HeyPuter/puter/commit/d6dd1a5bb0a2b2bba2cfe86d2e51ff2a6e42841c))
* **git:** Add a --debug option, which sets the DEBUG global ([fa3df72](https://github.com/HeyPuter/puter/commit/fa3df72f6ed2d45a440ebc2aacbbae67bf042478))
* **git:** Add authentication to clone, fetch, and pull. ([364d580](https://github.com/HeyPuter/puter/commit/364d580ff896691ee70d3735f495c720651a9f41))
* **git:** Add diff display to `show` and `log` subcommands ([3cad1ec](https://github.com/HeyPuter/puter/commit/3cad1ec436f99a78f782ab9576325d4341284964))
* **git:** Add start-revision and file arguments to `git log` ([49c2f16](https://github.com/HeyPuter/puter/commit/49c2f163515d2130c17a6f6a6a16bc27ea69336a))
* **git:** Allow checking out a commit instead of a branch ([057b3ac](https://github.com/HeyPuter/puter/commit/057b3acf00af49c005b9bf7069c5d22983a32e1e))
* **git:** Color output for `git status` files ([bab5204](https://github.com/HeyPuter/puter/commit/bab5204209aa2efc0c053643677a78db6ede0929))
* **git:** Display file contents as a string for `git show FILE_OID` ([a680371](https://github.com/HeyPuter/puter/commit/a68037111a04580cfa2688694a68ef6ac7a495fa))
* **git:** Display ref names in `git log` and `git show` ([45cdfcb](https://github.com/HeyPuter/puter/commit/45cdfcb5bfa66937b33054a127e0b17001f3faa4))
* **git:** Format output closer to canonical git ([60976b1](https://github.com/HeyPuter/puter/commit/60976b1ed61984d9d290f3a0ae99dd97632e9909))
* **git:** Handle detached HEAD in `git status` and `git branch --list` ([2c9b1a3](https://github.com/HeyPuter/puter/commit/2c9b1a3ffc3d5e282ffe5b83a86314e99445bbc6))
* **git:** Implement `git branch` ([ad4f132](https://github.com/HeyPuter/puter/commit/ad4f13255d52f8226f22800c16b388cf0e6384d7))
* **git:** Implement `git checkout` ([35e4453](https://github.com/HeyPuter/puter/commit/35e4453930bc4e151887f83c97efec19cc15da70))
* **git:** Implement `git cherry-pick` ([2e4259d](https://github.com/HeyPuter/puter/commit/2e4259d267b3cfafd5cefc57a02643c6432fec4d))
* **git:** Implement `git clone` ([95c8235](https://github.com/HeyPuter/puter/commit/95c8235a4a1fea39a46c40df04cb1004a2fe7b23))
* **git:** Implement `git diff` ([622b6a9](https://github.com/HeyPuter/puter/commit/622b6a9b921c3c03efc0b519c9a26c6701d80e50))
* **git:** Implement `git fetch` ([98a4b9e](https://github.com/HeyPuter/puter/commit/98a4b9ede39b94c0c6b6b8345d7551359961186a))
* **git:** Implement `git pull` ([eb2b6a0](https://github.com/HeyPuter/puter/commit/eb2b6a08b03cee0612885412cd4b03c9564044e3))
* **git:** Implement `git push` ([8c70229](https://github.com/HeyPuter/puter/commit/8c70229a188b743220db076a740a992fd7971301))
* **git:** Implement `git remote` ([43ce0d5](https://github.com/HeyPuter/puter/commit/43ce0d5b45d4eb4f296afcaaa1ecadc125c53e89))
* **git:** Implement `git restore` ([4ba8a32](https://github.com/HeyPuter/puter/commit/4ba8a32b45d395f28433572db5644d630776789e))
* **git:** Make `git add` work for deleted files ([9551544](https://github.com/HeyPuter/puter/commit/955154468f48e45028dad2e916708d6a763affad))
* **git:** Make shorten_hash() guaranteed to produce a unique hash ([dd10a37](https://github.com/HeyPuter/puter/commit/dd10a377493c0d8f10a1ac8779dc27f3f3bf6c37))
* **git:** Resolve more forms of commit reference ([b6906bb](https://github.com/HeyPuter/puter/commit/b6906bbcaaa50fc8a8c60beb6d2d38bcb7dda758))
* **git:** Understand references like `HEAD^` and `main~3` ([711dbc0](https://github.com/HeyPuter/puter/commit/711dbc0d2fde9c2ddc6c86f64fb4caa7837c9dcb))
* implicit access from apps to shared appdata dirs ([31d4eb0](https://github.com/HeyPuter/puter/commit/31d4eb090efb340fdfb7cb6b751145e859624eeb))
* introduce notification selection via driver ([c5334b0](https://github.com/HeyPuter/puter/commit/c5334b0e19cf9762f536ec482c3ff872e9c12399))
* multi-recipient multi-file share endpoint ([846fdc2](https://github.com/HeyPuter/puter/commit/846fdc20d4a887a1f8a4f3bda4fafe41efab2733))
* **parsely:** Add a fail() parser ([5656d9d](https://github.com/HeyPuter/puter/commit/5656d9d42f76202a534ad640d3a4e287e0e40418))
* **parsely:** Add stringUntil() parser ([d46b043](https://github.com/HeyPuter/puter/commit/d46b043c5d16f1205d61de3f3ba43ed8ad7bff93))
* **phoenix:** Add --dump and --file options to sed ([f250f86](https://github.com/HeyPuter/puter/commit/f250f86446a506f24fa2ad396328e3a2212a68d0))
* **phoenix:** Add more commands to sed, including labels and branching ([306014a](https://github.com/HeyPuter/puter/commit/306014adc77a7ca155feb95d1146cb46ee075b52))
* **phoenix:** Expose parsed arg tokens to apps that request them ([4067c82](https://github.com/HeyPuter/puter/commit/4067c82486c99cad20f41927ad39ebea438b717f))
* **phoenix:** Implement an `exit` builtin ([3184d34](https://github.com/HeyPuter/puter/commit/3184d3482c7b95c0fd1fc0745555ff82fc9a8c99))
* **phoenix:** Implement parsing of sed scripts ([0d4f907](https://github.com/HeyPuter/puter/commit/0d4f907b6675b15bd50a55f50aa28f0803b18b7b))
* **phoenix:** Make `clear` clear scrollback unless `-x` is given ([75a989a](https://github.com/HeyPuter/puter/commit/75a989a7b69bfdfdf69e5f0365027c5b27d8bfc6))
* **Phoenix:** Pass command line arguments and ENV when launching apps ([8f1c4fc](https://github.com/HeyPuter/puter/commit/8f1c4fcda98e72a7b970e8c6fc2fe39a5e012264))
* **phoenix:** Respond to exit status codes ([5de3052](https://github.com/HeyPuter/puter/commit/5de305202656a172b187dac87543d6c1c69a2958))
* **phoenix:** Show actual host name in prompt and neofetch ([4539408](https://github.com/HeyPuter/puter/commit/4539408a218a50244dc615cf7de56c29dcac53e6))
* rate-limit for excessive groups ([4af279a](https://github.com/HeyPuter/puter/commit/4af279a72fc9de89ddc3ba51806ca3760a36265d))
* re-send unreads on login ([02fc4d8](https://github.com/HeyPuter/puter/commit/02fc4d86b7166fb4803be5d28e2a593d6b7d9785))
* register dev center to apps ([10f4d7d](https://github.com/HeyPuter/puter/commit/10f4d7d50ce9314f9c3888c74cb17c8ebbecee98))
* send notification when file gets shared ([2f6c428](https://github.com/HeyPuter/puter/commit/2f6c428a403a006f7878861d2f0356c3294519be))
* start directory index frame ([fb1e2f2](https://github.com/HeyPuter/puter/commit/fb1e2f21fb67aefe0602f6c978199c7cd019bbf7))
* support canonical puter.js url in dev ([fd41ae2](https://github.com/HeyPuter/puter/commit/fd41ae217c7a9f7229326f62a829471580a744bd))
* **ui:** add new components ([577bd59](https://github.com/HeyPuter/puter/commit/577bd59b6cc94810e851ad544f8234e25a4e6e27))
* **ui:** add new components ([38ba425](https://github.com/HeyPuter/puter/commit/38ba42575ce9f3506f8ce219b9580202b3ed9993))
* **ui:** allow component-based settings tabs ([1245960](https://github.com/HeyPuter/puter/commit/124596058a286241b51dd87ce2fc1a68478cb5b8))
* update share endpoint to support more things ([dd5fde5](https://github.com/HeyPuter/puter/commit/dd5fde5130c1840ab598e6622766ae835142e58a))
### Bug Fixes
* add app_uid param to kv interface ([f7a0549](https://github.com/HeyPuter/puter/commit/f7a054956b8739a3bc305a49faee929ea0da1e15))
* add missing columns for public directory update ([b10302a](https://github.com/HeyPuter/puter/commit/b10302ad744fd9c58f9735743e075815183c772c))
* Add missing file extension to 0009_app-prefix-fix.sql in DB init ([a8160a8](https://github.com/HeyPuter/puter/commit/a8160a8cdcdd6aff98728a6f1643d93386e6bb5a))
* add permission implicator for file modes ([e63ab3a](https://github.com/HeyPuter/puter/commit/e63ab3a67f6555eb13d6af477a8da9f1b54d6608))
* add stream limit ([ceba309](https://github.com/HeyPuter/puter/commit/ceba309dbd4df89f310d1a530f939a5b7991f4c7))
* **backend:** remove a bad thing that really doesn't work ([8d22276](https://github.com/HeyPuter/puter/commit/8d22276f13106f7642d11da30b1500817a20ad43))
* bug introduced when refactoring /share to Sequence ([ecb9978](https://github.com/HeyPuter/puter/commit/ecb997885c1efb766827c84d2ffb8dc6ddabe992))
* check subdomain earlier for /apps ([4e3a24e](https://github.com/HeyPuter/puter/commit/4e3a24e6093e279e210765e07e436f4e63b74072))
* column nullability blunder ([1429d6f](https://github.com/HeyPuter/puter/commit/1429d6f57c67dff51fc41ca0c2868f8d000845f1))
* Correct APIError imports ([062e23b](https://github.com/HeyPuter/puter/commit/062e23b5c9673db1f8b0ff0469289d52dd1e3f99))
* correct shown flag behavior ([632c536](https://github.com/HeyPuter/puter/commit/632c5366161ff8fbbd4d60c61dfbe52dad488a2c))
* database migration ([9b39309](https://github.com/HeyPuter/puter/commit/9b39309e18a2927d25fe794d91da4e4d068c4bca))
* do not delegate to select on read like ever that is really dumb ([a2a10b9](https://github.com/HeyPuter/puter/commit/a2a10b94be59403e03fb08bec5d7c056ce5b554f))
* docker runtime fail because stdout columns ([94c0449](https://github.com/HeyPuter/puter/commit/94c0449437ce4cb26d00a15a3f277bc7b09367b4))
* fix issues with apps in /share endpoint ([0cf90ee](https://github.com/HeyPuter/puter/commit/0cf90ee39af6548d271dec45ed8ee9e6df1cd14d))
* fix owner ids for default apps ([283f409](https://github.com/HeyPuter/puter/commit/283f409a662d126e7f3ce811f1467ac6fab9a522))
* fix permission cascade properly this time ([de58866](https://github.com/HeyPuter/puter/commit/de5886698e1eae2b250baac174b57029f3244e96))
* Fix phoenix app prefix and TokenService test ([afb9d86](https://github.com/HeyPuter/puter/commit/afb9d866b5091058711db931cde904947e661c15))
* fix that fix ([b126b67](https://github.com/HeyPuter/puter/commit/b126b670940a0e20cfe7bd0eba3db891bab5c142))
* fix typo ([ce328b7](https://github.com/HeyPuter/puter/commit/ce328b7245ad741b64c5885f64f806fc98a55d84))
* **git:** Make git commit display detached HEAD correctly ([73d0f5a](https://github.com/HeyPuter/puter/commit/73d0f5a90cb5dcbadfc6d0fd22f14e8bc0e61f86))
* group permission audit table ([7d2f6d2](https://github.com/HeyPuter/puter/commit/7d2f6d256f56e30d752e9999c6e8bde68f9d9637))
* handle subpaths under another user ([d128cee](https://github.com/HeyPuter/puter/commit/d128ceed6f4928fa0793815feb2e2715cd273ff8))
* handling of batch requests with zero files ([c0063a8](https://github.com/HeyPuter/puter/commit/c0063a871fd891a1774f1bee00e86170fed249fa))
* i forgot to test reloading ([7eabb43](https://github.com/HeyPuter/puter/commit/7eabb43bd4257b4129d67eaeda2aa27e8268dc78))
* improve console experience on mac ([15465bf](https://github.com/HeyPuter/puter/commit/15465bfc5035a64762f7c86a3d38af8be6be5b59))
* incorrect error from suggested_apps ([b648817](https://github.com/HeyPuter/puter/commit/b648817f2743c2b6214ebe4177d921c9b9027594))
* Make polyfilled import.meta.filename getter a valid function ([85c6798](https://github.com/HeyPuter/puter/commit/85c679844869b6b05fcbda231d8dc7026a66da97))
* null email in request to /share ([bf63144](https://github.com/HeyPuter/puter/commit/bf63144f7a79c48bd650ae851ddd0c8a10d748c3))
* Only run Component initialization functions once ([5b43358](https://github.com/HeyPuter/puter/commit/5b43358219402bee3eadf4a0f184a4b924d3293b))
* oops ([a136ee5](https://github.com/HeyPuter/puter/commit/a136ee5edd3149798a0d82f494f423f503b65f00))
* **parsely:** Make Repeat parser work when no separator is given ([9b4d16f](https://github.com/HeyPuter/puter/commit/9b4d16fbe9d5698c57f9da725a22b528a7d7cac2))
* peers array assumption ([10cbf08](https://github.com/HeyPuter/puter/commit/10cbf08233620440aa39f5302deaac4f59f02247))
* **phoenix:** Add missing newlines to sed command output ([e047b0b](https://github.com/HeyPuter/puter/commit/e047b0bf302284da61e677432e4cc25b531b24f2))
* **phoenix:** Gracefully handle completing a non-existent path ([d76e713](https://github.com/HeyPuter/puter/commit/d76e7130cba9f0ca05940abafe4fd1a41464aa83))
* property validation on some permission endpoints ([0855f2b](https://github.com/HeyPuter/puter/commit/0855f2b36eca3bbdaa8429cbde3aa1242e8e96ee))
* readdir on file ([a72ec97](https://github.com/HeyPuter/puter/commit/a72ec9799ac3bd76ceafa22cce149e373a13f3b9))
* remove last component when share URL is file ([1166e69](https://github.com/HeyPuter/puter/commit/1166e69c76688d1811701c56cd4df9d38e286793))
* remove legacy permission check in stat ([f2c6e01](https://github.com/HeyPuter/puter/commit/f2c6e01296e4214336e63bc2d69bcbf17f59890f))
* Remove null or duplicate app entries from suggest_app_for_fsentry() ([6900233](https://github.com/HeyPuter/puter/commit/6900233c5aaa2d1a49f495e9f9a060796757a91e))
* **security:** Move token for socket.io to request body ([49b257e](https://github.com/HeyPuter/puter/commit/49b257ecffbb1e12090b86a67528a5ad09da69db))
* switch share notif username to sender ([cd65217](https://github.com/HeyPuter/puter/commit/cd65217f5cda1c986ee231e2eeeef5abefa36ecb))
* **Terminal:** Accept input from Chrome on Android ([4ef3e53](https://github.com/HeyPuter/puter/commit/4ef3e53de34f0097950a7e707ca2483863beafb5))
* Throw an error when readdir is called on a non-directory ([46eb4ed](https://github.com/HeyPuter/puter/commit/46eb4ed2b96c235e10e15645a30d2f192a1af0de))
* type error in puter-site ([d96f924](https://github.com/HeyPuter/puter/commit/d96f924cad7a13ea6e9084bb0ebb79ecc5fcb8a3))
* ui color input attributes ([d9c4fbb](https://github.com/HeyPuter/puter/commit/d9c4fbbd1dcce12ee05ee33652a5fa518196463d))
* **ui:** improve Component base class ([f8780d0](https://github.com/HeyPuter/puter/commit/f8780d032b10138851c22af53b8610c578139acc))
* update email share object ([9033f6f](https://github.com/HeyPuter/puter/commit/9033f6f8c74ef8739294d640ac1c7eba95519bbd))
* update PD alert custom details ([2f16322](https://github.com/HeyPuter/puter/commit/2f163221bdde09425cae11ef7f8e4eb0b10c7103))
* update test kernel ([55c609b](https://github.com/HeyPuter/puter/commit/55c609b3fec4ef018febc6e88c44a6277960d728))
* validate size metadata ([2008db0](https://github.com/HeyPuter/puter/commit/2008db08524259264a0c8186a34fc75d7a133f5f))
## 2.3.0 (2024-05-22)
### Features
* add /healthcheck endpoint ([c166560](https://github.com/HeyPuter/puter/commit/c166560ff4ab5a453d3ec4f97326c995deb7f522))
* Add command names to phoenix tab-completion ([cf0eee1](https://github.com/HeyPuter/puter/commit/cf0eee1fa35328e05aefc8a425b5977efe5f4ec9))
* add option to change desktop background to default ([03f05f3](https://github.com/HeyPuter/puter/commit/03f05f316f11e8afe5fcee40b2b80a0de5e6826f))
* allow apps to add a menubar via puter.js ([331d9e7](https://github.com/HeyPuter/puter/commit/331d9e75428ec7609394f59b1755374c7340f83e))
* Allow querying puter-apps driver by partial app names ([dc5b010](https://github.com/HeyPuter/puter/commit/dc5b010d0913d2151b4851f8da5df72d2c8f42e7))
* Display upload errors in UIWindowProgress dialog ([edebbee](https://github.com/HeyPuter/puter/commit/edebbee9e7e9efbb33bf709b637c103be40d15a8))
* Implement 'Like' predicate in entity storage ([a854a0d](https://github.com/HeyPuter/puter/commit/a854a0dc0aa79a31695db833184c5ca3698632a9))
* improve password recovery experience ([04432df](https://github.com/HeyPuter/puter/commit/04432df5540811710ce1cc47ce6c136e5453bccb))
* **security:** add ip rate limiting ([ccf1afc](https://github.com/HeyPuter/puter/commit/ccf1afc93c24ee7f9a126216209a185d6b4d9fe4))
* Show "Deleting /foo" in progress window when deleting files ([f07c13a](https://github.com/HeyPuter/puter/commit/f07c13a50cee790eec44bce2f6e56fbcbf73f9b0))
### Bug Fixes
* Add missing file extension to 0009_app-prefix-fix.sql in DB init ([a8160a8](https://github.com/HeyPuter/puter/commit/a8160a8cdcdd6aff98728a6f1643d93386e6bb5a))
* Add missing TextEncoder to PTT ([8d4a1e0](https://github.com/HeyPuter/puter/commit/8d4a1e0ed3872e2c82b9e4be9b6d8b359e9cea09))
* Correct APIError imports ([062e23b](https://github.com/HeyPuter/puter/commit/062e23b5c9673db1f8b0ff0469289d52dd1e3f99))
* Correct grep output when asking for line numbers ([c8a20ca](https://github.com/HeyPuter/puter/commit/c8a20cadbfd539d185d32f4558916825fcf265ba))
* Correct inverted instanceof check in SignalReader.read() ([d4c2b49](https://github.com/HeyPuter/puter/commit/d4c2b492ef4864804776d3cb7d24797fdc536886))
* Correct variables used in errors in sign.js ([fa7c6be](https://github.com/HeyPuter/puter/commit/fa7c6bee9699527028be0ae9759155bc67c52324))
* Eliminates duplicate translation keys ([5800350](https://github.com/HeyPuter/puter/commit/5800350b253994dea410afff64e3df2a171e7775))
* fix error handling for outdated node versions ([4c1d5a4](https://github.com/HeyPuter/puter/commit/4c1d5a4b6d009ce075897d499d3517219bd745a4))
* Fix phoenix app prefix and TokenService test ([afb9d86](https://github.com/HeyPuter/puter/commit/afb9d866b5091058711db931cde904947e661c15))
* increase QR code size ([d2de46e](https://github.com/HeyPuter/puter/commit/d2de46edfbc05d132d5c929f6935b82515fbbda0))
* Make PathCommandProvider reject queries with path separators ([d733119](https://github.com/HeyPuter/puter/commit/d73311945610417a1ebc7bb0723ced0a599594b4))
* Make url variable accessible to all users of it ([2f30ae7](https://github.com/HeyPuter/puter/commit/2f30ae7a825adcd8da95888c38fe39c34acee0ff))
* Only run Component initialization functions once ([5b43358](https://github.com/HeyPuter/puter/commit/5b43358219402bee3eadf4a0f184a4b924d3293b))
* Parse octal echo escapes ([6ad8f5e](https://github.com/HeyPuter/puter/commit/6ad8f5e06abd050d319271f818d72debf5bc8e44))
* reduce token lengths ([5a76bad](https://github.com/HeyPuter/puter/commit/5a76bad28dfd8ec89a309941e410a54927fae22d))
* reliability issue :bug: ([1d546d9](https://github.com/HeyPuter/puter/commit/1d546d9ef70ef9066ad5838e9782ae330d289f29))
* Remove null or duplicate app entries from suggest_app_for_fsentry() ([6900233](https://github.com/HeyPuter/puter/commit/6900233c5aaa2d1a49f495e9f9a060796757a91e))
* **security:** always use application/octet-stream ([74e213a](https://github.com/HeyPuter/puter/commit/74e213a534dbf2844c8cebeee7eb59ec70de306e))
* **security:** Fix session revocation ([eb166a6](https://github.com/HeyPuter/puter/commit/eb166a67a9f0caf4fd77f9e27dc8209c2fc51f4c))
* **security:** Move token for socket.io to request body ([49b257e](https://github.com/HeyPuter/puter/commit/49b257ecffbb1e12090b86a67528a5ad09da69db))
* **security:** Prevent email enumeration ([ed70314](https://github.com/HeyPuter/puter/commit/ed703146863f896df76c98fad7127c6748c0ef9b))
* **security:** skip cache when checking old passwd ([7800ef6](https://github.com/HeyPuter/puter/commit/7800ef61029c8d1ba47491b4028a0cb972298725))
* **Terminal:** Accept input from Chrome on Android ([4ef3e53](https://github.com/HeyPuter/puter/commit/4ef3e53de34f0097950a7e707ca2483863beafb5))
* test release-please action [#3](https://github.com/HeyPuter/puter/issues/3) ([8fb0a66](https://github.com/HeyPuter/puter/commit/8fb0a66ef21921990e564e5f61c0e80e7f929dc7))
* test release-please action [#4](https://github.com/HeyPuter/puter/issues/4) ([f392de7](https://github.com/HeyPuter/puter/commit/f392de722a5232b622ed91b656a31cdc443c2e84))
* typographical error :bug: ([2949f71](https://github.com/HeyPuter/puter/commit/2949f71691eb0a258888c5d2a5bb496d2fe64a23))
* typographical errors :bug: ([4d30740](https://github.com/HeyPuter/puter/commit/4d30740198402cd1cc61b9ea4c45e006b69ec87e))
* Use correct variable for version number ([52d5299](https://github.com/HeyPuter/puter/commit/52d52993744dffa9f7f59a232da5df9077560731))
* use primary read in signup ([30f17ad](https://github.com/HeyPuter/puter/commit/30f17ade3a893d2283316e581836607e2029f9b9))
## [2.2.0](https://github.com/HeyPuter/puter/compare/v2.1.1...v2.2.0) (2024-04-23)
### Features
* add /healthcheck endpoint ([c166560](https://github.com/HeyPuter/puter/commit/c166560ff4ab5a453d3ec4f97326c995deb7f522))
* allow apps to add a menubar via puter.js ([331d9e7](https://github.com/HeyPuter/puter/commit/331d9e75428ec7609394f59b1755374c7340f83e))
## [2.1.1](https://github.com/HeyPuter/puter/compare/v2.1.0...v2.1.1) (2024-04-22)
### Bug Fixes
* test release-please action [#3](https://github.com/HeyPuter/puter/issues/3) ([8fb0a66](https://github.com/HeyPuter/puter/commit/8fb0a66ef21921990e564e5f61c0e80e7f929dc7))
* test release-please action [#4](https://github.com/HeyPuter/puter/issues/4) ([f392de7](https://github.com/HeyPuter/puter/commit/f392de722a5232b622ed91b656a31cdc443c2e84))
+22
View File
@@ -57,6 +57,28 @@ See [doc/contributors/index.md](./doc/contributors/index.md) for more informatio
<br>
## Commit Messages
Use the imperative, as is the convention in the Linux kernel:
- correct: `Improve performance of readdir`
- incorrect: `Improved readdir`
- incorrect: `Improving readdir`
We have the following exceptions to this rule:
- If the commit message is in _past tense_, it's a shorthand for the following:
- `Apply changes that would be applied after one had <past tense message>`
- If the commit message is in _present tense_, it's shorthand for the following:
- `Apply changes that would be applied after <present-tense message>`
For example, the following are correct:
- `Improved readdir`
- interpret this as: `Apply changes that would be applied after one had improved readdir`
- `Improving readdir`
- interpret this as: `Apply changes that would be applied after improving readdir`
<br>
## Code Review
Once you've submitted your pull request, the project maintainers will review your changes. We may suggest some changes or improvements. This is a normal part of the process, and your contributions are greatly appreciated!
+55 -11
View File
@@ -1,30 +1,74 @@
# /!\ NOTICE /!\
# Many of the developers DO NOT USE the Dockerfile or image.
# While we do test new changes to Docker configuration, it's
# possible that future changes to the repo might break it.
# When changing this file, please try to make it as resiliant
# to such changes as possible; developers shouldn't need to
# worry about Docker unless the build/run process changes.
# Build stage
FROM node:21-alpine AS build
# Install build dependencies
RUN apk add --no-cache git python3 make g++ \
&& ln -sf /usr/bin/python3 /usr/bin/python
# Set up working directory
WORKDIR /app
# Copy package.json and package-lock.json
COPY package*.json ./
# Copy the source files
COPY . .
# Install mocha
RUN npm install -g mocha
# Install node modules
RUN npm cache clean --force && \
for i in 1 2 3; do \
npm ci && break || \
if [ $i -lt 3 ]; then \
sleep 15; \
else \
exit 1; \
fi; \
done
# Run the build command if necessary
RUN cd src/gui && npm run build && cd -
# Production stage
FROM node:21-alpine
# Set labels
LABEL repo="https://github.com/HeyPuter/puter"
LABEL license="AGPL-3.0,https://github.com/HeyPuter/puter/blob/master/LICENSE.txt"
LABEL version="v1.2.40-beta"
LABEL version="1.2.46-beta-1"
# Debugging
RUN apk add --no-cache bash # useful for debugging
# Install git (required by Puter to check version)
RUN apk add --no-cache git
# Setup working directory
# Set up working directory
RUN mkdir -p /opt/puter/app
WORKDIR /opt/puter/app
# Add source files
# NOTE: This might change (https://github.com/HeyPuter/puter/discussions/32)
# Copy built artifacts and necessary files from the build stage
COPY --from=build /app/src/gui/dist ./dist
COPY --from=build /app/node_modules ./node_modules
COPY . .
# Set permissions
RUN chown -R node:node /opt/puter/app
USER node
# Install node modules
RUN npm cache clean --force \
&& npm install
EXPOSE 4100
HEALTHCHECK --interval=30s --timeout=3s \
CMD wget --no-verbose --tries=1 --spider http://puter.localhost:4100/test || exit 1
CMD [ "npm", "start" ]
ENV NO_VAR_RUNTUME=1
CMD ["npm", "start"]
+56 -82
View File
@@ -1,6 +1,6 @@
<h3 align="center"><img width="80" alt="Puter.com, The Personal Cloud Computer: All your files, apps, and games in one place accessible from anywhere at any time." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">The Internet OS! Free, Open-Source, and Self-Hostable!</h3>
<h3 align="center">The Internet OS! Free, Open-Source, and Self-Hostable.</h3>
<p align="center">
<a href="https://puter.com/"><strong>« LIVE DEMO »</strong></a>
@@ -15,21 +15,30 @@
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
·
<a href="https://hackerone.com/puter_h1b">Bug Bounty</a>
</p>
<h3 align="center"><img width="700" style="border-radius:5px;" alt="screenshot" src="https://assets.puter.site/puter.com-screenshot-2.webp"></h3>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="screenshot" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
Puter is an advanced, open-source internet operating system designed to be feature-rich, exceptionally fast, and highly extensible. It can be used to build remote desktop environments or serve as an interface for cloud storage services, remote servers, web hosting platforms, and more.
Puter is an advanced, open-source internet operating system designed to be feature-rich, exceptionally fast, and highly extensible. Puter can be used as:
- A privacy-first personal cloud to keep all your files, apps, and games in one secure place, accessible from anywhere at any time.
- A platform for building and publishing websites, web apps, and games.
- An alternative to Dropbox, Google Drive, OneDrive, etc. with a fresh interface and powerful features.
- A remote desktop environment for servers and workstations.
- A friendly, open-source project and community to learn about web development, cloud computing, distributed systems, and much more!
<br/>
## Getting Started
### Local Development
### 💻 Local Development
```bash
git clone https://github.com/HeyPuter/puter
@@ -42,100 +51,65 @@ This will launch Puter at http://localhost:4000 (or the next available port).
<br/>
### Using Docker
### 🐳 Docker
```bash
git clone https://github.com/HeyPuter/puter
cd puter
docker compose up
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
See [Configuration](#configuration) for next steps.
### 🐙 Docker Compose
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
#### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
### ☁️ Puter.com
Puter is available as a hosted service at [**puter.com**](https://puter.com).
<br/>
## ⚠️ Self-Hosting ⚠️
The self-hosted version of Puter is currently in alpha stage and should not be used in production yet. It is under active development and may contain bugs, other issues. Please exercise caution and use it for testing and evaluation purposes only.
## Support
## Configuration
Connect with the maintainers and community through these channels:
Running the server will generate a configuration file at `volatile/config/config.json`.
- Bug report or feature request? Please [open an issue](github.com/HeyPuter/puter/issues/new/choose).
- Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
- Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
- Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
- Email maintainers at [[email protected]](mailto:[email protected])
### Domain Name
To access Puter on your device, you can simply go to the address printed in
the server console (usually `puter.localhost:4100`).
To access Puter from another device, a domain name must be configured, as well as
an `api` subdomain. For example, `example.local` might be the domain name pointing
to the IP address of the server running puter, and `api.example.com` must point to
this address as well. This domain must be specified in the configuration file
(usually `volatile/config/config.json`) as well.
See [domain configuration](./doc/self-hosters/domains.md) for more information.
### Default User
By default, Puter will create a user called `default_user` with the password
`changeme`. A warning will persist in the dev console until this user's
password is changed. Please login to this user and change the password as
your first step. This user by default has 10GB storage instead of the default
(500MB storage) for new/temporary users.
<br/>
## FAQ
### ❓ What's the use case for Puter?
Puter can be used as:
- An alternative to Dropbox, Google Drive, OneDrive, etc. with a fresh interface and powerful features.
- Remote desktop environment for servers and workstations.
- A platform for building and hosting websites, web apps, and games.
- A friendly, open-source project and community to learn about web development, cloud computing, distributed systems, and much more!
We are always happy to help you with any questions you may have. Don't hesitate to ask!
<br/>
### ❓ Why isn't Puter built with React, Angular, Vue, etc.?
## License
For performance reasons, Puter is built with vanilla JavaScript and jQuery. Additionally, we'd like to avoid complex abstractions and to remain in control of the entire stack, as much as possible.
Also partly inspired by some of our favorite projects that are not built with frameworks: [VSCode](https://github.com/microsoft/vscode), [Photopea](https://www.photopea.com/), and [OnlyOffice](https://www.onlyoffice.com/).
This repository, including all its contents, sub-projects, modules, and components, is licensed under [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) unless explicitly stated otherwise. Third-party libraries included in this repository may be subject to their own licenses.
<br/>
### ❓ Why jQuery?
Puter interacts directly with the DOM and jQuery provides an elegant yet powerful API to manipulate the DOM, handle events, and much more. It's also fast, mature, and battle-tested.
<br/>
## #DoesItRunPuter
- [Minecraft](https://twitter.com/HeyPuter/status/1771957571496092036) | [video](https://www.youtube.com/watch?v=GIowZUXkg5g)
- [PlayStation 4](https://twitter.com/HeyPuter/status/1767978053014270059)
- [Skyworth TV](https://twitter.com/ericalexdube/status/1767983049277411564)
- [Oculus Quest 2](https://twitter.com/HeyPuter/status/1768664081756754012)
- [Tesla Model S](https://twitter.com/HeyPuter/status/1767971178864587057)
- [Tesla Model Y](https://twitter.com/HeyPuter/status/1772858333751636310)
- Tesla Model 3
<br/>
## Credits
The default wallpaper is created by [Milad Fakurian](https://unsplash.com/photos/blue-orange-and-yellow-wallpaper-E8Ufcyxz514) and published on [Unsplash](https://unsplash.com/).
Icons by [Papirus](https://github.com/PapirusDevelopmentTeam/papirus-icon-theme) under GPL-3.0 license.
Icons by [Iconoir](https://iconoir.com/) under MIT license.
Icons by [Elementary Icons](https://github.com/elementary/icons) under GPL-3.0 license.
Icons by [Tabler Icons](https://tabler.io/) under MIT license.
Icons by [bootstrap-icons](https://icons.getbootstrap.com/) under MIT license.
+2 -1
View File
@@ -3,5 +3,6 @@ We would like to thank the following security researchers for their responsible
# 2024
- Tim Suess: [GitHub](https://github.com/blackfortresslabs) | [Email]([email protected]) | [Website](blackfortresslabs.com)
- Tim Suess: [GitHub](https://github.com/blackfortresslabs) | [Email]([email protected]) | [Website](https://www.blackfortresslabs.com)
- xyzeva: [Github](https://github.com/xyzeva) | [Email](mailto:[email protected]) | [Website](https://kibty.town/)
- Yusuf Kelany: [GitHub](https://github.com/YusufYaser) | [Twitter](https://x.com/RealYusufYaser) | [Website](https://yusufyaser.xyz)
+1
View File
@@ -0,0 +1 @@
header: doc/license_header.txt
+14
View File
@@ -0,0 +1,14 @@
# #DoesItRunPuter
- [Minecraft](https://twitter.com/HeyPuter/status/1771957571496092036) | [video](https://www.youtube.com/watch?v=GIowZUXkg5g)
- [Samsung Watch](https://twitter.com/CharmunkDev/status/1781501714543030554)
- [PlayStation 4](https://twitter.com/HeyPuter/status/1767978053014270059)
- [Skyworth TV](https://twitter.com/ericalexdube/status/1767983049277411564)
- [A Fridge!](https://twitter.com/HeyPuter/status/1778890003797745842)
- [Oculus Quest 2](https://twitter.com/HeyPuter/status/1768664081756754012)
- [Tesla Model 3](https://twitter.com/EricLighthall/status/1781479732997214501)
- [Tesla Model S](https://twitter.com/HeyPuter/status/1767971178864587057)
- [Tesla Model Y](https://twitter.com/HeyPuter/status/1772858333751636310)
- [Nintendo Switch](https://twitter.com/HeyPuter/status/1780645795240538518)
- [Steam Deck](https://twitter.com/everythingSung/status/1782162352403828793)
- [Ladybird Browser](https://x.com/HeyPuter/status/1810783504503800035)
-3
View File
@@ -1,3 +0,0 @@
import { build } from "./utils.js"
build();
+5
View File
@@ -0,0 +1,5 @@
# API Documentation
Note that this documentation is different from the [puter.js docs](https://docs.puter.com).
The scope of the documentation in this directory includes both stable API endpoints that
are used by **puter.js**, as well as API endpoints that may be subject to future changes.
+9
View File
@@ -0,0 +1,9 @@
# Share Links
A **share link** is a link to Puter's origin which contains a token
in the query string (the key is `share_token`; ex:
`http://puter.localhost:4100?share_token=...`).
This token can be used to apply permissions to the user of the
current session **if and only if** this user's email is confirmed
and matches the share link's associated email.
+219
View File
@@ -0,0 +1,219 @@
# Group Endpoints
## POST `/group/create` (auth required)
### Description
Creates a group and returns a UID (UUID formatted).
Groups do not have names, or any other descriptive attributes.
Instead they are always identified with a UUID, and they have
a `metadata` property.
The `metadata` property will always be given back to the client
in the same way it was provided. The `extra` property, also an
object, may be changed by the backend. The behavior of setting
any property on `extra` is currently undefined as all properties
are reserved for future use.
### Parameters
- **metadata:** _- optional_
- **accepts:** `object`
- **description:** arbitrary metadata to describe the group
- **extra:** _- optional_
- **accepts:** `object`
- **description:** extra parameters (server may change these)
### Request Example
```javascript
await fetch(`${window.api_origin}/group/create`, {
"headers": {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
"body": JSON.stringify({
metadata: { title: 'Some Title' }
}),
"method": "POST",
});
// { uid: '9c644a1c-3e43-4df4-ab67-de5b68b235b6' }
```
### Response Example
```json
{
"uid": "9c644a1c-3e43-4df4-ab67-de5b68b235b6"
}
```
## POST `/group/add-users`
### Description
Adds one or more users to a group
### Parameters
- **uid:** _- required_
- **accepts:** `string`
UUID of an existing group
- **users:** `Array<string>`
usernames of users to add to the group
### Request Example
```javascript
await fetch(`${window.api_origin}/group/add-users`, {
"headers": {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
"body": JSON.stringify({
uid: '9c644a1c-3e43-4df4-ab67-de5b68b235b6',
users: ['first_user', 'second_user'],
}),
"method": "POST",
});
```
## POST `/group/remove-users`
### Description
Remove one or more users from a group
### Parameters
- **uid:** _- required_
- **accepts:** `string`
UUID of an existing group
- **users:** `Array<string>`
usernames of users to remove from the group
### Request Example
```javascript
await fetch(`${window.api_origin}/group/add-users`, {
"headers": {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
"body": JSON.stringify({
uid: '9c644a1c-3e43-4df4-ab67-de5b68b235b6',
users: ['first_user', 'second_user'],
}),
"method": "POST",
});
```
## GET `/group/list`
### Description
List groups associated with the current user
### Parameters
_none_
### Response Example
```json
{
"owned_groups": [
{
"uid": "c3bd4047-fc65-4da8-9363-e52195890de4",
"metadata": {},
"members": [
"default_user"
]
}
],
"in_groups": [
{
"uid": "c3bd4047-fc65-4da8-9363-e52195890de4",
"metadata": {},
"members": [
"default_user"
]
}
]
}
```
# Group Permission Endpoints
## POST `/grant-user-group`
Grant permission from the current user to a group.
This creates an association between the user and the
group for this permission; the group will only have
the permission effectively while the user who granted
permission has the permission.
### Parameters
- **group_uid:** _- required_
- **accepts:** `string`
UUID of an existing group
- **permission:** _- required_
- **accepts:** `string`
A permission string
### Request Example
```javascript
await fetch("http://puter.localhost:4100/auth/grant-user-group", {
"headers": {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
"body": JSON.stringify({
group_uid: '9c644a1c-3e43-4df4-ab67-de5b68b235b6',
permission: 'fs:/someuser/somedir/somefile:read'
}),
"method": "POST",
});
```
## POST `/revoke-user-group`
Revoke permission granted from the current user
to a group.
### Parameters
- **group_uid:** _- required_
- **accepts:** `string`
UUID of an existing group
- **permission:** _- required_
- **accepts:** `string`
A permission string
### Request Example
```javascript
await fetch("http://puter.localhost:4100/auth/grant-user-group", {
"headers": {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
"body": JSON.stringify({
group_uid: '9c644a1c-3e43-4df4-ab67-de5b68b235b6',
permission: 'fs:/someuser/somedir/somefile:read'
}),
"method": "POST",
});
```
- > **TODO** figure out how to manage documentation that could
reasonably show up in two files. For example: this is a group
endpoint as well as a permission system endpoint.
(architecturally it's a permission system endpoint, and
the permissions feature depends on the groups feature;
at least until a time when PermissionService is refactored
so a service like GroupService can mutate the permission
check sequences)
+112
View File
@@ -0,0 +1,112 @@
# Notification Endpoints
Endpoints for managing notifications.
## POST `/notif/mark-ack` (auth required)
### Description
The `/notif/mark-ack` endpoint marks the specified notification
as "acknowledged". This indicates that the user has chosen to either
dismiss or act on this notification.
### Parameters
| Name | Description | Default Value |
| ---- | ----------- | -------- |
| uid | UUID associated with the notification | **required** |
### Response
This endpoint responds with an empty object (`{}`).
## POST `/notif/mark-read` (auth required)
### Description
The `/notif/mark-read` endpoint marks that the specified notification
has been shown to the user. It will not "pop up" as a new notification
if they load the gui again.
### Parameters
| Name | Description | Default Value |
| ---- | ----------- | -------- |
| uid | UUID associated with the notification | **required** |
### Response
This endpoint responds with an empty object (`{}`).
### Request Example
```javascript
await fetch("https://api.puter.local/notif/mark-read", {
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
body: JSON.stringify({
uid: 'a14ea3d5-828b-42f9-9613-35f43b0a3cb8',
}),
method: "POST",
});
```
## ENTITY STORAGE `puter-notifications`
The `puter-notifications` driver is an Entity Storage driver.
It is read-only.
### Request Examples
#### Select Unread Notifications
```javascript
await fetch("http://api.puter.localhost:4100/drivers/call", {
"headers": {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
"body": JSON.stringify({
interface: 'puter-notifications',
method: 'select',
args: { predicate: ['unread'] }
}),
"method": "POST",
});
```
#### Select First 200 Notifications
```javascript
await fetch("http://api.puter.localhost:4100/drivers/call", {
"headers": {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
"body": JSON.stringify({
interface: 'puter-notifications',
method: 'select',
args: {}
}),
"method": "POST",
});
```
#### Select Next 200 Notifications
```javascript
await fetch("http://api.puter.localhost:4100/drivers/call", {
"headers": {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
"body": JSON.stringify({
interface: 'puter-notifications',
method: 'select',
args: { offset: 200 }
}),
"method": "POST",
});
```
+367
View File
@@ -0,0 +1,367 @@
# Share Endpoints
Share endpoints allow sharing files with other users.
## POST `/share` (auth required)
### Description
The `/share` endpoint shares 1 or more filesystem items
with one or more recipients. The recipients will receive
some notification about the shared item, making this
different from calling `/grant-user-user` with a permission.
When users are **specified by email** they will receive
a [share link](./concepts/share-link.md).
Each item specified in the `shares` property is a tag-typed
object of type `fs-share` or `app-share`.
#### File Shares (`fs-share`)
File shares grant permission to a file or directory. By default
this is read permission. If `access` is specified as `"write"`,
then write permission will be granted.
#### App Shares (`app-share`)
App shares grant permission to read a protected app.
##### subdomain permission
If there is a subdomain associated with the app, and the owner
of the subdomain is the same as the owner of the app, then
permission to access the subdomain will be granted.
Note that the subdomain is only associated if the subdomain
entry has `associated_app_id` set according to the app's id,
and will not be considered "associated" if only the index_url
happens to match the subdomain url.
##### appdata permission
If the app has `shared_appdata` set to `true` in its metadata
object, the recipient of the share will also get write permission
to the app owner's corresponding appdata directory. The appdata
directory must exist for this to work as expected
(otherwise the permission rewrite rule fails since the uuid
can't be determined).
### Example
```json
{
"recipients": [
"user_that_gets_shared_to",
"[email protected]"
],
"shares": [
{
"$": "app-share",
"name": "some-app-name"
},
{
"$": "app-share",
"uid": "app-SOME-APP-UID"
},
{
"$": "fs-share",
"path": "/some/file/or/directory"
},
{
"$": "fs-share",
"path": "SOME-FILE-UUID"
}
]
}
```
### Parameters
- **recipients** _- required_
- **accepts:** `string | Array<string>`
- **description:**
recipients for the filesystem entries being shared.
- **notes:**
- validation on `string`: email or username
- requirement of at least one value
- **shares:** _- required_
- **accepts:** `object | Array<object>`
- object is [type-tagged](./type-tagged.md)
- type is either [file-share](./types/file-share.md)
or [app-share](./types/app-share.md)
- **notes:**
- requirement that file/directory or app exists
- requirement of at least one entry
- **dry_run:** _- optional_
- **accepts:** `bool`
- **description:**
when true, only validation will occur
### Response
- **$:** `api:share`
- **$version:** `v0.0.0`
- **status:** one of: `"success"`, `"mixed"`, `"aborted"`
- **recipients:** array of: `api:status-report` or
`heyputer:api/APIError`
- **paths:** array of: `api:status-report` or
`heyputer:api/APIError`
- **dry_run:** `true` if present
### Request Example
```javascript
await fetch("http://puter.localhost:4100/share", {
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
body: JSON.stringify({
recipients: [
"user_that_gets_shared_to",
"[email protected]"
],
shares: [
{
$: "app-share",
name: "some-app-name"
},
{
$: "app-share",
uid: "app-SOME-APP-UID"
},
{
$: "fs-share",
path: "/some/file/or/directory"
},
{
$: "fs-share",
path: "SOME-FILE-UUID"
}
]
}),
method: "POST",
});
```
### Success Response
```json
{
"$": "api:share",
"$version": "v0.0.0",
"status": "success",
"recipients": [
{
"$": "api:status-report",
"status": "success"
}
],
"paths": [
{
"$": "api:status-report",
"status": "success"
}
],
"dry_run": true
}
```
### Error response (missing file)
```json
{
"$": "api:share",
"$version": "v0.0.0",
"status": "mixed",
"recipients": [
{
"$": "api:status-report",
"status": "success"
}
],
"paths": [
{
"$": "heyputer:api/APIError",
"code": "subject_does_not_exist",
"message": "File or directory not found.",
"status": 404
}
],
"dry_run": true
}
```
### Error response (missing user)
```json
{
"$": "api:share",
"$version": "v0.0.0",
"status": "mixed",
"recipients": [
{
"$": "heyputer:api/APIError",
"code": "user_does_not_exist",
"message": "The user `non_existing_user` does not exist.",
"username": "non_existing_user",
"status": 422
}
],
"paths": [
{
"$": "api:status-report",
"status": "success"
}
],
"dry_run": true
}
```
## POST `/sharelink/check` (no auth)
### Description
The `/sharelink/check` endpoint verifies that a token provided
by a share link is valid.
### Example
```javascript
await fetch(`${config.api_origin}/sharelink/check`, {
"headers": {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
"body": JSON.stringify({
token: '...',
}),
"method": "POST",
});
```
### Parameters
- **token:** _- required_
- **accepts:** `string`
The token from the querystring parameter
### Response
A type-tagged object, either of type `api:share` or `api:error`
### Success Response
```json
{
"$": "api:share",
"uid": "836671d4-ac5d-4bd3-bc0a-ec357e0d8f02",
"email": "[email protected]"
}
```
### Error Response
```json
{
"$": "api:error",
"message":"Field `token` is required.",
"key":"token",
"code":"field_missing"
}
```
## POST `/sharelink/apply` (no auth)
### Description
The `/sharelink/apply` endpoint applies a share to the current
user **if and only if** that user's email is confirmed and matches
the email associated with the share.
### Example
```javascript
await fetch(`${config.api_origin}/sharelink/apply`, {
"headers": {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
"body": JSON.stringify({
uid: '836671d4-ac5d-4bd3-bc0a-ec357e0d8f02',
}),
"method": "POST",
});
```
### Parameters
- **uid:** _- required_
- **accepts:** `string`
The uid of an existing share, received using `/sharelink/check`
### Response
A type-tagged object, either of type `api:status-report` or `api:error`
### Success Response
```json
{"$":"api:status-report","status":"success"}
```
### Error Response
```json
{
"message": "This share can not be applied to this user.",
"code": "can_not_apply_to_this_user"
}
```
## POST `/sharelink/request` (no auth)
### Description
The `/sharelink/request` endpoint requests the permissions associated
with a share link to the issuer of the share (user that sent the share).
This can be used when a user is logged in, but that user's email does
not match the email associated with the share.
### Example
```javascript
await fetch(`${config.api_origin}/sharelink/request`, {
"headers": {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
"body": JSON.stringify({
uid: '836671d4-ac5d-4bd3-bc0a-ec357e0d8f02',
}),
"method": "POST",
});
```
### Parameters
- **uid:** _- required_
- **accepts:** `string`
The uid of an existing share, received using `/sharelink/check`
### Response
A type-tagged object, either of type `api:status-report` or `api:error`
### Success Response
```json
{"$":"api:status-report","status":"success"}
```
### Error Response
```json
{
"message": "This share is already valid for this user; POST to /apply for access",
"code": "no_need_to_request"
}
```
+79
View File
@@ -0,0 +1,79 @@
# Type-Tagged Objects
```js
{
"$": "some-type",
"$version": "0.0.0",
"some_property": "some value",
}
```
## What's a Type-Tagged Object?
Type-Tagged objects are a convention understood by Puter's backend
to communicate meta information along with a JSON object.
The key feature of Type-Tagged Objects is the type key: `"$"`.
## Why Type-Tagged Objects?
The primary reason: to have a consistent convention we can use
anywhere.
- Since other services rarely use `$` in their property names,
we can safely use this without introducing reserved words and
re-mapping property names.
- Some places we use this convention might not need it, but
staying consistent means API end-users can
[do more with less code](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself).
## Specification
- The `"$"` key indicates a type (or class) of object
- Any other key beginning with `$` is a **meta-key**
- Other keys are not allowed to contain `$`
- `"$version"` must follow [semver](https://semver.org/)
- Keys with multiple `"$"` symbols are reserved for future use
## Alternative Representations
Puter's API will always send results in the format described
above, which is called the "Standard Representation"
Any endpoint which accepts a Type-Tagged Object will also
accept these alternative representations:
### Structured Representation
Depending on the architecture of your client, this format
may be more convenient to work with:
```json
{
"$": "$meta-body",
"type": "some-type",
"meta": { "version": "0.0.0" },
"body": { "some_property": "some value" }
}
```
### Array Representation
In the array representation, meta values go at the end.
```json
["some-type",
{ "some_property": "some value" },
{ "version": "0.0.0" }
]
```
If the second element of the list is not an object, it
will implicitly be placed in a property called value.
The following are equivalent:
```json
["some-type", "hello"]
```
```json
["some-type", { "value": "hello" }]
```
+26
View File
@@ -0,0 +1,26 @@
# `{"$": "app-share"}` - File Share
## Structure
- **name:** name of the app
- **uid:** name of the app
## Notes
- One of `name` or `uid` **must** be specified
## Examples
Share app by name
```json
{
"$": "app-share",
"name": "some-app-name"
}
```
Share app by uid
```json
{
"$": "app-share",
"uid": "app-0a7337f7-0f8a-49ca-b71a-38d39304fe04"
}
```
+32
View File
@@ -0,0 +1,32 @@
# `{"$": "file-share"}` - File Share
## Structure
- **path:** file or directory's path or uuid
- **access:** one of: `"read"`, `"write"` (default: `"read"`)
## Examples
Share with read access
```json
{
"$": "file-share",
"path": "/some/path"
}
```
Share with write access
```json
{
"$": "file-share",
"path": "/some/path",
"access": "write"
}
```
Using a UUID
```json
{
"$": "file-share",
"path": "b912c381-0c0b-466c-95a6-f9a4fc680a7d"
}
```
+30
View File
@@ -0,0 +1,30 @@
# Comment Prefixes
Comments have prefixes using
[Conventional: Comments](https://conventionalcomments.org/)
as a **loose** guideline, and using this markdown file as a
the actual guideline.
This document will be updated on an _as-needed_ basis.
## The rules
- A comment line always looks like this:
- A whitespace character
- Optional prefix matching `/[a-z-]+\([a-z-]a+\):/`
- A whitespace character
- The comment
- Formalized prefixes must follow the rules below
- Any other prefix can be used. After some uses it
might be good to formalize it, but that's not a hard rule.
## Formalized prefixes
- `todo:` is interchangable with the famous `TODO:`, **except:**
when lowercase (`todo:`) it can include a scope: `todo(security):`.
- `track:` is used to track common patterns.
- Anything written after `track:` must be registered in
[track-comments.md](../devmeta/track-comments.md)
- `wet:` is usesd to track anything that doesn't adhere
to the DRY principle; the following message should describe
where similar code is
+2
View File
@@ -0,0 +1,2 @@
### `vscode`
- `es6-string-html`
+59
View File
@@ -0,0 +1,59 @@
# Track Comments
Comments beginning with `// track:`. See
[comment_prefixes.md](../contributors/comment_prefixes.md)
## Track Comment Registry
- `track: type check`:
A condition that's used to check the type of an imput.
- `track: adapt`
A value can by adapted from another type at this line.
- `track: bounds check`:
A condition that's used to check the bounds of an array
or other list-like entity.
- `track: ruleset`
A series of conditions that early-return or `continue`
- `track: object description in comment`
A comment above the creation of some object which
could potentially have a `description` property.
This is especially relevant if the object is stored
in some kind of registry where multiple objects
could be listed in the console.
- `track: slice a prefix`
A common pattern where a prefix string is "sliced off"
of another string to obtain a significant value, such
as an indentifier.
- `track: actor type`
The sub-type of an Actor object is checked.
- `track: scoping iife`
An immediately-invoked function expression specifically
used to reduce scope clutter.
- `track: good candidate for sequence`
Some code involves a series of similar steps,
or there's a common behavior that should happen
in between. The Sequence class is good for this so
it might be a worthy migration.
- `track: opposite condition of sibling`
A sibling class, function, method, or other construct of
source code has a boolean expression which always evaluates
to the opposite of the one below this track comment.
- `track: null check before processing`
An object could be undefined or null, additional processing
occurs after a null check, and the unprocessed object is not
relevant to the rest of the code. If the code for obtaining
the object and processing it is moved to a function outside,
then the null check should result in a early return of null;
this code with the track comment may have additional logic
for the null/undefined case.
- `track: manual safe object`
This code manually creates a new "client-safe" version of
some object that's in scope. This could be either to pass
onto the browser or to pass to something like the
notification service.
- `track: common operations on multiple items`
A patterm which emerges when multiple variables have
common operations done upon them in sequence.
It may be applicable to write an iterator in the
future, or something will come up that require
these to be handled with a modular approach instead.
+12
View File
@@ -0,0 +1,12 @@
# Meta Documentation
## Notes
- > This document is a work-in-progress
## Rules
### "is" and "is not"
- When "A is B", always bold "is": "A **is** B" (`A **is** B`)
- When "A is not B", always bold "not": "A is **not** B" (`A is **not** B`)
+136
View File
@@ -0,0 +1,136 @@
### Problem
When sending metadata along with arbitrary JSON objects,
a collision of property names may occur. For example, the
driver system can't place a "type" property on an arbitrary
response coming from a driver because that might also be
the name of a property in the response.
#### Example:
```json
{
"type": "api:thing",
"version": "v1.0.0",
"some": "info"
}
```
#### Awful Solution
Reserved words. Drivers need to know their response can't have
keys like `type` or `version`. If we'd like to add more meta
keys in the future we need to verify that no existing drivers
use the new key we'd like to reserve. If we have have such features
as user-submitted drivers this will be impossibe.
A `meta` key as a single reserved word could work, which is one
of the solutions discussed below.
#### Obvious Solution:
The obvious solution is to return an object with a
`head` property and a `body` propery:
```json
{
"head": {
"type": "api:thing",
"version": "v1.0.0"
},
"body": {
"some": "info"
}
}
```
I don't mind this solution. I've come up with some alternatives though,
because this solution has a couple drawbacks:
- it looks a little verbose
- it's not backwards-compatible with arbitrary JSON-object responses
## Solutions
### Dollar-Sign Convention
- Objects have two classes of keys:
- "meta" keys begin with "$"
- other keys must validate against the
usual identifier rules: `/[A-Za-z_][A-Za-z0-9_]*/`
- The meta key `$` indicates the schema or class of
the object.
- Example:
```json
{
"$": "api:thing",
"$version": "v1.0.0",
"some": "info"
}
```
- what sucks about it:
- `$` might be surprising or confusing
- response is a subset of valid JSON keys
(those not including `$`)
- what's nice about it:
- backwards-compatible with arbitrary JSON-object responses
which don't already use `$`
### Underscore Convention
- Same as above, but `_` instead of `$`
```json
{
"_": "api:thing",
"_version": "v1.0.0",
"some": "info"
}
```
- what sucks about it:
- `_` might be confusing
- response is a subset of valid JSON keys
(those not including `_`)
- what's nice about it:
- `_` is conventionally used for private property names,
so this might be a little less surprising
- backwards-compatible with arbitrary JSON-object responses
which don't already use `_`
### Nesting Convention, simplified
- Similar to the "obvious solution" except
metadata fields are lifted up a level.
It's relatively inconsequential if meta keys
have reserved words compared to value keys.
```json
{
"type": "api:thing",
"version": "v1.0.0",
"value": {
"some": "info"
}
}
```
### Modified Dollar/Underscore convention
- Using `_` in this example, but instead of prefixing
meta properties they all go under one key.
```json
{
"_": {
"type": "api:thing",
"version": "v1.0.0"
},
"some": "info"
}
```
- what sucks about it:
- `_` might be confusing
- response is a subset of valid JSON keys
(those not **exactly** `_`)
- what's nice about it:
- `_` is conventionally used for private property names,
so this might be a little less surprising
- backwards-compatible with arbitrary JSON-object responses
which don't already use `_` as an exact key
- only one reserved key
+12
View File
@@ -0,0 +1,12 @@
# Micro Modules
**CoreModule** has a large number of services. Each service handles
a general concern, like "notifications", but increasing this granularity
a little put more could allow a lot more code re-use.
One specific example that comes to mind is services that provide
CRUD operations for a database table. The **EntityStoreService** can
be used for a lot of these even though right now it's specifically
used for drivers. Having a common class of service like this can also
allow quickly configuring the equivalent service for providing those
CRUD operations through an API.
+12
View File
@@ -124,6 +124,18 @@ The GUI is a single page application (SPA) and as best practice any route under
In other words, consider the routes above as "reserved" for Puter.
### Publish My Website
Right-click anywhere on the desktop to display options
From the options menu, select "New".
Then, choose "Folder".
Give the folder a name according to your preference.
After creating the folder:
Right-click on the folder.
Select the option "Publish as Website".
### Best Practices
- The `title` tags and meta tags (`<title></title>`, `<meta property="og:title"`, `<meta name="twitter:title"`, ...) should be dynamically set by the server. For example, if the URL is of an app (e.g. `https://puter.com/app/editor`) the `title` tags and meta tags should contain the app's title rather than the generic Puter title.
+5 -5
View File
@@ -1,4 +1,4 @@
# Configurating Domains for Self-Hosted Puter
# Configuring Domains for Self-Hosted Puter
## Local Network Configuration
@@ -20,7 +20,7 @@ The hosts file is a straightforward way to map domain names to IP addresses on i
192.168.1.10 api.puter.local
```
### For macOS and Linux:
#### For macOS and Linux:
1. Open a terminal.
2. Edit the hosts file with a text editor, e.g., `sudo nano /etc/hosts`.
3. Add lines for your domain and subdomain with the server's IP address, in the
@@ -51,7 +51,7 @@ Setting up a local DNS server on your network allows for flexible and scalable d
- **Pi-hole**: Acts as both an ad-blocker and a DNS server. Ideal for easy setup and maintenance.
- **BIND9**: Offers comprehensive DNS server capabilities for complex setups.
- **Dnsmasq**: Lightweight and suitable for smaller networks or those new to running a DNS server.
- **dnsmasq**: Lightweight and suitable for smaller networks or those new to running a DNS server.
**contributors note:** feel free to add any software you're aware of
which might help with this to the list. Also, feel free to add instructions here for specific software; our goal is for Puter to be easy to setup with tools you're already familiar with.
@@ -60,7 +60,7 @@ which might help with this to the list. Also, feel free to add instructions here
1. Choose and install DNS server software on a device within your network.
2. Configure the DNS server to resolve `puter.local` and `api.puter.local` to the IP address of your Puter hosting device.
3. Update your router’s DHCP settings to distribute the DNS server's IP address to all devices on the network.
3. Update your router's DHCP settings to distribute the DNS server's IP address to all devices on the network.
By setting up a local DNS server, you gain the most flexibility and control over your network's domain name resolution, ensuring that all devices can access Puter and its API without manual configuration.
@@ -68,5 +68,5 @@ By setting up a local DNS server, you gain the most flexibility and control over
Please note the self-hosting feature is still in alpha and a public production
deployment is not recommended at this time. However, if you wish to host
publically you can do so following the same steps you normally would to configure
publicly you can do so following the same steps you normally would to configure
a domain name and ensuring the `api` subdomain points to the server as well.
+58
View File
@@ -0,0 +1,58 @@
# Self-Hosting Puter
> [!WARNING]
> The self-hosted version of Puter is currently in alpha stage and should not be used in production yet. It is under active development and may contain bugs, other issues. Please exercise caution and use it for testing and evaluation purposes only.
### Self-Hosting Differences
Currently, the self-hosted version of Puter is different in a few ways from [Puter.com](https://puter.com):
- There is no built-in way to install or create other apps (see below)
- Several "core" apps are missing, such as **Code** or **Draw**, because we can't include them in this repository
- Some icons are different
Work is ongoing to improve the **App Center** and make it available on self-hosted.
Until then, it's possible to add other apps by manually editing the database file.
This process is not recommended unless you know what you are doing.
The file will appear after you first launch Puter, and should be found in `puter/data/puter-database.sqlite` for Docker,
or `volatile/runtime/puter-database.sqlite` otherwise.
You will need a database tool that can understand SQLite databases.
<br/>
## Configuration
Running the server will generate a configuration file in one of these locations:
- `config/config.json` when [Using Docker](#using-docker)
- `volatile/config/config.json` in [Local Development](#local-development)
- `/etc/puter/config.json` on a server (or within a Docker container)
### Domain Name
To access Puter on your device, you can simply go to the address printed in
the server console (usually `puter.localhost:4100`).
To access Puter from another device, a domain name must be configured, as well as
an `api` subdomain. For example, `example.local` might be the domain name pointing
to the IP address of the server running puter, and `api.example.com` must point to
this address as well. This domain must be specified in the configuration file
(usually `volatile/config/config.json`) as well.
See [domain configuration](./domains.md) for more information.
### Configure the Port
- You can specify a custom port by setting `http_port` to a desired value
- If you're using a reverse-proxy such as nginx or cloudflare, you should
also set `pub_port` to the public (external) port (usually `443`)
- If you have HTTPS enabled on your reverse-proxy, ensure that
`protocol` in config.json is set accordingly
### Default User
By default, Puter will create a user called `default_user`.
This user will have a randomly generated password, which will be printed
in the development console.
A warning will persist in the dev console until this user's
password is changed. Please login to this user and change the password as
your first step.
<br/>
+39
View File
@@ -0,0 +1,39 @@
## Puter Support Levels for Repository Updates
This document describes issues requiring repository changes;
which issues will be fixed by Puter's core team, and which ones
will be fixed if the community makes a contribution.
This document is not "law". It is provided only as a helpful guide
on what to expect.
### Level Glossary
| Name | Description |
| ---- | ----------- |
| Core | Core developers will fix this |
| Community | We will accept contributions to fix this |
| Mixed | Core developers will fix this if it's currently a priority |
### Issues and their Levels
| Issue | Priority |
| ----- | -------- |
| Security vulnerability | Core |
| Breaking change to SDK or API | Core |
| Bug in service in CoreModule | Core |
| Bug in a built-in app | Core |
| Login/init failure in Docker on `release` branch | Core |
| Login/init failure in Linux or OSX | Core |
| Login/init failure in Docker on `main` branch | Mixed |
| Login/init failure with specific configuration | Mixed |
| Login/init failure in Windows | Community |
## Puter Support for a Particular Deployment
If you experience issues on a self-hosted deployment we're here to
help. Some issues are related to configuration or environment, so
we may only be able to help in a limited capacity. Issues related
to data loss, data corruption, or security will have higher priority
over other issues with particular deployments.
+31
View File
@@ -0,0 +1,31 @@
# Testing with Email
Testing anything involving email is really simple using [mailhog](https://github.com/mailhog/MailHog)
### Step 1: Configure email service
In your `config.json` for Puter (`volatile/config/config.json` usually, `/var/puter/config.json` in containers),
add this entry to the `"services`" map:
```javascript
"services": {
// ... there are probably other service configs
"email": {
"host": "localhost",
"port": 1025
}
}
```
### Step 2: Install and run mailhog
Follow the instructions on [MailHog](https://github.com/mailhog/MailHog)'s
repository, or install through your distro's package manager.
Run the command: `mailhog`.
You should now have an inbox at [http://127.0.0.1:8025](http://127.0.0.1:8025).
Every email that Puter sends will show up on this page.
+9
View File
@@ -0,0 +1,9 @@
# Uncategorized Documentation
Any document in this directory may be moved in the future to
a more suitable location. This is a good place to put any
documentation that needs to be written when it's unclear what
the best place for it is. This is to avoid situations where
documentation _doesn't_ get written simply because it's not clear
where it belongs (something which the author of this very document
has been guilty of at times).
+46
View File
@@ -0,0 +1,46 @@
# Notes about ES6 Class Syntax
## Document Meta
> **backend focus:** This documentation is more relevant to
> Puter's backend than frontend, but is placed here because
> it could apply to other areas in the future.
## Expressions as Methods
One important shortcoming in the ES6 class syntax to be aware of
is that it discourages the use of expressions as methods.
For example:
```javascript
class ExampleClass extends SomeBase {
intuitive_method_definition () {}
constructor () {
this.less_intuitive = some_expr();
}
}
```
Even if it is known that the return type of `some_expr` is a function,
it is still unclear whether it's being used as a callback or
as a method without other context in the code, since this is
how we typically assign instance members rather than methods.
We solve this in Puter's backend using a **trait** called
[AssignableMethodsTrait](../../packages/backend/src/traits/AssignableMethodsTrait.js)
which allows a static member called `METHODS` to contain
method definitions.
### Uses for Expressions as Methods
#### Method Composition
Method Composition is the act of composing methods from other
constituents. For example,
[Sequence](../../packages/backend/src/codex/Sequence.js)
allows composing a method from smaller functions, allowing
easier definition of "in-betwewen-each" behaviors and ways
to track which values from the arguments are actually read
during a particular call.
+66
View File
@@ -0,0 +1,66 @@
# Puter Mods
## What is a Puter Mod?
Currently, the definition of a Puter mod is:
> A [Module](../../packages/backend/doc/contributors/modules.md)
> which is exported by a package directory which itself exists
> within a directory specified in the `mod_directories` array
> in `config.json`.
## Enabling Puter Mods
### Step 1: Update Configuration
First update the configuration (usually at `./volatile/config.json`
or `/var/puter/config.json`) to specify mod directories.
```json
{
"config_name": "example config",
"mod_directories": [
"{source}/mods/mods_enabled"
]
// ... other config options
}
```
The first path you'll want to add is
`"{source}/mods/mods_enabled"`
which adds all the mods included in Puter's official repository.
You don't need to change `{source}` unless your entry javascript
file is in a different location than the default.
If you want to enable all the mods, you can change the path above
to `mods_available` instead and skip step 2 below.
### Step 2: Select Mods
To enable a Puter mod, create a symbolic link (AKA symlink) in
`mods/mods_enabled`, pointing to
a directory in `mods/mods_available`. This follows the same convention
as managing sites/mods in Apache or Nginx servers.
For example to enable KDMOD (which you can read as "Kernel Dev" mod,
or "the mod that GitHub user KernelDeimos created to help with testing")
you would run this command:
```sh
ln -rs ./mods/mods_available/kdmod ./mods/mods_enabled/
```
This will create a symlink at `./mods/mods_enabled/kdmod` pointing
to the directory `./mods/mods_available/kdmod`.
> **note:** here are some helpful tips for the `ln` command:
> - You can remember `ln`'s first argument is the unaffected
> source file by remembering `cp` and `mv` are the same in
> this way.
> - If you don't add `-s` you get a hard link. You will rarely
> find yourself needing to do that.
> - The `-r` flag allows you to write both paths relative to
> the directory from which you are calling the command, which
> is sometimes more intuitive.
+23 -5
View File
@@ -1,7 +1,25 @@
version: '3'
---
version: "3.8"
services:
app:
build: ./
puter:
container_name: puter
image: ghcr.io/heyputer/puter:latest
pull_policy: always
# build: ./
restart: unless-stopped
ports:
- 4100:4100
- '4100:4100'
environment:
# TZ: Europe/Paris
# CONFIG_PATH: /etc/puter
PUID: 1000
PGID: 1000
volumes:
- ./puter/config:/etc/puter
- ./puter/data:/var/puter
healthcheck:
test: wget --no-verbose --tries=1 --spider http://puter.localhost:4100/test || exit 1
interval: 30s
timeout: 3s
retries: 3
start_period: 30s
+139
View File
@@ -0,0 +1,139 @@
import js from "@eslint/js";
import globals from "globals";
export default [
js.configs.recommended,
{
// Global ignores
ignores: [
"**/*.min.js",
"**/src/lib/**",
"**/dist/",
"src/backend/src/public/assets/**",
"incubator/**"
],
},
{
// Top-level and tools use Node
files: [
"tools/**/*.js",
],
languageOptions: {
globals: {
...globals.node,
}
}
},
{
// Back end
files: [
"src/backend/**/*.js",
"mods/**/*.js",
"dev-server.js",
"utils.js",
],
languageOptions: {
globals: {
...globals.node,
"kv": true,
"def": true,
"use": true,
"ll":true,
}
}
},
{
// Front end
files: [
"src/**/*.js",
],
ignores: [
"src/backend/**/*.js",
],
languageOptions: {
globals: {
...globals.browser,
...globals.commonjs,
// Weird false positives
"Buffer": true,
// Puter Common
"puter": true,
"i18n": true,
"html_encode": true,
"html_decode": true,
"isMobile": true,
// Class Registry
"logger": true,
"def": true,
"use": true,
// Libraries
"saveAs": true, // FileSaver
"iro": true, // iro.js color picker
"$": true, // jQuery
"jQuery": true, // jQuery
"JSZip": true, // JSZip
"_": true, // lodash
"QRCode": true, // qrcode
"io": true, // socket.io
"timeago": true, // timeago
"SelectionArea": true, // viselect
// Puter GUI Globals
"set_menu_item_prop": true,
"determine_active_container_parent": true,
"privacy_aware_path": true,
"api_origin": true,
"auth_token": true,
"logout": true,
"is_email": true,
"select_ctxmenu_item": true,
}
}
},
{
// Mods
// NOTE: Mods have backend and frontend parts, so this just includes the globals for both.
files: [
"mods/**/*.js",
],
languageOptions: {
globals: {
...globals.node,
"use": true,
"window": true,
"puter": true,
}
}
},
{
// Tests
files: [
"**/test/**/*.js",
],
languageOptions: {
globals: {
...globals.mocha,
}
}
},
{
// Phoenix
files: [
"src/phoenix/**/*.js",
],
languageOptions: {
globals: {
...globals.node,
}
}
},
{
// Global rule settings
rules: {
"no-prototype-builtins": "off", // Complains about any use of hasOwnProperty()
"no-unused-vars": "off", // Temporary, we just have a lot of these
"no-debugger": "warn",
"no-async-promise-executor": "off", // We do this quite often and it's fine
}
},
];
+29
View File
@@ -0,0 +1,29 @@
# Parsing Javascript and Generating it Back
## What Purpose?
This would be really useful for refactoring tools. I also want
automatic comments to be placed when certain features are used,
such as the [Sequence](../../src/backend/src/codex/Sequence.js)
class, since its usefulness won't be immediately apparent where
it appears in the source code.
I turns out the state of affairs with respect to generating a
CST for javascript... [kind of sucks](https://github.com/benjamn/recast/issues/1412).
I hope that further discussion on the issue I linked renders the
previous statement ironic.
## So, What Next?
The options I see are:
1. Add support to recast to make use of @babel/parser tokens when
the `tokens: true` option is set.
2. Add a format-preserving outputter to @babel/outputter.
[this is being worked on](https://github.com/babel/rfcs/pull/15)
3. Wait for someone else to do either of the previous two things.
4. Write a CST parser for javascript.
I'm going to start with option #3. It's very disappointing that
I don't have time to do #4, because I don't very much like solutions
#1 and #2; I like my CSTs to be more cohesive - a pyramid of meaning -
rather than lexer output dumped at the end of an AST.
@@ -0,0 +1,20 @@
{
"name": "js-parse-and-output",
"version": "1.0.0",
"description": "",
"main": "test.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "AGPL-3.0-only",
"dependencies": {
"@babel/generator": "^7.24.7",
"@babel/parser": "^7.24.7",
"acorn": "^8.12.1",
"acorn-static-class-features": "^1.0.0",
"escodegen": "^2.1.0",
"recast": "^0.23.9"
}
}
+57
View File
@@ -0,0 +1,57 @@
/*
* Copyright (C) 2024 Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const babelParser = require('@babel/parser');
const generate = (require('@babel/generator')).default;
const fs = require('fs');
const recast = require('recast');
const example = fs.readFileSync('./src/backend/src/filesystem/ll_operations/ll_read.js');
{
const ast = recast.parse(example, {
parser: {
parse (source) {
return babelParser.parse(source, {
ranges: true,
tokens: true,
});
},
},
});
const { code } = recast.print(ast);
}
{
const ast = babelParser.parse('' + example, {
tokens: true,
});
console.log(JSON.stringify(ast, undefined, ' '));
}
/*
const { code } = generate(ast, {
retainLines: true,
});
*/
// console.log(code);
+2
View File
@@ -0,0 +1,2 @@
*.bin
*.wasm
+22
View File
@@ -0,0 +1,22 @@
Copyright (c) 2012, The v86 contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
File renamed without changes.
+91
View File
@@ -0,0 +1,91 @@
FROM i386/debian:buster
ENV DEBIAN_FRONTEND noninteractive
# Update and install necessary packages
RUN apt update && \
apt --yes --no-install-recommends install \
linux-image-686 grub2 systemd \
libterm-readline-perl-perl \
gcc make libc6-dev \
unzip bzip2 xz-utils \
fluxbox \
i3-wm \
cmake \
fuse \
xorg xserver-xorg-input-kbd xserver-xorg-input-mouse xserver-xorg-input-evdev \
xserver-xorg-video-fbdev xserver-xorg-video-vesa \
xserver-xorg x11-xserver-utils xinit dbus-x11 \
libgdk-pixbuf2.0 libpango-1.0 libpangocairo-1.0 libgtk2.0-bin \
libc-l10n locales \
fonts-noto fonts-droid-fallback \
strace file xterm vim apt-file \
dhcpcd5 \
ca-certificates \
git \
wget curl \
net-tools netcat \
wmctrl xdotool \
libssl-dev \
mesa-utils libgl1-mesa-dri \
&& \
touch /root/.Xdefaults && \
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen && \
locale-gen && \
echo 'LANG="en_US.UTF-8"' > /etc/default/locale && \
chsh -s /bin/bash && \
echo "root:root" | chpasswd && \
mkdir -p /etc/systemd/system/[email protected]/ && \
systemctl enable [email protected] && \
rm /lib/systemd/system/getty.target.wants/getty-static.service && \
rm /etc/motd /etc/issue && \
systemctl disable systemd-timesyncd.service && \
systemctl disable apt-daily.timer && \
systemctl disable apt-daily-upgrade.timer && \
systemctl disable dhcpcd.service && \
echo "tmpfs /tmp tmpfs nodev,nosuid 0 0" >> /etc/fstab && \
cd /root/ && \
wget http://www.math.utah.edu/~mayer/linux/nbench-byte-2.2.3.tar.gz && \
tar xfv nbench-byte-2.2.3.tar.gz && \
rm nbench-byte-2.2.3.tar.gz && \
mv nbench-byte-2.2.3 bench && \
cd bench && \
make
# Copy necessary configuration files
COPY getty-noclear.conf getty-override.conf /etc/systemd/system/[email protected]/
COPY getty-autologin-serial.conf /etc/systemd/system/[email protected]/
COPY logind.conf /etc/systemd/logind.conf
# COPY xinitrc /root/.xinitrc
COPY xorg.conf /etc/X11/
COPY networking.sh /root/
COPY boot-9p /etc/initramfs-tools/scripts/boot-9p
# this needs to be commented out in order to boot from hdd
RUN printf '%s\n' 9p 9pnet 9pnet_virtio virtio virtio_ring virtio_pci | tee -a /etc/initramfs-tools/modules && \
echo 'BOOT=boot-9p' | tee -a /etc/initramfs-tools/initramfs.conf && \
update-initramfs -u
# Clean up unnecessary files
RUN apt-get --yes clean && \
rm -r /var/lib/apt/lists/* && \
rm -r /usr/share/doc/* && \
rm -r /usr/share/man/* && \
rm -r /usr/share/locale/?? && \
rm /var/log/*.log /var/log/lastlog /var/log/wtmp /var/log/apt/*.log /var/log/apt/*.xz
# Install Tailscale
RUN curl -fsSL https://tailscale.com/install.sh | sh
RUN chmod +x /root/networking.sh
# Install Go and puter-fuse
RUN wget https://go.dev/dl/go1.22.1.linux-386.tar.gz && \
tar -C /usr/local -xzf go1.22.1.linux-386.tar.gz && \
rm go1.22.1.linux-386.tar.gz && \
export PATH=$PATH:/usr/local/go/bin && \
go install github.com/HeyPuter/[email protected] && \
mv /root/go/bin/puter-fuse /usr/local/bin && \
rm -rf /root/go && \
rm -f /go1.22.1.linux-386.tar.gz
RUN echo "kernel.printk = 3 4 1 3" >>/etc/sysctl.conf
@@ -0,0 +1,5 @@
rmmod ne2k-pci && modprobe ne2k-pci
ifconfig enp0s5 192.168.1.5 netmask 255.255.255.0 up
route add default gw 192.168.1.1
echo "nameserver 1.1.1.1" > /etc/resolv.conf
dhcpcd -w4 enp0s5
@@ -0,0 +1,20 @@
FROM library/node:lts-bookworm
WORKDIR /app
RUN apt-get update && \
apt-get install -y nodejs nasm gdb unzip p7zip-full openjdk-17-jre wget python3 qemu-system-x86 git git-core build-essential libc6-dev-i386-cross libc6-dev-i386 clang curl time
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y
RUN /root/.cargo/bin/rustup toolchain install stable && \
/root/.cargo/bin/rustup target add wasm32-unknown-unknown && \
/root/.cargo/bin/rustup component add rustfmt-preview && \
/root/.cargo/bin/rustup update && /root/.cargo/bin/rustup update nightly
RUN git clone https://github.com/copy/v86
WORKDIR /app/v86
ENV PATH="$PATH:/root/.cargo/bin"
RUN make all
+208
View File
@@ -0,0 +1,208 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: 0
AlignAfterOpenBracket: Align
AlignArrayOfStructures: None
AlignConsecutiveAssignments:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: true
AlignConsecutiveBitFields:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: false
AlignConsecutiveDeclarations:
Enabled: true
AcrossEmptyLines: true
AcrossComments: true
AlignCompound: true
PadOperators: true
AlignConsecutiveMacros:
Enabled: true
AcrossEmptyLines: true
AcrossComments: true
AlignCompound: true
PadOperators: true
AlignEscapedNewlines: Right
AlignOperands: Align
AlignTrailingComments:
Kind: Always
OverEmptyLines: 0
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortEnumsOnASingleLine: true
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine
AttributeMacros:
- __capability
BinPackArguments: true
BinPackParameters: true
BitFieldColonSpacing: Both
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterExternBlock: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakAfterAttributes: Never
BreakAfterJavaFieldAnnotations: false
BreakArrays: true
BreakBeforeBinaryOperators: None
BreakBeforeConceptDeclarations: Always
BreakBeforeBraces: Allman
BreakBeforeInlineASMColon: OnlyMultiline
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: BeforeColon
BreakStringLiterals: true
ColumnLimit: 100
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: Always
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IfMacros:
- KJ_IF_MAYBE
IncludeBlocks: Merge
IncludeIsMainRegex: '(Test)?$'
IncludeIsMainSourceRegex: ''
IndentAccessModifiers: true
IndentCaseBlocks: false
IndentCaseLabels: true
IndentExternBlock: AfterExternBlock
IndentGotoLabels: true
IndentPPDirectives: None
IndentRequiresClause: true
IndentWidth: 4
IndentWrappedFunctionNames: false
InsertBraces: false
InsertNewlineAtEOF: true
InsertTrailingCommas: None
IntegerLiteralSeparator:
Binary: 0
BinaryMinDigits: 0
Decimal: 0
DecimalMinDigits: 0
Hex: 0
HexMinDigits: 0
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
LambdaBodyIndentation: Signature
LineEnding: DeriveLF
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: All
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PackConstructorInitializers: BinPack
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakOpenParenthesis: 0
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyIndentedWhitespace: 0
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Left
PPIndentWidth: 1
QualifierAlignment: Left
ReferenceAlignment: Pointer
ReflowComments: true
RemoveBracesLLVM: false
RemoveSemicolon: false
RequiresClausePosition: OwnLine
RequiresExpressionIndentation: OuterScope
SeparateDefinitionBlocks: Leave
ShortNamespaceLines: 1
SortIncludes: Never
SortJavaStaticImport: Before
SortUsingDeclarations: LexicographicNumeric
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceAroundPointerQualifiers: Default
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeParensOptions:
AfterControlStatements: true
AfterForeachMacros: true
AfterFunctionDefinitionName: false
AfterFunctionDeclarationName: false
AfterIfMacros: true
AfterOverloadedOperator: false
AfterRequiresInClause: false
AfterRequiresInExpression: false
BeforeNonEmptyParentheses: false
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false
SpaceInEmptyBlock: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: Never
SpacesInContainerLiterals: true
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInSquareBrackets: false
Standard: Latest
StatementAttributeLikeMacros:
- Q_EMIT
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 4
UseTab: Never
WhitespaceSensitiveMacros:
- BOOST_PP_STRINGIZE
- CF_SWIFT_NAME
- NS_SWIFT_NAME
- PP_STRINGIZE
- STRINGIZE
...
+110
View File
@@ -0,0 +1,110 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas Manipulation</title>
<style>
body {
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
}
#canvasContainer {
position: relative;
display: block;
}
#controls {
position: fixed;
top: 10px;
right: 10px;
z-index: 999;
background-color: #f1f1f1;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
}
#canvasContainer canvas {
border: 1px solid #000;
margin-top: 10px;
display: block;
position: relative;
}
</style>
</head>
<body>
<div id="controls">
<label for="width">Width:</label>
<input type="number" id="width" min="1">
<label for="height">Height:</label>
<input type="number" id="height" min="1">
<button onclick="createCanvas()">Create Canvas</button>
</div>
<div id="canvasContainer">
</div>
<script>
let canvasCount = 0;
function createCanvas() {
const width = document.getElementById("width").value;
const height = document.getElementById("height").value;
if (width <= 0 || height <= 0 || width >= 1080 || height >= 1920) {
alert("Please enter valid width and height values.");
return;
}
const canvasId = `canvas_${canvasCount}`;
const canvasContainer = document.getElementById("canvasContainer");
const canvas = document.createElement("canvas");
canvas.id = canvasId;
canvas.width = width;
canvas.height = height;
canvasContainer.appendChild(canvas);
const canvasControls = document.createElement("div");
canvasControls.classList.add("canvasControls");
const clearButton = document.createElement("button");
clearButton.textContent = "Clear";
clearButton.onclick = function() {
const ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
};
const pauseButton = document.createElement("button");
pauseButton.textContent = "Pause";
pauseButton.onclick = function() {
const ctx = canvas.getContext("2d");
console.log("Pausing v86");
};
const consoleButton = document.createElement("button");
consoleButton.textContent = "Get console";
consoleButton.onclick = function() {
const ctx = canvas.getContext("2d");
console.log("Getting v86 console");
ctx.clearRect(0, 0, canvas.width, canvas.height);
};
const deleteButton = document.createElement("button");
deleteButton.textContent = "Delete";
deleteButton.onclick = function() {
canvas.remove();
canvasControls.remove();
};
canvasControls.appendChild(clearButton);
canvasControls.appendChild(deleteButton);
canvasControls.appendChild(pauseButton);
canvasControls.appendChild(consoleButton);
canvasContainer.appendChild(canvasControls);
canvasCount++;
}
</script>
</body>
</html>
+82
View File
@@ -0,0 +1,82 @@
#include <iostream>
#include <fstream>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
const char* PIPE_NAME = "/tmp/bash_pipe";
int main()
{
mkfifo(PIPE_NAME, 0666);
while (true)
{
int pipe_fd = open(PIPE_NAME, O_RDONLY);
if (pipe_fd == -1)
{
perror("open");
exit(EXIT_FAILURE);
}
std::string command;
char buffer[128];
ssize_t bytes_read;
while ((bytes_read = read(pipe_fd, buffer, sizeof(buffer))) > 0)
{
command.append(buffer, bytes_read);
}
close(pipe_fd);
int pipe_to_child[2];
int pipe_from_child[2];
if (pipe(pipe_to_child) == -1 || pipe(pipe_from_child) == -1)
{
std::cerr << "Failed to create pipes\n";
exit(EXIT_FAILURE);
}
pid_t pid = fork();
if (pid < 0)
{
std::cerr << "Fork failed\n";
exit(EXIT_FAILURE);
}
else if (pid == 0)
{
close(pipe_to_child[1]);
close(pipe_from_child[0]);
dup2(pipe_to_child[0], STDIN_FILENO);
dup2(pipe_from_child[1], STDOUT_FILENO);
execl("/bin/bash", "/bin/bash", "-i", nullptr);
perror("exec");
exit(EXIT_FAILURE);
}
else
{
close(pipe_to_child[0]);
close(pipe_from_child[1]);
write(pipe_to_child[1], command.c_str(), command.size());
close(pipe_to_child[1]);
char output_buffer[128];
ssize_t output_bytes_read;
std::ofstream pipe_out(PIPE_NAME, std::ofstream::trunc);
while ((output_bytes_read =
read(pipe_from_child[0], output_buffer, sizeof(output_buffer))) > 0)
{
pipe_out.write(output_buffer, output_bytes_read);
}
close(pipe_from_child[0]);
pipe_out.close();
}
}
unlink(PIPE_NAME);
return 0;
}
+2
View File
@@ -0,0 +1,2 @@
// Compile and pipe into aplay in emu for sound check
main(i){for(i=0;;++i)putchar((i+(i>>2)|(i>>8)|(i>>6)));}
+64
View File
@@ -0,0 +1,64 @@
#!/usr/bin/env bash
ROOT_DIR="$(pwd)"
# This has to be something, that isn't wrapped by a repo with a package.json
VM_DIR="/tmp/vm"
# Goes from 1 to 22
ZSTD_LEVEL=22
build()
{
mkdir -p "$VM_DIR"
rm -rf "$VM_DIR/v86"
cd "$ROOT_DIR/make_container" || exit
docker build . -t v86builder
docker run --name v86build v86builder
docker cp v86build:/app/v86 "$VM_DIR"
docker rm v86build
# Overwrite v86'd debian Dockerfile with our own
cat "$ROOT_DIR/imagegen/Dockerfile" > "$VM_DIR/v86/tools/docker/debian/Dockerfile"
# Navigate to the Dockerfile directory
cd "$VM_DIR/v86/tools/docker/debian" || exit
# Build the container which will be used to serve v86
chmod +x build-container.sh
./build-container.sh
# Build the state of the VM
chmod +x build-state.js
./build-state.js
# Compress the generated state image
zstd --ultra -$ZSTD_LEVEL < "$VM_DIR/v86/images/debian-state-base.bin" > "$VM_DIR/v86/images/image.bin"
# Make project directories
mkdir -p "$ROOT_DIR/www/third-party"
mkdir -p "$ROOT_DIR/www/static"
# Copy/move necessary files to deployment directory
mv "$VM_DIR/v86/images/image.bin" "$ROOT_DIR/www/static/image.bin"
cp "$VM_DIR/v86/build/libv86.js" "$ROOT_DIR/www/third-party/libv86.js"
cp "$VM_DIR/v86/build/v86.wasm" "$ROOT_DIR/www/third-party/v86.wasm"
cp -r "$VM_DIR/v86/images/debian-9p-rootfs-flat/" "$ROOT_DIR/www/static/9p-rootfs/"
}
if [ ! -d "$VM_DIR/v86" ]
then
build
else
echo "V86 appears to be built"
read -p "Do you want to rebuild V86? (yes/no): " rebuild_choice
if [ "$rebuild_choice" = "yes" ]; then
echo "Rebuilding v86..."
build
fi
fi
# Start a HTTP server
cd "$ROOT_DIR/www/" || exit
echo "Opening a server on localhost with port 8080"
python3 -m http.server -b 127.0.0.1 8080
+20
View File
@@ -0,0 +1,20 @@
<!doctype html>
<html>
<head>
<script src="./third-party/libv86.js"></script>
<link rel="stylesheet" href="./third-party/xterm.css" />
<script src="./third-party/xterm.js"></script>
<script type="module" defer>
"use strict";
import InstanceManager from "./js/InstanceManager.mjs"
document.addEventListener("DOMContentLoaded", () => {
const manager = new InstanceManager({spawnRoot: document.body, term: true});
manager.createInstance({spawnRoot: document.body, term: true});
});
</script>
</head>
<body>
</body>
</html>
+123
View File
@@ -0,0 +1,123 @@
/*
* Copyright (C) 2024 Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { V86 } from "./V86Wrapper.mjs";
/**
* Class representing an Instance of an emulator machine.
*/
class Instance {
/**
* Create an Instance.
* @param {Object} options - Options for configuring the instance.
* @param {boolean} [options.term=true] - Terminal option.
* @param {boolean} [options.screen=false] - Screen option.
* @param {number} [options.memory=1024] - Memory size for the instance; must be power of two.
* @param {HTMLElement} [options.spawnRoot=undefined] - Html element where instance should be spawned.
* @param {boolean} [options.autoStart=true] - Whether to automatically start the instance.
* @param {string} [options.remote="./"] - Remote URL, defaults to origin.
* @param {string} [options.wsUrl=""] - Websocket URL option for communication with the outside world.
* @throws Will throw an error if remote URL does not end with a slash. @throws Will throw an error if the amount of memory provided is not a power of two.
*/
constructor(options) {
const defaultOptions = {
term: false,
screen: false,
memory: 1024,
spawnRoot: undefined,
autoStart: true,
remote: "./",
instanceName: [...Array(10)].map(() => Math.random().toString(36)[2]).join(''),
wsUrl: "",
};
const instanceOptions = { ...defaultOptions, ...options };
if (!instanceOptions.remote.endsWith('/'))
throw new Error("Instance ctor: Remote URL must end with a slash");
if (typeof self !== 'undefined' && self.crypto) {
this.instanceID = self.crypto.randomUUID();
} else {
this.instanceID = "Node";
}
this.terminals = [];
let v86Options = {
wasm_path: instanceOptions.remote + "third-party/v86.wasm",
preserve_mac_from_state_image: true,
memory_size: instanceOptions.memory * 1024 * 1024,
vga_memory_size: 8 * 1024 * 1024,
initial_state: { url: instanceOptions.remote + "static/image.bin" },
filesystem: { baseurl: instanceOptions.remote + "static/9p-rootfs/" },
autostart: instanceOptions.autoStart,
};
if (!(instanceOptions.wsUrl === ""))
v86Options.network_relay_url = instanceOptions.wsUrl;
if (!((Math.log(v86Options.memory_size) / Math.log(2)) % 1 === 0))
throw new Error("Instance ctor: Amount of memory provided isn't a power of two");
if (instanceOptions.screen === true) {
if (instanceOptions.spawnRoot === undefined)
throw new Error("Instance ctor: spawnRoot is undefined, cannot continue")
instanceOptions.spawnRoot.appendChild((() => {
const div = document.createElement("div");
div.setAttribute("id", instanceOptions.instanceName + '-screen');
const child_div = document.createElement("div");
child_div.setAttribute("style", "white-space: pre; font: 14px monospace; line-height: 14px");
const canvas = document.createElement("canvas");
canvas.setAttribute("style", "display: none");
div.appendChild(child_div);
div.appendChild(canvas);
return div;
})());
v86Options.screen_container = document.getElementById(instanceOptions.instanceName + '-screen');
}
this.vm = new V86(v86Options);
if (instanceOptions.term === true) {
if (instanceOptions.spawnRoot === undefined)
throw new Error("Instance ctor: spawnRoot is undefined, cannot continue")
var term = new Terminal({
allowTransparency: true,
});
instanceOptions.spawnRoot.appendChild((() => {
const div = document.createElement("div");
div.setAttribute("id", instanceOptions.instanceName + '-terminal');
return div;
})());
term.open(document.getElementById(instanceOptions.instanceName + '-terminal'));
term.write("Now booting emu, please stand by ...");
this.vm.add_listener("emulator-started", () => {
// emulator.serial0_send("\nsh networking.sh > /dev/null 2>&1 &\n\n");
// emulator.serial0_send("clear\n");
term.write("Welcome to psl!");
this.vm.serial0_send("\n");
});
this.vm.add_listener("serial0-output-byte", (byte) => {
var chr = String.fromCharCode(byte);
if (chr <= "~") {
term.write(chr);
}
});
term.onData(data => {
this.vm.serial0_send(data);
});
}
}
}
export default Instance
@@ -0,0 +1,158 @@
/*
* Copyright (C) 2024 Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import Instance from "./Instance.mjs"
/**
* Class representing the basic interface for managing instances of emulated machines.
*/
class InstanceManager {
/**
* Create an Instance Manager.
* @param {Object} [options] - Options for configuring the instance manager.
* @param {boolean} [options.screen=true] - Spawn screen option.
* @param {boolean} [options.term=false] - Spawn terminal option.
* @param {string} [options.instanceName="Host"] - Name of the instance.
* @param {number} [options.memory=1024] - Memory size for the instance; must be power of two.
* @param {HTMLElement} [options.spawnRoot=undefined] - Htlm element where instance should be spawned.
* @param {boolean} [options.autoStart=true] - Whether to automatically start the instance.
* @param {string} [options.remote="./"] - Remote URL, defaults to origin.
* @param {string} [options.wsUrl=""] - Websocket URL option.
*/
constructor(options) {
const defaultOptions = {
term: false,
screen: false,
instanceName: "Host",
memory: 1024,
spawnRoot: undefined,
autoStart: true,
remote: "./",
wsUrl: "",
};
const instanceOptions = { ...defaultOptions, ...options };
this.instances = {};
this.instanceNames = [];
this.curr_inst = 0;
this.instanceNames.push(instanceOptions.instanceName);
this.instances[instanceOptions.instanceName] = new Instance(instanceOptions);
}
/**
* Create an instance with given options and adds it to the pool of instances.
* @param {Object} options - Options for configuring the instance.
* @returns {Promise<Object>} - Resolves with the initialized instance.
*/
async createInstance(options) {
const instance = new Instance(options);
this.instanceNames.push(instance.instanceName);
this.instances[instance.instanceName] = instance;
return instance;
}
/**
* Continue running a suspended instance.
* @param {string} instName - instName of the instance to continue.
*/
async continueInstance(instName) {
var instance = await this.getInstanceByinstName(instName);
if (!instance.vm.cpu_is_running)
await instance.vm.run();
}
/**
* Suspend a running instance.
* @param {string} instName - instName of the instance to suspend.
*/
async suspendInstance(instName) {
var instance = await this.getInstanceByinstName(instName);
if (instance.vm.cpu_is_running)
await instance.vm.stop();
}
/**
* Save the state of a running instance.
* @param {string} instName - instName of the instance to save state.
* @returns {Promise} - Promise resolving once state is saved.
*/
async saveState(instName) {
const instance = this.getInstanceByinstName(instName);
if (instance.vm.cpu_is_running)
return instance.vm.save_state();
}
/**
* Load the state of a previously saved instance.
* @param {string} instName - instName of the instance to load state.
* @param {any} state - State to load.
* @returns {Promise} - Promise resolving once state is loaded.
*/
async loadState(instName, state) {
const instance = this.getInstanceByinstName(instName);
if (instance.vm.cpu_is_running)
await instance.vm.save_state(state);
}
/**
* Connect two instances for communication through NIC's.
* @param {string} destinationinstName - instName of the destination instance.
* @param {string} sourceinstName - instName of the source instance.
*/
async connectInstances(destinationinstName, sourceinstName) {
const destinationInstance = this.getInstanceByinstName(destinationinstName);
const sourceInstance = this.getInstanceByinstName(sourceinstName);
destinationInstance.add_listener("net0-send", (data) => {
source.bus.send("net0-receive", data);
});
sourceInstance.add_listener("net0-send", (data) => {
destination.bus.send("net0-receive", data);
});
}
/**
* Execute a command within an instance.
* @param {Object} inst - Instance object.
* @param {string} cmd - Command to execute.
* @param {Object} env - Environment variables.
* @param {number} [timeout=60] - Timeout for the command execution.
*/
async exec(inst, cmd, env, timeout = 60) {
// TODO: instNamed pipes on the instance would make this super nice so multiple terminals can be had
}
/**
* Destroy a specific instance.
* @param {string} instName - instName of the instance to destroy.
*/
async destroyInstance(instName) {
await this.getInstanceByinstName(instName).destroy();
}
/**
* Destroy all instances.
*/
async destroyInstances() {
for (const instance in this.instances)
destroyInstance(instance)
}
/**
* Get an instance by its instName.
* @param {string} instName - instName of the instance.
* @returns {Object} - The instance object.
* @throws Will throw an error if the instance instName is not found.
*/
async getInstanceByinstName(instName) {
if (!(instName in this.instances))
throw Error("getInstance: instName not found in instances object");
return this.instances[instName];
}
}
export default InstanceManager
+35
View File
@@ -0,0 +1,35 @@
/*
* Copyright (C) 2024 Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
let V86;
if (typeof window !== 'undefined') {
V86 = window.V86;
} else {
try {
const { createRequire } = await import('module');
const require = createRequire(import.meta.url);
const NodeV86 = require("../third-party/libv86.js");
V86 = NodeV86.V86;
} catch (error) {
console.error('Failed to load V86 in Node.js environment:', error);
}
}
export { V86 };
+81
View File
@@ -0,0 +1,81 @@
/*
* Copyright (C) 2024 Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#!/usr/bin/env node
/*
* Copyright (C) 2024 Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
"use strict";
import('./js/InstanceManager.mjs').then(module => {
const InstanceManager = module.default;
process.stdin.setRawMode(true);
process.stdin.resume();
process.stdin.setEncoding("utf8");
console.log("Now booting, please stand by ...");
const manager = new InstanceManager({ screen: false, term: false, spawnRoot: undefined });
manager.getInstanceByinstName("Host").then(result => {
const hostvm = result.vm;
hostvm.add_listener("emulator-started", () => {
process.stdout.write("Welcome to psl!");
hostvm.serial0_send("\n");
});
hostvm.add_listener("serial0-output-byte", (byte) => {
var chr = String.fromCharCode(byte);
if (chr <= "~") {
process.stdout.write(chr);
}
});
process.stdin.on("data", (c) => {
if (c === "\u0004") {
hostvm.stop();
process.stdin.pause();
}
else {
hostvm.serial0_send(c);
}
});
}).catch(error => {
console.error(error);
throw Error("Error in getting host inastance, quitting");
});
}).catch(error => {
console.error('Error loading InstanceManager:', error);
});
+11
View File
@@ -0,0 +1,11 @@
{
"name": "x86incubator",
"version": "1.0.0",
"description": "x86emu experimental repo for puter",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Puter Technologies Inc.",
"license": "AGPL-3.0-only"
}
+644
View File
@@ -0,0 +1,644 @@
/*
* Copyright (C) 2024 Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
;(function(){'use strict';function ba(a,b){function c(x){x=x.toString(16);return"#"+"0".repeat(6-x.length)+x}function d(x,C,S,P){x.style.width="";x.style.height="";P&&(x.style.transform="");var aa=x.getBoundingClientRect();P?x.style.transform=(1===C?"":" scaleX("+C+")")+(1===S?"":" scaleY("+S+")"):(0===C%1&&0===S%1?(e.style.imageRendering="crisp-edges",e.style.imageRendering="pixelated",e.style["-ms-interpolation-mode"]="nearest-neighbor"):(e.style.imageRendering="",e.style["-ms-interpolation-mode"]=""),P=window.devicePixelRatio||
1,0!==P%1&&(C/=P,S/=P));1!==C&&(x.style.width=aa.width*C+"px");1!==S&&(x.style.height=aa.height*S+"px")}console.assert(a,"1st argument must be a DOM container");var e=a.getElementsByTagName("canvas")[0],g=e.getContext("2d",{alpha:!1}),f=a.getElementsByTagName("div")[0],k=document.createElement("div"),l,m,n=1,p=1,t=1,q,z=!1,w,u,I,U=!1,ea=this;a=new Uint16Array([8962,199,252,233,226,228,224,229,231,234,235,232,239,238,236,196,197,201,230,198,244,246,242,251,249,255,214,220,162,163,165,8359,402,225,
237,243,250,241,209,170,186,191,8976,172,189,188,161,171,187,9617,9618,9619,9474,9508,9569,9570,9558,9557,9571,9553,9559,9565,9564,9563,9488,9492,9524,9516,9500,9472,9532,9566,9567,9562,9556,9577,9574,9568,9552,9580,9575,9576,9572,9573,9561,9560,9554,9555,9579,9578,9496,9484,9608,9604,9612,9616,9600,945,223,915,960,931,963,181,964,934,920,937,948,8734,966,949,8745,8801,177,8805,8804,8992,8993,247,8776,176,8729,183,8730,8319,178,9632,160]);for(var Ab=new Uint16Array([32,9786,9787,9829,9830,9827,9824,
8226,9688,9675,9689,9794,9792,9834,9835,9788,9658,9668,8597,8252,182,167,9644,8616,8593,8595,8594,8592,8735,8596,9650,9660]),Ra=[],db,sa=0;256>sa;sa++)db=126<sa?a[sa-127]:32>sa?Ab[sa]:sa,Ra[sa]=String.fromCharCode(db);g.imageSmoothingEnabled=!1;k.style.position="absolute";k.style.backgroundColor="#ccc";k.style.width="7px";k.style.display="inline-block";f.style.display="block";e.style.display="none";this.bus=b;b.register("screen-set-mode",function(x){this.set_mode(x)},this);b.register("screen-fill-buffer-end",
function(x){this.update_buffer(x)},this);b.register("screen-put-char",function(x){this.put_char(x[0],x[1],x[2],x[3],x[4])},this);b.register("screen-update-cursor",function(x){this.update_cursor(x[0],x[1])},this);b.register("screen-update-cursor-scanline",function(x){this.update_cursor_scanline(x[0],x[1])},this);b.register("screen-clear",function(){this.clear_screen()},this);b.register("screen-set-size-text",function(x){this.set_size_text(x[0],x[1])},this);b.register("screen-set-size-graphical",function(x){this.set_size_graphical(x[0],
x[1],x[2],x[3])},this);this.init=function(){this.set_size_text(80,25);this.timer()};this.make_screenshot=function(){const x=new Image;if(z)x.src=e.toDataURL("image/png");else{const C=[9,16],S=document.createElement("canvas");S.width=u*C[0];S.height=I*C[1];const P=S.getContext("2d");P.imageSmoothingEnabled=!1;P.font=window.getComputedStyle(f).font;P.textBaseline="top";for(let aa=0;aa<u;aa++)for(let fa=0;fa<I;fa++){const ta=3*(fa*u+aa);P.fillStyle=c(w[ta+1]);P.fillRect(aa*C[0],fa*C[1],C[0],C[1]);P.fillStyle=
c(w[ta+2]);P.fillText(Ra[w[ta]],aa*C[0],fa*C[1])}"none"!==k.style.display&&(P.fillStyle=k.style.backgroundColor,P.fillRect(m*C[0],l*C[1]+parseInt(k.style.marginTop,10)-1,parseInt(k.style.width,10),parseInt(k.style.height,10)));x.src=S.toDataURL("image/png")}return x};this.put_char=function(x,C,S,P,aa){x<I&&C<u&&(C=3*(x*u+C),w[C]=S,w[C+1]=P,w[C+2]=aa,q[x]=1)};this.timer=function(){U||requestAnimationFrame(z?Bb:Cb)};var Cb=function(){for(var x=0;x<I;x++)q[x]&&(ea.text_update_row(x),q[x]=0);this.timer()}.bind(this),
Bb=function(){this.bus.send("screen-fill-buffer");this.timer()}.bind(this);this.destroy=function(){U=!0};this.set_mode=function(x){(z=x)?(f.style.display="none",e.style.display="block"):(f.style.display="block",e.style.display="none")};this.clear_screen=function(){g.fillStyle="#000";g.fillRect(0,0,e.width,e.height)};this.set_size_text=function(x,C){if(x!==u||C!==I){q=new Int8Array(C);w=new Int32Array(x*C*3);u=x;for(I=C;f.childNodes.length>C;)f.removeChild(f.firstChild);for(;f.childNodes.length<C;)f.appendChild(document.createElement("div"));
for(x=0;x<C;x++)this.text_update_row(x);d(f,n,p,!0)}};this.set_size_graphical=function(x,C){e.style.display="block";e.width=x;e.height=C;t=640>=x&&2*x<window.innerWidth*window.devicePixelRatio&&2*C<window.innerHeight*window.devicePixelRatio?2:1;d(e,n*t,p*t,!1)};this.set_scale=function(x,C){n=x;p=C;d(f,n,p,!0);d(e,n*t,p*t,!1)};this.set_scale(n,p);this.update_cursor_scanline=function(x,C){x&32?k.style.display="none":(k.style.display="inline",k.style.height=Math.min(15,C-x)+"px",k.style.marginTop=Math.min(15,
x)+"px")};this.update_cursor=function(x,C){if(x!==l||C!==m)q[x]=1,q[l]=1,l=x,m=C};this.text_update_row=function(x){var C=3*x*u,S;var P=f.childNodes[x];var aa=document.createElement("div");for(var fa=0;fa<u;){var ta=document.createElement("span");var eb=w[C+1];var fb=w[C+2];ta.style.backgroundColor=c(eb);ta.style.color=c(fb);for(S="";fa<u&&w[C+1]===eb&&w[C+2]===fb;)if(S+=Ra[w[C]],fa++,C+=3,x===l)if(fa===m)break;else if(fa===m+1){aa.appendChild(k);break}ta.textContent=S;aa.appendChild(ta)}P.parentNode.replaceChild(aa,
P)};this.update_buffer=function(x){x.forEach(C=>{g.putImageData(C.image_data,C.screen_x-C.buffer_x,C.screen_y-C.buffer_y,C.buffer_x,C.buffer_y,C.buffer_width,C.buffer_height)})};this.init()};const ca=Object.freeze(["shared","exclusive","unlock"]);
function da(a,b,c){this.fs=a;this.bus=c;this.configspace_tagname=[104,111,115,116,57,112];this.configspace_taglen=this.configspace_tagname.length;this.VERSION="9P2000.L";this.msize=this.BLOCKSIZE=8192;this.replybuffer=new Uint8Array(2*this.msize);this.replybuffersize=0;this.fids=[];this.virtio=new h(b,{name:"virtio-9p",pci_id:48,device_id:4169,subsystem_device_id:9,common:{initial_port:43008,queues:[{size_supported:32,notify_offset:0}],features:[0,32,29,28],on_driver_ok:()=>{}},notification:{initial_port:43264,
single_handler:!1,handlers:[d=>{if(0===d){for(;this.virtqueue.has_request();)d=this.virtqueue.pop_request(),this.ReceiveRequest(d);this.virtqueue.notify_me_after(0)}}]},isr_status:{initial_port:42752},device_specific:{initial_port:42496,struct:[{bytes:2,name:"mount tag length",read:()=>this.configspace_taglen,write:()=>{}}].concat(r.range(254).map(d=>({bytes:1,name:"mount tag name "+d,read:()=>this.configspace_tagname[d]||0,write:()=>{}})))}});this.virtqueue=this.virtio.queues[0]}
da.prototype.get_state=function(){var a=[];a[0]=this.configspace_tagname;a[1]=this.configspace_taglen;a[2]=this.virtio;a[3]=this.VERSION;a[4]=this.BLOCKSIZE;a[5]=this.msize;a[6]=this.replybuffer;a[7]=this.replybuffersize;a[8]=this.fids.map(function(b){return[b.inodeid,b.type,b.uid,b.dbg_name]});a[9]=this.fs;return a};
da.prototype.set_state=function(a){this.configspace_tagname=a[0];this.configspace_taglen=a[1];this.virtio.set_state(a[2]);this.virtqueue=this.virtio.queues[0];this.VERSION=a[3];this.BLOCKSIZE=a[4];this.msize=a[5];this.replybuffer=a[6];this.replybuffersize=a[7];this.fids=a[8].map(function(b){return{inodeid:b[0],type:b[1],uid:b[2],dbg_name:b[3]}});this.fs.set_state(a[9])};da.prototype.Createfid=function(a,b,c,d){return{inodeid:a,type:b,uid:c,dbg_name:d}};
da.prototype.update_dbg_name=function(a,b){for(const c of this.fids)c.inodeid===a&&(c.dbg_name=b)};da.prototype.Reset=function(){this.fids=[]};da.prototype.BuildReply=function(a,b,c){v.Marshall(["w","b","h"],[c+7,a+1,b],this.replybuffer,0);c+7>=this.replybuffer.length&&y.Debug("Error in 9p: payloadsize exceeds maximum length");this.replybuffersize=c+7};da.prototype.SendError=function(a,b,c){b=v.Marshall(["w"],[c],this.replybuffer,7);this.BuildReply(6,a,b)};
da.prototype.SendReply=function(a){a.set_next_blob(this.replybuffer.subarray(0,this.replybuffersize));this.virtqueue.push_reply(a);this.virtqueue.flush_replies()};
da.prototype.ReceiveRequest=async function(a){var b=new Uint8Array(a.length_readable);a.get_next_blob(b);var c={offset:0},d=v.Unmarshall(["w","b","h"],b,c),e=d[0],g=d[1],f=d[2];switch(g){case 8:e=this.fs.GetTotalSize();b=this.fs.GetSpace();d=[16914839];d[1]=this.BLOCKSIZE;d[2]=Math.floor(b/d[1]);d[3]=d[2]-Math.floor(e/d[1]);d[4]=d[2]-Math.floor(e/d[1]);d[5]=this.fs.CountUsedInodes();d[6]=this.fs.CountFreeInodes();d[7]=0;d[8]=256;e=v.Marshall("wwddddddw".split(""),d,this.replybuffer,7);this.BuildReply(g,
f,e);this.SendReply(a);break;case 112:case 12:d=v.Unmarshall(["w","w"],b,c);var k=d[0];c=d[1];y.Debug("[open] fid="+k+", mode="+c);b=this.fids[k].inodeid;var l=this.fs.GetInode(b);y.Debug("file open "+this.fids[k].dbg_name);e=this.fs.OpenInode(b,c);this.fs.AddEvent(this.fids[k].inodeid,function(){y.Debug("file opened "+this.fids[k].dbg_name+" tag:"+f);var t=[];t[0]=l.qid;t[1]=this.msize-24;v.Marshall(["Q","w"],t,this.replybuffer,7);this.BuildReply(g,f,17);this.SendReply(a)}.bind(this));break;case 70:d=
v.Unmarshall(["w","w","s"],b,c);b=d[0];k=d[1];e=d[2];y.Debug("[link] dfid="+b+", name="+e);e=this.fs.Link(this.fids[b].inodeid,this.fids[k].inodeid,e);if(0>e){this.SendError(f,-1===e?"Operation not permitted":"Unknown error: "+-e,-e);this.SendReply(a);break}this.BuildReply(g,f,0);this.SendReply(a);break;case 16:d=v.Unmarshall(["w","s","s","w"],b,c);k=d[0];e=d[1];b=d[2];d=d[3];y.Debug("[symlink] fid="+k+", name="+e+", symgt="+b+", gid="+d);b=this.fs.CreateSymlink(e,this.fids[k].inodeid,b);l=this.fs.GetInode(b);
l.uid=this.fids[k].uid;l.gid=d;v.Marshall(["Q"],[l.qid],this.replybuffer,7);this.BuildReply(g,f,13);this.SendReply(a);break;case 18:d=v.Unmarshall("wswwww".split(""),b,c);k=d[0];e=d[1];c=d[2];b=d[3];var m=d[4];d=d[5];y.Debug("[mknod] fid="+k+", name="+e+", major="+b+", minor="+m);b=this.fs.CreateNode(e,this.fids[k].inodeid,b,m);l=this.fs.GetInode(b);l.mode=c;l.uid=this.fids[k].uid;l.gid=d;v.Marshall(["Q"],[l.qid],this.replybuffer,7);this.BuildReply(g,f,13);this.SendReply(a);break;case 22:d=v.Unmarshall(["w"],
b,c);k=d[0];l=this.fs.GetInode(this.fids[k].inodeid);y.Debug("[readlink] fid="+k+" name="+this.fids[k].dbg_name+" target="+l.symlink);e=v.Marshall(["s"],[l.symlink],this.replybuffer,7);this.BuildReply(g,f,e);this.SendReply(a);break;case 72:d=v.Unmarshall(["w","s","w","w"],b,c);k=d[0];e=d[1];c=d[2];d=d[3];y.Debug("[mkdir] fid="+k+", name="+e+", mode="+c+", gid="+d);b=this.fs.CreateDirectory(e,this.fids[k].inodeid);l=this.fs.GetInode(b);l.mode=c|ha;l.uid=this.fids[k].uid;l.gid=d;v.Marshall(["Q"],[l.qid],
this.replybuffer,7);this.BuildReply(g,f,13);this.SendReply(a);break;case 14:d=v.Unmarshall(["w","s","w","w","w"],b,c);k=d[0];e=d[1];b=d[2];c=d[3];d=d[4];this.bus.send("9p-create",[e,this.fids[k].inodeid]);y.Debug("[create] fid="+k+", name="+e+", flags="+b+", mode="+c+", gid="+d);b=this.fs.CreateFile(e,this.fids[k].inodeid);this.fids[k].inodeid=b;this.fids[k].type=1;this.fids[k].dbg_name=e;l=this.fs.GetInode(b);l.uid=this.fids[k].uid;l.gid=d;l.mode=c;v.Marshall(["Q","w"],[l.qid,this.msize-24],this.replybuffer,
7);this.BuildReply(g,f,17);this.SendReply(a);break;case 52:d=v.Unmarshall("wbwddws".split(""),b,c);k=d[0];b=d[2];e=0===d[4]?Infinity:d[4];d=this.fs.DescribeLock(d[1],d[3],e,d[5],d[6]);y.Debug("[lock] fid="+k+", type="+ca[d.type]+", start="+d.start+", length="+d.length+", proc_id="+d.proc_id);e=this.fs.Lock(this.fids[k].inodeid,d,b);v.Marshall(["b"],[e],this.replybuffer,7);this.BuildReply(g,f,1);this.SendReply(a);break;case 54:d=v.Unmarshall("wbddws".split(""),b,c);k=d[0];e=0===d[3]?Infinity:d[3];
d=this.fs.DescribeLock(d[1],d[2],e,d[4],d[5]);y.Debug("[getlock] fid="+k+", type="+ca[d.type]+", start="+d.start+", length="+d.length+", proc_id="+d.proc_id);e=this.fs.GetLock(this.fids[k].inodeid,d);e||(e=d,e.type=2);e=v.Marshall(["b","d","d","w","s"],[e.type,e.start,Infinity===e.length?0:e.length,e.proc_id,e.client_id],this.replybuffer,7);this.BuildReply(g,f,e);this.SendReply(a);break;case 24:d=v.Unmarshall(["w","d"],b,c);k=d[0];l=this.fs.GetInode(this.fids[k].inodeid);y.Debug("[getattr]: fid="+
k+" name="+this.fids[k].dbg_name+" request mask="+d[1]);if(!l||l.status===ia){y.Debug("getattr: unlinked");this.SendError(f,"No such file or directory",2);this.SendReply(a);break}d[0]|=4096;d[0]=d[1];d[1]=l.qid;d[2]=l.mode;d[3]=l.uid;d[4]=l.gid;d[5]=l.nlinks;d[6]=l.major<<8|l.minor;d[7]=l.size;d[8]=this.BLOCKSIZE;d[9]=Math.floor(l.size/512+1);d[10]=l.atime;d[11]=0;d[12]=l.mtime;d[13]=0;d[14]=l.ctime;d[15]=0;d[16]=0;d[17]=0;d[18]=0;d[19]=0;v.Marshall("dQwwwddddddddddddddd".split(""),d,this.replybuffer,
7);this.BuildReply(g,f,153);this.SendReply(a);break;case 26:d=v.Unmarshall("wwwwwddddd".split(""),b,c);k=d[0];l=this.fs.GetInode(this.fids[k].inodeid);y.Debug("[setattr]: fid="+k+" request mask="+d[1]+" name="+this.fids[k].dbg_name);d[1]&1&&(l.mode=d[2]);d[1]&2&&(l.uid=d[3]);d[1]&4&&(l.gid=d[4]);d[1]&16&&(l.atime=Math.floor((new Date).getTime()/1E3));d[1]&32&&(l.mtime=Math.floor((new Date).getTime()/1E3));d[1]&64&&(l.ctime=Math.floor((new Date).getTime()/1E3));d[1]&128&&(l.atime=d[6]);d[1]&256&&(l.mtime=
d[8]);d[1]&8&&await this.fs.ChangeSize(this.fids[k].inodeid,d[5]);this.BuildReply(g,f,0);this.SendReply(a);break;case 50:d=v.Unmarshall(["w","d"],b,c);k=d[0];this.BuildReply(g,f,0);this.SendReply(a);break;case 40:case 116:d=v.Unmarshall(["w","d","w"],b,c);k=d[0];e=d[1];m=d[2];l=this.fs.GetInode(this.fids[k].inodeid);40==g&&y.Debug("[treaddir]: fid="+k+" offset="+e+" count="+m);116==g&&y.Debug("[read]: fid="+k+" ("+this.fids[k].dbg_name+") offset="+e+" count="+m+" fidtype="+this.fids[k].type);if(!l||
l.status===ia){y.Debug("read/treaddir: unlinked");this.SendError(f,"No such file or directory",2);this.SendReply(a);break}if(2==this.fids[k].type)for(l.caps.length<e+m&&(m=l.caps.length-e),d=0;d<m;d++)this.replybuffer[11+d]=l.caps[e+d];else this.fs.OpenInode(this.fids[k].inodeid,void 0),d=this.fids[k].inodeid,m=Math.min(m,this.replybuffer.length-11),l.size<e+m?m=l.size-e:40==g&&(m=this.fs.RoundToDirentry(d,e+m)-e),e>l.size&&(m=0),this.bus.send("9p-read-start",[this.fids[k].dbg_name]),d=await this.fs.Read(d,
e,m),this.bus.send("9p-read-end",[this.fids[k].dbg_name,m]),d&&this.replybuffer.set(d,11);v.Marshall(["w"],[m],this.replybuffer,7);this.BuildReply(g,f,4+m);this.SendReply(a);break;case 118:d=v.Unmarshall(["w","d","w"],b,c);k=d[0];e=d[1];m=d[2];d=this.fids[k].dbg_name;y.Debug("[write]: fid="+k+" ("+d+") offset="+e+" count="+m+" fidtype="+this.fids[k].type);if(2===this.fids[k].type){this.SendError(f,"Setxattr not supported",95);this.SendReply(a);break}else await this.fs.Write(this.fids[k].inodeid,e,
m,b.subarray(c.offset));this.bus.send("9p-write-end",[d,m]);v.Marshall(["w"],[m],this.replybuffer,7);this.BuildReply(g,f,4);this.SendReply(a);break;case 74:d=v.Unmarshall(["w","s","w","s"],b,c);e=d[0];b=d[1];c=d[2];d=d[3];y.Debug("[renameat]: oldname="+b+" newname="+d);e=await this.fs.Rename(this.fids[e].inodeid,b,this.fids[c].inodeid,d);if(0>e){this.SendError(f,-2===e?"No such file or directory":-1===e?"Operation not permitted":-39===e?"Directory not empty":"Unknown error: "+-e,-e);this.SendReply(a);
break}this.BuildReply(g,f,0);this.SendReply(a);break;case 76:d=v.Unmarshall(["w","s","w"],b,c);c=d[0];e=d[1];b=d[2];y.Debug("[unlink]: dirfd="+c+" name="+e+" flags="+b);k=this.fs.Search(this.fids[c].inodeid,e);if(-1==k){this.SendError(f,"No such file or directory",2);this.SendReply(a);break}e=this.fs.Unlink(this.fids[c].inodeid,e);if(0>e){this.SendError(f,-39===e?"Directory not empty":-1===e?"Operation not permitted":"Unknown error: "+-e,-e);this.SendReply(a);break}this.BuildReply(g,f,0);this.SendReply(a);
break;case 100:d=v.Unmarshall(["w","s"],b,c);y.Debug("[version]: msize="+d[0]+" version="+d[1]);this.msize=d[0];e=v.Marshall(["w","s"],[this.msize,this.VERSION],this.replybuffer,7);this.BuildReply(g,f,e);this.SendReply(a);break;case 104:d=v.Unmarshall(["w","w","s","s","w"],b,c);k=d[0];e=d[4];y.Debug("[attach]: fid="+k+" afid="+A(d[1])+" uname="+d[2]+" aname="+d[3]);this.fids[k]=this.Createfid(0,1,e,"");l=this.fs.GetInode(this.fids[k].inodeid);v.Marshall(["Q"],[l.qid],this.replybuffer,7);this.BuildReply(g,
f,13);this.SendReply(a);this.bus.send("9p-attach");break;case 108:d=v.Unmarshall(["h"],b,c);y.Debug("[flush] "+f);this.BuildReply(g,f,0);this.SendReply(a);break;case 110:d=v.Unmarshall(["w","w","h"],b,c);k=d[0];m=d[1];var n=d[2];y.Debug("[walk]: fid="+d[0]+" nwfid="+d[1]+" nwname="+n);if(0==n){this.fids[m]=this.Createfid(this.fids[k].inodeid,1,this.fids[k].uid,this.fids[k].dbg_name);v.Marshall(["h"],[0],this.replybuffer,7);this.BuildReply(g,f,2);this.SendReply(a);break}e=[];for(d=0;d<n;d++)e.push("s");
c=v.Unmarshall(e,b,c);b=this.fids[k].inodeid;e=9;var p=0;y.Debug("walk in dir "+this.fids[k].dbg_name+" to: "+c.toString());for(d=0;d<n;d++){b=this.fs.Search(b,c[d]);if(-1==b){y.Debug("Could not find: "+c[d]);break}e+=v.Marshall(["Q"],[this.fs.GetInode(b).qid],this.replybuffer,e);p++;this.fids[m]=this.Createfid(b,1,this.fids[k].uid,c[d])}v.Marshall(["h"],[p],this.replybuffer,7);this.BuildReply(g,f,e-7);this.SendReply(a);break;case 120:d=v.Unmarshall(["w"],b,c);y.Debug("[clunk]: fid="+d[0]);this.fids[d[0]]&&
0<=this.fids[d[0]].inodeid&&(await this.fs.CloseInode(this.fids[d[0]].inodeid),this.fids[d[0]].inodeid=-1,this.fids[d[0]].type=-1);this.BuildReply(g,f,0);this.SendReply(a);break;case 32:d=v.Unmarshall(["w","s","d","w"],b,c);k=d[0];e=d[1];c=d[2];b=d[3];y.Debug("[txattrcreate]: fid="+k+" name="+e+" attr_size="+c+" flags="+b);this.fids[k].type=2;this.BuildReply(g,f,0);this.SendReply(a);break;case 30:d=v.Unmarshall(["w","w","s"],b,c);k=d[0];e=d[2];y.Debug("[xattrwalk]: fid="+d[0]+" newfid="+d[1]+" name="+
d[2]);this.SendError(f,"Setxattr not supported",95);this.SendReply(a);break;default:y.Debug("Error in Virtio9p: Unknown id "+g+" received"),y.Abort()}};function B(a){this.ports=[];this.cpu=a;for(var b=0;65536>b;b++)this.ports[b]=this.create_empty_entry();var c=a.memory_size[0];for(b=0;b<<17<c;b++)a.memory_map_read8[b]=a.memory_map_write8[b]=void 0,a.memory_map_read32[b]=a.memory_map_write32[b]=void 0;this.mmap_register(c,4294967296-c,function(d){A(d>>>0,8);return 255},function(d,e){A(d>>>0,8);A(e,2)},function(d){A(d>>>0,8);return-1},function(d,e){A(d>>>0,8);A(e>>>0,8)})}
B.prototype.create_empty_entry=function(){return{read8:this.empty_port_read8,read16:this.empty_port_read16,read32:this.empty_port_read32,write8:this.empty_port_write,write16:this.empty_port_write,write32:this.empty_port_write,device:void 0}};B.prototype.empty_port_read8=function(){return 255};B.prototype.empty_port_read16=function(){return 65535};B.prototype.empty_port_read32=function(){return-1};B.prototype.empty_port_write=function(){};
B.prototype.register_read=function(a,b,c,d,e){c&&(this.ports[a].read8=c);d&&(this.ports[a].read16=d);e&&(this.ports[a].read32=e);this.ports[a].device=b};B.prototype.register_write=function(a,b,c,d,e){c&&(this.ports[a].write8=c);d&&(this.ports[a].write16=d);e&&(this.ports[a].write32=e);this.ports[a].device=b};
B.prototype.register_read_consecutive=function(a,b,c,d,e,g){function f(){return c.call(this)|d.call(this)<<8}function k(){return e.call(this)|g.call(this)<<8}function l(){return c.call(this)|d.call(this)<<8|e.call(this)<<16|g.call(this)<<24}e&&g?(this.register_read(a,b,c,f,l),this.register_read(a+1,b,d),this.register_read(a+2,b,e,k),this.register_read(a+3,b,g)):(this.register_read(a,b,c,f),this.register_read(a+1,b,d))};
B.prototype.register_write_consecutive=function(a,b,c,d,e,g){function f(m){c.call(this,m&255);d.call(this,m>>8&255)}function k(m){e.call(this,m&255);g.call(this,m>>8&255)}function l(m){c.call(this,m&255);d.call(this,m>>8&255);e.call(this,m>>16&255);g.call(this,m>>>24)}e&&g?(this.register_write(a,b,c,f,l),this.register_write(a+1,b,d),this.register_write(a+2,b,e,k),this.register_write(a+3,b,g)):(this.register_write(a,b,c,f),this.register_write(a+1,b,d))};
B.prototype.mmap_read32_shim=function(a){var b=this.cpu.memory_map_read8[a>>>17];return b(a)|b(a+1)<<8|b(a+2)<<16|b(a+3)<<24};B.prototype.mmap_write32_shim=function(a,b){var c=this.cpu.memory_map_write8[a>>>17];c(a,b&255);c(a+1,b>>8&255);c(a+2,b>>16&255);c(a+3,b>>>24)};
B.prototype.mmap_register=function(a,b,c,d,e,g){A(a>>>0,8);A(b,8);e||(e=this.mmap_read32_shim.bind(this));g||(g=this.mmap_write32_shim.bind(this));for(a>>>=17;0<b;a++)this.cpu.memory_map_read8[a]=c,this.cpu.memory_map_write8[a]=d,this.cpu.memory_map_read32[a]=e,this.cpu.memory_map_write32[a]=g,b-=131072};B.prototype.port_write8=function(a,b){var c=this.ports[a];c.write8===this.empty_port_write&&(A(a,4),A(b,2),this.get_port_description(a));return c.write8.call(c.device,b)};
B.prototype.port_write16=function(a,b){var c=this.ports[a];c.write16===this.empty_port_write&&(A(a,4),A(b,4),this.get_port_description(a));return c.write16.call(c.device,b)};B.prototype.port_write32=function(a,b){var c=this.ports[a];c.write32===this.empty_port_write&&(A(a,4),A(b>>>0,8),this.get_port_description(a));return c.write32.call(c.device,b)};
B.prototype.port_read8=function(a){var b=this.ports[a];b.read8===this.empty_port_read8&&(A(a,4),this.get_port_description(a));b=b.read8.call(b.device);A(a);return b};B.prototype.port_read16=function(a){var b=this.ports[a];b.read16===this.empty_port_read16&&(A(a,4),this.get_port_description(a));b=b.read16.call(b.device);A(a);return b};B.prototype.port_read32=function(a){var b=this.ports[a];b.read32===this.empty_port_read32&&(A(a,4),this.get_port_description(a));return b.read32.call(b.device)};
var ja={4:"PORT_DMA_ADDR_2",5:"PORT_DMA_CNT_2",10:"PORT_DMA1_MASK_REG",11:"PORT_DMA1_MODE_REG",12:"PORT_DMA1_CLEAR_FF_REG",13:"PORT_DMA1_MASTER_CLEAR",32:"PORT_PIC1_CMD",33:"PORT_PIC1_DATA",64:"PORT_PIT_COUNTER0",65:"PORT_PIT_COUNTER1",66:"PORT_PIT_COUNTER2",67:"PORT_PIT_MODE",96:"PORT_PS2_DATA",97:"PORT_PS2_CTRLB",100:"PORT_PS2_STATUS",112:"PORT_CMOS_INDEX",113:"PORT_CMOS_DATA",128:"PORT_DIAG",129:"PORT_DMA_PAGE_2",146:"PORT_A20",160:"PORT_PIC2_CMD",161:"PORT_PIC2_DATA",178:"PORT_SMI_CMD",179:"PORT_SMI_STATUS",
212:"PORT_DMA2_MASK_REG",214:"PORT_DMA2_MODE_REG",218:"PORT_DMA2_MASTER_CLEAR",240:"PORT_MATH_CLEAR",368:"PORT_ATA2_CMD_BASE",496:"PORT_ATA1_CMD_BASE",632:"PORT_LPT2",744:"PORT_SERIAL4",760:"PORT_SERIAL2",884:"PORT_ATA2_CTRL_BASE",888:"PORT_LPT1",1E3:"PORT_SERIAL3",1008:"PORT_FD_BASE",1010:"PORT_FD_DOR",1012:"PORT_FD_STATUS",1013:"PORT_FD_DATA",1014:"PORT_HD_DATA",1015:"PORT_FD_DIR",1016:"PORT_SERIAL1",3320:"PORT_PCI_CMD",3321:"PORT_PCI_REBOOT",3324:"PORT_PCI_DATA",1026:"PORT_BIOS_DEBUG",1296:"PORT_QEMU_CFG_CTL",
1297:"PORT_QEMU_CFG_DATA",45056:"PORT_ACPI_PM_BASE",45312:"PORT_SMB_BASE",35072:"PORT_BIOS_APM"};B.prototype.get_port_description=function(a){return ja[a]?" ("+ja[a]+")":""};function D(a,b){this.stopping=this.running=!1;this.tick_counter=0;this.worker=null;this.cpu=new E(a,b,()=>{this.idle&&this.next_tick(0)});this.bus=a;a.register("cpu-init",this.init,this);a.register("cpu-run",this.run,this);a.register("cpu-stop",this.stop,this);a.register("cpu-restart",this.restart,this);this.register_yield()}D.prototype.run=function(){this.stopping=!1;this.running||(this.running=!0,this.bus.send("emulator-started"));this.next_tick(0)};
D.prototype.do_tick=function(){if(this.stopping||!this.running)this.stopping=this.running=!1,this.bus.send("emulator-stopped");else{this.idle=!1;var a=this.cpu.main_loop();this.next_tick(a)}};D.prototype.next_tick=function(a){const b=++this.tick_counter;this.idle=!0;this.yield(a,b)};D.prototype.yield_callback=function(a){a===this.tick_counter&&this.do_tick()};D.prototype.stop=function(){this.running&&(this.stopping=!0)};D.prototype.destroy=function(){this.unregister_yield()};
D.prototype.restart=function(){this.cpu.reset_cpu();this.cpu.load_bios()};D.prototype.init=function(a){this.cpu.init(a,this.bus);this.bus.send("emulator-ready")};
if("undefined"!==typeof process)D.prototype.yield=function(a,b){1>a?global.setImmediate(c=>this.yield_callback(c),b):setTimeout(c=>this.yield_callback(c),a,b)},D.prototype.register_yield=function(){},D.prototype.unregister_yield=function(){};else if("undefined"!==typeof Worker){function a(){globalThis.onmessage=function(b){const c=b.data.t;1>c?postMessage(b.data.tick):setTimeout(()=>postMessage(b.data.tick),c)}}D.prototype.register_yield=function(){const b=URL.createObjectURL(new Blob(["("+a.toString()+
")()"],{type:"text/javascript"}));this.worker=new Worker(b);this.worker.onmessage=c=>this.yield_callback(c.data);URL.revokeObjectURL(b)};D.prototype.yield=function(b,c){this.worker.postMessage({t:b,tick:c})};D.prototype.unregister_yield=function(){this.worker&&this.worker.terminate();this.worker=null}}else D.prototype.yield=function(a){setTimeout(()=>{this.do_tick()},a)},D.prototype.register_yield=function(){},D.prototype.unregister_yield=function(){};D.prototype.save_state=function(){return this.cpu.save_state()};
D.prototype.restore_state=function(a){return this.cpu.restore_state(a)};if("object"===typeof performance&&performance.now)D.microtick=performance.now.bind(performance);else if("function"===typeof require){const {performance:a}=require("perf_hooks");D.microtick=a.now.bind(a)}else D.microtick="object"===typeof process&&process.hrtime?function(){var a=process.hrtime();return 1E3*a[0]+a[1]/1E6}:Date.now;var F=F||{};F.exportSymbol=function(){};F.exportProperty=function(){};var r=r||{};r.pads=function(a,b){return(a||0===a?a+"":"").padEnd(b," ")};r.pad0=function(a,b){return(a||0===a?a+"":"").padStart(b,"0")};r.zeros=function(a){return Array(a).fill(0)};r.range=function(a){return Array.from(Array(a).keys())};
r.view=function(a,b,c,d){return new Proxy({},{get:function(e,g){e=new a(b.buffer,c,d);const f=e[g];if("function"===typeof f)return f.bind(e);/^\d+$/.test(g);return f},set:function(e,g,f){/^\d+$/.test(g);(new a(b.buffer,c,d))[g]=f;return!0}})};function A(a,b){a=a?a.toString(16):"";return"0x"+r.pad0(a.toUpperCase(),b||1)}
if("undefined"!==typeof crypto&&crypto.getRandomValues){let a=new Int32Array(1);r.get_rand_int=function(){crypto.getRandomValues(a);return a[0]}}else if("undefined"!==typeof require){const a=require("crypto");r.get_rand_int=function(){return a.randomBytes(4).readInt32LE(0)}}
(function(){if("function"===typeof Math.clz32)r.int_log2_byte=function(d){return 31-Math.clz32(d)},r.int_log2=function(d){return 31-Math.clz32(d)};else{for(var a=new Int8Array(256),b=0,c=-2;256>b;b++)b&b-1||c++,a[b]=c;r.int_log2_byte=function(d){return a[d]};r.int_log2=function(d){d>>>=0;var e=d>>>16;if(e){var g=e>>>8;return g?24+a[g]:16+a[e]}return(g=d>>>8)?8+a[g]:a[d]}}})();
function ka(a){var b=new Uint8Array(a),c,d;this.length=0;this.push=function(e){this.length!==a&&this.length++;b[d]=e;d=d+1&a-1};this.shift=function(){if(this.length){var e=b[c];c=c+1&a-1;this.length--;return e}return-1};this.peek=function(){return this.length?b[c]:-1};this.clear=function(){this.length=d=c=0};this.clear()}function la(a){this.size=a;this.data=new Float32Array(a);this.length=this.end=this.start=0}
la.prototype.push=function(a){this.length===this.size?this.start=this.start+1&this.size-1:this.length++;this.data[this.end]=a;this.end=this.end+1&this.size-1};la.prototype.shift=function(){if(this.length){var a=this.data[this.start];this.start=this.start+1&this.size-1;this.length--;return a}};
la.prototype.shift_block=function(a){var b=new Float32Array(a);a>this.length&&(a=this.length);var c=this.start+a,d=this.data.subarray(this.start,c);b.set(d);c>=this.size&&(c-=this.size,b.set(this.data.subarray(0,c),d.length));this.start=c;this.length-=a;return b};la.prototype.peek=function(){if(this.length)return this.data[this.start]};la.prototype.clear=function(){this.length=this.end=this.start=0};
r.Bitmap=function(a){"number"===typeof a?this.view=new Uint8Array(a+7>>3):a instanceof ArrayBuffer&&(this.view=new Uint8Array(a))};r.Bitmap.prototype.set=function(a,b){const c=a>>3;a=1<<(a&7);this.view[c]=b?this.view[c]|a:this.view[c]&~a};r.Bitmap.prototype.get=function(a){return this.view[a>>3]>>(a&7)&1};r.Bitmap.prototype.get_buffer=function(){return this.view.buffer};r.load_file="undefined"===typeof XMLHttpRequest?ma:na;
function na(a,b,c){function d(){const l=c||0;setTimeout(()=>{na(a,b,l+1)},1E3*([1,1,2,3,5,8,13,21][l]||34))}var e=new XMLHttpRequest;e.open(b.method||"get",a,!0);e.responseType=b.as_json?"json":"arraybuffer";if(b.headers)for(var g=Object.keys(b.headers),f=0;f<g.length;f++){var k=g[f];e.setRequestHeader(k,b.headers[k])}b.range&&(g=b.range.start,e.setRequestHeader("Range","bytes="+g+"-"+(g+b.range.length-1)),e.setRequestHeader("X-Accept-Encoding","identity"),e.onreadystatechange=function(){200===e.status&&
e.abort()});e.onload=function(){if(4===e.readyState)if(200!==e.status&&206!==e.status)console.error("Loading the image "+a+" failed (status %d)",e.status),500<=e.status&&600>e.status&&d();else if(e.response){if(b.range){let l=e.getResponseHeader("Content-Encoding");l&&"identity"!==l&&console.error("Server sent Content-Encoding in response to ranged request",{filename:a,enc:l})}b.done&&b.done(e.response,e)}};e.onerror=function(l){console.error("Loading the image "+a+" failed",l);d()};b.progress&&(e.onprogress=
function(l){b.progress(l)});e.send(null)}function ma(a,b){let c=require("fs");b.range?c.open(a,"r",(d,e)=>{if(d)throw d;d=b.range.length;var g=Buffer.allocUnsafe(d);c.read(e,g,0,d,b.range.start,f=>{if(f)throw f;b.done&&b.done(new Uint8Array(g));c.close(e,k=>{if(k)throw k;})})}):c.readFile(a,{encoding:b.as_json?"utf-8":null},function(d,e){d?console.log("Could not read file:",a,d):(d=e,d=b.as_json?JSON.parse(d):(new Uint8Array(d)).buffer,b.done(d))})}
r.read_sized_string_from_mem=function(a,b,c){return String.fromCharCode(...(new Uint8Array(a.buffer,b>>>0,c>>>0)))};(function(){function a(f){this.buffer=f;this.byteLength=f.byteLength;this.onprogress=this.onload=void 0}function b(f,k,l){this.filename=f;this.byteLength=k;this.block_cache=new Map;this.block_cache_is_write=new Set;this.fixed_chunk_size=l;this.cache_reads=!!l;this.onprogress=this.onload=void 0}function c(f,k,l,m,n){const p=f.match(/\.[^\.]+(\.zst)?$/);this.extension=p?p[0]:"";this.basename=f.substring(0,f.length-this.extension.length);this.is_zstd=this.extension.endsWith(".zst");this.basename.endsWith("/")||
(this.basename+="-");this.block_cache=new Map;this.block_cache_is_write=new Set;this.byteLength=k;this.fixed_chunk_size=l;this.partfile_alt_format=!!m;this.zstd_decompress=n;this.cache_reads=!!l;this.onprogress=this.onload=void 0}function d(f){this.file=f;this.byteLength=f.size;1073741824<f.size&&console.warn("SyncFileBuffer: Allocating buffer of "+(f.size>>20)+" MB ...");this.buffer=new ArrayBuffer(f.size);this.onprogress=this.onload=void 0}function e(f){this.file=f;this.byteLength=f.size;this.block_cache=
new Map;this.block_cache_is_write=new Set;this.onprogress=this.onload=void 0}r.SyncBuffer=a;r.AsyncXHRBuffer=b;r.AsyncXHRPartfileBuffer=c;r.AsyncFileBuffer=e;r.SyncFileBuffer=d;r.buffer_from_object=function(f,k){if(f.buffer instanceof ArrayBuffer)return new r.SyncBuffer(f.buffer);if("undefined"!==typeof File&&f.buffer instanceof File)return k=f.async,void 0===k&&(k=268435456<=f.buffer.size),k?new r.AsyncFileBuffer(f.buffer):new r.SyncFileBuffer(f.buffer);if(f.url)return f.use_parts?new r.AsyncXHRPartfileBuffer(f.url,
f.size,f.fixed_chunk_size,!1,k):new r.AsyncXHRBuffer(f.url,f.size,f.fixed_chunk_size)};a.prototype.load=function(){this.onload&&this.onload({buffer:this.buffer})};a.prototype.get=function(f,k,l){l(new Uint8Array(this.buffer,f,k))};a.prototype.set=function(f,k,l){(new Uint8Array(this.buffer,f,k.byteLength)).set(k);l()};a.prototype.get_buffer=function(f){f(this.buffer)};a.prototype.get_state=function(){const f=[];f[0]=this.byteLength;f[1]=new Uint8Array(this.buffer);return f};a.prototype.set_state=
function(f){this.byteLength=f[0];this.buffer=f[1].slice().buffer};b.prototype.load=function(){void 0!==this.byteLength?this.onload&&this.onload(Object.create(null)):g(this.filename,(f,k)=>{if(f)throw Error("Cannot use: "+this.filename+". "+f);this.byteLength=k;this.onload&&this.onload(Object.create(null))})};b.prototype.get_from_cache=function(f,k){var l=k/256;f/=256;for(var m=0;m<l;m++)if(!this.block_cache.get(f+m))return;if(1===l)return this.block_cache.get(f);k=new Uint8Array(k);for(m=0;m<l;m++)k.set(this.block_cache.get(f+
m),256*m);return k};b.prototype.get=function(f,k,l){var m=this.get_from_cache(f,k);if(m)l(m);else{var n=f,p=k;this.fixed_chunk_size&&(n=f-f%this.fixed_chunk_size,p=Math.ceil((f-n+k)/this.fixed_chunk_size)*this.fixed_chunk_size);r.load_file(this.filename,{done:function(t){t=new Uint8Array(t);this.handle_read(n,p,t);n===f&&p===k?l(t):l(t.subarray(f-n,f-n+k))}.bind(this),range:{start:n,length:p}})}};b.prototype.set=function(f,k,l){f/=256;for(var m=k.length/256,n=0;n<m;n++){var p=this.block_cache.get(f+
n);if(void 0===p)p=k.slice(256*n,256*(n+1)),this.block_cache.set(f+n,p);else{const t=k.subarray(256*n,256*(n+1));p.set(t)}this.block_cache_is_write.add(f+n)}l()};b.prototype.handle_read=function(f,k,l){f/=256;k/=256;for(var m=0;m<k;m++){const n=this.block_cache.get(f+m);n?l.set(n,256*m):this.cache_reads&&this.block_cache.set(f+m,l.slice(256*m,256*(m+1)))}};b.prototype.get_buffer=function(f){f()};b.prototype.get_state=function(){const f=[],k=[];for(let [l,m]of this.block_cache)isFinite(l),this.block_cache_is_write.has(l)&&
k.push([l,m]);f[0]=k;return f};b.prototype.set_state=function(f){f=f[0];this.block_cache.clear();this.block_cache_is_write.clear();for(let [k,l]of f)isFinite(k),this.block_cache.set(k,l),this.block_cache_is_write.add(k)};c.prototype.load=function(){this.onload&&this.onload(Object.create(null))};c.prototype.get=function(f,k,l){var m=this.get_from_cache(f,k);if(m)l(m);else if(this.fixed_chunk_size){const p=Math.floor(f/this.fixed_chunk_size),t=f-p*this.fixed_chunk_size,q=Math.ceil((t+k)/this.fixed_chunk_size),
z=new Uint8Array(q*this.fixed_chunk_size);let w=0;for(let u=0;u<q;u++){var n=(p+u)*this.fixed_chunk_size;m=this.partfile_alt_format?this.basename+(p+u+"").padStart(8,"0")+this.extension:this.basename+n+"-"+(n+this.fixed_chunk_size)+this.extension;(n=this.get_from_cache(n,this.fixed_chunk_size))?(z.set(n,u*this.fixed_chunk_size),w++,w===q&&l(z.subarray(t,t+k))):r.load_file(m,{done:async function(I){I=new Uint8Array(I);this.is_zstd&&(I=await this.zstd_decompress(this.fixed_chunk_size,I),I=new Uint8Array(I));
z.set(I,u*this.fixed_chunk_size);this.handle_read((p+u)*this.fixed_chunk_size,this.fixed_chunk_size|0,I);w++;w===q&&l(z.subarray(t,t+k))}.bind(this)})}}else r.load_file(this.basename+f+"-"+(f+k)+this.extension,{done:function(p){p=new Uint8Array(p);this.handle_read(f,k,p);l(p)}.bind(this)})};c.prototype.get_from_cache=b.prototype.get_from_cache;c.prototype.set=b.prototype.set;c.prototype.handle_read=b.prototype.handle_read;c.prototype.get_state=b.prototype.get_state;c.prototype.set_state=b.prototype.set_state;
d.prototype.load=function(){this.load_next(0)};d.prototype.load_next=function(f){var k=new FileReader;k.onload=function(m){m=new Uint8Array(m.target.result);(new Uint8Array(this.buffer,f)).set(m);this.load_next(f+4194304)}.bind(this);if(this.onprogress)this.onprogress({loaded:f,total:this.byteLength,lengthComputable:!0});if(f<this.byteLength){var l=this.file.slice(f,Math.min(f+4194304,this.byteLength));k.readAsArrayBuffer(l)}else this.file=void 0,this.onload&&this.onload({buffer:this.buffer})};d.prototype.get=
a.prototype.get;d.prototype.set=a.prototype.set;d.prototype.get_buffer=a.prototype.get_buffer;d.prototype.get_state=a.prototype.get_state;d.prototype.set_state=a.prototype.set_state;e.prototype.load=function(){this.onload&&this.onload(Object.create(null))};e.prototype.get=function(f,k,l){var m=this.get_from_cache(f,k);m?l(m):(m=new FileReader,m.onload=function(n){n=new Uint8Array(n.target.result);this.handle_read(f,k,n);l(n)}.bind(this),m.readAsArrayBuffer(this.file.slice(f,f+k)))};e.prototype.get_from_cache=
b.prototype.get_from_cache;e.prototype.set=b.prototype.set;e.prototype.handle_read=b.prototype.handle_read;e.prototype.get_state=b.prototype.get_state;e.prototype.set_state=b.prototype.set_state;e.prototype.get_buffer=function(f){f()};e.prototype.get_as_file=function(f){for(var k=[],l=Array.from(this.block_cache.keys()).sort(function(q,z){return q-z}),m=0,n=0;n<l.length;n++){var p=l[n],t=this.block_cache.get(p);p*=256;p!==m&&(k.push(this.file.slice(m,p)),m=p);k.push(t);m+=t.length}m!==this.file.size&&
k.push(this.file.slice(m));return new File(k,f)};var g="undefined"===typeof XMLHttpRequest?function(f,k){require("fs").stat(f,(l,m)=>{l?k(l):k(null,m.size)})}:function(f,k){r.load_file(f,{done:(l,m)=>{l=m.getResponseHeader("Content-Range")||"";(m=l.match(/\/(\d+)\s*$/))?k(null,+m[1]):k("`Range: bytes=...` header not supported (Got `"+l+"`)")},headers:{Range:"bytes=0-0","X-Accept-Encoding":"identity"}})}})();function G(a,b,c,d,e,g){this.master=new H(this,a,b,d,e,0,g);this.slave=new H(this,a,c,!1,e,1,g);this.current_interface=this.master;this.cpu=a;0===e?(this.ata_port=496,this.irq=14,this.pci_id=240):1===e&&(this.ata_port=368,this.irq=15,this.pci_id=248);this.ata_port_high=this.ata_port|516;this.master_port=46080;this.pci_space=[134,128,16,112,5,0,160,2,0,128,1,1,0,0,0,0,this.ata_port&255|1,this.ata_port>>8,0,0,this.ata_port_high&255|1,this.ata_port_high>>8,0,0,0,0,0,0,0,0,0,0,this.master_port&255|1,
this.master_port>>8,0,0,0,0,0,0,0,0,0,0,67,16,212,130,0,0,0,0,0,0,0,0,0,0,0,0,this.irq,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];this.pci_bars=[{size:8},{size:4},void 0,void 0,{size:16}];this.name="ide"+e;this.device_control=2;a.io.register_read(this.ata_port|7,this,function(){this.cpu.device_lower_irq(this.irq);return this.read_status()});a.io.register_read(this.ata_port_high|
2,this,this.read_status);a.io.register_write(this.ata_port_high|2,this,this.write_control);a.io.register_read(this.ata_port|0,this,function(){return this.current_interface.read_data(1)},function(){return this.current_interface.read_data(2)},function(){return this.current_interface.read_data(4)});a.io.register_read(this.ata_port|1,this,function(){A(this.current_interface.error&255);return this.current_interface.error&255});a.io.register_read(this.ata_port|2,this,function(){A(this.current_interface.bytecount&
255);return this.current_interface.bytecount&255});a.io.register_read(this.ata_port|3,this,function(){A(this.current_interface.sector&255);return this.current_interface.sector&255});a.io.register_read(this.ata_port|4,this,function(){A(this.current_interface.cylinder_low&255);return this.current_interface.cylinder_low&255});a.io.register_read(this.ata_port|5,this,function(){A(this.current_interface.cylinder_high&255);return this.current_interface.cylinder_high&255});a.io.register_read(this.ata_port|
6,this,function(){return this.current_interface.drive_head&255});a.io.register_write(this.ata_port|0,this,function(f){this.current_interface.write_data_port8(f)},function(f){this.current_interface.write_data_port16(f)},function(f){this.current_interface.write_data_port32(f)});a.io.register_write(this.ata_port|1,this,function(f){A(f);this.master.lba_count=(this.master.lba_count<<8|f)&65535;this.slave.lba_count=(this.slave.lba_count<<8|f)&65535});a.io.register_write(this.ata_port|2,this,function(f){A(f);
this.master.bytecount=(this.master.bytecount<<8|f)&65535;this.slave.bytecount=(this.slave.bytecount<<8|f)&65535});a.io.register_write(this.ata_port|3,this,function(f){A(f);this.master.sector=(this.master.sector<<8|f)&65535;this.slave.sector=(this.slave.sector<<8|f)&65535});a.io.register_write(this.ata_port|4,this,function(f){A(f);this.master.cylinder_low=(this.master.cylinder_low<<8|f)&65535;this.slave.cylinder_low=(this.slave.cylinder_low<<8|f)&65535});a.io.register_write(this.ata_port|5,this,function(f){A(f);
this.master.cylinder_high=(this.master.cylinder_high<<8|f)&65535;this.slave.cylinder_high=(this.slave.cylinder_high<<8|f)&65535});a.io.register_write(this.ata_port|6,this,function(f){var k=f&16;A(f,2);this.current_interface=k?this.slave:this.master;this.master.drive_head=f;this.slave.drive_head=f;this.master.is_lba=this.slave.is_lba=f>>6&1;this.master.head=this.slave.head=f&15});this.dma_command=this.dma_status=this.prdt_addr=0;a.io.register_write(this.ata_port|7,this,function(f){this.cpu.device_lower_irq(this.irq);
this.current_interface.ata_command(f)});a.io.register_read(this.master_port|4,this,void 0,void 0,this.dma_read_addr);a.io.register_write(this.master_port|4,this,void 0,void 0,this.dma_set_addr);a.io.register_read(this.master_port,this,this.dma_read_command8,void 0,this.dma_read_command);a.io.register_write(this.master_port,this,this.dma_write_command8,void 0,this.dma_write_command);a.io.register_read(this.master_port|2,this,this.dma_read_status);a.io.register_write(this.master_port|2,this,this.dma_write_status);
a.io.register_read(this.master_port|8,this,function(){return 0});a.io.register_read(this.master_port|10,this,function(){return 0});a.devices.pci.register_device(this)}G.prototype.read_status=function(){if(this.current_interface.buffer){var a=this.current_interface.status;A(a,2);return a}return 0};G.prototype.write_control=function(a){A(a,2);a&4&&(this.cpu.device_lower_irq(this.irq),this.master.device_reset(),this.slave.device_reset());this.device_control=a};
G.prototype.dma_read_addr=function(){A(this.prdt_addr,8);return this.prdt_addr};G.prototype.dma_set_addr=function(a){A(a,8);this.prdt_addr=a};G.prototype.dma_read_status=function(){A(this.dma_status);return this.dma_status};G.prototype.dma_write_status=function(a){A(a);this.dma_status&=~(a&6)};G.prototype.dma_read_command=function(){return this.dma_read_command8()|this.dma_read_status()<<16};G.prototype.dma_read_command8=function(){A(this.dma_command);return this.dma_command};
G.prototype.dma_write_command=function(a){A(a);this.dma_write_command8(a&255);this.dma_write_status(a>>16&255)};
G.prototype.dma_write_command8=function(a){A(a);let b=this.dma_command;this.dma_command=a&9;if((b&1)!==(a&1))if(0===(a&1))this.dma_status&=-2;else switch(this.dma_status|=1,this.current_interface.current_command){case 37:case 200:this.current_interface.do_ata_read_sectors_dma();break;case 202:case 53:this.current_interface.do_ata_write_sectors_dma();break;case 160:this.current_interface.do_atapi_dma();break;default:A(this.current_interface.current_command)}};
G.prototype.push_irq=function(){0===(this.device_control&2)&&(this.dma_status|=4,this.cpu.device_raise_irq(this.irq))};G.prototype.get_state=function(){var a=[];a[0]=this.master;a[1]=this.slave;a[2]=this.ata_port;a[3]=this.irq;a[4]=this.pci_id;a[5]=this.ata_port_high;a[6]=this.master_port;a[7]=this.name;a[8]=this.device_control;a[9]=this.prdt_addr;a[10]=this.dma_status;a[11]=this.current_interface===this.master;a[12]=this.dma_command;return a};
G.prototype.set_state=function(a){this.master.set_state(a[0]);this.slave.set_state(a[1]);this.ata_port=a[2];this.irq=a[3];this.pci_id=a[4];this.ata_port_high=a[5];this.master_port=a[6];this.name=a[7];this.device_control=a[8];this.prdt_addr=a[9];this.dma_status=a[10];this.current_interface=a[11]?this.master:this.slave;this.dma_command=a[12]};
function H(a,b,c,d,e,g,f){this.device=a;this.bus=f;this.nr=e;this.cpu=b;this.buffer=c;this.sector_size=d?2048:512;this.is_atapi=d;this.cylinder_count=this.sectors_per_track=this.head_count=this.sector_count=0;this.buffer&&(this.sector_count=this.buffer.byteLength/this.sector_size,this.sector_count!==(this.sector_count|0)&&(this.sector_count=Math.ceil(this.sector_count)),d?(this.head_count=1,this.sectors_per_track=0):(this.head_count=16,this.sectors_per_track=63),this.cylinder_count=this.sector_count/
this.head_count/this.sectors_per_track,this.cylinder_count!==(this.cylinder_count|0)&&(this.cylinder_count=Math.floor(this.cylinder_count)),a=b.devices.rtc,a.cmos_write(57,a.cmos_read(57)|1<<4*this.nr),a.cmos_write(18,a.cmos_read(18)&15|240),a.cmos_write(27,this.cylinder_count&255),a.cmos_write(28,this.cylinder_count>>8&255),a.cmos_write(29,this.head_count&255),a.cmos_write(30,255),a.cmos_write(31,255),a.cmos_write(32,200),a.cmos_write(33,this.cylinder_count&255),a.cmos_write(34,this.cylinder_count>>
8&255),a.cmos_write(35,this.sectors_per_track&255));this.stats={sectors_read:0,sectors_written:0,bytes_read:0,bytes_written:0,loading:!1};this.buffer=c;this.drive_head=this.head=this.cylinder_high=this.cylinder_low=this.lba_count=this.sector=this.bytecount=this.is_lba=0;this.status=80;this.sectors_per_drq=128;this.data_pointer=this.error=0;this.data=new Uint8Array(65536);this.data16=new Uint16Array(this.data.buffer);this.data32=new Int32Array(this.data.buffer);this.data_end=this.data_length=0;this.current_atapi_command=
this.current_command=-1;this.last_io_id=this.write_dest=0;this.in_progress_io_ids=new Set;this.cancelled_io_ids=new Set;Object.seal(this)}H.prototype.device_reset=function(){this.is_atapi?(this.status=0,this.sector=this.error=this.bytecount=1,this.cylinder_low=20,this.cylinder_high=235):(this.status=81,this.sector=this.error=this.bytecount=1,this.cylinder_high=this.cylinder_low=0);this.cancel_io_operations()};H.prototype.push_irq=function(){this.device.push_irq()};
H.prototype.ata_command=function(a){A(a);if(this.buffer)switch(this.current_command=a,this.error=0,a){case 8:this.data_length=this.data_end=this.data_pointer=0;this.device_reset();this.push_irq();break;case 16:this.status=80;this.cylinder_low=0;this.push_irq();break;case 248:this.status=80;a=this.sector_count-1;this.sector=a&255;this.cylinder_low=a>>8&255;this.cylinder_high=a>>16&255;this.drive_head=this.drive_head&240|a>>24&15;this.push_irq();break;case 39:this.status=80;a=this.sector_count-1;this.sector=
a&255;this.cylinder_low=a>>8&255;this.cylinder_high=a>>16&255;this.sector|=a>>24<<8&65280;this.push_irq();break;case 32:case 36:case 41:case 196:this.ata_read_sectors(a);break;case 48:case 52:case 57:case 197:this.ata_write_sectors(a);break;case 144:this.push_irq();this.error=257;this.status=80;break;case 145:this.status=80;this.push_irq();break;case 160:this.is_atapi&&(this.status=88,this.data_allocate(12),this.data_end=12,this.bytecount=1,this.push_irq());break;case 161:this.is_atapi?(this.create_identify_packet(),
this.status=88,this.cylinder_low=20,this.cylinder_high=235):this.status=65;this.push_irq();break;case 198:A(this.bytecount&255);this.sectors_per_drq=this.bytecount&255;this.status=80;this.push_irq();break;case 37:case 200:this.ata_read_sectors_dma(a);break;case 53:case 202:this.ata_write_sectors_dma(a);break;case 64:this.status=80;this.push_irq();break;case 218:this.status=65;this.error=4;this.push_irq();break;case 224:this.status=80;this.push_irq();break;case 225:this.status=80;this.push_irq();break;
case 231:this.status=80;this.push_irq();break;case 236:if(this.is_atapi){this.status=65;this.error=4;this.push_irq();break}this.create_identify_packet();this.status=88;this.push_irq();break;case 234:this.status=80;this.push_irq();break;case 239:A(this.bytecount&255);this.status=80;this.push_irq();break;case 222:this.status=80;this.push_irq();break;case 245:this.status=80;this.push_irq();break;case 249:this.status=65;this.error=4;break;default:A(a),this.status=65,this.error=4}else this.error=4,this.status=
65,this.push_irq()};
H.prototype.atapi_handle=function(){A(this.data[0]);this.data_pointer=0;this.current_atapi_command=this.data[0];switch(this.current_atapi_command){case 0:this.data_allocate(0);this.data_end=this.data_length;this.status=80;break;case 3:this.data_allocate(this.data[4]);this.data_end=this.data_length;this.status=88;this.data[0]=240;this.data[2]=5;this.data[7]=8;break;case 18:var a=this.data[4];this.status=88;A(this.data[1],2);this.data.set([5,128,1,49,31,0,0,0,83,79,78,89,32,32,32,32,67,68,45,82,79,
77,32,67,68,85,45,49,48,48,48,32,49,46,49,97]);this.data_end=this.data_length=Math.min(36,a);break;case 26:this.data_allocate(this.data[4]);this.data_end=this.data_length;this.status=88;break;case 30:this.data_allocate(0);this.data_end=this.data_length;this.status=80;break;case 37:a=this.sector_count-1;this.data_set(new Uint8Array([a>>24&255,a>>16&255,a>>8&255,a&255,0,0,this.sector_size>>8&255,this.sector_size&255]));this.data_end=this.data_length;this.status=88;break;case 40:this.lba_count&1?this.atapi_read_dma(this.data):
this.atapi_read(this.data);break;case 66:a=this.data[8];this.data_allocate(Math.min(8,a));this.data_end=this.data_length;this.status=88;break;case 67:a=this.data[8]|this.data[7]<<8;var b=this.data[9]>>6;this.data_allocate(a);this.data_end=this.data_length;A(b,2);A(this.data[6]);0===b?(a=this.sector_count,this.data.set(new Uint8Array([0,18,1,1,0,20,1,0,0,0,0,0,0,22,170,0,a>>24,a>>16&255,a>>8&255,a&255]))):1===b&&this.data.set(new Uint8Array([0,10,1,1,0,0,0,0,0,0,0,0]));this.status=88;break;case 70:a=
this.data[8]|this.data[7]<<8;a=Math.min(a,32);this.data_allocate(a);this.data_end=this.data_length;this.data[0]=a-4>>24&255;this.data[1]=a-4>>16&255;this.data[2]=a-4>>8&255;this.data[3]=a-4&255;this.data[6]=8;this.data[10]=3;this.status=88;break;case 81:this.data_allocate(0);this.data_end=this.data_length;this.status=80;break;case 82:A(this.data[0]);this.status=81;this.data_length=0;this.error=80;break;case 90:a=this.data[8]|this.data[7]<<8;b=this.data[2];A(b);42===b&&this.data_allocate(Math.min(30,
a));this.data_end=this.data_length;this.status=88;break;case 189:this.data_allocate(this.data[9]|this.data[8]<<8);this.data_end=this.data_length;this.data[5]=1;this.status=88;break;case 74:this.status=81;this.data_length=0;this.error=80;A(this.data[0]);break;case 190:A(this.data[0]);this.data_allocate(0);this.data_end=this.data_length;this.status=80;break;default:this.status=81,this.data_length=0,this.error=80,A(this.data[0])}this.bytecount=this.bytecount&-8|2;0===(this.status&128)&&this.push_irq();
0===(this.status&128)&&0===this.data_length&&(this.bytecount|=1,this.status&=-9)};H.prototype.do_write=function(){this.status=80;var a=this.data.subarray(0,this.data_length);this.ata_advance(this.current_command,this.data_length/512);this.push_irq();this.buffer.set(this.write_dest,a,function(){});this.report_write(this.data_length)};
H.prototype.atapi_read=function(a){var b=a[2]<<24|a[3]<<16|a[4]<<8|a[5],c=a[7]<<8|a[8];a=a[1];var d=c*this.sector_size,e=b*this.sector_size;J("CD read lba="+A(b)+" lbacount="+A(c)+" bytecount="+A(d)+" flags="+A(a),32768);this.data_length=0;var g=this.cylinder_high<<8&65280|this.cylinder_low&255;J(A(this.cylinder_high,2)+" "+A(this.cylinder_low,2),32768);this.cylinder_low=this.cylinder_high=0;65535===g&&g--;g>d&&(g=d);e>=this.buffer.byteLength?(oa(!1,"CD read: Outside of disk end="+A(e+d)+" size="+
A(this.buffer.byteLength),32768),this.status=255,this.push_irq()):0===d?(this.status=80,this.data_pointer=0):(d=Math.min(d,this.buffer.byteLength-e),this.status=208,this.report_read_start(),this.read_buffer(e,d,f=>{this.data_set(f);this.status=88;this.bytecount=this.bytecount&-8|2;this.push_irq();this.data_end=g&=-4;this.data_end>this.data_length&&(this.data_end=this.data_length);this.cylinder_low=this.data_end&255;this.cylinder_high=this.data_end>>8&255;this.report_read_end(d)}))};
H.prototype.atapi_read_dma=function(a){var b=a[2]<<24|a[3]<<16|a[4]<<8|a[5],c=a[7]<<8|a[8];a=a[1];var d=c*this.sector_size,e=b*this.sector_size;J("CD read DMA lba="+A(b)+" lbacount="+A(c)+" bytecount="+A(d)+" flags="+A(a),32768);e>=this.buffer.byteLength?(oa(!1,"CD read: Outside of disk end="+A(e+d)+" size="+A(this.buffer.byteLength),32768),this.status=255,this.push_irq()):(this.status=208,this.report_read_start(),this.read_buffer(e,d,g=>{this.report_read_end(d);this.status=88;this.bytecount=this.bytecount&
-8|2;this.data_set(g);this.do_atapi_dma()}))};
H.prototype.do_atapi_dma=function(){if(0!==(this.device.dma_status&1)&&0!==(this.status&8)){var a=this.device.prdt_addr,b=0,c=this.data;do{var d=this.cpu.read32s(a),e=this.cpu.read16(a+4),g=this.cpu.read8(a+7)&128;e||(e=65536);A(d);A(e);A(this.data_length);this.cpu.write_blob(c.subarray(b,Math.min(b+e,this.data_length)),d);b+=e;a+=8;if(b>=this.data_length&&!g){A(b);A(this.data_length);A(this.current_command);break}}while(!g);this.status=80;this.device.dma_status&=-2;this.bytecount=this.bytecount&
-8|3;this.push_irq()}};H.prototype.read_data=function(a){if(this.data_pointer<this.data_end){A(this.data_pointer);var b=1===a?this.data[this.data_pointer]:2===a?this.data16[this.data_pointer>>>1]:this.data32[this.data_pointer>>>2];this.data_pointer+=a;0===(this.data_pointer&(0===(this.data_end&4095)?4095:255))&&(A(this.data[this.data_pointer],2),A(this.data_pointer),A(this.data_length));this.data_pointer>=this.data_end&&this.read_end();return b}this.data_pointer+=a;return 0};
H.prototype.read_end=function(){A(this.current_command);A(this.data_pointer);A(this.data_end);A(this.data_length);if(160===this.current_command)if(this.data_end===this.data_length)this.status=80,this.bytecount=this.bytecount&-8|3,this.push_irq();else{this.status=88;this.bytecount=this.bytecount&-8|2;this.push_irq();var a=this.cylinder_high<<8&65280|this.cylinder_low&255;this.data_end+a>this.data_length?(this.cylinder_low=this.data_length-this.data_end&255,this.cylinder_high=this.data_length-this.data_end>>
8&255,this.data_end=this.data_length):this.data_end+=a;A(this.data_end)}else this.error=0,this.data_pointer>=this.data_length?this.status=80:(a=196===this.current_command||41===this.current_command?Math.min(this.sectors_per_drq,(this.data_length-this.data_end)/512):1,this.ata_advance(this.current_command,a),this.data_end+=512*a,this.status=88,this.push_irq())};
H.prototype.write_data_port=function(a,b){if(this.data_pointer>=this.data_end)A(a),A(this.data_end),A(this.data_pointer);else{if(0===(this.data_pointer+b&(0===(this.data_end&4095)?4095:255))||20>this.data_end)A(a>>>0),A(this.data_end),A(this.data_pointer);1===b?this.data[this.data_pointer++]=a:2===b?(this.data16[this.data_pointer>>>1]=a,this.data_pointer+=2):(this.data32[this.data_pointer>>>2]=a,this.data_pointer+=4);this.data_pointer===this.data_end&&this.write_end()}};
H.prototype.write_data_port8=function(a){this.write_data_port(a,1)};H.prototype.write_data_port16=function(a){this.write_data_port(a,2)};H.prototype.write_data_port32=function(a){this.write_data_port(a,4)};H.prototype.write_end=function(){160===this.current_command?this.atapi_handle():(A(this.data_pointer),A(this.data_length),this.data_pointer>=this.data_length?this.do_write():(A(this.current_command),this.status=88,this.data_end+=512,this.push_irq()))};
H.prototype.ata_advance=function(a,b){this.bytecount-=b;36===a||41===a||52===a||57===a||37===a||53===a?(a=b+this.get_lba48(),this.sector=a&255|a>>16&65280,this.cylinder_low=a>>8&255,this.cylinder_high=a>>16&255):this.is_lba?(a=b+this.get_lba28(),this.sector=a&255,this.cylinder_low=a>>8&255,this.cylinder_high=a>>16&255,this.head=this.head&-16|a&15):(a=b+this.get_chs(),b=a/(this.head_count*this.sectors_per_track)|0,this.cylinder_low=b&255,this.cylinder_high=b>>8&255,this.head=(a/this.sectors_per_track|
0)%this.head_count&15,this.sector=a%this.sectors_per_track+1&255,this.get_chs())};
H.prototype.ata_read_sectors=function(a){var b=36===a||41===a,c=this.get_count(b);b=this.get_lba(b);var d=32===a||36===a,e=c*this.sector_size,g=b*this.sector_size;J("ATA read cmd="+A(a)+" mode="+(this.is_lba?"lba":"chs")+" lba="+A(b)+" lbacount="+A(c)+" bytecount="+A(e),32768);g+e>this.buffer.byteLength?(this.status=255,this.push_irq()):(this.status=192,this.report_read_start(),this.read_buffer(g,e,f=>{this.data_set(f);this.status=88;this.data_end=d?512:Math.min(e,512*this.sectors_per_drq);this.ata_advance(a,
d?1:Math.min(c,this.sectors_per_track));this.push_irq();this.report_read_end(e)}))};H.prototype.ata_read_sectors_dma=function(a){var b=37===a;a=this.get_count(b);b=this.get_lba(b);var c=a*this.sector_size,d=b*this.sector_size;A(b);A(a);A(c);d+c>this.buffer.byteLength?(this.status=255,this.push_irq()):(this.status=88,this.device.dma_status|=1)};
H.prototype.do_ata_read_sectors_dma=function(){var a=37===this.current_command,b=this.get_count(a);a=this.get_lba(a);var c=b*this.sector_size;a*=this.sector_size;this.report_read_start();this.read_buffer(a,c,d=>{var e=this.device.prdt_addr,g=0;do{var f=this.cpu.read32s(e),k=this.cpu.read16(e+4),l=this.cpu.read8(e+7)&128;k||(k=65536);A(f);A(k);this.cpu.write_blob(d.subarray(g,g+k),f);g+=k;e+=8}while(!l);this.ata_advance(this.current_command,b);this.status=80;this.device.dma_status&=-2;this.current_command=
-1;this.push_irq();this.report_read_end(c)})};H.prototype.ata_write_sectors=function(a){var b=52===a||57===a,c=this.get_count(b);b=this.get_lba(b);a=48===a||52===a;var d=c*this.sector_size,e=b*this.sector_size;A(b);A(c);A(d);e+d>this.buffer.byteLength?(this.status=255,this.push_irq()):(this.status=88,this.data_allocate_noclear(d),this.data_end=a?512:Math.min(d,512*this.sectors_per_drq),this.write_dest=e)};
H.prototype.ata_write_sectors_dma=function(a){var b=53===a;a=this.get_count(b);b=this.get_lba(b);var c=a*this.sector_size,d=b*this.sector_size;A(b);A(a);A(c);d+c>this.buffer.byteLength?(this.status=255,this.push_irq()):(this.status=88,this.device.dma_status|=1)};
H.prototype.do_ata_write_sectors_dma=function(){var a=53===this.current_command,b=this.get_count(a),c=this.get_lba(a);a=b*this.sector_size;c*=this.sector_size;var d=this.device.prdt_addr,e=0;J("prdt addr: "+A(d,8),32768);const g=new Uint8Array(a);do{var f=this.cpu.read32s(d),k=this.cpu.read16(d+4),l=this.cpu.read8(d+7)&128;k||(k=65536);J("dma write transfer dest="+A(f)+" prd_count="+A(k),32768);f=this.cpu.mem8.subarray(f,f+k);g.set(f,e);e+=k;d+=8}while(!l);this.buffer.set(c,g,()=>{this.ata_advance(this.current_command,
b);this.status=80;this.push_irq();this.device.dma_status&=-2;this.current_command=-1});this.report_write(a)};H.prototype.get_chs=function(){return((this.cylinder_low&255|this.cylinder_high<<8&65280)*this.head_count+this.head)*this.sectors_per_track+(this.sector&255)-1};H.prototype.get_lba28=function(){return this.sector&255|this.cylinder_low<<8&65280|this.cylinder_high<<16&16711680|(this.head&15)<<24};
H.prototype.get_lba48=function(){return(this.sector&255|this.cylinder_low<<8&65280|this.cylinder_high<<16&16711680|this.sector>>8<<24&4278190080)>>>0};H.prototype.get_lba=function(a){return a?this.get_lba48():this.is_lba?this.get_lba28():this.get_chs()};H.prototype.get_count=function(a){a?(a=this.bytecount,0===a&&(a=65536)):(a=this.bytecount&255,0===a&&(a=256));return a};
H.prototype.create_identify_packet=function(){if(this.drive_head&16)this.data_allocate(0);else{for(var a=0;512>a;a++)this.data[a]=0;a=Math.min(16383,this.cylinder_count);this.data_set([64,this.is_atapi?133:0,a,a>>8,0,0,this.head_count,this.head_count>>8,this.sectors_per_track/512,this.sectors_per_track/512>>8,0,2,this.sectors_per_track,this.sectors_per_track>>8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,2,4,0,0,0,0,0,0,0,0,0,56,118,32,54,68,72,32,32,32,32,32,32,32,32,32,32,32,32,32,
32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,128,0,1,0,0,2,0,0,0,2,0,2,7,0,a,a>>8,this.head_count,this.head_count>>8,this.sectors_per_track,0,this.sector_count&255,this.sector_count>>8&255,this.sector_count>>16&255,this.sector_count>>24&255,0,0,this.sector_count&255,this.sector_count>>8&255,this.sector_count>>16&255,this.sector_count>>24&255,0,0,160===this.current_command?0:7,160===this.current_command?0:4,0,0,30,0,30,0,30,0,30,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,126,0,
0,0,0,0,0,116,0,64,0,64,0,116,0,64,0,0,0,0,0,0,0,0,0,0,1,96,0,0,0,0,0,0,0,0,0,0,0,0,this.sector_count&255,this.sector_count>>8&255,this.sector_count>>16&255,this.sector_count>>24&255]);this.data_end=this.data_length=512}};H.prototype.data_allocate=function(a){this.data_allocate_noclear(a);for(var b=0;b<a+3>>2;b++)this.data32[b]=0};
H.prototype.data_allocate_noclear=function(a){this.data.length<a&&(this.data=new Uint8Array(a+3&-4),this.data16=new Uint16Array(this.data.buffer),this.data32=new Int32Array(this.data.buffer));this.data_length=a;this.data_pointer=0};H.prototype.data_set=function(a){this.data_allocate_noclear(a.length);this.data.set(a)};H.prototype.report_read_start=function(){this.stats.loading=!0;this.bus.send("ide-read-start")};
H.prototype.report_read_end=function(a){this.stats.loading=!1;var b=a/this.sector_size|0;this.stats.sectors_read+=b;this.stats.bytes_read+=a;this.bus.send("ide-read-end",[this.nr,a,b])};H.prototype.report_write=function(a){var b=a/this.sector_size|0;this.stats.sectors_written+=b;this.stats.bytes_written+=a;this.bus.send("ide-write-end",[this.nr,a,b])};
H.prototype.read_buffer=function(a,b,c){const d=this.last_io_id++;this.in_progress_io_ids.add(d);this.buffer.get(a,b,e=>{this.cancelled_io_ids.delete(d)?this.in_progress_io_ids.has(d):(this.in_progress_io_ids.delete(d),c(e))})};H.prototype.cancel_io_operations=function(){for(const a of this.in_progress_io_ids)this.cancelled_io_ids.add(a);this.in_progress_io_ids.clear()};
H.prototype.get_state=function(){var a=[];a[0]=this.bytecount;a[1]=this.cylinder_count;a[2]=this.cylinder_high;a[3]=this.cylinder_low;a[4]=this.data_pointer;a[5]=0;a[6]=0;a[7]=0;a[8]=0;a[9]=this.drive_head;a[10]=this.error;a[11]=this.head;a[12]=this.head_count;a[13]=this.is_atapi;a[14]=this.is_lba;a[15]=this.lba_count;a[16]=this.data;a[17]=this.data_length;a[18]=this.sector;a[19]=this.sector_count;a[20]=this.sector_size;a[21]=this.sectors_per_drq;a[22]=this.sectors_per_track;a[23]=this.status;a[24]=
this.write_dest;a[25]=this.current_command;a[26]=this.data_end;a[27]=this.current_atapi_command;a[28]=this.buffer;return a};
H.prototype.set_state=function(a){this.bytecount=a[0];this.cylinder_count=a[1];this.cylinder_high=a[2];this.cylinder_low=a[3];this.data_pointer=a[4];this.drive_head=a[9];this.error=a[10];this.head=a[11];this.head_count=a[12];this.is_atapi=a[13];this.is_lba=a[14];this.lba_count=a[15];this.data=a[16];this.data_length=a[17];this.sector=a[18];this.sector_count=a[19];this.sector_size=a[20];this.sectors_per_drq=a[21];this.sectors_per_track=a[22];this.status=a[23];this.write_dest=a[24];this.current_command=
a[25];this.data_end=a[26];this.current_atapi_command=a[27];this.data16=new Uint16Array(this.data.buffer);this.data32=new Int32Array(this.data.buffer);this.buffer&&this.buffer.set_state(a[28])};function pa(a){this.pci_addr=new Uint8Array(4);this.pci_value=new Uint8Array(4);this.pci_response=new Uint8Array(4);this.pci_status=new Uint8Array(4);this.pci_addr32=new Int32Array(this.pci_addr.buffer);this.pci_value32=new Int32Array(this.pci_value.buffer);this.pci_response32=new Int32Array(this.pci_response.buffer);this.pci_status32=new Int32Array(this.pci_status.buffer);this.device_spaces=[];this.devices=[];this.cpu=a;for(var b=0;256>b;b++)this.device_spaces[b]=void 0,this.devices[b]=void 0;this.io=
a.io;a.io.register_write(3324,this,function(c){this.pci_write8(this.pci_addr32[0],c)},function(c){this.pci_write16(this.pci_addr32[0],c)},function(c){this.pci_write32(this.pci_addr32[0],c)});a.io.register_write(3325,this,function(c){this.pci_write8(this.pci_addr32[0]+1|0,c)});a.io.register_write(3326,this,function(c){this.pci_write8(this.pci_addr32[0]+2|0,c)},function(c){this.pci_write16(this.pci_addr32[0]+2|0,c)});a.io.register_write(3327,this,function(c){this.pci_write8(this.pci_addr32[0]+3|0,c)});
a.io.register_read_consecutive(3324,this,function(){return this.pci_response[0]},function(){return this.pci_response[1]},function(){return this.pci_response[2]},function(){return this.pci_response[3]});a.io.register_read_consecutive(3320,this,function(){return this.pci_status[0]},function(){return this.pci_status[1]},function(){return this.pci_status[2]},function(){return this.pci_status[3]});a.io.register_write_consecutive(3320,this,function(c){this.pci_addr[0]=c&252},function(c){2===(this.pci_addr[1]&
6)&&6===(c&6)?a.reboot_internal():this.pci_addr[1]=c},function(c){this.pci_addr[2]=c},function(c){this.pci_addr[3]=c;this.pci_query()});this.register_device({pci_id:0,pci_space:[134,128,55,18,0,0,0,0,2,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0],pci_bars:[],name:"82441FX PMC"});this.isa_bridge={pci_id:8,pci_space:[134,128,0,112,7,0,0,2,0,0,1,6,0,0,128,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],pci_bars:[],name:"82371SB PIIX3 ISA"};this.isa_bridge_space=this.register_device(this.isa_bridge);this.isa_bridge_space8=new Uint8Array(this.isa_bridge_space.buffer)}pa.prototype.get_state=function(){for(var a=[],b=0;256>b;b++)a[b]=this.device_spaces[b];a[256]=this.pci_addr;a[257]=this.pci_value;a[258]=this.pci_response;a[259]=this.pci_status;return a};
pa.prototype.set_state=function(a){for(var b=0;256>b;b++){var c=this.devices[b],d=a[b];if(c&&d){for(var e=0;e<c.pci_bars.length;e++){var g=d[4+e];if(g&1){var f=c.pci_bars[e];this.set_io_bars(f,f.original_bar&65534,g&65534)}}this.device_spaces[b].set(d)}else d&&A(b,2)}this.pci_addr.set(a[256]);this.pci_value.set(a[257]);this.pci_response.set(a[258]);this.pci_status.set(a[259])};
pa.prototype.pci_query=function(){var a=this.pci_addr[2]<<8|this.pci_addr[1],b=this.pci_addr[0]&252,c=a>>3&31;var d="query enabled="+(this.pci_addr[3]>>7)+(" bdf="+A(a,4));d+=" dev="+A(c,2);d+=" addr="+A(b,2);a=this.device_spaces[a];void 0!==a?(this.pci_status32[0]=-2147483648,this.pci_response32[0]=b<a.byteLength?a[b>>2]:0,d+=" "+A(this.pci_addr32[0]>>>0,8)+" -> "+A(this.pci_response32[0]>>>0,8)):(this.pci_response32[0]=-1,this.pci_status32[0]=0)};
pa.prototype.pci_write8=function(a,b){var c=a>>8&65535;a&=255;var d=new Uint8Array(this.device_spaces[c].buffer);A(a);A(c>>3,2);A(a,4);A(b,2);d[a]=b};pa.prototype.pci_write16=function(a,b){var c=a>>8&65535;a&=255;var d=new Uint16Array(this.device_spaces[c].buffer);16<=a&&44>a?A(a):(A(a),A(c>>3,2),A(a,4),A(b,4),d[a>>>1]=b)};
pa.prototype.pci_write32=function(a,b){var c=a>>8&65535;a&=255;var d=this.device_spaces[c],e=this.devices[c];if(d)if(16<=a&&40>a){e=e.pci_bars[a-16>>2];A(b>>>0);A(c>>3,2);if(e){c=a>>2;var g=d[c]&1;-1===(b|3|e.size-1)?(b=~(e.size-1)|g,0===g&&(d[c]=b)):0===g&&(d[c]=e.original_bar);if(1===g){g=d[c]&65534;var f=b&65534;A(g>>>0,8);A(f>>>0,8);this.set_io_bars(e,g,f);d[c]=b|1}}else d[a>>2]=0;A(d[a>>2]>>>0)}else 48===a?(A(c>>3,2),A(b>>>0,8),d[a>>2]=e.pci_rom_size?-1===(b|2047)?-e.pci_rom_size|0:e.pci_rom_address|
0:0):4===a?(A(c>>3,2),A(a,4),A(b>>>0,8)):(A(c>>3,2),A(a,4),A(b>>>0,8),d[a>>>2]=b)};pa.prototype.register_device=function(a){var b=a.pci_id;A(b);var c=new Int32Array(64);c.set(new Int32Array((new Uint8Array(a.pci_space)).buffer));this.device_spaces[b]=c;this.devices[b]=a;b=c.slice(4,10);for(var d=0;d<a.pci_bars.length;d++){var e=a.pci_bars[d];if(e){var g=b[d],f=g&1;e.original_bar=g;e.entries=[];if(0!==f)for(g&=-2,f=0;f<e.size;f++)e.entries[f]=this.io.ports[g+f]}}return c};
pa.prototype.set_io_bars=function(a,b,c){var d=a.size;A(b);A(c);for(var e=this.io.ports,g=0;g<d;g++){var f=e[b+g];4096<=b+g&&(e[b+g]=this.io.create_empty_entry());f.read8===this.io.empty_port_read8&&f.read16===this.io.empty_port_read16&&f.read32===this.io.empty_port_read32&&f.write8===this.io.empty_port_write&&f.write16===this.io.empty_port_write&&f.write32===this.io.empty_port_write&&A(b+g,4);f=a.entries[g];var k=e[c+g];4096<=c+g&&(e[c+g]=f);k.read8!==this.io.empty_port_read8&&k.read16!==this.io.empty_port_read16&&
k.read32!==this.io.empty_port_read32&&k.write8!==this.io.empty_port_write&&k.write16!==this.io.empty_port_write&&k.write32!==this.io.empty_port_write||A(c+g,4)}};pa.prototype.raise_irq=function(a){this.cpu.device_raise_irq(this.isa_bridge_space8[96+((this.device_spaces[a][15]>>8&255)-1+((a>>3)-1&255)&3)])};pa.prototype.lower_irq=function(a){this.cpu.device_lower_irq(this.isa_bridge_space8[96+((this.device_spaces[a][15]>>8&255)+(a>>3&255)-2&3)])};function K(a,b){this.io=a.io;this.cpu=a;this.dma=a.devices.dma;this.bytes_expecting=0;this.receiving_command=new Uint8Array(10);this.receiving_index=0;this.next_command=null;this.response_data=new Uint8Array(10);this.last_head=this.last_cylinder=this.drive=this.status_reg2=this.status_reg1=this.status_reg0=this.response_length=this.response_index=0;this.last_sector=1;this.dir=this.dor=0;this.fdb_image=this.fda_image=null;b?this.set_fda(b):(this.eject_fda(),this.cpu.devices.rtc.cmos_write(16,64));
this.io.register_read(1008,this,this.port3F0_read);this.io.register_read(1010,this,this.port3F2_read);this.io.register_read(1012,this,this.port3F4_read);this.io.register_read(1013,this,this.port3F5_read);this.io.register_read(1015,this,this.port3F7_read);this.io.register_write(1010,this,this.port3F2_write);this.io.register_write(1012,this,this.port3F4_write);this.io.register_write(1013,this,this.port3F5_write)}
K.prototype.eject_fda=function(){this.fda_image=null;this.number_of_cylinders=this.number_of_heads=this.sectors_per_track=0;this.dir=128};
K.prototype.set_fda=function(a){var b={[163840]:{type:1,tracks:40,sectors:8,heads:1},[184320]:{type:1,tracks:40,sectors:9,heads:1},[204800]:{type:1,tracks:40,sectors:10,heads:1},[327680]:{type:1,tracks:40,sectors:8,heads:2},[368640]:{type:1,tracks:40,sectors:9,heads:2},[409600]:{type:1,tracks:40,sectors:10,heads:2},[737280]:{type:3,tracks:80,sectors:9,heads:2},[1228800]:{type:2,tracks:80,sectors:15,heads:2},[1474560]:{type:4,tracks:80,sectors:18,heads:2},[1763328]:{type:5,tracks:82,sectors:21,heads:2},
[2949120]:{type:5,tracks:80,sectors:36,heads:2},512:{type:1,tracks:1,sectors:1,heads:1}};let c=a.byteLength,d=b[c];d||(c=1474560<a.byteLength?2949120:1474560,d=b[c],b=new Uint8Array(c),b.set(new Uint8Array(a.buffer)),a=new r.SyncBuffer(b.buffer));this.sectors_per_track=d.sectors;this.number_of_heads=d.heads;this.number_of_cylinders=d.tracks;this.fda_image=a;this.dir=128;this.cpu.devices.rtc.cmos_write(16,d.type<<4)};
K.prototype.get_state=function(){var a=[];a[0]=this.bytes_expecting;a[1]=this.receiving_command;a[2]=this.receiving_index;a[4]=this.response_data;a[5]=this.response_index;a[6]=this.response_length;a[8]=this.status_reg0;a[9]=this.status_reg1;a[10]=this.status_reg2;a[11]=this.drive;a[12]=this.last_cylinder;a[13]=this.last_head;a[14]=this.last_sector;a[15]=this.dor;a[16]=this.sectors_per_track;a[17]=this.number_of_heads;a[18]=this.number_of_cylinders;return a};
K.prototype.set_state=function(a){this.bytes_expecting=a[0];this.receiving_command=a[1];this.receiving_index=a[2];this.next_command=a[3];this.response_data=a[4];this.response_index=a[5];this.response_length=a[6];this.status_reg0=a[8];this.status_reg1=a[9];this.status_reg2=a[10];this.drive=a[11];this.last_cylinder=a[12];this.last_head=a[13];this.last_sector=a[14];this.dor=a[15];this.sectors_per_track=a[16];this.number_of_heads=a[17];this.number_of_cylinders=a[18]};K.prototype.port3F0_read=function(){return 0};
K.prototype.port3F4_read=function(){var a=128;this.response_index<this.response_length&&(a|=80);0===(this.dor&8)&&(a|=32);return a};K.prototype.port3F7_read=function(){return this.dir};K.prototype.port3F5_read=function(){return this.response_index<this.response_length?(this.cpu.device_lower_irq(6),this.response_data[this.response_index++]):255};K.prototype.port3F4_write=function(a){A(a);a&128&&(this.status_reg0=192,this.cpu.device_raise_irq(6))};
K.prototype.port3F5_write=function(a){J("3F5 write "+A(a),8192);if(0<this.bytes_expecting)this.receiving_command[this.receiving_index++]=a,this.bytes_expecting--,0===this.bytes_expecting&&this.next_command.call(this,this.receiving_command);else{switch(a){case 3:this.next_command=this.fix_drive_data;this.bytes_expecting=2;break;case 19:this.next_command=this.configure;this.bytes_expecting=3;break;case 4:this.next_command=this.check_drive_status;this.bytes_expecting=1;break;case 5:case 69:case 197:this.next_command=
function(b){this.do_sector(!0,b)};this.bytes_expecting=8;break;case 6:case 70:case 230:this.next_command=function(b){this.do_sector(!1,b)};this.bytes_expecting=8;break;case 7:this.next_command=this.calibrate;this.bytes_expecting=1;break;case 8:this.check_interrupt_status();break;case 74:this.next_command=this.read_sector_id;this.bytes_expecting=1;break;case 15:this.bytes_expecting=2;this.next_command=this.seek;break;case 14:case 16:this.status_reg0=128;this.response_data[0]=this.status_reg0;this.response_index=
0;this.response_length=1;this.bytes_expecting=0;break;default:oa(!1,"Unimplemented floppy command call "+A(a))}this.receiving_index=0}};K.prototype.port3F2_read=function(){return this.dor};K.prototype.port3F2_write=function(a){4===(a&4)&&0===(this.dor&4)&&(this.status_reg0=192,this.cpu.device_raise_irq(6));A(a>>4);A(a);this.dor=a};K.prototype.check_drive_status=function(){this.status_reg1=this.fda_image?0:5;this.response_index=0;this.response_length=1;this.response_data[0]=0};
K.prototype.seek=function(a){if(0===(a[0]&3)){var b=a[1];a=a[0]>>2&1;b!==this.last_cylinder&&(this.dir=0);this.status_reg1=this.fda_image?0:5;this.status_reg0=32;this.last_cylinder=b;this.last_head=a}this.raise_irq()};K.prototype.calibrate=function(a){this.seek([a[0],0])};K.prototype.check_interrupt_status=function(){this.response_index=0;this.response_length=2;this.response_data[0]=this.status_reg0;this.response_data[1]=this.last_cylinder};
K.prototype.do_sector=function(a,b){var c=b[2],d=b[1],e=b[3],g=128<<b[4],f=b[5]-b[3]+1,k=((c+this.number_of_heads*d)*this.sectors_per_track+e-1)*g;A(k);A(f*g);this.fda_image?(this.status_reg1=0,a?this.dma.do_write(this.fda_image,k,f*g,2,this.done.bind(this,b,d,c,e)):this.dma.do_read(this.fda_image,k,f*g,2,this.done.bind(this,b,d,c,e))):this.status_reg1=5};
K.prototype.done=function(a,b,c,d,e){e||(d++,d>this.sectors_per_track&&(d=1,c++,c>=this.number_of_heads&&(c=0,b++)),b!==this.last_cylinder&&(this.dir=0),this.status_reg0=32,this.last_cylinder=b,this.last_head=c,this.last_sector=d,this.response_index=0,this.response_length=7,this.response_data[0]=c<<2|32,this.response_data[1]=0,this.response_data[2]=0,this.response_data[3]=b,this.response_data[4]=c,this.response_data[5]=d,this.response_data[6]=a[4],this.raise_irq())};
K.prototype.fix_drive_data=function(a){a.slice(0,this.bytes_expecting)};K.prototype.configure=function(a){a.slice(0,this.bytes_expecting)};K.prototype.read_sector_id=function(){this.response_index=0;this.response_length=7;this.response_data[0]=0;this.response_data[1]=0;this.response_data[2]=0;this.response_data[3]=0;this.response_data[4]=0;this.response_data[5]=0;this.response_data[6]=0;this.raise_irq()};K.prototype.raise_irq=function(){this.dor&8&&this.cpu.device_raise_irq(6)};E.prototype.mmap_read8=function(a){return this.memory_map_read8[a>>>17](a)};E.prototype.mmap_write8=function(a,b){this.memory_map_write8[a>>>17](a,b)};E.prototype.mmap_read16=function(a){var b=this.memory_map_read8[a>>>17];return b(a)|b(a+1|0)<<8};E.prototype.mmap_write16=function(a,b){var c=this.memory_map_write8[a>>>17];c(a,b&255);c(a+1|0,b>>8)};E.prototype.mmap_read32=function(a){return this.memory_map_read32[a>>>17](a)};
E.prototype.mmap_write32=function(a,b){this.memory_map_write32[a>>>17](a,b)};E.prototype.mmap_write64=function(a,b,c){var d=this.memory_map_write32[a>>>17];d(a,b);d(a+4,c)};E.prototype.mmap_write128=function(a,b,c,d,e){var g=this.memory_map_write32[a>>>17];g(a,b);g(a+4,c);g(a+8,d);g(a+12,e)};E.prototype.write_blob=function(a,b){a.length&&(this.in_mapped_range(b),this.in_mapped_range(b+a.length-1),this.jit_dirty_cache(b,b+a.length),this.mem8.set(a,b))};
E.prototype.read_blob=function(a,b){b&&(this.in_mapped_range(a),this.in_mapped_range(a+b-1));return this.mem8.subarray(a,a+b)};function L(a){this.cpu=a;this.channel_page=new Uint8Array(8);this.channel_pagehi=new Uint8Array(8);this.channel_addr=new Uint16Array(8);this.channel_addr_init=new Uint16Array(8);this.channel_count=new Uint16Array(8);this.channel_count_init=new Uint16Array(8);this.channel_mask=new Uint8Array(8);this.channel_mode=new Uint8Array(8);this.unmask_listeners=[];this.lsb_msb_flipflop=0;a=a.io;a.register_write(0,this,this.port_addr_write.bind(this,0));a.register_write(2,this,this.port_addr_write.bind(this,
1));a.register_write(4,this,this.port_addr_write.bind(this,2));a.register_write(6,this,this.port_addr_write.bind(this,3));a.register_write(1,this,this.port_count_write.bind(this,0));a.register_write(3,this,this.port_count_write.bind(this,1));a.register_write(5,this,this.port_count_write.bind(this,2));a.register_write(7,this,this.port_count_write.bind(this,3));a.register_read(0,this,this.port_addr_read.bind(this,0));a.register_read(2,this,this.port_addr_read.bind(this,1));a.register_read(4,this,this.port_addr_read.bind(this,
2));a.register_read(6,this,this.port_addr_read.bind(this,3));a.register_read(1,this,this.port_count_read.bind(this,0));a.register_read(3,this,this.port_count_read.bind(this,1));a.register_read(5,this,this.port_count_read.bind(this,2));a.register_read(7,this,this.port_count_read.bind(this,3));a.register_write(192,this,this.port_addr_write.bind(this,4));a.register_write(196,this,this.port_addr_write.bind(this,5));a.register_write(200,this,this.port_addr_write.bind(this,6));a.register_write(204,this,
this.port_addr_write.bind(this,7));a.register_write(194,this,this.port_count_write.bind(this,4));a.register_write(198,this,this.port_count_write.bind(this,5));a.register_write(202,this,this.port_count_write.bind(this,6));a.register_write(206,this,this.port_count_write.bind(this,7));a.register_read(192,this,this.port_addr_read.bind(this,4));a.register_read(196,this,this.port_addr_read.bind(this,5));a.register_read(200,this,this.port_addr_read.bind(this,6));a.register_read(204,this,this.port_addr_read.bind(this,
7));a.register_read(194,this,this.port_count_read.bind(this,4));a.register_read(198,this,this.port_count_read.bind(this,5));a.register_read(202,this,this.port_count_read.bind(this,6));a.register_read(206,this,this.port_count_read.bind(this,7));a.register_write(135,this,this.port_page_write.bind(this,0));a.register_write(131,this,this.port_page_write.bind(this,1));a.register_write(129,this,this.port_page_write.bind(this,2));a.register_write(130,this,this.port_page_write.bind(this,3));a.register_write(143,
this,this.port_page_write.bind(this,4));a.register_write(139,this,this.port_page_write.bind(this,5));a.register_write(137,this,this.port_page_write.bind(this,6));a.register_write(138,this,this.port_page_write.bind(this,7));a.register_read(135,this,this.port_page_read.bind(this,0));a.register_read(131,this,this.port_page_read.bind(this,1));a.register_read(129,this,this.port_page_read.bind(this,2));a.register_read(130,this,this.port_page_read.bind(this,3));a.register_read(143,this,this.port_page_read.bind(this,
4));a.register_read(139,this,this.port_page_read.bind(this,5));a.register_read(137,this,this.port_page_read.bind(this,6));a.register_read(138,this,this.port_page_read.bind(this,7));a.register_write(1159,this,this.port_pagehi_write.bind(this,0));a.register_write(1155,this,this.port_pagehi_write.bind(this,1));a.register_write(1153,this,this.port_pagehi_write.bind(this,2));a.register_write(1154,this,this.port_pagehi_write.bind(this,3));a.register_write(1163,this,this.port_pagehi_write.bind(this,5));
a.register_write(1161,this,this.port_pagehi_write.bind(this,6));a.register_write(1162,this,this.port_pagehi_write.bind(this,7));a.register_read(1159,this,this.port_pagehi_read.bind(this,0));a.register_read(1155,this,this.port_pagehi_read.bind(this,1));a.register_read(1153,this,this.port_pagehi_read.bind(this,2));a.register_read(1154,this,this.port_pagehi_read.bind(this,3));a.register_read(1163,this,this.port_pagehi_read.bind(this,5));a.register_read(1161,this,this.port_pagehi_read.bind(this,6));a.register_read(1162,
this,this.port_pagehi_read.bind(this,7));a.register_write(10,this,this.port_singlemask_write.bind(this,0));a.register_write(212,this,this.port_singlemask_write.bind(this,4));a.register_write(15,this,this.port_multimask_write.bind(this,0));a.register_write(222,this,this.port_multimask_write.bind(this,4));a.register_read(15,this,this.port_multimask_read.bind(this,0));a.register_read(222,this,this.port_multimask_read.bind(this,4));a.register_write(11,this,this.port_mode_write.bind(this,0));a.register_write(214,
this,this.port_mode_write.bind(this,4));a.register_write(12,this,this.portC_write);a.register_write(216,this,this.portC_write)}L.prototype.get_state=function(){return[this.channel_page,this.channel_pagehi,this.channel_addr,this.channel_addr_init,this.channel_count,this.channel_count_init,this.channel_mask,this.channel_mode,this.lsb_msb_flipflop]};
L.prototype.set_state=function(a){this.channel_page=a[0];this.channel_pagehi=a[1];this.channel_addr=a[2];this.channel_addr_init=a[3];this.channel_count=a[4];this.channel_count_init=a[5];this.channel_mask=a[6];this.channel_mode=a[7];this.lsb_msb_flipflop=a[8]};L.prototype.port_count_write=function(a,b){A(b);this.channel_count[a]=this.flipflop_get(this.channel_count[a],b,!1);this.channel_count_init[a]=this.flipflop_get(this.channel_count_init[a],b,!0)};
L.prototype.port_count_read=function(a){A(this.channel_count[a]);return this.flipflop_read(this.channel_count[a])};L.prototype.port_addr_write=function(a,b){A(b);this.channel_addr[a]=this.flipflop_get(this.channel_addr[a],b,!1);this.channel_addr_init[a]=this.flipflop_get(this.channel_addr_init[a],b,!0)};L.prototype.port_addr_read=function(a){A(this.channel_addr[a]);return this.flipflop_read(this.channel_addr[a])};L.prototype.port_pagehi_write=function(a,b){A(b);this.channel_pagehi[a]=b};
L.prototype.port_pagehi_read=function(a){return this.channel_pagehi[a]};L.prototype.port_page_write=function(a,b){A(b);this.channel_page[a]=b};L.prototype.port_page_read=function(a){return this.channel_page[a]};L.prototype.port_singlemask_write=function(a,b){this.update_mask((b&3)+a,b&4?1:0)};L.prototype.port_multimask_write=function(a,b){A(b);for(var c=0;4>c;c++)this.update_mask(a+c,b&1<<c)};
L.prototype.port_multimask_read=function(a){var b=0|this.channel_mask[a+0];b|=this.channel_mask[a+1]<<1;b|=this.channel_mask[a+2]<<2;b|=this.channel_mask[a+3]<<3;A(b);return b};L.prototype.port_mode_write=function(a,b){a=(b&3)+a;A(b);this.channel_mode[a]=b};L.prototype.portC_write=function(){this.lsb_msb_flipflop=0};L.prototype.on_unmask=function(a,b){this.unmask_listeners.push({fn:a,this_value:b})};
L.prototype.update_mask=function(a,b){if(this.channel_mask[a]!==b&&(this.channel_mask[a]=b,!b))for(b=0;b<this.unmask_listeners.length;b++)this.unmask_listeners[b].fn.call(this.unmask_listeners[b].this_value,a)};
L.prototype.do_read=function(a,b,c,d,e){var g=this.count_get_8bit(d),f=this.address_get_8bit(d);J("to "+A(f)+" len "+A(g),16);c<g&&J("DMA should read more than provided: "+A(c)+" "+A(g),16);if(b+g>a.byteLength)e(!0);else{var k=this.cpu;this.channel_addr[d]+=g;a.get(b,g,function(l){k.write_blob(l,f);e(!1)})}};
L.prototype.do_write=function(a,b,c,d,e){var g=this.channel_count[d]+1&65535,f=5<=d?2:1,k=g*f,l=this.address_get_8bit(d),m=!1,n=!1,p=this.channel_mode[d]&16;J("to "+A(l)+" len "+A(k),16);c<k?(g=Math.floor(c/f),k=g*f,m=!0):c>k&&(n=!0);b+k>a.byteLength?e(!0):(this.channel_addr[d]+=g,this.channel_count[d]-=g,!m&&p&&(this.channel_addr[d]=this.channel_addr_init[d],this.channel_count[d]=this.channel_count_init[d]),a.set(b,this.cpu.mem8.subarray(l,l+k),()=>{n&&p?this.do_write(a,b+k,c-k,d,e):e(!1)}))};
L.prototype.address_get_8bit=function(a){var b=this.channel_addr[a];5<=a&&(b<<=1);b=b&65535|this.channel_page[a]<<16;return b|=this.channel_pagehi[a]<<24};L.prototype.count_get_8bit=function(a){var b=this.channel_count[a]+1;5<=a&&(b*=2);return b};L.prototype.flipflop_get=function(a,b,c){c||(this.lsb_msb_flipflop^=1);return this.lsb_msb_flipflop?a&-256|b:a&-65281|b<<8};L.prototype.flipflop_read=function(a){return(this.lsb_msb_flipflop^=1)?a&255:a>>8&255};function qa(a,b){this.cpu=a;this.bus=b;this.counter_start_time=new Float64Array(3);this.counter_start_value=new Uint16Array(3);this.counter_next_low=new Uint8Array(4);this.counter_enabled=new Uint8Array(4);this.counter_mode=new Uint8Array(4);this.counter_read_mode=new Uint8Array(4);this.counter_latch=new Uint8Array(4);this.counter_latch_value=new Uint16Array(3);this.counter_reload=new Uint16Array(3);a.io.register_read(97,this,function(){var c=D.microtick(),d=66.66666666666667*c&1;c=this.did_rollover(2,
c);return d<<4|c<<5});a.io.register_write(97,this,function(c){c&1?this.bus.send("pcspeaker-enable"):this.bus.send("pcspeaker-disable")});a.io.register_read(64,this,function(){return this.counter_read(0)});a.io.register_read(65,this,function(){return this.counter_read(1)});a.io.register_read(66,this,function(){return this.counter_read(2)});a.io.register_write(64,this,function(c){this.counter_write(0,c)});a.io.register_write(65,this,function(c){this.counter_write(1,c)});a.io.register_write(66,this,
function(c){this.counter_write(2,c);this.bus.send("pcspeaker-update",[this.counter_mode[2],this.counter_reload[2]])});a.io.register_write(67,this,this.port43_write)}qa.prototype.get_state=function(){var a=[];a[0]=this.counter_next_low;a[1]=this.counter_enabled;a[2]=this.counter_mode;a[3]=this.counter_read_mode;a[4]=this.counter_latch;a[5]=this.counter_latch_value;a[6]=this.counter_reload;a[7]=this.counter_start_time;a[8]=this.counter_start_value;return a};
qa.prototype.set_state=function(a){this.counter_next_low=a[0];this.counter_enabled=a[1];this.counter_mode=a[2];this.counter_read_mode=a[3];this.counter_latch=a[4];this.counter_latch_value=a[5];this.counter_reload=a[6];this.counter_start_time=a[7];this.counter_start_value=a[8]};
qa.prototype.timer=function(a,b){var c=100;b||(this.counter_enabled[0]&&this.did_rollover(0,a)?(this.counter_start_value[0]=this.get_counter_value(0,a),this.counter_start_time[0]=a,this.cpu.device_lower_irq(0),this.cpu.device_raise_irq(0),0===this.counter_mode[0]&&(this.counter_enabled[0]=0)):this.cpu.device_lower_irq(0),this.counter_enabled[0]&&(c=(this.counter_start_value[0]-Math.floor(1193.1816666*(a-this.counter_start_time[0])))/1193.1816666));return c};
qa.prototype.get_counter_value=function(a,b){if(!this.counter_enabled[a])return 0;b=this.counter_start_value[a]-Math.floor(1193.1816666*(b-this.counter_start_time[a]));a=this.counter_reload[a];b>=a?b%=a:0>b&&(b=b%a+a);return b};qa.prototype.did_rollover=function(a,b){b-=this.counter_start_time[a];return 0>b?!0:this.counter_start_value[a]<Math.floor(1193.1816666*b)};
qa.prototype.counter_read=function(a){var b=this.counter_latch[a];if(b)return this.counter_latch[a]--,2===b?this.counter_latch_value[a]&255:this.counter_latch_value[a]>>8;b=this.counter_next_low[a];3===this.counter_mode[a]&&(this.counter_next_low[a]^=1);a=this.get_counter_value(a,D.microtick());return b?a&255:a>>8};
qa.prototype.counter_write=function(a,b){this.counter_reload[a]=this.counter_next_low[a]?this.counter_reload[a]&-256|b:this.counter_reload[a]&255|b<<8;3===this.counter_read_mode[a]&&this.counter_next_low[a]||(this.counter_reload[a]||(this.counter_reload[a]=65535),this.counter_start_value[a]=this.counter_reload[a],this.counter_enabled[a]=!0,this.counter_start_time[a]=D.microtick(),A(this.counter_reload[a]));3===this.counter_read_mode[a]&&(this.counter_next_low[a]^=1)};
qa.prototype.port43_write=function(a){var b=a>>1&7,c=a>>6&3;a=a>>4&3;3!==c&&(0===a?(this.counter_latch[c]=2,b=this.get_counter_value(c,D.microtick()),this.counter_latch_value[c]=b?b-1:0):(6<=b&&(b&=-5),this.counter_next_low[c]=1===a?0:1,0===c&&this.cpu.device_lower_irq(0),0!==b&&3!==b&&2!==b&&A(b),this.counter_mode[c]=b,this.counter_read_mode[c]=a,2===c&&this.bus.send("pcspeaker-update",[this.counter_mode[2],this.counter_reload[2]])))};qa.prototype.dump=function(){};var ra=Uint32Array.from([655360,655360,720896,753664]),ua=Uint32Array.from([131072,65536,32768,32768]);
function M(a,b,c){this.cpu=a;this.bus=b;this.vga_memory_size=c;this.cursor_address=0;this.cursor_scanline_start=14;this.cursor_scanline_end=15;this.max_cols=80;this.max_rows=25;this.virtual_height=this.virtual_width=this.screen_height=this.screen_width=0;this.layers=[];this.start_address_latched=this.start_address=0;this.crtc=new Uint8Array(25);this.line_compare=this.offset_register=this.preset_row_scan=this.underline_location_register=this.vertical_blank_start=this.vertical_display_enable_end=this.horizontal_blank_start=
this.horizontal_display_enable_end=this.crtc_mode=0;this.graphical_mode_is_linear=!0;this.graphical_mode=!1;setTimeout(()=>{b.send("screen-set-mode",this.graphical_mode)},0);this.vga256_palette=new Int32Array(256);this.latch_dword=0;this.svga_version=45253;this.svga_height=this.svga_width=0;this.svga_enabled=!1;this.svga_bpp=32;this.svga_offset_y=this.svga_offset=this.svga_bank_offset=0;this.pci_space=[52,18,17,17,3,1,0,0,0,0,0,3,0,0,0,0,8,14680064,57344,224,0,0,0,0,0,0,191,254,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,244,26,0,17,0,0,190,254,0,0,0,0,0,0,0,0,0,0,0,0];this.pci_id=144;this.pci_bars=[{size:c}];this.pci_rom_size=65536;this.pci_rom_address=4272947200;this.name="vga";this.stats={is_graphical:!1,res_x:0,res_y:0,bpp:0};this.dac_state=this.dac_color_index_read=this.dac_color_index_write=this.index_crtc=0;this.dac_mask=255;this.dac_map=new Uint8Array(16);this.attribute_controller_index=-1;this.palette_source=32;this.color_select=this.horizontal_panning=this.color_plane_enable=this.attribute_mode=
0;this.sequencer_index=-1;this.plane_write_bm=15;this.clocking_mode=this.sequencer_memory_mode=0;this.graphics_index=-1;this.planar_rotate_reg=this.planar_mode=this.plane_read=0;this.planar_bitmap=255;this.max_scan_line=this.color_dont_care=this.color_compare=this.miscellaneous_graphics_register=this.planar_setreset_enable=this.planar_setreset=0;this.port_3DA_value=this.miscellaneous_output_register=255;c=a.io;c.register_write(960,this,this.port3C0_write);c.register_read(960,this,this.port3C0_read,
this.port3C0_read16);c.register_read(961,this,this.port3C1_read);c.register_write(962,this,this.port3C2_write);c.register_write_consecutive(964,this,this.port3C4_write,this.port3C5_write);c.register_read(964,this,this.port3C4_read);c.register_read(965,this,this.port3C5_read);c.register_write_consecutive(974,this,this.port3CE_write,this.port3CF_write);c.register_read(974,this,this.port3CE_read);c.register_read(975,this,this.port3CF_read);c.register_read(966,this,this.port3C6_read);c.register_write(966,
this,this.port3C6_write);c.register_write(967,this,this.port3C7_write);c.register_read(967,this,this.port3C7_read);c.register_write(968,this,this.port3C8_write);c.register_read(968,this,this.port3C8_read);c.register_write(969,this,this.port3C9_write);c.register_read(969,this,this.port3C9_read);c.register_read(972,this,this.port3CC_read);c.register_write_consecutive(980,this,this.port3D4_write,this.port3D5_write);c.register_read(980,this,this.port3D4_read);c.register_read(981,this,this.port3D5_read,
()=>this.port3D5_read());c.register_read(970,this,function(){return 0});c.register_read(986,this,this.port3DA_read);c.register_read(954,this,this.port3DA_read);this.dispi_index=-1;this.dispi_enable_value=0;c.register_write(462,this,void 0,this.port1CE_write);c.register_write(463,this,void 0,this.port1CF_write);c.register_read(463,this,void 0,this.port1CF_read);void 0===this.vga_memory_size||262144>this.vga_memory_size?this.vga_memory_size=262144:268435456<this.vga_memory_size?this.vga_memory_size=
268435456:this.vga_memory_size&65535&&(this.vga_memory_size|=65535,this.vga_memory_size++);const d=a.svga_allocate_memory(this.vga_memory_size)>>>0;this.svga_memory=r.view(Uint8Array,a.wasm_memory,d,this.vga_memory_size);this.diff_addr_min=this.vga_memory_size;this.diff_addr_max=0;this.diff_plot_min=this.vga_memory_size;this.diff_plot_max=0;this.image_data=null;b.register("screen-fill-buffer",function(){this.screen_fill_buffer()},this);this.vga_memory=new Uint8Array(262144);this.plane0=new Uint8Array(this.vga_memory.buffer,
0,65536);this.plane1=new Uint8Array(this.vga_memory.buffer,65536,65536);this.plane2=new Uint8Array(this.vga_memory.buffer,131072,65536);this.plane3=new Uint8Array(this.vga_memory.buffer,196608,65536);this.pixel_buffer=new Uint8Array(524288);var e=this;c.mmap_register(655360,131072,function(g){return e.vga_memory_read(g)},function(g,f){e.vga_memory_write(g,f)});a.devices.pci.register_device(this)}
M.prototype.get_state=function(){var a=[];a[0]=this.vga_memory_size;a[1]=this.cursor_address;a[2]=this.cursor_scanline_start;a[3]=this.cursor_scanline_end;a[4]=this.max_cols;a[5]=this.max_rows;a[6]=this.vga_memory;a[7]=this.dac_state;a[8]=this.start_address;a[9]=this.graphical_mode;a[10]=this.vga256_palette;a[11]=this.latch_dword;a[12]=this.color_compare;a[13]=this.color_dont_care;a[14]=this.miscellaneous_graphics_register;a[15]=this.svga_width;a[16]=this.svga_height;a[17]=this.crtc_mode;a[18]=this.svga_enabled;
a[19]=this.svga_bpp;a[20]=this.svga_bank_offset;a[21]=this.svga_offset;a[22]=this.index_crtc;a[23]=this.dac_color_index_write;a[24]=this.dac_color_index_read;a[25]=this.dac_map;a[26]=this.sequencer_index;a[27]=this.plane_write_bm;a[28]=this.sequencer_memory_mode;a[29]=this.graphics_index;a[30]=this.plane_read;a[31]=this.planar_mode;a[32]=this.planar_rotate_reg;a[33]=this.planar_bitmap;a[34]=this.max_scan_line;a[35]=this.miscellaneous_output_register;a[36]=this.port_3DA_value;a[37]=this.dispi_index;
a[38]=this.dispi_enable_value;a[39]=this.svga_memory;a[40]=this.graphical_mode_is_linear;a[41]=this.attribute_controller_index;a[42]=this.offset_register;a[43]=this.planar_setreset;a[44]=this.planar_setreset_enable;a[45]=this.start_address_latched;a[46]=this.crtc;a[47]=this.horizontal_display_enable_end;a[48]=this.horizontal_blank_start;a[49]=this.vertical_display_enable_end;a[50]=this.vertical_blank_start;a[51]=this.underline_location_register;a[52]=this.preset_row_scan;a[53]=this.offset_register;
a[54]=this.palette_source;a[55]=this.attribute_mode;a[56]=this.color_plane_enable;a[57]=this.horizontal_panning;a[58]=this.color_select;a[59]=this.clocking_mode;a[60]=this.line_compare;a[61]=this.pixel_buffer;a[62]=this.dac_mask;return a};
M.prototype.set_state=function(a){this.vga_memory_size=a[0];this.cursor_address=a[1];this.cursor_scanline_start=a[2];this.cursor_scanline_end=a[3];this.max_cols=a[4];this.max_rows=a[5];a[6]&&this.vga_memory.set(a[6]);this.dac_state=a[7];this.start_address=a[8];this.graphical_mode=a[9];this.vga256_palette=a[10];this.latch_dword=a[11];this.color_compare=a[12];this.color_dont_care=a[13];this.miscellaneous_graphics_register=a[14];this.svga_width=a[15];this.svga_height=a[16];this.crtc_mode=a[17];this.svga_enabled=
a[18];this.svga_bpp=a[19];this.svga_bank_offset=a[20];this.svga_offset=a[21];this.index_crtc=a[22];this.dac_color_index_write=a[23];this.dac_color_index_read=a[24];this.dac_map=a[25];this.sequencer_index=a[26];this.plane_write_bm=a[27];this.sequencer_memory_mode=a[28];this.graphics_index=a[29];this.plane_read=a[30];this.planar_mode=a[31];this.planar_rotate_reg=a[32];this.planar_bitmap=a[33];this.max_scan_line=a[34];this.miscellaneous_output_register=a[35];this.port_3DA_value=a[36];this.dispi_index=
a[37];this.dispi_enable_value=a[38];this.svga_memory.set(a[39]);this.graphical_mode_is_linear=a[40];this.attribute_controller_index=a[41];this.offset_register=a[42];this.planar_setreset=a[43];this.planar_setreset_enable=a[44];this.start_address_latched=a[45];this.crtc.set(a[46]);this.horizontal_display_enable_end=a[47];this.horizontal_blank_start=a[48];this.vertical_display_enable_end=a[49];this.vertical_blank_start=a[50];this.underline_location_register=a[51];this.preset_row_scan=a[52];this.offset_register=
a[53];this.palette_source=a[54];this.attribute_mode=a[55];this.color_plane_enable=a[56];this.horizontal_panning=a[57];this.color_select=a[58];this.clocking_mode=a[59];this.line_compare=a[60];a[61]&&this.pixel_buffer.set(a[61]);this.dac_mask=void 0===a[62]?255:a[62];this.bus.send("screen-set-mode",this.graphical_mode);this.graphical_mode?(this.screen_height=this.screen_width=0,this.svga_enabled?(this.set_size_graphical(this.svga_width,this.svga_height,this.svga_bpp,this.svga_width,this.svga_height),
this.update_layers()):(this.update_vga_size(),this.update_layers(),this.complete_replot())):(this.set_size_text(this.max_cols,this.max_rows),this.update_cursor_scanline(),this.update_cursor());this.complete_redraw()};
M.prototype.vga_memory_read=function(a){if(this.svga_enabled&&this.graphical_mode_is_linear)return this.cpu.read8((a-655360|this.svga_bank_offset)+3758096384|0);var b=this.miscellaneous_graphics_register>>2&3;a-=ra[b];if(0>a||a>=ua[b])return A(a),0;this.latch_dword=this.plane0[a];this.latch_dword|=this.plane1[a]<<8;this.latch_dword|=this.plane2[a]<<16;this.latch_dword|=this.plane3[a]<<24;if(this.planar_mode&8)return b=255,this.color_dont_care&1&&(b&=this.plane0[a]^~(this.color_compare&1?255:0)),this.color_dont_care&
2&&(b&=this.plane1[a]^~(this.color_compare&2?255:0)),this.color_dont_care&4&&(b&=this.plane2[a]^~(this.color_compare&4?255:0)),this.color_dont_care&8&&(b&=this.plane3[a]^~(this.color_compare&8?255:0)),b;b=this.plane_read;this.graphical_mode?this.sequencer_memory_mode&8?(b=a&3,a&=-4):this.planar_mode&16&&(b=a&1,a&=-2):b=0;return this.vga_memory[b<<16|a]};
M.prototype.vga_memory_write=function(a,b){if(this.svga_enabled&&this.graphical_mode&&this.graphical_mode_is_linear)this.cpu.write8((a-655360|this.svga_bank_offset)+3758096384|0,b);else{var c=this.miscellaneous_graphics_register>>2&3;a-=ra[c];0>a||a>=ua[c]?(A(a),A(b)):this.graphical_mode?this.vga_memory_write_graphical(a,b):this.plane_write_bm&3&&this.vga_memory_write_text_mode(a,b)}};
M.prototype.vga_memory_write_graphical=function(a,b){var c=this.planar_mode&3,d=this.apply_feed(this.planar_bitmap),e=this.apply_expand(this.planar_setreset),g=this.apply_expand(this.planar_setreset_enable);switch(c){case 0:b=this.apply_rotate(b);var f=this.apply_feed(b);f=this.apply_setreset(f,g);f=this.apply_logical(f,this.latch_dword);f=this.apply_bitmask(f,d);break;case 1:f=this.latch_dword;break;case 2:f=this.apply_expand(b);f=this.apply_logical(f,this.latch_dword);f=this.apply_bitmask(f,d);
break;case 3:b=this.apply_rotate(b),d&=this.apply_feed(b),f=this.apply_bitmask(e,d)}b=15;switch(this.sequencer_memory_mode&12){case 0:b=5<<(a&1);a&=-2;break;case 8:case 12:b=1<<(a&3),a&=-4}b&=this.plane_write_bm;b&1&&(this.plane0[a]=f>>0&255);b&2&&(this.plane1[a]=f>>8&255);b&4&&(this.plane2[a]=f>>16&255);b&8&&(this.plane3[a]=f>>24&255);a=this.vga_addr_to_pixel(a);this.partial_replot(a,a+7)};M.prototype.apply_feed=function(a){return a|a<<8|a<<16|a<<24};
M.prototype.apply_expand=function(a){return(a&1?255:0)|(a&2?255:0)<<8|(a&4?255:0)<<16|(a&8?255:0)<<24};M.prototype.apply_rotate=function(a){return(a|a<<8)>>>(this.planar_rotate_reg&7)&255};M.prototype.apply_setreset=function(a,b){var c=this.apply_expand(this.planar_setreset);return(a|b&c)&(~b|c)};M.prototype.apply_logical=function(a,b){switch(this.planar_rotate_reg&24){case 8:return a&b;case 16:return a|b;case 24:return a^b}return a};M.prototype.apply_bitmask=function(a,b){return b&a|~b&this.latch_dword};
M.prototype.text_mode_redraw=function(){var a=this.start_address<<1;const b=this.scan_line_to_screen_row(this.line_compare),c=Math.max(0,2*(2*this.offset_register-this.max_cols));for(var d=0;d<this.max_rows;d++){d===b&&(a=0);for(var e=0;e<this.max_cols;e++){var g=this.vga_memory[a];var f=this.vga_memory[a|1];this.bus.send("screen-put-char",[d,e,g,this.vga256_palette[this.dac_mask&this.dac_map[f>>4&15]],this.vga256_palette[this.dac_mask&this.dac_map[f&15]]]);a+=2}a+=c}};
M.prototype.vga_memory_write_text_mode=function(a,b){var c=Math.max(this.max_cols,2*this.offset_register);let d;if(a>>1>=this.start_address){var e=(a>>1)-this.start_address;d=e/c|0;c=e%c}else e=a>>1,d=(e/c|0)+this.scan_line_to_screen_row(this.line_compare),c=e%c;if(!(c>=this.max_cols||d>=this.max_rows)){if(a&1){var g=b;e=this.vga_memory[a&-2]}else e=b,g=this.vga_memory[a|1];this.bus.send("screen-put-char",[d,c,e,this.vga256_palette[this.dac_mask&this.dac_map[g>>4&15]],this.vga256_palette[this.dac_mask&
this.dac_map[g&15]]]);this.vga_memory[a]=b}};M.prototype.update_cursor=function(){var a=Math.max(this.max_cols,2*this.offset_register);let b;this.cursor_address>=this.start_address?(b=(this.cursor_address-this.start_address)/a|0,a=(this.cursor_address-this.start_address)%a):(b=(this.cursor_address/a|0)+this.scan_line_to_screen_row(this.line_compare),a=this.cursor_address%a);b=Math.min(this.max_rows-1,b);a=Math.min(this.max_cols-1,a);this.bus.send("screen-update-cursor",[b,a])};
M.prototype.complete_redraw=function(){this.graphical_mode?this.svga_enabled?this.cpu.svga_mark_dirty():(this.diff_addr_min=0,this.diff_addr_max=524288):this.text_mode_redraw()};M.prototype.complete_replot=function(){this.graphical_mode&&!this.svga_enabled&&(this.diff_plot_min=0,this.diff_plot_max=524288,this.complete_redraw())};M.prototype.partial_redraw=function(a,b){a<this.diff_addr_min&&(this.diff_addr_min=a);b>this.diff_addr_max&&(this.diff_addr_max=b)};
M.prototype.partial_replot=function(a,b){a<this.diff_plot_min&&(this.diff_plot_min=a);b>this.diff_plot_max&&(this.diff_plot_max=b);this.partial_redraw(a,b)};M.prototype.reset_diffs=function(){this.diff_addr_min=this.vga_memory_size;this.diff_addr_max=0;this.diff_plot_min=this.vga_memory_size;this.diff_plot_max=0};M.prototype.destroy=function(){};M.prototype.vga_bytes_per_line=function(){var a=this.offset_register<<2;this.underline_location_register&64?a<<=1:this.crtc_mode&64&&(a>>>=1);return a};
M.prototype.vga_addr_shift_count=function(){var a=128+(~this.underline_location_register&this.crtc_mode&64);a-=this.underline_location_register&64;a-=this.attribute_mode&64;return a>>>6};
M.prototype.vga_addr_to_pixel=function(a){var b=this.vga_addr_shift_count();if(~this.crtc_mode&3){var c=a-this.start_address;c&=this.crtc_mode<<13|-24577;c<<=b;var d=c/this.virtual_width|0;c%=this.virtual_width;switch(this.crtc_mode&3){case 2:d=d<<1|a>>13&1;break;case 1:d=d<<1|a>>14&1;break;case 0:d=d<<2|a>>13&3}return d*this.virtual_width+c+(this.start_address<<b)}return a<<b};
M.prototype.scan_line_to_screen_row=function(a){this.max_scan_line&128&&(a>>>=1);a=Math.ceil(a/(1+(this.max_scan_line&31)));this.crtc_mode&1||(a<<=1);this.crtc_mode&2||(a<<=1);return a};M.prototype.set_size_text=function(a,b){this.max_cols=a;this.max_rows=b;this.bus.send("screen-set-size-text",[a,b])};
M.prototype.set_size_graphical=function(a,b,c,d,e){if(!this.stats.is_graphical||this.stats.bpp!==c||this.screen_width!==a||this.screen_height!==b||this.virtual_width!==d||this.virtual_height!==e){this.screen_width=a;this.screen_height=b;this.virtual_width=d;this.virtual_height=e;this.stats.bpp=c;this.stats.is_graphical=!0;this.stats.res_x=a;this.stats.res_y=b;if("undefined"!==typeof ImageData){const g=d*e,f=this.cpu.svga_allocate_dest_buffer(g)>>>0;this.dest_buffet_offset=f;this.image_data=new ImageData(new Uint8ClampedArray(this.cpu.wasm_memory.buffer,
f,4*g),d,e);this.cpu.svga_mark_dirty()}this.bus.send("screen-set-size-graphical",[a,b,d,e,c])}};
M.prototype.update_vga_size=function(){if(!this.svga_enabled){var a=Math.min(1+this.horizontal_display_enable_end,this.horizontal_blank_start),b=Math.min(1+this.vertical_display_enable_end,this.vertical_blank_start);if(a&&b)if(this.graphical_mode){a<<=3;var c=this.offset_register<<4;this.attribute_mode&64&&(a>>>=1,c>>>=1);b=this.scan_line_to_screen_row(b);var d=Math.ceil(ua[0]/this.vga_bytes_per_line());this.set_size_graphical(a,b,8,c,d);this.update_vertical_retrace();this.update_layers()}else this.max_scan_line&
128&&(b>>>=1),c=b/(1+(this.max_scan_line&31))|0,a&&c&&this.set_size_text(a,c)}};
M.prototype.update_layers=function(){this.graphical_mode||this.text_mode_redraw();if(this.svga_enabled)this.layers=[];else if(this.virtual_width&&this.screen_width)if(!this.palette_source||this.clocking_mode&32)this.layers=[],this.bus.send("screen-clear");else{var a=this.start_address_latched,b=this.horizontal_panning;this.attribute_mode&64&&(b>>>=1);var c=this.preset_row_scan>>5&3,d=this.vga_addr_to_pixel(a+c);a=d/this.virtual_width|0;var e=d%this.virtual_width+b;d=this.scan_line_to_screen_row(1+
this.line_compare);d=Math.min(d,this.screen_height);var g=this.screen_height-d;this.layers=[];e=-e;for(var f=0;e<this.screen_width;e+=this.virtual_width,f++)this.layers.push({image_data:this.image_data,screen_x:e,screen_y:0,buffer_x:0,buffer_y:a+f,buffer_width:this.virtual_width,buffer_height:d});a=0;this.attribute_mode&32||(a=this.vga_addr_to_pixel(c)+b);e=-a;for(f=0;e<this.screen_width;e+=this.virtual_width,f++)this.layers.push({image_data:this.image_data,screen_x:e,screen_y:d,buffer_x:0,buffer_y:f,
buffer_width:this.virtual_width,buffer_height:g})}};M.prototype.update_vertical_retrace=function(){this.port_3DA_value|=8;this.start_address_latched!==this.start_address&&(this.start_address_latched=this.start_address,this.update_layers())};M.prototype.update_cursor_scanline=function(){this.bus.send("screen-update-cursor-scanline",[this.cursor_scanline_start,this.cursor_scanline_end])};
M.prototype.port3C0_write=function(a){if(-1===this.attribute_controller_index)A(a),this.attribute_controller_index=a&31,A(this.attribute_controller_index),this.palette_source!==(a&32)&&(this.palette_source=a&32,this.update_layers());else{if(16>this.attribute_controller_index)A(this.attribute_controller_index),A(a),this.dac_map[this.attribute_controller_index]=a,this.attribute_mode&64||this.complete_redraw();else switch(this.attribute_controller_index){case 16:A(a);if(this.attribute_mode!==a){var b=
this.attribute_mode;this.attribute_mode=a;var c=0<(a&1);this.svga_enabled||this.graphical_mode===c||(this.graphical_mode=c,this.bus.send("screen-set-mode",this.graphical_mode));(b^a)&64&&this.complete_replot();this.update_vga_size();this.complete_redraw()}break;case 18:A(a);this.color_plane_enable!==a&&(this.color_plane_enable=a,this.complete_redraw());break;case 19:A(a);this.horizontal_panning!==a&&(this.horizontal_panning=a&15,this.update_layers());break;case 20:A(a);this.color_select!==a&&(this.color_select=
a,this.complete_redraw());break;default:A(this.attribute_controller_index),A(a)}this.attribute_controller_index=-1}};M.prototype.port3C0_read=function(){return(this.attribute_controller_index|this.palette_source)&255};M.prototype.port3C0_read16=function(){return this.port3C0_read()|this.port3C1_read()<<8&65280};
M.prototype.port3C1_read=function(){if(16>this.attribute_controller_index)return A(this.attribute_controller_index),A(this.dac_map[this.attribute_controller_index]),this.dac_map[this.attribute_controller_index]&255;switch(this.attribute_controller_index){case 16:return A(this.attribute_mode),this.attribute_mode;case 18:return A(this.color_plane_enable),this.color_plane_enable;case 19:return A(this.horizontal_panning),this.horizontal_panning;case 20:return A(this.color_select),this.color_select;default:A(this.attribute_controller_index)}return 255};
M.prototype.port3C2_write=function(a){A(a);this.miscellaneous_output_register=a};M.prototype.port3C4_write=function(a){this.sequencer_index=a};M.prototype.port3C4_read=function(){return this.sequencer_index};M.prototype.port3C5_write=function(a){switch(this.sequencer_index){case 1:A(a);var b=this.clocking_mode;this.clocking_mode=a;(b^a)&32&&this.update_layers();break;case 2:A(a);this.plane_write_bm=a;break;case 4:A(a);this.sequencer_memory_mode=a;break;default:A(this.sequencer_index),A(a)}};
M.prototype.port3C5_read=function(){A(this.sequencer_index);switch(this.sequencer_index){case 1:return this.clocking_mode;case 2:return this.plane_write_bm;case 4:return this.sequencer_memory_mode;case 6:return 18}return 0};M.prototype.port3C6_write=function(a){this.dac_mask=a};M.prototype.port3C6_read=function(){return this.dac_mask};M.prototype.port3C7_write=function(a){A(a);this.dac_color_index_read=3*a;this.dac_state&=0};M.prototype.port3C7_read=function(){return this.dac_state};
M.prototype.port3C8_write=function(a){this.dac_color_index_write=3*a;this.dac_state|=3};M.prototype.port3C8_read=function(){return this.dac_color_index_write/3&255};
M.prototype.port3C9_write=function(a){var b=this.dac_color_index_write/3|0,c=this.dac_color_index_write%3,d=this.vga256_palette[b];if(0===(this.dispi_enable_value&32)){a&=63;const e=a&1;a=a<<2|e<<1|e}0===c?d=d&-16711681|a<<16:1===c?d=d&-65281|a<<8:(d=d&-256|a,A(b),A(d));this.vga256_palette[b]!==d&&(this.vga256_palette[b]=d,this.complete_redraw());this.dac_color_index_write++};
M.prototype.port3C9_read=function(){var a=this.vga256_palette[this.dac_color_index_read/3|0]>>8*(2-this.dac_color_index_read%3)&255;this.dac_color_index_read++;return this.dispi_enable_value&32?a:a>>2};M.prototype.port3CC_read=function(){return this.miscellaneous_output_register};M.prototype.port3CE_write=function(a){this.graphics_index=a};M.prototype.port3CE_read=function(){return this.graphics_index};
M.prototype.port3CF_write=function(a){switch(this.graphics_index){case 0:this.planar_setreset=a;A(a);break;case 1:this.planar_setreset_enable=a;A(a);break;case 2:this.color_compare=a;A(a);break;case 3:this.planar_rotate_reg=a;A(a);break;case 4:this.plane_read=a;A(a);break;case 5:var b=this.planar_mode;this.planar_mode=a;A(a);(b^a)&96&&this.complete_replot();break;case 6:A(a);this.miscellaneous_graphics_register!==a&&(this.miscellaneous_graphics_register=a,this.update_vga_size());break;case 7:this.color_dont_care=
a;A(a);break;case 8:this.planar_bitmap=a;A(a);break;default:A(this.graphics_index),A(a)}};M.prototype.port3CF_read=function(){A(this.graphics_index);switch(this.graphics_index){case 0:return this.planar_setreset;case 1:return this.planar_setreset_enable;case 2:return this.color_compare;case 3:return this.planar_rotate_reg;case 4:return this.plane_read;case 5:return this.planar_mode;case 6:return this.miscellaneous_graphics_register;case 7:return this.color_dont_care;case 8:return this.planar_bitmap}return 0};
M.prototype.port3D4_write=function(a){this.index_crtc=a};M.prototype.port3D4_read=function(){return this.index_crtc};
M.prototype.port3D5_write=function(a){switch(this.index_crtc){case 1:A(a);this.horizontal_display_enable_end!==a&&(this.horizontal_display_enable_end=a,this.update_vga_size());break;case 2:this.horizontal_blank_start!==a&&(this.horizontal_blank_start=a,this.update_vga_size());break;case 7:A(a);var b=this.vertical_display_enable_end;this.vertical_display_enable_end&=255;this.vertical_display_enable_end=this.vertical_display_enable_end|a<<3&512|a<<7&256;b!=this.vertical_display_enable_end&&this.update_vga_size();
this.line_compare=this.line_compare&767|a<<4&256;b=this.vertical_blank_start;this.vertical_blank_start=this.vertical_blank_start&767|a<<5&256;b!==this.vertical_blank_start&&this.update_vga_size();this.update_layers();break;case 8:A(a);this.preset_row_scan=a;this.update_layers();break;case 9:A(a);this.max_scan_line=a;this.line_compare=this.line_compare&511|a<<3&512;b=this.vertical_blank_start;this.vertical_blank_start=this.vertical_blank_start&511|a<<4&512;b!==this.vertical_blank_start&&this.update_vga_size();
this.update_layers();break;case 10:A(a);this.cursor_scanline_start=a;this.update_cursor_scanline();break;case 11:A(a);this.cursor_scanline_end=a;this.update_cursor_scanline();break;case 12:(this.start_address>>8&255)!==a&&(this.start_address=this.start_address&255|a<<8,this.update_layers(),~this.crtc_mode&3&&this.complete_replot());A(a);A(this.start_address,4);break;case 13:(this.start_address&255)!==a&&(this.start_address=this.start_address&65280|a,this.update_layers(),~this.crtc_mode&3&&this.complete_replot());
A(a);A(this.start_address,4);break;case 14:A(a);this.cursor_address=this.cursor_address&255|a<<8;this.update_cursor();break;case 15:A(a);this.cursor_address=this.cursor_address&65280|a;this.update_cursor();break;case 18:A(a);(this.vertical_display_enable_end&255)!==a&&(this.vertical_display_enable_end=this.vertical_display_enable_end&768|a,this.update_vga_size());break;case 19:A(a);this.offset_register!==a&&(this.offset_register=a,this.update_vga_size(),~this.crtc_mode&3&&this.complete_replot());
break;case 20:A(a);this.underline_location_register!==a&&(b=this.underline_location_register,this.underline_location_register=a,this.update_vga_size(),(b^a)&64&&this.complete_replot());break;case 21:A(a);(this.vertical_blank_start&255)!==a&&(this.vertical_blank_start=this.vertical_blank_start&768|a,this.update_vga_size());break;case 23:A(a);this.crtc_mode!==a&&(b=this.crtc_mode,this.crtc_mode=a,this.update_vga_size(),(b^a)&67&&this.complete_replot());break;case 24:A(a);this.line_compare=this.line_compare&
768|a;this.update_layers();break;default:this.index_crtc<this.crtc.length&&(this.crtc[this.index_crtc]=a),A(this.index_crtc),A(a)}};
M.prototype.port3D5_read=function(){A(this.index_crtc);switch(this.index_crtc){case 1:return this.horizontal_display_enable_end;case 2:return this.horizontal_blank_start;case 7:return this.vertical_display_enable_end>>7&2|this.vertical_blank_start>>5&8|this.line_compare>>4&16|this.vertical_display_enable_end>>3&64;case 8:return this.preset_row_scan;case 9:return this.max_scan_line;case 10:return this.cursor_scanline_start;case 11:return this.cursor_scanline_end;case 12:return this.start_address&255;
case 13:return this.start_address>>8;case 14:return this.cursor_address>>8;case 15:return this.cursor_address&255;case 18:return this.vertical_display_enable_end&255;case 19:return this.offset_register;case 20:return this.underline_location_register;case 21:return this.vertical_blank_start&255;case 23:return this.crtc_mode;case 24:return this.line_compare&255}return this.index_crtc<this.crtc.length?this.crtc[this.index_crtc]:0};
M.prototype.port3DA_read=function(){var a=this.port_3DA_value;this.graphical_mode?(this.port_3DA_value^=1,this.port_3DA_value&=1):(this.port_3DA_value&1&&(this.port_3DA_value^=8),this.port_3DA_value^=1);this.attribute_controller_index=-1;return a};M.prototype.port1CE_write=function(a){this.dispi_index=a};
M.prototype.port1CF_write=function(a){A(this.dispi_index);A(a);switch(this.dispi_index){case 0:45248<=a&&45253>=a?this.svga_version=a:A(a);break;case 1:this.svga_width=a;2560<this.svga_width&&(this.svga_width=2560);break;case 2:this.svga_height=a;1600<this.svga_height&&(this.svga_height=1600);break;case 3:this.svga_bpp=a;break;case 4:this.svga_enabled=1===(a&1);this.dispi_enable_value=a;break;case 5:A(a<<16);this.svga_bank_offset=a<<16;break;case 9:const b=a*this.svga_width;A(b);A(a);this.svga_offset_y!==
a&&(this.svga_offset_y=a,this.svga_offset=b,this.complete_redraw());break;default:A(this.dispi_index)}!this.svga_enabled||this.svga_width&&this.svga_height||(this.svga_enabled=!1);this.svga_enabled&&4===this.dispi_index&&(this.set_size_graphical(this.svga_width,this.svga_height,this.svga_bpp,this.svga_width,this.svga_height),this.bus.send("screen-set-mode",!0),this.graphical_mode_is_linear=this.graphical_mode=!0);this.svga_enabled||(this.svga_bank_offset=0);this.update_layers()};
M.prototype.port1CF_read=function(){A(this.dispi_index);return this.svga_register_read(this.dispi_index)};
M.prototype.svga_register_read=function(a){switch(a){case 0:return this.svga_version;case 1:return this.dispi_enable_value&2?2560:this.svga_width;case 2:return this.dispi_enable_value&2?1600:this.svga_height;case 3:return this.dispi_enable_value&2?32:this.svga_bpp;case 4:return this.dispi_enable_value;case 5:return this.svga_bank_offset>>>16;case 6:return this.screen_width?this.screen_width:1;case 8:return 0;case 9:return this.svga_offset_y;case 10:return this.vga_memory_size/65536|0;default:A(this.dispi_index)}return 255};
M.prototype.vga_replot=function(){for(var a=this.diff_plot_min&-16,b=Math.min(this.diff_plot_max|15,524287),c=this.vga_addr_shift_count(),d=~this.crtc_mode&3,e=this.planar_mode&96,g=this.attribute_mode&64;a<=b;){var f=a>>>c;if(d){var k=a/this.virtual_width|0,l=a-this.virtual_width*k;switch(d){case 1:f=(k&1)<<13;k>>>=1;break;case 2:f=(k&1)<<14;k>>>=1;break;case 3:f=(k&3)<<13,k>>>=2}f|=(k*this.virtual_width+l>>>c)+this.start_address}k=this.plane0[f];l=this.plane1[f];var m=this.plane2[f],n=this.plane3[f];
f=new Uint8Array(8);switch(e){case 0:k<<=0;l<<=1;m<<=2;n<<=3;for(var p=7;0<=p;p--)f[7-p]=k>>p&1|l>>p&2|m>>p&4|n>>p&8;break;case 32:f[0]=k>>6&3|m>>4&12;f[1]=k>>4&3|m>>2&12;f[2]=k>>2&3|m>>0&12;f[3]=k>>0&3|m<<2&12;f[4]=l>>6&3|n>>4&12;f[5]=l>>4&3|n>>2&12;f[6]=l>>2&3|n>>0&12;f[7]=l>>0&3|n<<2&12;break;case 64:case 96:f[0]=k>>4&15,f[1]=k>>0&15,f[2]=l>>4&15,f[3]=l>>0&15,f[4]=m>>4&15,f[5]=m>>0&15,f[6]=n>>4&15,f[7]=n>>0&15}if(g)for(k=p=0;4>p;p++,a++,k+=2)this.pixel_buffer[a]=f[k]<<4|f[k+1];else for(p=0;8>p;p++,
a++)this.pixel_buffer[a]=f[p]}};
M.prototype.vga_redraw=function(){var a=this.diff_addr_min,b=Math.min(this.diff_addr_max,524287);const c=new Int32Array(this.cpu.wasm_memory.buffer,this.dest_buffet_offset,this.virtual_width*this.virtual_height);var d=255,e=0;this.attribute_mode&128&&(d&=207,e|=this.color_select<<4&48);if(this.attribute_mode&64)for(;a<=b;a++){var g=this.pixel_buffer[a]&d|e;g=this.vga256_palette[g];c[a]=g&65280|g<<16|g>>16|4278190080}else for(d&=63,e|=this.color_select<<4&192;a<=b;a++)g=this.dac_map[this.pixel_buffer[a]&
this.color_plane_enable]&d|e,g=this.vga256_palette[g],c[a]=g&65280|g<<16|g>>16|4278190080};
M.prototype.screen_fill_buffer=function(){if(this.graphical_mode){if(0===this.image_data.data.byteLength){var a=new Uint8ClampedArray(this.cpu.wasm_memory.buffer,this.dest_buffet_offset,4*this.virtual_width*this.virtual_height);this.image_data=new ImageData(a,this.virtual_width,this.virtual_height);this.update_layers()}if(this.svga_enabled){a=0;let d=this.svga_height;if(8===this.svga_bpp){const e=new Int32Array(this.cpu.wasm_memory.buffer,this.dest_buffet_offset,this.screen_width*this.screen_height),
g=new Uint8Array(this.cpu.wasm_memory.buffer,this.svga_memory.byteOffset,this.vga_memory_size);for(var b=0;b<e.length;b++){var c=this.vga256_palette[g[b]];e[b]=c&65280|c<<16|c>>16|4278190080}}else this.cpu.svga_fill_pixel_buffer(this.svga_bpp,this.svga_offset),b=15===this.svga_bpp?2:this.svga_bpp/8,a=((this.cpu.svga_dirty_bitmap_min_offset[0]/b|0)-this.svga_offset)/this.svga_width|0,d=(((this.cpu.svga_dirty_bitmap_max_offset[0]/b|0)-this.svga_offset)/this.svga_width|0)+1;a<d&&(a=Math.max(a,0),d=Math.min(d,
this.svga_height),this.bus.send("screen-fill-buffer-end",[{image_data:this.image_data,screen_x:0,screen_y:a,buffer_x:0,buffer_y:a,buffer_width:this.svga_width,buffer_height:d-a}]))}else this.vga_replot(),this.vga_redraw(),this.bus.send("screen-fill-buffer-end",this.layers);this.reset_diffs()}this.update_vertical_retrace()};function N(a,b){this.cpu=a;this.bus=b;this.use_mouse=this.enable_mouse_stream=!1;this.have_mouse=!0;this.mouse_clicks=this.mouse_delta_y=this.mouse_delta_x=0;this.have_keyboard=!0;this.next_read_resolution=this.next_read_rate=this.next_handle_scan_code_set=this.next_read_led=this.next_read_sample=this.next_is_mouse_command=this.enable_keyboard_stream=!1;this.kbd_buffer=new ka(1024);this.last_port60_byte=0;this.sample_rate=100;this.mouse_id=this.mouse_detect_state=0;this.mouse_reset_workaround=!1;
this.wheel_movement=0;this.resolution=4;this.scaling2=!1;this.last_mouse_packet=-1;this.mouse_buffer=new ka(1024);this.next_byte_is_aux=this.next_byte_is_ready=!1;this.bus.register("keyboard-code",function(c){this.kbd_send_code(c)},this);this.bus.register("mouse-click",function(c){this.mouse_send_click(c[0],c[1],c[2])},this);this.bus.register("mouse-delta",function(c){this.mouse_send_delta(c[0],c[1])},this);this.bus.register("mouse-wheel",function(c){this.wheel_movement-=c[0];this.wheel_movement-=
2*c[1];this.wheel_movement=Math.min(7,Math.max(-8,this.wheel_movement));this.send_mouse_packet(0,0)},this);this.command_register=5;this.controller_output_port=0;this.read_controller_output_port=this.read_command_register=this.read_output_register=!1;a.io.register_read(96,this,this.port60_read);a.io.register_read(100,this,this.port64_read);a.io.register_write(96,this,this.port60_write);a.io.register_write(100,this,this.port64_write)}
N.prototype.get_state=function(){var a=[];a[0]=this.enable_mouse_stream;a[1]=this.use_mouse;a[2]=this.have_mouse;a[3]=this.mouse_delta_x;a[4]=this.mouse_delta_y;a[5]=this.mouse_clicks;a[6]=this.have_keyboard;a[7]=this.enable_keyboard_stream;a[8]=this.next_is_mouse_command;a[9]=this.next_read_sample;a[10]=this.next_read_led;a[11]=this.next_handle_scan_code_set;a[12]=this.next_read_rate;a[13]=this.next_read_resolution;a[15]=this.last_port60_byte;a[16]=this.sample_rate;a[17]=this.resolution;a[18]=this.scaling2;
a[20]=this.command_register;a[21]=this.read_output_register;a[22]=this.read_command_register;a[23]=this.controller_output_port;a[24]=this.read_controller_output_port;a[25]=this.mouse_id;a[26]=this.mouse_detect_state;a[27]=this.mouse_reset_workaround;return a};
N.prototype.set_state=function(a){this.enable_mouse_stream=a[0];this.use_mouse=a[1];this.have_mouse=a[2];this.mouse_delta_x=a[3];this.mouse_delta_y=a[4];this.mouse_clicks=a[5];this.have_keyboard=a[6];this.enable_keyboard_stream=a[7];this.next_is_mouse_command=a[8];this.next_read_sample=a[9];this.next_read_led=a[10];this.next_handle_scan_code_set=a[11];this.next_read_rate=a[12];this.next_read_resolution=a[13];this.last_port60_byte=a[15];this.sample_rate=a[16];this.resolution=a[17];this.scaling2=a[18];
this.command_register=a[20];this.read_output_register=a[21];this.read_command_register=a[22];this.controller_output_port=a[23];this.read_controller_output_port=a[24];this.mouse_id=a[25]||0;this.mouse_detect_state=a[26]||0;this.mouse_reset_workaround=a[27]||!1;this.next_byte_is_aux=this.next_byte_is_ready=!1;this.kbd_buffer.clear();this.mouse_buffer.clear();this.bus.send("mouse-enable",this.use_mouse)};
N.prototype.raise_irq=function(){this.next_byte_is_ready||(this.kbd_buffer.length?this.kbd_irq():this.mouse_buffer.length&&this.mouse_irq())};N.prototype.mouse_irq=function(){this.next_byte_is_aux=this.next_byte_is_ready=!0;this.command_register&2&&(this.cpu.device_lower_irq(12),this.cpu.device_raise_irq(12))};N.prototype.kbd_irq=function(){this.next_byte_is_ready=!0;this.next_byte_is_aux=!1;this.command_register&1&&(this.cpu.device_lower_irq(1),this.cpu.device_raise_irq(1))};
N.prototype.kbd_send_code=function(a){this.enable_keyboard_stream&&(A(a),this.kbd_buffer.push(a),this.raise_irq())};N.prototype.mouse_send_delta=function(a,b){if(this.have_mouse&&this.use_mouse){var c=this.resolution*this.sample_rate/80;this.mouse_delta_x+=a*c;this.mouse_delta_y+=b*c;this.enable_mouse_stream&&(a=this.mouse_delta_x|0,b=this.mouse_delta_y|0,a||b)&&(Date.now(),this.mouse_delta_x-=a,this.mouse_delta_y-=b,this.send_mouse_packet(a,b))}};
N.prototype.mouse_send_click=function(a,b,c){this.have_mouse&&this.use_mouse&&(this.mouse_clicks=a|c<<1|b<<2,this.enable_mouse_stream&&this.send_mouse_packet(0,0))};
N.prototype.send_mouse_packet=function(a,b){var c=(0>b)<<5|(0>a)<<4|8|this.mouse_clicks;this.last_mouse_packet=Date.now();this.mouse_buffer.push(c);this.mouse_buffer.push(a);this.mouse_buffer.push(b);4===this.mouse_id?(this.mouse_buffer.push(0|this.wheel_movement&15),this.wheel_movement=0):3===this.mouse_id&&(this.mouse_buffer.push(this.wheel_movement&255),this.wheel_movement=0);this.raise_irq()};
N.prototype.apply_scaling2=function(a){var b=a>>31;switch(Math.abs(a)){case 0:case 1:case 3:return a;case 2:return b;case 4:return 6*b;case 5:return 9*b;default:return a<<1}};
N.prototype.port60_read=function(){this.next_byte_is_ready=!1;if(!this.kbd_buffer.length&&!this.mouse_buffer.length)return this.last_port60_byte;this.next_byte_is_aux?(this.cpu.device_lower_irq(12),this.last_port60_byte=this.mouse_buffer.shift()):(this.cpu.device_lower_irq(1),this.last_port60_byte=this.kbd_buffer.shift());A(this.last_port60_byte);(this.kbd_buffer.length||this.mouse_buffer.length)&&this.raise_irq();return this.last_port60_byte};
N.prototype.port64_read=function(){var a=16;this.next_byte_is_ready&&(a|=1);this.next_byte_is_aux&&(a|=32);A(a);return a};
N.prototype.port60_write=function(a){A(a);if(this.read_command_register)this.command_register=a,this.read_command_register=!1,A(this.command_register);else if(this.read_output_register)this.read_output_register=!1,this.mouse_buffer.clear(),this.mouse_buffer.push(a),this.mouse_irq();else if(this.next_read_sample){this.next_read_sample=!1;this.mouse_buffer.clear();this.mouse_buffer.push(250);this.sample_rate=a;switch(this.mouse_detect_state){case -1:60===a?(this.mouse_reset_workaround=!0,this.mouse_detect_state=
0):(this.mouse_reset_workaround=!1,this.mouse_detect_state=200===a?1:0);break;case 0:200===a&&(this.mouse_detect_state=1);break;case 1:this.mouse_detect_state=100===a?2:200===a?3:0;break;case 2:80===a&&(this.mouse_id=3);this.mouse_detect_state=-1;break;case 3:80===a&&(this.mouse_id=4),this.mouse_detect_state=-1}A(a);A(this.mouse_id);this.sample_rate||(this.sample_rate=100);this.mouse_irq()}else if(this.next_read_resolution)this.next_read_resolution=!1,this.mouse_buffer.clear(),this.mouse_buffer.push(250),
this.resolution=3<a?4:1<<a,this.mouse_irq();else if(this.next_read_led)this.next_read_led=!1,this.kbd_buffer.push(250),this.kbd_irq();else if(this.next_handle_scan_code_set)this.next_handle_scan_code_set=!1,this.kbd_buffer.push(250),this.kbd_irq(),a||this.kbd_buffer.push(2);else if(this.next_read_rate)this.next_read_rate=!1,this.kbd_buffer.push(250),this.kbd_irq();else if(this.next_is_mouse_command){if(this.next_is_mouse_command=!1,A(a),this.have_mouse){this.kbd_buffer.clear();this.mouse_buffer.clear();
this.mouse_buffer.push(250);switch(a){case 230:this.scaling2=!1;break;case 231:this.scaling2=!0;break;case 232:this.next_read_resolution=!0;break;case 233:this.send_mouse_packet(0,0);break;case 235:this.send_mouse_packet(0,0);break;case 242:A(this.mouse_id);this.mouse_buffer.push(this.mouse_id);this.mouse_clicks=this.mouse_delta_x=this.mouse_delta_y=0;this.raise_irq();break;case 243:this.next_read_sample=!0;break;case 244:this.use_mouse=this.enable_mouse_stream=!0;this.bus.send("mouse-enable",!0);
this.mouse_clicks=this.mouse_delta_x=this.mouse_delta_y=0;break;case 245:this.enable_mouse_stream=!1;break;case 246:this.enable_mouse_stream=!1;this.sample_rate=100;this.scaling2=!1;this.resolution=4;break;case 255:this.mouse_buffer.push(170);this.mouse_buffer.push(0);this.use_mouse=!0;this.bus.send("mouse-enable",!0);this.enable_mouse_stream=!1;this.sample_rate=100;this.scaling2=!1;this.resolution=4;this.mouse_reset_workaround||(this.mouse_id=0);this.mouse_clicks=this.mouse_delta_x=this.mouse_delta_y=
0;break;default:A(a)}this.mouse_irq()}}else if(this.read_controller_output_port)this.read_controller_output_port=!1,this.controller_output_port=a;else{A(a);this.mouse_buffer.clear();this.kbd_buffer.clear();this.kbd_buffer.push(250);switch(a){case 237:this.next_read_led=!0;break;case 240:this.next_handle_scan_code_set=!0;break;case 242:this.kbd_buffer.push(171);this.kbd_buffer.push(83);break;case 243:this.next_read_rate=!0;break;case 244:this.enable_keyboard_stream=!0;break;case 245:this.enable_keyboard_stream=
!1;break;case 246:break;case 255:this.kbd_buffer.clear();this.kbd_buffer.push(250);this.kbd_buffer.push(170);this.kbd_buffer.push(0);break;default:A(a)}this.kbd_irq()}};
N.prototype.port64_write=function(a){A(a);switch(a){case 32:this.kbd_buffer.clear();this.mouse_buffer.clear();this.kbd_buffer.push(this.command_register);this.kbd_irq();break;case 96:this.read_command_register=!0;break;case 209:this.read_controller_output_port=!0;break;case 211:this.read_output_register=!0;break;case 212:this.next_is_mouse_command=!0;break;case 167:this.command_register|=32;break;case 168:this.command_register&=-33;break;case 169:this.kbd_buffer.clear();this.mouse_buffer.clear();
this.kbd_buffer.push(0);this.kbd_irq();break;case 170:this.kbd_buffer.clear();this.mouse_buffer.clear();this.kbd_buffer.push(85);this.kbd_irq();break;case 171:this.kbd_buffer.clear();this.mouse_buffer.clear();this.kbd_buffer.push(0);this.kbd_irq();break;case 173:this.command_register|=16;break;case 174:this.command_register&=-17;break;case 254:this.cpu.reboot_internal();break;default:A(a)}};function va(a){this.cpu=a;this.cmos_index=0;this.cmos_data=new Uint8Array(128);this.last_update=this.rtc_time=Date.now();this.next_interrupt_alarm=this.next_interrupt=0;this.periodic_interrupt=!1;this.periodic_interrupt_time=.9765625;this.cmos_a=38;this.cmos_b=2;this.nmi_disabled=this.cmos_c=0;a.io.register_write(112,this,function(b){this.cmos_index=b&127;this.nmi_disabled=b>>7});a.io.register_write(113,this,this.cmos_port_write);a.io.register_read(113,this,this.cmos_port_read)}
va.prototype.get_state=function(){var a=[];a[0]=this.cmos_index;a[1]=this.cmos_data;a[2]=this.rtc_time;a[3]=this.last_update;a[4]=this.next_interrupt;a[5]=this.next_interrupt_alarm;a[6]=this.periodic_interrupt;a[7]=this.periodic_interrupt_time;a[8]=this.cmos_a;a[9]=this.cmos_b;a[10]=this.cmos_c;a[11]=this.nmi_disabled;return a};
va.prototype.set_state=function(a){this.cmos_index=a[0];this.cmos_data=a[1];this.rtc_time=a[2];this.last_update=a[3];this.next_interrupt=a[4];this.next_interrupt_alarm=a[5];this.periodic_interrupt=a[6];this.periodic_interrupt_time=a[7];this.cmos_a=a[8];this.cmos_b=a[9];this.cmos_c=a[10];this.nmi_disabled=a[11]};
va.prototype.timer=function(a){a=Date.now();this.rtc_time+=a-this.last_update;this.last_update=a;this.periodic_interrupt&&this.next_interrupt<a?(this.cpu.device_raise_irq(8),this.cmos_c|=192,this.next_interrupt+=this.periodic_interrupt_time*Math.ceil((a-this.next_interrupt)/this.periodic_interrupt_time)):this.next_interrupt_alarm&&this.next_interrupt_alarm<a&&(this.cpu.device_raise_irq(8),this.cmos_c|=160,this.next_interrupt_alarm=0);let b=100;this.periodic_interrupt&&this.next_interrupt&&(b=Math.min(b,
Math.max(0,this.next_interrupt-a)));this.next_interrupt_alarm&&(b=Math.min(b,Math.max(0,this.next_interrupt_alarm-a)));return b};va.prototype.bcd_pack=function(a){for(var b=0,c=0,d;a;)d=a%10,c|=d<<4*b,b++,a=(a-d)/10;return c};va.prototype.bcd_unpack=function(a){return(a&15)+10*(a>>4&15)};va.prototype.encode_time=function(a){return this.cmos_b&4?a:this.bcd_pack(a)};va.prototype.decode_time=function(a){return this.cmos_b&4?a:this.bcd_unpack(a)};
va.prototype.cmos_port_read=function(){var a=this.cmos_index;switch(a){case 0:return this.encode_time((new Date(this.rtc_time)).getUTCSeconds());case 2:return this.encode_time((new Date(this.rtc_time)).getUTCMinutes());case 4:return this.encode_time((new Date(this.rtc_time)).getUTCHours());case 7:return this.encode_time((new Date(this.rtc_time)).getUTCDate());case 8:return this.encode_time((new Date(this.rtc_time)).getUTCMonth()+1);case 9:return this.encode_time((new Date(this.rtc_time)).getUTCFullYear()%
100);case 10:return 999<=D.microtick()%1E3?this.cmos_a|128:this.cmos_a;case 11:return this.cmos_b;case 12:return this.cpu.device_lower_irq(8),a=this.cmos_c,this.cmos_c&=-241,a;case 13:return 0;case 50:return this.encode_time((new Date(this.rtc_time)).getUTCFullYear()/100|0);default:return A(a),this.cmos_data[this.cmos_index]}};
va.prototype.cmos_port_write=function(a){switch(this.cmos_index){case 10:this.cmos_a=a&127;this.periodic_interrupt_time=1E3/(32768>>(this.cmos_a&15)-1);A(this.cmos_a,2);break;case 11:this.cmos_b=a;this.cmos_b&64&&(this.next_interrupt=Date.now());if(this.cmos_b&32){a=new Date;const b=this.decode_time(this.cmos_data[1]),c=this.decode_time(this.cmos_data[3]),d=this.decode_time(this.cmos_data[5]);this.next_interrupt_alarm=+new Date(Date.UTC(a.getUTCFullYear(),a.getUTCMonth(),a.getUTCDate(),d,c,b))}A(this.cmos_b,
2);break;case 1:case 3:case 5:this.cmos_write(this.cmos_index,a);break;default:A(this.cmos_index),A(a)}this.periodic_interrupt=64===(this.cmos_b&64)&&0<(this.cmos_a&15)};va.prototype.cmos_read=function(a){return this.cmos_data[a]};va.prototype.cmos_write=function(a,b){A(a);A(b);this.cmos_data[a]=b};function wa(a,b,c){this.bus=c;this.cpu=a;this.ints=4;this.line_control=this.baud_rate=0;this.lsr=96;this.ier=this.fifo_control=0;this.iir=1;this.irq=this.scratch_register=this.modem_status=this.modem_control=0;this.input=[];this.current_line="";switch(b){case 1016:this.com=0;this.irq=4;break;case 760:this.com=1;this.irq=3;break;case 1E3:this.com=2;this.irq=4;break;case 744:this.irq=this.com=3;break;default:J("Invalid serial port: "+A(b),16384),this.com=0,this.irq=4}this.bus.register("serial"+this.com+
"-input",function(d){this.data_received(d)},this);this.bus.register("serial"+this.com+"-modem-status-input",function(d){this.set_modem_status(d)},this);this.bus.register("serial"+this.com+"-carrier-detect-input",function(d){this.set_modem_status(d?this.modem_status|136:this.modem_status&-137)},this);this.bus.register("serial"+this.com+"-ring-indicator-input",function(d){this.set_modem_status(d?this.modem_status|68:this.modem_status&-69)},this);this.bus.register("serial"+this.com+"-data-set-ready-input",
function(d){this.set_modem_status(d?this.modem_status|34:this.modem_status&-35)},this);this.bus.register("serial"+this.com+"-clear-to-send-input",function(d){this.set_modem_status(d?this.modem_status|17:this.modem_status&-18)},this);a=a.io;a.register_write(b,this,function(d){this.write_data(d)},function(d){this.write_data(d&255);this.write_data(d>>8)});a.register_write(b|1,this,function(d){this.line_control&128?(this.baud_rate=this.baud_rate&255|d<<8,A(this.baud_rate)):(0===(this.ier&2)&&d&2&&this.ThrowInterrupt(2),
this.ier=d&15,A(d),this.CheckInterrupt())});a.register_read(b,this,function(){if(this.line_control&128)return this.baud_rate&255;let d=0;0!==this.input.length&&(d=this.input.shift(),A(d));0===this.input.length&&(this.lsr&=-2,this.ClearInterrupt(12),this.ClearInterrupt(4));return d});a.register_read(b|1,this,function(){return this.line_control&128?this.baud_rate>>8:this.ier&15});a.register_read(b|2,this,function(){var d=this.iir&15;A(this.iir);2==this.iir&&this.ClearInterrupt(2);this.fifo_control&
1&&(d|=192);return d});a.register_write(b|2,this,function(d){A(d);this.fifo_control=d});a.register_read(b|3,this,function(){A(this.line_control);return this.line_control});a.register_write(b|3,this,function(d){A(d);this.line_control=d});a.register_read(b|4,this,function(){return this.modem_control});a.register_write(b|4,this,function(d){A(d);this.modem_control=d});a.register_read(b|5,this,function(){A(this.lsr);return this.lsr});a.register_write(b|5,this,function(){});a.register_read(b|6,this,function(){A(this.modem_status);
return this.modem_status&=240});a.register_write(b|6,this,function(d){A(d);this.set_modem_status(d)});a.register_read(b|7,this,function(){return this.scratch_register});a.register_write(b|7,this,function(d){this.scratch_register=d})}wa.prototype.get_state=function(){var a=[];a[0]=this.ints;a[1]=this.baud_rate;a[2]=this.line_control;a[3]=this.lsr;a[4]=this.fifo_control;a[5]=this.ier;a[6]=this.iir;a[7]=this.modem_control;a[8]=this.modem_status;a[9]=this.scratch_register;a[10]=this.irq;return a};
wa.prototype.set_state=function(a){this.ints=a[0];this.baud_rate=a[1];this.line_control=a[2];this.lsr=a[3];this.fifo_control=a[4];this.ier=a[5];this.iir=a[6];this.modem_control=a[7];this.modem_status=a[8];this.scratch_register=a[9];this.irq=a[10]};
wa.prototype.CheckInterrupt=function(){this.ints&4096&&this.ier&1?(this.iir=12,this.cpu.device_raise_irq(this.irq)):this.ints&16&&this.ier&1?(this.iir=4,this.cpu.device_raise_irq(this.irq)):this.ints&4&&this.ier&2?(this.iir=2,this.cpu.device_raise_irq(this.irq)):this.ints&1&&this.ier&8?(this.iir=0,this.cpu.device_raise_irq(this.irq)):(this.iir=1,this.cpu.device_lower_irq(this.irq))};wa.prototype.ThrowInterrupt=function(a){this.ints|=1<<a;this.CheckInterrupt()};
wa.prototype.ClearInterrupt=function(a){this.ints&=~(1<<a);this.CheckInterrupt()};wa.prototype.data_received=function(a){A(a);this.input.push(a);this.lsr|=1;this.fifo_control&1?this.ThrowInterrupt(12):this.ThrowInterrupt(4)};wa.prototype.write_data=function(a){this.line_control&128?this.baud_rate=this.baud_rate&-256|a:(A(a),this.ThrowInterrupt(2),this.bus.send("serial"+this.com+"-output-byte",a))};
wa.prototype.set_modem_status=function(a){A(a);const b=this.modem_status&15;let c=(this.modem_status^a)>>4;this.modem_status=a;this.modem_status=this.modem_status|c|b};function xa(a){this.cpu=a;var b=a.io;a.devices.pci.register_device({pci_id:56,pci_space:[134,128,19,113,7,0,128,2,8,0,128,6,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,1,0,0],pci_bars:[],name:"acpi"});this.timer_imprecision_offset=this.timer_last_value=0;this.status=1;this.pm1_enable=this.pm1_status=0;this.last_timer=this.get_timer(D.microtick());this.gpe=new Uint8Array(4);b.register_read(45056,this,void 0,function(){return this.pm1_status});
b.register_write(45056,this,void 0,function(c){A(c,4);this.pm1_status&=~c});b.register_read(45058,this,void 0,function(){return this.pm1_enable});b.register_write(45058,this,void 0,function(c){A(c);this.pm1_enable=c});b.register_read(45060,this,void 0,function(){return this.status});b.register_write(45060,this,void 0,function(c){A(c);this.status=c});b.register_read(45064,this,void 0,void 0,function(){return this.get_timer(D.microtick())&16777215});b.register_read(45024,this,function(){return this.gpe[0]});
b.register_read(45025,this,function(){return this.gpe[1]});b.register_read(45026,this,function(){return this.gpe[2]});b.register_read(45027,this,function(){return this.gpe[3]});b.register_write(45024,this,function(c){A(c);this.gpe[0]=c});b.register_write(45025,this,function(c){A(c);this.gpe[1]=c});b.register_write(45026,this,function(c){A(c);this.gpe[2]=c});b.register_write(45027,this,function(c){A(c);this.gpe[3]=c})}
xa.prototype.timer=function(a){a=this.get_timer(a);var b=0!==((a^this.last_timer)&8388608);this.pm1_enable&1&&b?(this.pm1_status|=1,this.cpu.device_raise_irq(9)):this.cpu.device_lower_irq(9);this.last_timer=a;return 100};
xa.prototype.get_timer=function(a){a=Math.round(3579.545*a);a===this.timer_last_value?3579.545>this.timer_imprecision_offset&&this.timer_imprecision_offset++:this.timer_last_value+this.timer_imprecision_offset<=a&&(this.timer_imprecision_offset=0,this.timer_last_value=a);return this.timer_last_value+this.timer_imprecision_offset};xa.prototype.get_state=function(){var a=[];a[0]=this.status;a[1]=this.pm1_status;a[2]=this.pm1_enable;a[3]=this.gpe;return a};
xa.prototype.set_state=function(a){this.status=a[0];this.pm1_status=a[1];this.pm1_enable=a[2];this.gpe=a[3]};function O(a){this.cpu=a;this.timer_divider=this.apic_id=0;this.timer_divider_shift=1;this.timer_current_count=this.timer_initial_count=0;this.next_tick=D.microtick();this.lvt_error=this.lvt_int1=this.lvt_int0=this.lvt_perf_counter=this.lvt_timer=65536;this.icr1=this.icr0=this.tpr=0;this.irr=new Int32Array(8);this.isr=new Int32Array(8);this.tmr=new Int32Array(8);this.spurious_vector=254;this.destination_format=-1;this.read_error=this.error=this.local_destination=0;a.io.mmap_register(4276092928,1048576,
b=>{A(b>>>0);var c=b&3;return this.read32(b&-4)>>8*c&255},(b,c)=>{A(b);A(c)},b=>this.read32(b),(b,c)=>this.write32(b,c))}
O.prototype.read32=function(a){a=a-4276092928|0;switch(a){case 32:return this.apic_id;case 48:return 327700;case 128:return this.tpr;case 208:return this.local_destination;case 224:return this.destination_format;case 240:return this.spurious_vector;case 256:case 272:case 288:case 304:case 320:case 336:case 352:case 368:return a=a-256>>4,A(this.isr[a]>>>0,8),this.isr[a];case 384:case 400:case 416:case 432:case 448:case 464:case 480:case 496:return a=a-384>>4,A(this.tmr[a]>>>0,8),this.tmr[a];case 512:case 528:case 544:case 560:case 576:case 592:case 608:case 624:return a=
a-512>>4,A(this.irr[a]>>>0,8),this.irr[a];case 640:return A(this.read_error>>>0,8),this.read_error;case 768:return this.icr0;case 784:return this.icr1;case 800:return this.lvt_timer;case 832:return this.lvt_perf_counter;case 848:return this.lvt_int0;case 864:return this.lvt_int1;case 880:return this.lvt_error;case 992:return this.timer_divider;case 896:return this.timer_initial_count;case 912:return A(this.timer_current_count>>>0,8),this.timer_current_count;default:return A(a),0}};
O.prototype.write32=function(a,b){a=a-4276092928|0;switch(a){case 48:A(b>>>0,8);break;case 128:this.tpr=b&255;this.check_vector();break;case 176:b=this.highest_isr();-1!==b&&(this.register_clear_bit(this.isr,b),this.register_get_bit(this.tmr,b)&&this.cpu.devices.ioapic.remote_eoi(b),this.check_vector());break;case 208:A(b>>>0,8);this.local_destination=b&4278190080;break;case 224:A(b>>>0,8);this.destination_format=b|16777215;break;case 240:A(b>>>0,8);this.spurious_vector=b;break;case 640:A(b>>>0,8);
this.read_error=this.error;this.error=0;break;case 768:a=b&255;var c=b>>8&7,d=b>>11&1,e=b>>15&1,g=b>>18&3,f=this.icr1>>>24;A(b,8);A(a,2);this.icr0=b&-4097;0===g?this.route(a,c,e,f,d):1===g?this.deliver(a,0,e):2===g&&this.deliver(a,c,e);break;case 784:A(b>>>0,8);this.icr1=b;break;case 800:A(b>>>0,8);this.lvt_timer=b;break;case 832:A(b>>>0,8);this.lvt_perf_counter=b;break;case 848:A(b>>>0,8);this.lvt_int0=b;break;case 864:A(b>>>0,8);this.lvt_int1=b;break;case 880:A(b>>>0,8);this.lvt_error=b;break;case 992:A(b>>>
0,8);this.timer_divider=b;b=b&3|(b&8)>>1;this.timer_divider_shift=7===b?0:b+1;break;case 896:A(b>>>0,8);this.timer_initial_count=b>>>0;this.timer_current_count=b>>>0;this.next_tick=D.microtick();this.timer_active=!0;break;case 912:A(b>>>0,8);break;default:A(a),A(b>>>0,8)}};
O.prototype.timer=function(a){if(0===this.timer_current_count)return 100;const b=1E6/(1<<this.timer_divider_shift);a=(a-this.next_tick)*b>>>0;this.next_tick+=a/b;this.timer_current_count-=a;0>=this.timer_current_count&&(a=this.lvt_timer&393216,131072===a?(this.timer_current_count%=this.timer_initial_count,0>=this.timer_current_count&&(this.timer_current_count+=this.timer_initial_count),0===(this.lvt_timer&65536)&&this.deliver(this.lvt_timer&255,0,!1)):0===a&&(this.timer_current_count=0,0===(this.lvt_timer&
65536)&&this.deliver(this.lvt_timer&255,0,!1)));return Math.max(0,this.timer_current_count/b)};O.prototype.route=function(a,b,c){this.deliver(a,b,c)};O.prototype.deliver=function(a,b,c){5!==b&&4!==b&&(this.register_get_bit(this.irr,a)?A(a,2):(this.register_set_bit(this.irr,a),c?this.register_set_bit(this.tmr,a):this.register_clear_bit(this.tmr,a),this.check_vector()))};O.prototype.highest_irr=function(){return this.register_get_highest_bit(this.irr)};O.prototype.highest_isr=function(){return this.register_get_highest_bit(this.isr)};
O.prototype.check_vector=function(){var a=this.highest_irr();-1!==a&&(this.highest_isr()>=a||(a&240)<=(this.tpr&240)||this.cpu.handle_irqs())};O.prototype.acknowledge_irq=function(){var a=this.highest_irr();if(-1===a||this.highest_isr()>=a||(a&240)<=(this.tpr&240))return-1;this.register_clear_bit(this.irr,a);this.register_set_bit(this.isr,a);this.check_vector();return a};
O.prototype.get_state=function(){var a=[];a[0]=this.apic_id;a[1]=this.timer_divider;a[2]=this.timer_divider_shift;a[3]=this.timer_initial_count;a[4]=this.timer_current_count;a[5]=this.next_tick;a[6]=this.lvt_timer;a[7]=this.lvt_perf_counter;a[8]=this.lvt_int0;a[9]=this.lvt_int1;a[10]=this.lvt_error;a[11]=this.tpr;a[12]=this.icr0;a[13]=this.icr1;a[14]=this.irr;a[15]=this.isr;a[16]=this.tmr;a[17]=this.spurious_vector;a[18]=this.destination_format;a[19]=this.local_destination;a[20]=this.error;a[21]=
this.read_error;return a};
O.prototype.set_state=function(a){this.apic_id=a[0];this.timer_divider=a[1];this.timer_divider_shift=a[2];this.timer_initial_count=a[3];this.timer_current_count=a[4];this.next_tick=a[5];this.lvt_timer=a[6];this.lvt_perf_counter=a[7];this.lvt_int0=a[8];this.lvt_int1=a[9];this.lvt_error=a[10];this.tpr=a[11];this.icr0=a[12];this.icr1=a[13];this.irr=a[14];this.isr=a[15];this.tmr=a[16];this.spurious_vector=a[17];this.destination_format=a[18];this.local_destination=a[19];this.error=a[20];this.read_error=
a[21]};O.prototype.register_get_bit=function(a,b){return a[b>>5]>>(b&31)&1};O.prototype.register_set_bit=function(a,b){a[b>>5]|=1<<(b&31)};O.prototype.register_clear_bit=function(a,b){a[b>>5]&=~(1<<(b&31))};O.prototype.register_get_highest_bit=function(a){for(var b=7;0<=b;b--){var c=a[b];if(c)return r.int_log2(c>>>0)|b<<5}return-1};function ya(a){this.cpu=a;this.ioredtbl_config=new Int32Array(24);this.ioredtbl_destination=new Int32Array(24);for(var b=0;b<this.ioredtbl_config.length;b++)this.ioredtbl_config[b]=65536;this.irq_value=this.irr=this.ioapic_id=this.ioregsel=0;a.io.mmap_register(4273995776,131072,c=>{c=c-4273995776|0;if(16<=c&&20>c)return c-=16,A(this.ioregsel),this.read(this.ioregsel)>>8*c&255;A(c>>>0);return 0},c=>{A(c>>>0)},c=>{c=c-4273995776|0;if(0===c)return this.ioregsel;if(16===c)return this.read(this.ioregsel);
A(c>>>0);return 0},(c,d)=>{c=c-4273995776|0;0===c?this.ioregsel=d:16===c?this.write(this.ioregsel,d):(A(c>>>0),A(d>>>0,8))})}ya.prototype.remote_eoi=function(a){for(var b=0;24>b;b++){var c=this.ioredtbl_config[b];(c&255)===a&&c&16384&&(A(b),this.ioredtbl_config[b]&=-16385,this.check_irq(b))}};
ya.prototype.check_irq=function(a){var b=1<<a;if(0!==(this.irr&b)){var c=this.ioredtbl_config[a];if(0===(c&65536)){var d=c>>8&7,e=this.ioredtbl_destination[a]>>>24;if(0===(c&32768))this.irr&=~b;else if(this.ioredtbl_config[a]|=16384,c&16384)return;0!==d&&1!==d||this.cpu.devices.apic.route(c&255,d,32768===(c&32768),e,c>>11&1);this.ioredtbl_config[a]&=-4097}}};
ya.prototype.set_irq=function(a){if(!(24<=a)){var b=1<<a;0===(this.irq_value&b)&&(this.irq_value|=b,65536!==(this.ioredtbl_config[a]&98304)&&(this.irr|=b,this.check_irq(a)))}};ya.prototype.clear_irq=function(a){if(!(24<=a)){var b=1<<a;(this.irq_value&b)===b&&(this.irq_value&=~b,this.ioredtbl_config[a]&32768&&(this.irr&=~b))}};
ya.prototype.read=function(a){if(0===a)return this.ioapic_id<<24;if(1===a)return 1507345;if(2===a)return this.ioapic_id<<24;if(16<=a&&64>a){var b=a-16>>1;a=a&1?this.ioredtbl_destination[b]:this.ioredtbl_config[b];A(b);A(a,8);return a}A(a);return 0};
ya.prototype.write=function(a,b){if(0===a)this.ioapic_id=b>>>24&15;else if(1!==a&&2!==a)if(16<=a&&64>a){var c=a-16>>1;a&1?(this.ioredtbl_destination[c]=b&4278190080,A(b>>>0,8),A(c),A(b>>>24,2)):(this.ioredtbl_config[c]=b&110591|this.ioredtbl_config[c]&-110592,a=b&255,A(b>>>0,8),A(c),A(a,2),this.check_irq(c))}else A(a),A(b>>>0,8)};
ya.prototype.get_state=function(){var a=[];a[0]=this.ioredtbl_config;a[1]=this.ioredtbl_destination;a[2]=this.ioregsel;a[3]=this.ioapic_id;a[4]=this.irr;a[5]=this.irq_value;return a};ya.prototype.set_state=function(a){this.ioredtbl_config=a[0];this.ioredtbl_destination=a[1];this.ioregsel=a[2];this.ioapic_id=a[3];this.irr=a[4];this.irq_value=a[5]};function za(a){this.message=a}za.prototype=Error();const Aa={Uint8Array,Int8Array,Uint16Array,Int16Array,Uint32Array,Int32Array,Float32Array,Float64Array};
function Ba(a,b){if("object"!==typeof a||null===a)return a;if(a instanceof Array)return a.map(e=>Ba(e,b));a.constructor===Object&&console.log(a);if(a.BYTES_PER_ELEMENT){var c=new Uint8Array(a.buffer,a.byteOffset,a.length*a.BYTES_PER_ELEMENT);return{__state_type__:a.constructor.name.replace("bound ",""),buffer_id:b.push(c)-1}}a=a.get_state();c=[];for(var d=0;d<a.length;d++)c[d]=Ba(a[d],b);return c}
function Ca(a,b){if("object"!==typeof a||null===a)return a;if(a instanceof Array){for(let c=0;c<a.length;c++)a[c]=Ca(a[c],b);return a}return new Aa[a.__state_type__](b[a.buffer_id])}
E.prototype.save_state=function(){for(var a=[],b=Ba(this,a),c=[],d=0,e=0;e<a.length;e++){var g=a[e].byteLength;c[e]={offset:d,length:g};d+=g;d=d+3&-4}e=JSON.stringify({buffer_infos:c,state:b});e=(new TextEncoder).encode(e);b=16+e.length;b=b+3&-4;g=b+d;d=new ArrayBuffer(g);var f=new Int32Array(d,0,4);(new Uint8Array(d,16,e.length)).set(e);b=new Uint8Array(d,b);f[0]=-2039052682;f[1]=6;f[2]=g;f[3]=e.length;for(e=0;e<a.length;e++)b.set(a[e],c[e].offset);return d};
E.prototype.restore_state=function(a){function b(p,t){const q=p.length;if(16>q)throw new za("Invalid length: "+q);p=new Int32Array(p.buffer,p.byteOffset,4);if(-2039052682!==p[0])throw new za("Invalid header: "+A(p[0]>>>0));if(6!==p[1])throw new za("Version mismatch: dump="+p[1]+" we=6");if(t&&p[2]!==q)throw new za("Length doesn't match header: real="+q+" header="+p[2]);return p[3]}function c(p){p=(new TextDecoder).decode(p);return JSON.parse(p)}a=new Uint8Array(a);if(4247762216===(new Uint32Array(a.buffer,
0,1))[0]){var d=this.zstd_create_ctx(a.length);(new Uint8Array(this.wasm_memory.buffer,this.zstd_get_src_ptr(d),a.length)).set(a);var e=this.zstd_read(d,16),g=new Uint8Array(this.wasm_memory.buffer,e,16),f=b(g,!1);this.zstd_read_free(e,16);e=this.zstd_read(d,f);g=new Uint8Array(this.wasm_memory.buffer,e,f);g=c(g);this.zstd_read_free(e,f);e=g.state;var k=g.buffer_infos;g=[];f=16+f;for(var l of k){k=(f+3&-4)-f;if(1048576<l.length){var m=this.zstd_read(d,k);this.zstd_read_free(m,k);m=new Uint8Array(l.length);
g.push(m.buffer);for(var n=0;n<l.length;){const p=Math.min(l.length-n,1048576),t=this.zstd_read(d,p);m.set(new Uint8Array(this.wasm_memory.buffer,t,p),n);this.zstd_read_free(t,p);n+=p}}else m=this.zstd_read(d,k+l.length),n=m+k,g.push(this.wasm_memory.buffer.slice(n,n+l.length)),this.zstd_read_free(m,k+l.length);f+=k+l.length}e=Ca(e,g);this.set_state(e);this.zstd_free_ctx(d)}else{d=b(a,!0);if(0>d||d+12>=a.length)throw new za("Invalid info block length: "+d);l=a.subarray(16,16+d);e=c(l);l=e.state;e=
e.buffer_infos;let p=16+d;p=p+3&-4;d=e.map(t=>{const q=p+t.offset;return a.buffer.slice(q,q+t.length)});l=Ca(l,d);this.set_state(l)}};function Da(a,b,c){a[0]===b[0]&&a[1]===b[1]&&a[2]===b[2]&&a[3]===b[3]&&a[4]===b[4]&&a[5]===b[5]&&(a[0]=c[0],a[1]=c[1],a[2]=c[2],a[3]=c[3],a[4]=c[4],a[5]=c[5]);a[6]===b[0]&&a[7]===b[1]&&a[8]===b[2]&&a[9]===b[3]&&a[10]===b[4]&&a[11]===b[5]&&(a[6]=c[0],a[7]=c[1],a[8]=c[2],a[9]=c[3],a[10]=c[4],a[11]=c[5]);var d=a[12]<<8|a[13];if(2048===d){if(a=a.subarray(14),4===a[0]>>4&&17===a[9]){a=a.subarray(20);d=a[0]<<8|a[1];var e=a[2]<<8|a[3];A(a[6]<<8|a[7],4);if(67===d||67===e)if(d=a.subarray(8),e=d[236]<<24|d[237]<<
16|d[238]<<8|d[239],1669485411!==e)A(e,8);else for(d[28]===b[0]&&d[29]===b[1]&&d[30]===b[2]&&d[31]===b[3]&&d[32]===b[4]&&d[33]===b[5]&&(d[28]=c[0],d[29]=c[1],d[30]=c[2],d[31]=c[3],d[32]=c[4],d[33]=c[5],a[6]=a[7]=0),e=240;e<d.length;){const g=d[e++];if(255===g)break;const f=d[e++];61===g&&1===d[e+0]&&d[e+1]===b[0]&&d[e+2]===b[1]&&d[e+3]===b[2]&&d[e+4]===b[3]&&d[e+5]===b[4]&&d[e+6]===b[5]&&(d[e+1]=c[0],d[e+2]=c[1],d[e+3]=c[2],d[e+4]=c[3],d[e+5]=c[4],d[e+6]=c[5],a[6]=a[7]=0);e+=f}}}else 2054===d&&(a=
a.subarray(14),Ea(a.subarray(8,14)),Ea(a.subarray(18,24)),a[8]===b[0]&&a[9]===b[1]&&a[10]===b[2]&&a[11]===b[3]&&a[12]===b[4]&&a[13]===b[5]&&(a[8]=c[0],a[9]=c[1],a[10]=c[2],a[11]=c[3],a[12]=c[4],a[13]=c[5]))}function Ea(a){return[a[0].toString(16).padStart(2,"0"),a[1].toString(16).padStart(2,"0"),a[2].toString(16).padStart(2,"0"),a[3].toString(16).padStart(2,"0"),a[4].toString(16).padStart(2,"0"),a[5].toString(16).padStart(2,"0")].join(":")}
function Fa(a,b,c,d){this.cpu=a;this.pci=a.devices.pci;this.preserve_mac_from_state_image=c;this.mac_address_translation=d;this.bus=b;this.bus.register("net0-receive",function(e){this.receive(e)},this);this.port=768;this.name="ne2k";this.pci_space=[236,16,41,128,3,1,0,0,0,0,0,2,0,0,0,0,this.port&255|1,this.port>>8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,244,26,0,17,0,0,184,254,0,0,0,0,0,0,0,0,0,1,0,0];this.pci_id=40;this.pci_bars=[{size:32}];this.imr=this.isr=0;this.cr=1;this.tpsr=this.tcnt=
this.rcnt=this.dcfg=0;this.memory=new Uint8Array(32768);this.txcr=this.rxcr=0;this.tsr=1;this.mac=new Uint8Array([0,34,21,255*Math.random()|0,255*Math.random()|0,255*Math.random()|0]);this.mar=Uint8Array.of(255,255,255,255,255,255,255,255);this.mac_address_in_state=null;for(b=0;6>b;b++)this.memory[b<<1]=this.memory[b<<1|1]=this.mac[b];this.memory[28]=this.memory[29]=87;this.memory[30]=this.memory[31]=87;J("Mac: "+Ea(this.mac),1048576);this.rsar=0;this.pstart=64;this.pstop=128;this.boundary=this.curpg=
76;b=a.io;b.register_read(this.port|0,this,function(){return this.cr});b.register_write(this.port|0,this,function(e){this.cr=e;A(e,2);A(this.txcr,2);this.cr&1||(e&24&&0===this.rcnt&&this.do_interrupt(64),e&4&&(e=this.tpsr<<8,e=this.memory.subarray(e,e+this.tcnt),this.mac_address_in_state&&(e=new Uint8Array(e),Da(e,this.mac_address_in_state,this.mac)),this.bus.send("net0-send",e),this.bus.send("eth-transmit-end",[e.length]),this.cr&=-5,this.do_interrupt(2),A(e.byteLength)))});b.register_read(this.port|
13,this,function(){return 1===this.get_page()?this.mar[5]:0});b.register_read(this.port|14,this,function(){return 1===this.get_page()?this.mar[6]:0},function(){this.get_page();return 0});b.register_read(this.port|15,this,function(){return 1===this.get_page()?this.mar[7]:0});b.register_read(this.port|31,this,function(){this.get_page();this.do_interrupt(128);return 0});b.register_write(this.port|31,this,function(e){this.get_page();A(e,2)});b.register_read(this.port|1,this,function(){var e=this.get_page();
return 0===e?this.pstart:1===e?this.mac[0]:2===e?this.pstart:0});b.register_write(this.port|1,this,function(e){var g=this.get_page();0===g?(A(e,2),this.pstart=e):1===g?(A(e),this.mac[0]=e):A(e)});b.register_read(this.port|2,this,function(){var e=this.get_page();return 0===e?this.pstop:1===e?this.mac[1]:2===e?this.pstop:0});b.register_write(this.port|2,this,function(e){var g=this.get_page();0===g?(A(e,2),e>this.memory.length>>8&&(e=this.memory.length>>8,A(e)),this.pstop=e):1===g?(A(e),this.mac[1]=
e):A(e)});b.register_read(this.port|7,this,function(){var e=this.get_page();return 0===e?(A(this.isr,2),this.isr):1===e?(A(this.curpg,2),this.curpg):0});b.register_write(this.port|7,this,function(e){var g=this.get_page();0===g?(A(e,2),this.isr&=~e,this.update_irq()):1===g&&(A(e,2),this.curpg=e)});b.register_write(this.port|13,this,function(e){0===this.get_page()&&(this.txcr=e);A(e,2)});b.register_write(this.port|14,this,function(e){0===this.get_page()?(A(e,2),this.dcfg=e):A(e,2)});b.register_read(this.port|
10,this,function(){var e=this.get_page();return 0===e?80:1===e?this.mar[2]:0});b.register_write(this.port|10,this,function(e){0===this.get_page()?(A(e,2),this.rcnt=this.rcnt&65280|e&255):A(e,2)});b.register_read(this.port|11,this,function(){var e=this.get_page();return 0===e?67:1===e?this.mar[3]:0});b.register_write(this.port|11,this,function(e){0===this.get_page()?(A(e,2),this.rcnt=this.rcnt&255|e<<8&65280):A(e,2)});b.register_read(this.port|8,this,function(){var e=this.get_page();return 0===e?this.rsar&
255:1===e?this.mar[0]:0});b.register_write(this.port|8,this,function(e){0===this.get_page()?(A(e,2),this.rsar=this.rsar&65280|e&255):A(e,2)});b.register_read(this.port|9,this,function(){var e=this.get_page();return 0===e?this.rsar>>8&255:1===e?this.mar[1]:0});b.register_write(this.port|9,this,function(e){0===this.get_page()?(A(e,2),this.rsar=this.rsar&255|e<<8&65280):A(e,2)});b.register_write(this.port|15,this,function(e){0===this.get_page()?(A(e,2),A(this.isr,2),this.imr=e,this.update_irq()):A(e,
2)});b.register_read(this.port|3,this,function(){var e=this.get_page();return 0===e?(A(this.boundary,2),this.boundary):1===e?this.mac[2]:0});b.register_write(this.port|3,this,function(e){var g=this.get_page();0===g?(A(e,2),this.boundary=e):1===g?(A(e),this.mac[2]=e):A(e)});b.register_read(this.port|4,this,function(){var e=this.get_page();return 0===e?this.tsr:1===e?this.mac[3]:0});b.register_write(this.port|4,this,function(e){var g=this.get_page();0===g?(A(e,2),this.tpsr=e):1===g?(A(e),this.mac[3]=
e):A(e)});b.register_read(this.port|5,this,function(){var e=this.get_page();return 0===e?0:1===e?this.mac[4]:0});b.register_write(this.port|5,this,function(e){var g=this.get_page();0===g?(A(e,2),this.tcnt=this.tcnt&-256|e):1===g?(A(e),this.mac[4]=e):A(e)});b.register_read(this.port|6,this,function(){var e=this.get_page();return 0===e?0:1===e?this.mac[5]:0});b.register_write(this.port|6,this,function(e){var g=this.get_page();0===g?(A(e,2),this.tcnt=this.tcnt&255|e<<8):1===g?(A(e),this.mac[5]=e):A(e)});
b.register_read(this.port|12,this,function(){var e=this.get_page();return 0===e?9:1===e?this.mar[4]:0});b.register_write(this.port|12,this,function(e){0===this.get_page()?(A(e,2),this.rxcr=e):A(e)});b.register_read(this.port|16,this,this.data_port_read8,this.data_port_read16,this.data_port_read32);b.register_write(this.port|16,this,this.data_port_write16,this.data_port_write16,this.data_port_write32);a.devices.pci.register_device(this)}
Fa.prototype.get_state=function(){var a=[];a[0]=this.isr;a[1]=this.imr;a[2]=this.cr;a[3]=this.dcfg;a[4]=this.rcnt;a[5]=this.tcnt;a[6]=this.tpsr;a[7]=this.rsar;a[8]=this.pstart;a[9]=this.curpg;a[10]=this.boundary;a[11]=this.pstop;a[12]=this.rxcr;a[13]=this.txcr;a[14]=this.tsr;a[15]=this.mac;a[16]=this.memory;return a};
Fa.prototype.set_state=function(a){this.isr=a[0];this.imr=a[1];this.cr=a[2];this.dcfg=a[3];this.rcnt=a[4];this.tcnt=a[5];this.tpsr=a[6];this.rsar=a[7];this.pstart=a[8];this.curpg=a[9];this.boundary=a[10];this.pstop=a[11];this.rxcr=a[12];this.txcr=a[13];this.tsr=a[14];this.preserve_mac_from_state_image?(this.mac=a[15],this.memory=a[16]):this.mac_address_translation&&(this.mac_address_in_state=a[15],this.memory=a[16],Ea(this.mac_address_in_state),Ea(this.mac))};
Fa.prototype.do_interrupt=function(a){A(a,2);this.isr|=a;this.update_irq()};Fa.prototype.update_irq=function(){this.imr&this.isr?this.pci.raise_irq(this.pci_id):this.pci.lower_irq(this.pci_id)};Fa.prototype.data_port_write=function(a){if(16>=this.rsar||16384<=this.rsar&&32768>this.rsar)this.memory[this.rsar]=a;this.rsar++;this.rcnt--;this.rsar>=this.pstop<<8&&(this.rsar+=this.pstart-this.pstop<<8);0===this.rcnt&&this.do_interrupt(64)};
Fa.prototype.data_port_write16=function(a){this.data_port_write(a);this.dcfg&1&&this.data_port_write(a>>8)};Fa.prototype.data_port_write32=function(a){this.data_port_write(a);this.data_port_write(a>>8);this.data_port_write(a>>16);this.data_port_write(a>>24)};Fa.prototype.data_port_read=function(){let a=0;32768>this.rsar&&(a=this.memory[this.rsar]);this.rsar++;this.rcnt--;this.rsar>=this.pstop<<8&&(this.rsar+=this.pstart-this.pstop<<8);0===this.rcnt&&this.do_interrupt(64);return a};
Fa.prototype.data_port_read8=function(){return this.data_port_read16()&255};Fa.prototype.data_port_read16=function(){return this.dcfg&1?this.data_port_read()|this.data_port_read()<<8:this.data_port_read()};Fa.prototype.data_port_read32=function(){return this.data_port_read()|this.data_port_read()<<8|this.data_port_read()<<16|this.data_port_read()<<24};
Fa.prototype.receive=function(a){if(!(this.cr&1)&&(this.bus.send("eth-receive-end",[a.length]),this.rxcr&16||this.rxcr&4&&255===a[0]&&255===a[1]&&255===a[2]&&255===a[3]&&255===a[4]&&255===a[5]||!(this.rxcr&8&&1===(a[0]&1)||a[0]!==this.mac[0]||a[1]!==this.mac[1]||a[2]!==this.mac[2]||a[3]!==this.mac[3]||a[4]!==this.mac[4]||a[5]!==this.mac[5]))){this.mac_address_in_state&&(a=new Uint8Array(a),Da(a,this.mac,this.mac_address_in_state));var b=this.curpg<<8,c=Math.max(60,a.length)+4,d=b+4,e=this.curpg+1+
(c>>8),g=b+c,f=1+(c>>8),k=this.boundary>this.curpg?this.boundary-this.curpg:this.pstop-this.curpg+this.boundary-this.pstart;k<f&&0!==this.boundary?(A(this.pstart),A(this.pstop),A(this.curpg),A(f),A(this.boundary),A(k)):(g>this.pstop<<8?(g=(this.pstop<<8)-d,this.memory.set(a.subarray(0,g),d),this.memory.set(a.subarray(g),this.pstart<<8),A(g)):(this.memory.set(a,d),60>a.length&&this.memory.fill(0,d+a.length,d+60)),e>=this.pstop&&(e+=this.pstart-this.pstop),this.memory[b]=1,this.memory[b+1]=e,this.memory[b+
2]=c,this.memory[b+3]=c>>8,this.curpg=e,A(b),A(c),A(e),this.do_interrupt(1))}};Fa.prototype.get_page=function(){return this.cr>>6&3};var Ga=new Uint8Array(256),Ha=[],Ia=[],Ja=[],Ka=new Uint8Array(256),La=[];
function Q(a,b){this.cpu=a;this.bus=b;this.write_buffer=new ka(64);this.read_buffer=new ka(64);this.mixer_current_address=this.command_size=this.command=this.read_buffer_lastvalue=0;this.mixer_registers=new Uint8Array(256);this.mixer_reset();this.dummy_speaker_enabled=!1;this.test_register=0;this.dsp_signed=this.dsp_16bit=this.dsp_stereo=this.dsp_highspeed=!1;this.dac_buffers=[new la(65536),new la(65536)];this.dma=a.devices.dma;this.dma_channel=this.dma_irq=this.dma_bytes_block=this.dma_bytes_left=
this.dma_bytes_count=this.dma_sample_count=0;this.dma_channel_8bit=1;this.dma_channel_16bit=5;this.dma_autoinit=!1;this.dma_buffer=new ArrayBuffer(65536);this.dma_buffer_int8=new Int8Array(this.dma_buffer);this.dma_buffer_uint8=new Uint8Array(this.dma_buffer);this.dma_buffer_int16=new Int16Array(this.dma_buffer);this.dma_buffer_uint16=new Uint16Array(this.dma_buffer);this.dma_syncbuffer=new r.SyncBuffer(this.dma_buffer);this.dma_paused=this.dma_waiting_transfer=!1;this.sampling_rate=22050;b.send("dac-tell-sampling-rate",
this.sampling_rate);this.bytes_per_sample=1;this.e2_value=170;this.e2_count=0;this.asp_registers=new Uint8Array(256);this.mpu_read_buffer=new ka(64);this.fm_current_address1=this.fm_current_address0=this.mpu_read_buffer_lastvalue=0;this.fm_waveform_select_enable=!1;this.irq=5;this.irq_triggered=new Uint8Array(16);a.io.register_read_consecutive(544,this,this.port2x0_read,this.port2x1_read,this.port2x2_read,this.port2x3_read);a.io.register_read_consecutive(904,this,this.port2x0_read,this.port2x1_read);
a.io.register_read_consecutive(548,this,this.port2x4_read,this.port2x5_read);a.io.register_read(550,this,this.port2x6_read);a.io.register_read(551,this,this.port2x7_read);a.io.register_read(552,this,this.port2x8_read);a.io.register_read(553,this,this.port2x9_read);a.io.register_read(554,this,this.port2xA_read);a.io.register_read(555,this,this.port2xB_read);a.io.register_read(556,this,this.port2xC_read);a.io.register_read(557,this,this.port2xD_read);a.io.register_read_consecutive(558,this,this.port2xE_read,
this.port2xF_read);a.io.register_write_consecutive(544,this,this.port2x0_write,this.port2x1_write,this.port2x2_write,this.port2x3_write);a.io.register_write_consecutive(904,this,this.port2x0_write,this.port2x1_write);a.io.register_write_consecutive(548,this,this.port2x4_write,this.port2x5_write);a.io.register_write(550,this,this.port2x6_write);a.io.register_write(551,this,this.port2x7_write);a.io.register_write_consecutive(552,this,this.port2x8_write,this.port2x9_write);a.io.register_write(554,this,
this.port2xA_write);a.io.register_write(555,this,this.port2xB_write);a.io.register_write(556,this,this.port2xC_write);a.io.register_write(557,this,this.port2xD_write);a.io.register_write(558,this,this.port2xE_write);a.io.register_write(559,this,this.port2xF_write);a.io.register_read_consecutive(816,this,this.port3x0_read,this.port3x1_read);a.io.register_write_consecutive(816,this,this.port3x0_write,this.port3x1_write);this.dma.on_unmask(this.dma_on_unmask,this);b.register("dac-request-data",function(){this.dac_handle_request()},
this);b.register("speaker-has-initialized",function(){this.mixer_reset()},this);b.send("speaker-confirm-initialized");this.dsp_reset()}
Q.prototype.dsp_reset=function(){this.write_buffer.clear();this.read_buffer.clear();this.command_size=this.command=0;this.dummy_speaker_enabled=!1;this.test_register=0;this.dsp_signed=this.dsp_16bit=this.dsp_stereo=this.dsp_highspeed=!1;this.dac_buffers[0].clear();this.dac_buffers[1].clear();this.dma_channel=this.dma_irq=this.dma_bytes_block=this.dma_bytes_left=this.dma_bytes_count=this.dma_sample_count=0;this.dma_autoinit=!1;this.dma_buffer_uint8.fill(0);this.dma_paused=this.dma_waiting_transfer=
!1;this.e2_value=170;this.e2_count=0;this.sampling_rate=22050;this.bytes_per_sample=1;this.lower_irq(1);this.irq_triggered.fill(0);this.asp_registers.fill(0);this.asp_registers[5]=1;this.asp_registers[9]=248};
Q.prototype.get_state=function(){var a=[];a[2]=this.read_buffer_lastvalue;a[3]=this.command;a[4]=this.command_size;a[5]=this.mixer_current_address;a[6]=this.mixer_registers;a[7]=this.dummy_speaker_enabled;a[8]=this.test_register;a[9]=this.dsp_highspeed;a[10]=this.dsp_stereo;a[11]=this.dsp_16bit;a[12]=this.dsp_signed;a[15]=this.dma_sample_count;a[16]=this.dma_bytes_count;a[17]=this.dma_bytes_left;a[18]=this.dma_bytes_block;a[19]=this.dma_irq;a[20]=this.dma_channel;a[21]=this.dma_channel_8bit;a[22]=
this.dma_channel_16bit;a[23]=this.dma_autoinit;a[24]=this.dma_buffer_uint8;a[25]=this.dma_waiting_transfer;a[26]=this.dma_paused;a[27]=this.sampling_rate;a[28]=this.bytes_per_sample;a[29]=this.e2_value;a[30]=this.e2_count;a[31]=this.asp_registers;a[33]=this.mpu_read_buffer_last_value;a[34]=this.irq;a[35]=this.irq_triggered;return a};
Q.prototype.set_state=function(a){this.read_buffer_lastvalue=a[2];this.command=a[3];this.command_size=a[4];this.mixer_current_address=a[5];this.mixer_registers=a[6];this.mixer_full_update();this.dummy_speaker_enabled=a[7];this.test_register=a[8];this.dsp_highspeed=a[9];this.dsp_stereo=a[10];this.dsp_16bit=a[11];this.dsp_signed=a[12];this.dma_sample_count=a[15];this.dma_bytes_count=a[16];this.dma_bytes_left=a[17];this.dma_bytes_block=a[18];this.dma_irq=a[19];this.dma_channel=a[20];this.dma_channel_8bit=
a[21];this.dma_channel_16bit=a[22];this.dma_autoinit=a[23];this.dma_buffer_uint8=a[24];this.dma_waiting_transfer=a[25];this.dma_paused=a[26];this.sampling_rate=a[27];this.bytes_per_sample=a[28];this.e2_value=a[29];this.e2_count=a[30];this.asp_registers=a[31];this.mpu_read_buffer_last_value=a[33];this.irq=a[34];this.irq_triggered=a[35];this.dma_buffer=this.dma_buffer_uint8.buffer;this.dma_buffer_int8=new Int8Array(this.dma_buffer);this.dma_buffer_int16=new Int16Array(this.dma_buffer);this.dma_buffer_uint16=
new Uint16Array(this.dma_buffer);this.dma_syncbuffer=new r.SyncBuffer(this.dma_buffer);this.dma_paused?this.bus.send("dac-disable"):this.bus.send("dac-enable")};Q.prototype.port2x0_read=function(){return 255};Q.prototype.port2x1_read=function(){return 255};Q.prototype.port2x2_read=function(){return 255};Q.prototype.port2x3_read=function(){return 255};Q.prototype.port2x4_read=function(){return this.mixer_current_address};Q.prototype.port2x5_read=function(){return this.mixer_read(this.mixer_current_address)};
Q.prototype.port2x6_read=function(){return 255};Q.prototype.port2x7_read=function(){return 255};Q.prototype.port2x8_read=function(){return 255};Q.prototype.port2x9_read=function(){return 255};Q.prototype.port2xA_read=function(){this.read_buffer.length&&(this.read_buffer_lastvalue=this.read_buffer.shift());A(this.read_buffer_lastvalue);String.fromCharCode(this.read_buffer_lastvalue);return this.read_buffer_lastvalue};Q.prototype.port2xB_read=function(){return 255};Q.prototype.port2xC_read=function(){return 127};
Q.prototype.port2xD_read=function(){return 255};Q.prototype.port2xE_read=function(){this.irq_triggered[1]&&this.lower_irq(1);return(this.read_buffer.length&&!this.dsp_highspeed)<<7|127};Q.prototype.port2xF_read=function(){this.lower_irq(2);return 0};Q.prototype.port2x0_write=function(a){A(a);this.fm_current_address0=0};Q.prototype.port2x1_write=function(a){A(a);var b=La[this.fm_current_address0];b||(b=this.fm_default_write);b.call(this,a,0,this.fm_current_address0)};
Q.prototype.port2x2_write=function(a){A(a);this.fm_current_address1=0};Q.prototype.port2x3_write=function(a){A(a);var b=La[this.fm_current_address1];b||(b=this.fm_default_write);b.call(this,a,1,this.fm_current_address1)};Q.prototype.port2x4_write=function(a){A(a);this.mixer_current_address=a};Q.prototype.port2x5_write=function(a){A(a);this.mixer_write(this.mixer_current_address,a)};
Q.prototype.port2x6_write=function(a){A(a);this.dsp_highspeed?this.dsp_highspeed=!1:a&&this.dsp_reset();this.read_buffer.clear();this.read_buffer.push(170)};Q.prototype.port2x7_write=function(){};Q.prototype.port2x8_write=function(){};Q.prototype.port2x9_write=function(){};Q.prototype.port2xA_write=function(){};Q.prototype.port2xB_write=function(){};
Q.prototype.port2xC_write=function(a){0===this.command?(A(a),this.command=a,this.write_buffer.clear(),this.command_size=Ga[a]):(A(a),this.write_buffer.push(a));this.write_buffer.length>=this.command_size&&this.command_do()};Q.prototype.port2xD_write=function(){};Q.prototype.port2xE_write=function(){};Q.prototype.port2xF_write=function(){};
Q.prototype.port3x0_read=function(){this.mpu_read_buffer.length&&(this.mpu_read_buffer_lastvalue=this.mpu_read_buffer.shift());A(this.mpu_read_buffer_lastvalue);return this.mpu_read_buffer_lastvalue};Q.prototype.port3x0_write=function(a){A(a)};Q.prototype.port3x1_read=function(){return 0|128*!this.mpu_read_buffer.length};Q.prototype.port3x1_write=function(a){A(a);255==a&&(this.mpu_read_buffer.clear(),this.mpu_read_buffer.push(254))};
Q.prototype.command_do=function(){var a=Ha[this.command];a||(a=this.dsp_default_handler);a.call(this);this.command_size=this.command=0;this.write_buffer.clear()};Q.prototype.dsp_default_handler=function(){A(this.command)};function R(a,b,c){c||(c=Q.prototype.dsp_default_handler);for(var d=0;d<a.length;d++)Ga[a[d]]=b,Ha[a[d]]=c}function Ma(a){for(var b=[],c=0;16>c;c++)b.push(a+c);return b}R([14],2,function(){this.asp_registers[this.write_buffer.shift()]=this.write_buffer.shift()});
R([15],1,function(){this.read_buffer.clear();this.read_buffer.push(this.asp_registers[this.write_buffer.shift()])});R([16],1,function(){var a=this.write_buffer.shift();a=Na(a/127.5+-1,-1,1);this.dac_buffers[0].push(a);this.dac_buffers[1].push(a);this.bus.send("dac-enable")});R([20,21],2,function(){this.dma_irq=1;this.dma_channel=this.dma_channel_8bit;this.dsp_highspeed=this.dsp_16bit=this.dsp_signed=this.dma_autoinit=!1;this.dma_transfer_size_set();this.dma_transfer_start()});R([22],2);R([23],2);
R([28],0,function(){this.dma_irq=1;this.dma_channel=this.dma_channel_8bit;this.dma_autoinit=!0;this.dsp_highspeed=this.dsp_16bit=this.dsp_signed=!1;this.dma_transfer_start()});R([31],0);R([32],0,function(){this.read_buffer.clear();this.read_buffer.push(127)});R([36],2);R([44],0);R([48],0);R([49],0);R([52],0);R([53],0);R([54],0);R([55],0);R([56],0);R([64],1,function(){this.sampling_rate_change(1E6/(256-this.write_buffer.shift())/this.get_channel_count())});
R([65,66],2,function(){this.sampling_rate_change(this.write_buffer.shift()<<8|this.write_buffer.shift())});R([72],2,function(){this.dma_transfer_size_set()});R([116],2);R([117],2);R([118],2);R([119],2);R([125],0);R([127],0);R([128],2);R([144],0,function(){this.dma_irq=1;this.dma_channel=this.dma_channel_8bit;this.dma_autoinit=!0;this.dsp_signed=!1;this.dsp_highspeed=!0;this.dsp_16bit=!1;this.dma_transfer_start()});R([145],0);R([152],0);R([153],0);R([160],0);R([168],0);
R(Ma(176),3,function(){if(this.command&8)this.dsp_default_handler();else{var a=this.write_buffer.shift();this.dma_irq=2;this.dma_channel=this.dma_channel_16bit;this.dma_autoinit=!!(this.command&4);this.dsp_signed=!!(a&16);this.dsp_stereo=!!(a&32);this.dsp_16bit=!0;this.dma_transfer_size_set();this.dma_transfer_start()}});
R(Ma(192),3,function(){if(this.command&8)this.dsp_default_handler();else{var a=this.write_buffer.shift();this.dma_irq=1;this.dma_channel=this.dma_channel_8bit;this.dma_autoinit=!!(this.command&4);this.dsp_signed=!!(a&16);this.dsp_stereo=!!(a&32);this.dsp_16bit=!1;this.dma_transfer_size_set();this.dma_transfer_start()}});R([208],0,function(){this.dma_paused=!0;this.bus.send("dac-disable")});R([209],0,function(){this.dummy_speaker_enabled=!0});R([211],0,function(){this.dummy_speaker_enabled=!1});
R([212],0,function(){this.dma_paused=!1;this.bus.send("dac-enable")});R([213],0,function(){this.dma_paused=!0;this.bus.send("dac-disable")});R([214],0,function(){this.dma_paused=!1;this.bus.send("dac-enable")});R([216],0,function(){this.read_buffer.clear();this.read_buffer.push(255*this.dummy_speaker_enabled)});R([217,218],0,function(){this.dma_autoinit=!1});R([224],1,function(){this.read_buffer.clear();this.read_buffer.push(~this.write_buffer.shift())});
R([225],0,function(){this.read_buffer.clear();this.read_buffer.push(4);this.read_buffer.push(5)});R([226],1);R([227],0,function(){this.read_buffer.clear();for(var a=0;44>a;a++)this.read_buffer.push("COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.".charCodeAt(a));this.read_buffer.push(0)});R([228],1,function(){this.test_register=this.write_buffer.shift()});R([232],0,function(){this.read_buffer.clear();this.read_buffer.push(this.test_register)});R([242,243],0,function(){this.raise_irq()});var Oa=new Uint8Array(256);
Oa[14]=255;Oa[15]=7;Oa[55]=56;R([249],1,function(){var a=this.write_buffer.shift();this.read_buffer.clear();this.read_buffer.push(Oa[a])});Q.prototype.mixer_read=function(a){var b=Ia[a];b?b=b.call(this):(b=this.mixer_registers[a],A(a),A(b));return b};Q.prototype.mixer_write=function(a,b){var c=Ja[a];c?c.call(this,b):(A(a),A(b))};Q.prototype.mixer_default_read=function(){A(this.mixer_current_address);return this.mixer_registers[this.mixer_current_address]};
Q.prototype.mixer_default_write=function(a){A(this.mixer_current_address);A(a);this.mixer_registers[this.mixer_current_address]=a};
Q.prototype.mixer_reset=function(){this.mixer_registers[4]=204;this.mixer_registers[34]=204;this.mixer_registers[38]=204;this.mixer_registers[40]=0;this.mixer_registers[46]=0;this.mixer_registers[10]=0;this.mixer_registers[48]=192;this.mixer_registers[49]=192;this.mixer_registers[50]=192;this.mixer_registers[51]=192;this.mixer_registers[52]=192;this.mixer_registers[53]=192;this.mixer_registers[54]=0;this.mixer_registers[55]=0;this.mixer_registers[56]=0;this.mixer_registers[57]=0;this.mixer_registers[59]=
0;this.mixer_registers[60]=31;this.mixer_registers[61]=21;this.mixer_registers[62]=11;this.mixer_registers[63]=0;this.mixer_registers[64]=0;this.mixer_registers[65]=0;this.mixer_registers[66]=0;this.mixer_registers[67]=0;this.mixer_registers[68]=128;this.mixer_registers[69]=128;this.mixer_registers[70]=128;this.mixer_registers[71]=128;this.mixer_full_update()};Q.prototype.mixer_full_update=function(){for(var a=1;a<this.mixer_registers.length;a++)Ka[a]||this.mixer_write(a,this.mixer_registers[a])};
function Pa(a,b){b||(b=Q.prototype.mixer_default_read);Ia[a]=b}function Qa(a,b){b||(b=Q.prototype.mixer_default_write);Ja[a]=b}function Sa(a,b,c){Ka[a]=1;Ia[a]=function(){return this.mixer_registers[b]&240|this.mixer_registers[c]>>>4};Ja[a]=function(d){this.mixer_registers[a]=d;var e=d<<4&240|this.mixer_registers[c]&15;this.mixer_write(b,d&240|this.mixer_registers[b]&15);this.mixer_write(c,e)}}
function Ta(a,b,c){Ia[a]=Q.prototype.mixer_default_read;Ja[a]=function(d){this.mixer_registers[a]=d;this.bus.send("mixer-volume",[b,c,(d>>>2)-62])}}Pa(0,function(){this.mixer_reset();return 0});Qa(0);Sa(4,50,51);Sa(34,48,49);Sa(38,52,53);Sa(40,54,55);Sa(46,56,57);Ta(48,0,0);Ta(49,0,1);Ta(50,2,0);Ta(51,2,1);Pa(59);Qa(59,function(a){this.mixer_registers[59]=a;this.bus.send("mixer-volume",[1,2,6*(a>>>6)-18])});Pa(65);
Qa(65,function(a){this.mixer_registers[65]=a;this.bus.send("mixer-gain-left",6*(a>>>6))});Pa(66);Qa(66,function(a){this.mixer_registers[66]=a;this.bus.send("mixer-gain-right",6*(a>>>6))});Pa(68);Qa(68,function(a){this.mixer_registers[68]=a;a>>>=3;this.bus.send("mixer-treble-left",a-(16>a?14:16))});Pa(69);Qa(69,function(a){this.mixer_registers[69]=a;a>>>=3;this.bus.send("mixer-treble-right",a-(16>a?14:16))});Pa(70);
Qa(70,function(a){this.mixer_registers[70]=a;a>>>=3;this.bus.send("mixer-bass-right",a-(16>a?14:16))});Pa(71);Qa(71,function(a){this.mixer_registers[71]=a;a>>>=3;this.bus.send("mixer-bass-right",a-(16>a?14:16))});Pa(128,function(){switch(this.irq){case 2:return 1;case 5:return 2;case 7:return 4;case 10:return 8;default:return 0}});Qa(128,function(a){a&1&&(this.irq=2);a&2&&(this.irq=5);a&4&&(this.irq=7);a&8&&(this.irq=10)});
Pa(129,function(){var a=0;switch(this.dma_channel_8bit){case 0:a|=1;break;case 1:a|=2;break;case 3:a|=8}switch(this.dma_channel_16bit){case 5:a|=32;break;case 6:a|=64;break;case 7:a|=128}return a});Qa(129,function(a){a&1&&(this.dma_channel_8bit=0);a&2&&(this.dma_channel_8bit=1);a&8&&(this.dma_channel_8bit=3);a&32&&(this.dma_channel_16bit=5);a&64&&(this.dma_channel_16bit=6);a&128&&(this.dma_channel_16bit=7)});Pa(130,function(){for(var a=32,b=0;16>b;b++)a|=b*this.irq_triggered[b];return a});
Q.prototype.fm_default_write=function(a,b,c){A(c);A(a)};function T(a,b){b||(b=Q.prototype.fm_default_write);for(var c=0;c<a.length;c++)La[a[c]]=b}function Ua(a,b){for(var c=[];a<=b;a++)c.push(a);return c}var V=new Uint8Array(32);V[0]=0;V[1]=1;V[2]=2;V[3]=3;V[4]=4;V[5]=5;V[8]=6;V[9]=7;V[10]=8;V[11]=9;V[12]=10;V[13]=11;V[16]=12;V[17]=13;V[18]=14;V[19]=15;V[20]=16;V[21]=17;T([1],function(a,b){this.fm_waveform_select_enable[b]=a&1;this.fm_update_waveforms()});T([2]);T([3]);T([4],function(){});
T([5],function(a,b,c){0===b&&this.fm_default_write(a,b,c)});T([8],function(){});T(Ua(32,53),function(){});T(Ua(64,85),function(){});T(Ua(96,117),function(){});T(Ua(128,149),function(){});T(Ua(160,168),function(){});T(Ua(176,184),function(){});T([189],function(){});T(Ua(192,200),function(){});T(Ua(224,245),function(){});Q.prototype.fm_update_waveforms=function(){};Q.prototype.sampling_rate_change=function(a){this.sampling_rate=a;this.bus.send("dac-tell-sampling-rate",a)};
Q.prototype.get_channel_count=function(){return this.dsp_stereo?2:1};Q.prototype.dma_transfer_size_set=function(){this.dma_sample_count=1+(this.write_buffer.shift()<<0)+(this.write_buffer.shift()<<8)};
Q.prototype.dma_transfer_start=function(){this.bytes_per_sample=1;this.dsp_16bit&&(this.bytes_per_sample*=2);this.dma_bytes_count=this.dma_sample_count*this.bytes_per_sample;this.dma_bytes_block=1024*this.bytes_per_sample;this.dma_bytes_block=Math.min(Math.max(this.dma_bytes_count>>2&-4,32),this.dma_bytes_block);this.dma_waiting_transfer=!0;this.dma.channel_mask[this.dma_channel]||this.dma_on_unmask(this.dma_channel)};
Q.prototype.dma_on_unmask=function(a){a===this.dma_channel&&this.dma_waiting_transfer&&(this.dma_waiting_transfer=!1,this.dma_bytes_left=this.dma_bytes_count,this.dma_paused=!1,this.bus.send("dac-enable"))};
Q.prototype.dma_transfer_next=function(){var a=Math.min(this.dma_bytes_left,this.dma_bytes_block),b=Math.floor(a/this.bytes_per_sample);this.dma.do_write(this.dma_syncbuffer,0,a,this.dma_channel,c=>{c||(this.dma_to_dac(b),this.dma_bytes_left-=a,this.dma_bytes_left||(this.raise_irq(this.dma_irq),this.dma_autoinit&&(this.dma_bytes_left=this.dma_bytes_count)))})};
Q.prototype.dma_to_dac=function(a){var b=this.dsp_16bit?32767.5:127.5,c=this.dsp_signed?0:-1,d=this.dsp_stereo?1:2;var e=this.dsp_16bit?this.dsp_signed?this.dma_buffer_int16:this.dma_buffer_uint16:this.dsp_signed?this.dma_buffer_int8:this.dma_buffer_uint8;for(var g=0,f=0;f<a;f++)for(var k=Na(e[f]/b+c,-1,1),l=0;l<d;l++)this.dac_buffers[g].push(k),g^=1;this.dac_send()};Q.prototype.dac_handle_request=function(){!this.dma_bytes_left||this.dma_paused?this.dac_send():this.dma_transfer_next()};
Q.prototype.dac_send=function(){if(this.dac_buffers[0].length){var a=this.dac_buffers[0].shift_block(this.dac_buffers[0].length),b=this.dac_buffers[1].shift_block(this.dac_buffers[1].length);this.bus.send("dac-send-data",[a,b],[a.buffer,b.buffer])}};Q.prototype.raise_irq=function(a){this.irq_triggered[a]=1;this.cpu.device_raise_irq(this.irq)};Q.prototype.lower_irq=function(a){this.irq_triggered[a]=0;this.cpu.device_lower_irq(this.irq)};function Na(a,b,c){return(a<b)*b+(a>c)*c+(b<=a&&a<=c)*a};function h(a,b){this.cpu=a;this.pci=a.devices.pci;this.device_id=b.device_id;this.pci_space=[244,26,b.device_id&255,b.device_id>>8,7,5,16,0,1,0,2,0,0,0,0,0,1,168,0,0,0,16,191,254,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,244,26,b.subsystem_device_id&255,b.subsystem_device_id>>8,0,0,0,0,64,0,0,0,0,0,0,0,0,1,0,0];this.pci_space=this.pci_space.concat(r.zeros(256-this.pci_space.length));this.pci_id=b.pci_id;this.pci_bars=[];this.name=b.name;this.driver_feature_select=this.device_feature_select=0;this.device_feature=
new Uint32Array(4);this.driver_feature=new Uint32Array(4);for(var c of b.common.features)this.device_feature[c>>>5]|=1<<(c&31),this.driver_feature[c>>>5]|=1<<(c&31);b.common.features.includes(32);this.features_ok=!0;this.device_status=0;this.config_has_changed=!1;this.config_generation=0;this.queues=[];for(const d of b.common.queues)this.queues.push(new W(a,this,d));this.queue_select=0;this.queue_selected=this.queues[0];this.isr_status=0;c=[];c.push(this.create_common_capability(b.common));c.push(this.create_notification_capability(b.notification));
c.push(this.create_isr_capability(b.isr_status));b.device_specific&&c.push(this.create_device_specific_capability(b.device_specific));this.init_capabilities(c);a.devices.pci.register_device(this);this.reset()}
h.prototype.create_common_capability=function(a){return{type:1,bar:0,port:a.initial_port,use_mmio:!1,offset:0,extra:new Uint8Array(0),struct:[{bytes:4,name:"device_feature_select",read:()=>this.device_feature_select,write:b=>{this.device_feature_select=b}},{bytes:4,name:"device_feature",read:()=>this.device_feature[this.device_feature_select]||0,write:()=>{}},{bytes:4,name:"driver_feature_select",read:()=>this.driver_feature_select,write:b=>{this.driver_feature_select=b}},{bytes:4,name:"driver_feature",
read:()=>this.driver_feature[this.driver_feature_select]||0,write:b=>{const c=this.device_feature[this.driver_feature_select];this.driver_feature_select<this.driver_feature.length&&(this.driver_feature[this.driver_feature_select]=b&c);this.features_ok=this.features_ok&&!(b&~c)}},{bytes:2,name:"msix_config",read:()=>65535,write:()=>{}},{bytes:2,name:"num_queues",read:()=>this.queues.length,write:()=>{}},{bytes:1,name:"device_status",read:()=>this.device_status,write:b=>{0===b&&this.reset();b&~this.device_status&
4&&this.device_status&64&&this.notify_config_changes();this.features_ok||(b&=-9);this.device_status=b;if(b&~this.device_status&4)a.on_driver_ok()}},{bytes:1,name:"config_generation",read:()=>this.config_generation,write:()=>{}},{bytes:2,name:"queue_select",read:()=>this.queue_select,write:b=>{this.queue_select=b;this.queue_selected=this.queue_select<this.queues.length?this.queues[this.queue_select]:null}},{bytes:2,name:"queue_size",read:()=>this.queue_selected?this.queue_selected.size:0,write:b=>
{this.queue_selected&&(b&b-1&&(b=1<<r.int_log2(b-1)+1),b>this.queue_selected.size_supported&&(b=this.queue_selected.size_supported),this.queue_selected.set_size(b))}},{bytes:2,name:"queue_msix_vector",read:()=>65535,write:()=>{}},{bytes:2,name:"queue_enable",read:()=>this.queue_selected?this.queue_selected.enabled|0:0,write:b=>{this.queue_selected&&1===b&&this.queue_selected.is_configured()&&this.queue_selected.enable()}},{bytes:2,name:"queue_notify_off",read:()=>this.queue_selected?this.queue_selected.notify_offset:
0,write:()=>{}},{bytes:4,name:"queue_desc (low dword)",read:()=>this.queue_selected?this.queue_selected.desc_addr:0,write:b=>{this.queue_selected&&(this.queue_selected.desc_addr=b)}},{bytes:4,name:"queue_desc (high dword)",read:()=>0,write:()=>{}},{bytes:4,name:"queue_avail (low dword)",read:()=>this.queue_selected?this.queue_selected.avail_addr:0,write:b=>{this.queue_selected&&(this.queue_selected.avail_addr=b)}},{bytes:4,name:"queue_avail (high dword)",read:()=>0,write:()=>{}},{bytes:4,name:"queue_used (low dword)",
read:()=>this.queue_selected?this.queue_selected.used_addr:0,write:b=>{this.queue_selected&&(this.queue_selected.used_addr=b)}},{bytes:4,name:"queue_used (high dword)",read:()=>0,write:()=>{}}]}};
h.prototype.create_notification_capability=function(a){const b=[];let c;c=a.single_handler?0:2;for(const [d,e]of a.handlers.entries())b.push({bytes:2,name:"notify"+d,read:()=>65535,write:e||(()=>{})});return{type:2,bar:1,port:a.initial_port,use_mmio:!1,offset:0,extra:new Uint8Array([c&255,c>>8&255,c>>16&255,c>>24]),struct:b}};
h.prototype.create_isr_capability=function(a){return{type:3,bar:2,port:a.initial_port,use_mmio:!1,offset:0,extra:new Uint8Array(0),struct:[{bytes:1,name:"isr_status",read:()=>{const b=this.isr_status;this.lower_irq();return b},write:()=>{}}]}};h.prototype.create_device_specific_capability=function(a){return{type:4,bar:3,port:a.initial_port,use_mmio:!1,offset:0,extra:new Uint8Array(0),struct:a.struct}};
h.prototype.init_capabilities=function(a){let b=this.pci_space[52]=64;var c=b;for(const e of a){a=16+e.extra.length;c=b;b=c+a;var d=e.struct.reduce((g,f)=>g+f.bytes,0);d+=e.offset;d=16>d?16:1<<r.int_log2(d-1)+1;this.pci_bars[e.bar]={size:d};this.pci_space[c]=9;this.pci_space[c+1]=b;this.pci_space[c+2]=a;this.pci_space[c+3]=e.type;this.pci_space[c+4]=e.bar;this.pci_space[c+5]=0;this.pci_space[c+6]=0;this.pci_space[c+7]=0;this.pci_space[c+8]=e.offset&255;this.pci_space[c+9]=e.offset>>>8&255;this.pci_space[c+
10]=e.offset>>>16&255;this.pci_space[c+11]=e.offset>>>24;this.pci_space[c+12]=d&255;this.pci_space[c+13]=d>>>8&255;this.pci_space[c+14]=d>>>16&255;this.pci_space[c+15]=d>>>24;for(const [g,f]of e.extra.entries())this.pci_space[c+16+g]=f;c=16+4*e.bar;this.pci_space[c]=e.port&254|!e.use_mmio;this.pci_space[c+1]=e.port>>>8&255;this.pci_space[c+2]=e.port>>>16&255;this.pci_space[c+3]=e.port>>>24&255;c=e.port+e.offset;for(const g of e.struct){let f=g.read;a=g.write;if(!e.use_mmio){d=function(l){return f(l&
-2)>>((l&1)<<3)&255};const k=function(l){return f(l&-4)>>((l&3)<<3)&255};switch(g.bytes){case 4:this.cpu.io.register_read(c,this,k,void 0,f);this.cpu.io.register_write(c,this,void 0,void 0,a);break;case 2:this.cpu.io.register_read(c,this,d,f);this.cpu.io.register_write(c,this,void 0,a);break;case 1:this.cpu.io.register_read(c,this,f),this.cpu.io.register_write(c,this,a)}}c+=g.bytes}}this.pci_space[b]=9;this.pci_space[b+1]=0;this.pci_space[b+2]=20;this.pci_space[b+3]=5;this.pci_space[b+4]=0;this.pci_space[b+
5]=0;this.pci_space[b+6]=0;this.pci_space[b+7]=0;this.pci_space[b+8]=0;this.pci_space[b+9]=0;this.pci_space[b+10]=0;this.pci_space[b+11]=0;this.pci_space[b+12]=0;this.pci_space[b+13]=0;this.pci_space[b+14]=0;this.pci_space[b+15]=0;this.pci_space[b+16]=0;this.pci_space[b+17]=0;this.pci_space[b+18]=0;this.pci_space[b+19]=0};
h.prototype.get_state=function(){let a=[];a[0]=this.device_feature_select;a[1]=this.driver_feature_select;a[2]=this.device_feature;a[3]=this.driver_feature;a[4]=this.features_ok;a[5]=this.device_status;a[6]=this.config_has_changed;a[7]=this.config_generation;a[8]=this.isr_status;a[9]=this.queue_select;return a=a.concat(this.queues)};
h.prototype.set_state=function(a){this.device_feature_select=a[0];this.driver_feature_select=a[1];this.device_feature=a[2];this.driver_feature=a[3];this.features_ok=a[4];this.device_status=a[5];this.config_has_changed=a[6];this.config_generation=a[7];this.isr_status=a[8];this.queue_select=a[9];let b=0;for(let c of a.slice(10))this.queues[b].set_state(c),b++;this.queue_selected=this.queues[this.queue_select]||null};
h.prototype.reset=function(){this.driver_feature_select=this.device_feature_select=0;this.driver_feature.set(this.device_feature);this.features_ok=!0;this.queue_select=this.device_status=0;this.queue_selected=this.queues[0];for(const a of this.queues)a.reset();this.config_has_changed=!1;this.config_generation=0;this.lower_irq()};h.prototype.notify_config_changes=function(){this.config_has_changed=!0;this.device_status&4&&this.raise_irq(2)};
h.prototype.update_config_generation=function(){this.config_has_changed&&(this.config_generation++,this.config_generation&=255,this.config_has_changed=!1)};h.prototype.is_feature_negotiated=function(a){return 0<(this.driver_feature[a>>>5]&1<<(a&31))};h.prototype.needs_reset=function(){this.device_status|=64;this.device_status&4&&this.notify_config_changes()};h.prototype.raise_irq=function(a){A(a);this.isr_status|=a;this.pci.raise_irq(this.pci_id)};
h.prototype.lower_irq=function(){this.isr_status=0;this.pci.lower_irq(this.pci_id)};function W(a,b,c){this.cpu=a;this.virtio=b;this.size_supported=this.size=c.size_supported;this.mask=this.size-1;this.enabled=!1;this.notify_offset=c.notify_offset;this.num_staged_replies=this.used_addr=this.avail_last_idx=this.avail_addr=this.desc_addr=0;this.reset()}
W.prototype.get_state=function(){const a=[];a[0]=this.size;a[1]=this.size_supported;a[2]=this.enabled;a[3]=this.notify_offset;a[4]=this.desc_addr;a[5]=this.avail_addr;a[6]=this.avail_last_idx;a[7]=this.used_addr;a[8]=this.num_staged_replies;return a};
W.prototype.set_state=function(a){this.size=a[0];this.size_supported=a[1];this.enabled=a[2];this.notify_offset=a[3];this.desc_addr=a[4];this.avail_addr=a[5];this.avail_last_idx=a[6];this.used_addr=a[7];this.num_staged_replies=a[8];this.mask=this.size-1};W.prototype.reset=function(){this.enabled=!1;this.num_staged_replies=this.used_addr=this.avail_last_idx=this.avail_addr=this.desc_addr=0;this.set_size(this.size_supported)};
W.prototype.is_configured=function(){return this.desc_addr&&this.avail_addr&&this.used_addr};W.prototype.enable=function(){this.is_configured();this.enabled=!0};W.prototype.set_size=function(a){this.size=a;this.mask=a-1};W.prototype.count_requests=function(){return this.avail_get_idx()-this.avail_last_idx&this.mask};W.prototype.has_request=function(){return(this.avail_get_idx()&this.mask)!==this.avail_last_idx};
W.prototype.pop_request=function(){this.has_request();var a=this.avail_get_entry(this.avail_last_idx);a=new Va(this,a);this.avail_last_idx=this.avail_last_idx+1&this.mask;return a};W.prototype.push_reply=function(a){const b=this.used_get_idx()+this.num_staged_replies&this.mask;this.used_set_entry(b,a.head_idx,a.length_written);this.num_staged_replies++};
W.prototype.flush_replies=function(){if(0!==this.num_staged_replies){var a=this.used_get_idx()+this.num_staged_replies&65535;this.used_set_idx(a);this.num_staged_replies=0;this.virtio.is_feature_negotiated(29)?(this.avail_get_used_event(),this.virtio.raise_irq(1)):~this.avail_get_flags()&1&&this.virtio.raise_irq(1)}};W.prototype.notify_me_after=function(a){a=this.avail_get_idx()+a&65535;this.used_set_avail_event(a)};
W.prototype.get_descriptor=function(a,b){return{addr_low:this.cpu.read32s(a+16*b),addr_high:this.cpu.read32s(a+16*b+4),len:this.cpu.read32s(a+16*b+8),flags:this.cpu.read16(a+16*b+12),next:this.cpu.read16(a+16*b+14)}};W.prototype.avail_get_flags=function(){return this.cpu.read16(this.avail_addr)};W.prototype.avail_get_idx=function(){return this.cpu.read16(this.avail_addr+2)};W.prototype.avail_get_entry=function(a){return this.cpu.read16(this.avail_addr+4+2*a)};
W.prototype.avail_get_used_event=function(){return this.cpu.read16(this.avail_addr+4+2*this.size)};W.prototype.used_get_flags=function(){return this.cpu.read16(this.used_addr)};W.prototype.used_set_flags=function(a){this.cpu.write16(this.used_addr,a)};W.prototype.used_get_idx=function(){return this.cpu.read16(this.used_addr+2)};W.prototype.used_set_idx=function(a){this.cpu.write16(this.used_addr+2,a)};
W.prototype.used_set_entry=function(a,b,c){this.cpu.write32(this.used_addr+4+8*a,b);this.cpu.write32(this.used_addr+8+8*a,c)};W.prototype.used_set_avail_event=function(a){this.cpu.write16(this.used_addr+4+8*this.size,a)};
function Va(a,b){this.cpu=a.cpu;this.virtio=a.virtio;this.head_idx=b;this.read_buffers=[];this.length_readable=this.read_buffer_offset=this.read_buffer_idx=0;this.write_buffers=[];this.length_writable=this.length_written=this.write_buffer_offset=this.write_buffer_idx=0;let c=a.desc_addr,d=0,e=a.size,g=!1;const f=this.virtio.is_feature_negotiated(28);do{const k=a.get_descriptor(c,b);A(k.addr_high,8);A(k.addr_low,8);A(k.len,8);A(k.flags,4);A(k.next,4);if(f&&k.flags&4)c=k.addr_low,d=b=0,e=k.len/16;else{if(k.flags&
2)g=!0,this.write_buffers.push(k),this.length_writable+=k.len;else{if(g)break;this.read_buffers.push(k);this.length_readable+=k.len}d++;if(d>e)break;if(k.flags&1)b=k.next;else break}}while(1)}
Va.prototype.get_next_blob=function(a){let b=0,c=a.length;for(;c&&this.read_buffer_idx!==this.read_buffers.length;){var d=this.read_buffers[this.read_buffer_idx];const e=d.addr_low+this.read_buffer_offset;d=d.len-this.read_buffer_offset;d>c?(d=c,this.read_buffer_offset+=c):(this.read_buffer_idx++,this.read_buffer_offset=0);a.set(this.cpu.read_blob(e,d),b);b+=d;c-=d}return b};
Va.prototype.set_next_blob=function(a){let b=0,c=a.length;for(;c&&this.write_buffer_idx!==this.write_buffers.length;){var d=this.write_buffers[this.write_buffer_idx];const e=d.addr_low+this.write_buffer_offset;d=d.len-this.write_buffer_offset;d>c?(d=c,this.write_buffer_offset+=c):(this.write_buffer_idx++,this.write_buffer_offset=0);this.cpu.write_blob(a.subarray(b,b+d),e);b+=d;c-=d}this.length_written+=b;return b};function Wa(a,b){this.bus=b;this.rows=25;this.cols=80;this.ports=4;b=[{size_supported:16,notify_offset:0},{size_supported:16,notify_offset:1},{size_supported:16,notify_offset:2},{size_supported:16,notify_offset:3}];for(let c=1;c<this.ports;++c)b.push({size_supported:16,notify_offset:0}),b.push({size_supported:8,notify_offset:1});this.virtio=new h(a,{name:"virtio-console",pci_id:56,device_id:4163,subsystem_device_id:3,common:{initial_port:47104,queues:b,features:[0,1,32],on_driver_ok:()=>{}},notification:{initial_port:47360,
single_handler:!1,handlers:[c=>{for(c=this.virtio.queues[c];c.count_requests()>c.size-2;)c.pop_request()},c=>{let d=this.virtio.queues[c],e=3<c?c-3>>1:0;for(;d.has_request();){const g=d.pop_request(),f=new Uint8Array(g.length_readable);g.get_next_blob(f);this.bus.send("virtio-console"+e+"-output-bytes",f);this.Ack(c,g)}},c=>{if(2==c)for(c=this.virtio.queues[c];c.count_requests()>c.size-2;)c.pop_request()},c=>{if(3==c)for(var d=this.virtio.queues[c];d.has_request();){var e=d.pop_request(),g=new Uint8Array(e.length_readable);
e.get_next_blob(g);var f=v.Unmarshall(["w","h","h"],g,{offset:0});g=f[0];f=f[1];this.Ack(c,e);switch(f){case 0:for(e=0;e<this.ports;++e)this.SendEvent(e,1,0);break;case 3:this.Ack(c,e);this.SendEvent(g,4,1);this.SendName(g,"virtio-"+g);this.SendEvent(g,6,1);break;case 6:this.Ack(c,e);0==g&&this.SendWindowSize(g);break;default:return}}}]},isr_status:{initial_port:46848},device_specific:{initial_port:46592,struct:[{bytes:2,name:"cols",read:()=>this.cols,write:()=>{}},{bytes:2,name:"rows",read:()=>this.rows,
write:()=>{}},{bytes:4,name:"max_nr_ports",read:()=>this.ports,write:()=>{}},{bytes:4,name:"emerg_wr",read:()=>0,write:()=>{}}]}});for(let c=0;c<this.ports;++c){let d=0==c?0:2*c+2;this.bus.register("virtio-console"+c+"-input-bytes",function(e){var g=this.virtio.queues[d];g.has_request()&&(g=g.pop_request(),this.Send(d,g,new Uint8Array(e)))},this);this.bus.register("virtio-console"+c+"-resize",function(e){this.cols=e[0];this.rows=e[1];this.virtio.queues[2].is_configured()&&this.virtio.queues[2].has_request()&&
this.SendWindowSize(c)},this)}}Wa.prototype.SendWindowSize=function(a){const b=this.virtio.queues[2].pop_request();let c=new Uint8Array(12);v.Marshall(["w","h","h","h","h"],[a,5,0,this.rows,this.cols],c,0);this.Send(2,b,c)};Wa.prototype.SendName=function(a,b){const c=this.virtio.queues[2].pop_request();b=(new TextEncoder).encode(b);let d=new Uint8Array(8+b.length+1);v.Marshall(["w","h","h"],[a,7,1],d,0);for(a=0;a<b.length;++a)d[a+8]=b[a];d[8+b.length]=0;this.Send(2,c,d)};
Wa.prototype.get_state=function(){let a=[];a[0]=this.virtio;a[1]=this.rows;a[2]=this.cols;a[3]=this.ports;return a};Wa.prototype.set_state=function(a){this.virtio.set_state(a[0]);this.rows=a[1];this.cols=a[2];this.ports=a[3]};Wa.prototype.Reset=function(){};Wa.prototype.SendEvent=function(a,b,c){const d=this.virtio.queues[2].pop_request();let e=new Uint8Array(8);v.Marshall(["w","h","h"],[a,b,c],e,0);this.Send(2,d,e)};
Wa.prototype.Send=function(a,b,c){b.set_next_blob(c);this.virtio.queues[a].push_reply(b);this.virtio.queues[a].flush_replies()};Wa.prototype.Ack=function(a,b){b.set_next_blob(new Uint8Array(0));this.virtio.queues[a].push_reply(b);this.virtio.queues[a].flush_replies()};var Xa={};function Ya(){this.listeners={};this.pair=void 0}Ya.prototype.register=function(a,b,c){var d=this.listeners[a];void 0===d&&(d=this.listeners[a]=[]);d.push({fn:b,this_value:c})};Ya.prototype.unregister=function(a,b){var c=this.listeners[a];void 0!==c&&(this.listeners[a]=c.filter(function(d){return d.fn!==b}))};Ya.prototype.send=function(a,b){if(this.pair&&(a=this.pair.listeners[a],void 0!==a))for(var c=0;c<a.length;c++){var d=a[c];d.fn.call(d.this_value,b)}};
Ya.prototype.send_async=function(a,b){setTimeout(this.send.bind(this,a,b),0)};Xa.create=function(){var a=new Ya,b=new Ya;a.pair=b;b.pair=a;return[a,b]};function J(){}function oa(){};function E(a,b,c){this.next_tick_immediately=c;this.wm=b;this.wasm_patch();this.create_jit_imports();this.wasm_memory=b=this.wm.exports.memory;this.memory_size=r.view(Uint32Array,b,812,1);this.mem8=new Uint8Array(0);this.mem32s=new Int32Array(this.mem8.buffer);this.segment_is_null=r.view(Uint8Array,b,724,8);this.segment_offsets=r.view(Int32Array,b,736,8);this.segment_limits=r.view(Uint32Array,b,768,8);this.protected_mode=r.view(Int32Array,b,800,1);this.idtr_size=r.view(Int32Array,b,564,1);this.idtr_offset=
r.view(Int32Array,b,568,1);this.gdtr_size=r.view(Int32Array,b,572,1);this.gdtr_offset=r.view(Int32Array,b,576,1);this.tss_size_32=r.view(Int32Array,b,1128,1);this.page_fault=r.view(Uint32Array,b,540,8);this.cr=r.view(Int32Array,b,580,8);this.cpl=r.view(Uint8Array,b,612,1);this.is_32=r.view(Int32Array,b,804,1);this.stack_size_32=r.view(Int32Array,b,808,1);this.in_hlt=r.view(Uint8Array,b,616,1);this.last_virt_eip=r.view(Int32Array,b,620,1);this.eip_phys=r.view(Int32Array,b,624,1);this.sysenter_cs=r.view(Int32Array,
b,636,1);this.sysenter_esp=r.view(Int32Array,b,640,1);this.sysenter_eip=r.view(Int32Array,b,644,1);this.prefixes=r.view(Int32Array,b,648,1);this.flags=r.view(Int32Array,b,120,1);this.flags_changed=r.view(Int32Array,b,100,1);this.last_op_size=r.view(Int32Array,b,96,1);this.last_op1=r.view(Int32Array,b,104,1);this.last_result=r.view(Int32Array,b,112,1);this.current_tsc=r.view(Uint32Array,b,960,2);this.devices={};this.instruction_pointer=r.view(Int32Array,b,556,1);this.previous_ip=r.view(Int32Array,
b,560,1);this.apic_enabled=r.view(Uint8Array,b,548,1);this.acpi_enabled=r.view(Uint8Array,b,552,1);this.memory_map_read8=[];this.memory_map_write8=[];this.memory_map_read32=[];this.memory_map_write32=[];this.bios={main:null,vga:null};this.instruction_counter=r.view(Uint32Array,b,664,1);this.reg32=r.view(Int32Array,b,64,8);this.fpu_st=r.view(Int32Array,b,1152,32);this.fpu_stack_empty=r.view(Uint8Array,b,816,1);this.fpu_stack_empty[0]=255;this.fpu_stack_ptr=r.view(Uint8Array,b,1032,1);this.fpu_stack_ptr[0]=
0;this.fpu_control_word=r.view(Uint16Array,b,1036,1);this.fpu_control_word[0]=895;this.fpu_status_word=r.view(Uint16Array,b,1040,1);this.fpu_status_word[0]=0;this.fpu_ip=r.view(Int32Array,b,1048,1);this.fpu_ip[0]=0;this.fpu_ip_selector=r.view(Int32Array,b,1052,1);this.fpu_ip_selector[0]=0;this.fpu_opcode=r.view(Int32Array,b,1044,1);this.fpu_opcode[0]=0;this.fpu_dp=r.view(Int32Array,b,1056,1);this.fpu_dp[0]=0;this.fpu_dp_selector=r.view(Int32Array,b,1060,1);this.fpu_dp_selector[0]=0;this.reg_xmm32s=
r.view(Int32Array,b,832,32);this.mxcsr=r.view(Int32Array,b,824,1);this.sreg=r.view(Uint16Array,b,668,8);this.dreg=r.view(Int32Array,b,684,8);this.reg_pdpte=r.view(Int32Array,b,968,8);this.svga_dirty_bitmap_min_offset=r.view(Uint32Array,b,716,1);this.svga_dirty_bitmap_max_offset=r.view(Uint32Array,b,720,1);this.fw_value=[];this.fw_pointer=0;this.option_roms=[];this.io=void 0;this.bus=a;this.set_tsc(0,0);this.debug_init()}
E.prototype.clear_opstats=function(){(new Uint8Array(this.wasm_memory.buffer,32768,131072)).fill(0);this.wm.exports.profiler_init()};E.prototype.create_jit_imports=function(){const a=Object.create(null);a.m=this.wm.exports.memory;for(let b of Object.keys(this.wm.exports))b.startsWith("_")||b.startsWith("zstd")||b.endsWith("_js")||(a[b]=this.wm.exports[b]);this.jit_imports=a};
E.prototype.wasm_patch=function(){const a=c=>this.wm.exports[c],b=c=>{const d=a(c);console.assert(d,"Missing import: "+c);return d};this.reset_cpu=b("reset_cpu");this.getiopl=b("getiopl");this.get_eflags=b("get_eflags");this.handle_irqs=b("handle_irqs");this.main_loop=b("main_loop");this.set_jit_config=b("set_jit_config");this.read8=b("read8");this.read16=b("read16");this.read32s=b("read32s");this.write8=b("write8");this.write16=b("write16");this.write32=b("write32");this.in_mapped_range=b("in_mapped_range");
this.fpu_load_tag_word=b("fpu_load_tag_word");this.fpu_load_status_word=b("fpu_load_status_word");this.fpu_get_sti_f64=b("fpu_get_sti_f64");this.translate_address_system_read=b("translate_address_system_read_js");this.get_seg_cs=b("get_seg_cs");this.get_real_eip=b("get_real_eip");this.clear_tlb=b("clear_tlb");this.full_clear_tlb=b("full_clear_tlb");this.update_state_flags=b("update_state_flags");this.set_tsc=b("set_tsc");this.store_current_tsc=b("store_current_tsc");this.set_cpuid_level=b("set_cpuid_level");
this.pic_set_irq=b("pic_set_irq");this.pic_clear_irq=b("pic_clear_irq");this.jit_clear_cache=b("jit_clear_cache_js");this.jit_dirty_cache=b("jit_dirty_cache");this.codegen_finalize_finished=b("codegen_finalize_finished");this.allocate_memory=b("allocate_memory");this.zero_memory=b("zero_memory");this.svga_allocate_memory=b("svga_allocate_memory");this.svga_allocate_dest_buffer=b("svga_allocate_dest_buffer");this.svga_fill_pixel_buffer=b("svga_fill_pixel_buffer");this.svga_mark_dirty=b("svga_mark_dirty");
this.get_pic_addr_master=b("get_pic_addr_master");this.get_pic_addr_slave=b("get_pic_addr_slave");this.zstd_create_ctx=b("zstd_create_ctx");this.zstd_get_src_ptr=b("zstd_get_src_ptr");this.zstd_free_ctx=b("zstd_free_ctx");this.zstd_read=b("zstd_read");this.zstd_read_free=b("zstd_read_free");this.port20_read=b("port20_read");this.port21_read=b("port21_read");this.portA0_read=b("portA0_read");this.portA1_read=b("portA1_read");this.port20_write=b("port20_write");this.port21_write=b("port21_write");this.portA0_write=
b("portA0_write");this.portA1_write=b("portA1_write");this.port4D0_read=b("port4D0_read");this.port4D1_read=b("port4D1_read");this.port4D0_write=b("port4D0_write");this.port4D1_write=b("port4D1_write")};E.prototype.jit_force_generate=function(a){this.jit_force_generate_unsafe&&this.jit_force_generate_unsafe(a)};E.prototype.jit_clear_func=function(a){this.wm.wasm_table.set(a+1024,null)};E.prototype.jit_clear_all_funcs=function(){const a=this.wm.wasm_table;for(let b=0;900>b;b++)a.set(1024+b,null)};
E.prototype.get_state=function(){var a=[];a[0]=this.memory_size[0];a[1]=this.segment_is_null;a[2]=this.segment_offsets;a[3]=this.segment_limits;a[4]=this.protected_mode[0];a[5]=this.idtr_offset[0];a[6]=this.idtr_size[0];a[7]=this.gdtr_offset[0];a[8]=this.gdtr_size[0];a[9]=this.page_fault[0];a[10]=this.cr;a[11]=this.cpl[0];a[13]=this.is_32[0];a[16]=this.stack_size_32[0];a[17]=this.in_hlt[0];a[18]=this.last_virt_eip[0];a[19]=this.eip_phys[0];a[22]=this.sysenter_cs[0];a[23]=this.sysenter_eip[0];a[24]=
this.sysenter_esp[0];a[25]=this.prefixes[0];a[26]=this.flags[0];a[27]=this.flags_changed[0];a[28]=this.last_op1[0];a[30]=this.last_op_size[0];a[37]=this.instruction_pointer[0];a[38]=this.previous_ip[0];a[39]=this.reg32;a[40]=this.sreg;a[41]=this.dreg;a[42]=this.reg_pdpte;this.store_current_tsc();a[43]=this.current_tsc;a[45]=this.devices.virtio_9p;a[46]=this.devices.apic;a[47]=this.devices.rtc;a[48]=this.devices.pci;a[49]=this.devices.dma;a[50]=this.devices.acpi;a[52]=this.devices.vga;a[53]=this.devices.ps2;
a[54]=this.devices.uart0;a[55]=this.devices.fdc;a[56]=this.devices.cdrom;a[57]=this.devices.hda;a[58]=this.devices.pit;a[59]=this.devices.net;a[60]=this.get_state_pic();a[61]=this.devices.sb16;a[62]=this.fw_value;a[63]=this.devices.ioapic;a[64]=this.tss_size_32[0];a[66]=this.reg_xmm32s;a[67]=this.fpu_st;a[68]=this.fpu_stack_empty[0];a[69]=this.fpu_stack_ptr[0];a[70]=this.fpu_control_word[0];a[71]=this.fpu_ip[0];a[72]=this.fpu_ip_selector[0];a[73]=this.fpu_dp[0];a[74]=this.fpu_dp_selector[0];a[75]=
this.fpu_opcode[0];const {packed_memory:b,bitmap:c}=this.pack_memory();a[77]=b;a[78]=new Uint8Array(c.get_buffer());a[79]=this.devices.uart1;a[80]=this.devices.uart2;a[81]=this.devices.uart3;a[82]=this.devices.virtio_console;return a};
E.prototype.get_state_pic=function(){const a=new Uint8Array(this.wasm_memory.buffer,this.get_pic_addr_master(),13),b=new Uint8Array(this.wasm_memory.buffer,this.get_pic_addr_slave(),13),c=[],d=[];c[0]=a[0];c[1]=a[1];c[2]=a[2];c[3]=a[3];c[4]=a[4];c[5]=d;c[6]=a[6];c[7]=a[7];c[8]=a[8];c[9]=a[9];c[10]=a[10];c[11]=a[11];c[12]=a[12];d[0]=b[0];d[1]=b[1];d[2]=b[2];d[3]=b[3];d[4]=b[4];d[5]=null;d[6]=b[6];d[7]=b[7];d[8]=b[8];d[9]=b[9];d[10]=b[10];d[12]=b[12];d[12]=b[12];return c};
E.prototype.set_state=function(a){this.memory_size[0]=a[0];this.mem8.length!==this.memory_size[0]&&console.warn("Note: Memory size mismatch. we="+this.mem8.length+" state="+this.memory_size[0]);this.segment_is_null.set(a[1]);this.segment_offsets.set(a[2]);this.segment_limits.set(a[3]);this.protected_mode[0]=a[4];this.idtr_offset[0]=a[5];this.idtr_size[0]=a[6];this.gdtr_offset[0]=a[7];this.gdtr_size[0]=a[8];this.page_fault[0]=a[9];this.cr.set(a[10]);this.cpl[0]=a[11];this.is_32[0]=a[13];this.stack_size_32[0]=
a[16];this.in_hlt[0]=a[17];this.last_virt_eip[0]=a[18];this.eip_phys[0]=a[19];this.sysenter_cs[0]=a[22];this.sysenter_eip[0]=a[23];this.sysenter_esp[0]=a[24];this.prefixes[0]=a[25];this.flags[0]=a[26];this.flags_changed[0]=a[27];this.last_op1[0]=a[28];this.last_op_size[0]=a[30];this.instruction_pointer[0]=a[37];this.previous_ip[0]=a[38];this.reg32.set(a[39]);this.sreg.set(a[40]);this.dreg.set(a[41]);a[42]&&this.reg_pdpte.set(a[42]);this.set_tsc(a[43][0],a[43][1]);this.devices.virtio_9p&&this.devices.virtio_9p.set_state(a[45]);
this.devices.apic&&this.devices.apic.set_state(a[46]);this.devices.rtc&&this.devices.rtc.set_state(a[47]);this.devices.pci&&this.devices.pci.set_state(a[48]);this.devices.dma&&this.devices.dma.set_state(a[49]);this.devices.acpi&&this.devices.acpi.set_state(a[50]);this.devices.vga&&this.devices.vga.set_state(a[52]);this.devices.ps2&&this.devices.ps2.set_state(a[53]);this.devices.uart0&&this.devices.uart0.set_state(a[54]);this.devices.fdc&&this.devices.fdc.set_state(a[55]);this.devices.cdrom&&this.devices.cdrom.set_state(a[56]);
this.devices.hda&&this.devices.hda.set_state(a[57]);this.devices.pit&&this.devices.pit.set_state(a[58]);this.devices.net&&this.devices.net.set_state(a[59]);this.set_state_pic(a[60]);this.devices.sb16&&this.devices.sb16.set_state(a[61]);this.devices.uart1&&this.devices.uart1.set_state(a[79]);this.devices.uart2&&this.devices.uart2.set_state(a[80]);this.devices.uart3&&this.devices.uart3.set_state(a[81]);this.devices.virtio_console&&this.devices.virtio_console.set_state(a[82]);this.fw_value=a[62];this.devices.ioapic&&
this.devices.ioapic.set_state(a[63]);this.tss_size_32[0]=a[64];this.reg_xmm32s.set(a[66]);this.fpu_st.set(a[67]);this.fpu_stack_empty[0]=a[68];this.fpu_stack_ptr[0]=a[69];this.fpu_control_word[0]=a[70];this.fpu_ip[0]=a[71];this.fpu_ip_selector[0]=a[72];this.fpu_dp[0]=a[73];this.fpu_dp_selector[0]=a[74];this.fpu_opcode[0]=a[75];const b=new r.Bitmap(a[78].buffer);this.unpack_memory(b,a[77]);this.update_state_flags();this.full_clear_tlb();this.jit_clear_cache()};
E.prototype.set_state_pic=function(a){const b=new Uint8Array(this.wasm_memory.buffer,this.get_pic_addr_master(),13),c=new Uint8Array(this.wasm_memory.buffer,this.get_pic_addr_slave(),13);b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];const d=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9];b[10]=a[10];b[11]=a[11];b[12]=a[12];c[0]=d[0];c[1]=d[1];c[2]=d[2];c[3]=d[3];c[4]=d[4];c[6]=d[6];c[7]=d[7];c[8]=d[8];c[9]=d[9];c[10]=d[10];c[12]=d[12];c[12]=d[12]};
E.prototype.pack_memory=function(){var a=this.mem8.length>>12,b=[];for(var c=0;c<a;c++){var d=c<<12;d=this.mem32s.subarray(d>>2,d+4096>>2);let e=!0;for(let g=0;g<d.length;g++)if(0!==d[g]){e=!1;break}e||b.push(c)}a=new r.Bitmap(a);c=new Uint8Array(b.length<<12);for(let [e,g]of b.entries())a.set(g,1),b=g<<12,b=this.mem8.subarray(b,b+4096),c.set(b,e<<12);return{bitmap:a,packed_memory:c}};
E.prototype.unpack_memory=function(a,b){this.zero_memory(this.memory_size[0]);const c=this.memory_size[0]>>12;let d=0;for(let g=0;g<c;g++)if(a.get(g)){var e=d<<12;e=b.subarray(e,e+4096);this.mem8.set(e,g<<12);d++}};E.prototype.reboot_internal=function(){this.reset_cpu();this.fw_value=[];this.devices.virtio_9p&&this.devices.virtio_9p.reset();this.devices.virtio_console&&this.devices.virtio_console.reset();this.load_bios()};E.prototype.reset_memory=function(){this.mem8.fill(0)};
E.prototype.create_memory=function(a){1048576>a?a=1048576:0>(a|0)&&(a=Math.pow(2,31)-131072);a=(a-1|131071)+1|0;console.assert(0===this.memory_size[0],"Expected uninitialised memory");this.memory_size[0]=a;const b=this.allocate_memory(a);this.mem8=r.view(Uint8Array,this.wasm_memory,b,a);this.mem32s=r.view(Uint32Array,this.wasm_memory,b,a>>2)};F.exportProperty(E.prototype,"create_memory",E.prototype.create_memory);
E.prototype.init=function(a,b){this.create_memory("number"===typeof a.memory_size?a.memory_size:67108864);a.disable_jit&&this.set_jit_config(0,1);a.cpuid_level&&this.set_cpuid_level(a.cpuid_level);this.acpi_enabled[0]=+a.acpi;this.reset_cpu();var c=new B(this);this.io=c;this.bios.main=a.bios;this.bios.vga=a.vga_bios;this.load_bios();if(a.bzimage){const e=Za(this.mem8,a.bzimage,a.initrd,a.cmdline||"");e&&this.option_roms.push(e)}c.register_read(179,this,function(){return 0});var d=0;c.register_read(146,
this,function(){return d});c.register_write(146,this,function(e){d=e});c.register_read(1297,this,function(){return this.fw_pointer<this.fw_value.length?this.fw_value[this.fw_pointer++]:0});c.register_write(1296,this,void 0,function(e){function g(l){return new Uint8Array(Int32Array.of(l).buffer)}function f(l){return l>>8|l<<8&65280}function k(l){return l<<24|l<<8&16711680|l>>8&65280|l>>>24}J("bios config port, index="+A(e));this.fw_pointer=0;if(0===e)this.fw_value=g(1431127377);else if(1===e)this.fw_value=
g(0);else if(3===e)this.fw_value=g(this.memory_size[0]);else if(5===e)this.fw_value=g(1);else if(15===e)this.fw_value=g(1);else if(13===e)this.fw_value=new Uint8Array(16);else if(25===e){e=new Int32Array(4+64*this.option_roms.length);const l=new Uint8Array(e.buffer);e[0]=k(this.option_roms.length);for(let m=0;m<this.option_roms.length;m++){const {name:n,data:p}=this.option_roms[m],t=4+64*m;e[t+0>>2]=k(p.length);e[t+4>>2]=f(49152+m);for(let q=0;q<n.length;q++)l[t+8+q]=n.charCodeAt(q)}this.fw_value=
l}else 32768<=e&&49152>e?this.fw_value=g(0):49152<=e&&e-49152<this.option_roms.length?this.fw_value=this.option_roms[e-49152].data:(J("Warning: Unimplemented fw index: "+A(e)),this.fw_value=g(0))});c.register_read(32,this,this.port20_read);c.register_read(33,this,this.port21_read);c.register_read(160,this,this.portA0_read);c.register_read(161,this,this.portA1_read);c.register_write(32,this,this.port20_write);c.register_write(33,this,this.port21_write);c.register_write(160,this,this.portA0_write);
c.register_write(161,this,this.portA1_write);c.register_read(1232,this,this.port4D0_read);c.register_read(1233,this,this.port4D1_read);c.register_write(1232,this,this.port4D0_write);c.register_write(1233,this,this.port4D1_write);this.devices={};a.load_devices&&(this.devices.pci=new pa(this),this.acpi_enabled[0]&&(this.devices.ioapic=new ya(this),this.devices.apic=new O(this),this.devices.acpi=new xa(this)),this.devices.rtc=new va(this),this.fill_cmos(this.devices.rtc,a),this.devices.dma=new L(this),
this.devices.vga=new M(this,b,a.vga_memory_size||8388608),this.devices.ps2=new N(this,b),this.devices.uart0=new wa(this,1016,b),a.uart1&&(this.devices.uart1=new wa(this,760,b)),a.uart2&&(this.devices.uart2=new wa(this,1E3,b)),a.uart3&&(this.devices.uart3=new wa(this,744,b)),this.devices.fdc=new K(this,a.fda,a.fdb),c=0,a.hda&&(this.devices.hda=new G(this,a.hda,a.hdb,!1,c++,b)),a.cdrom&&(this.devices.cdrom=new G(this,a.cdrom,void 0,!0,c++,b)),this.devices.pit=new qa(this,b),a.enable_ne2k&&(this.devices.net=
new Fa(this,b,a.preserve_mac_from_state_image,a.mac_address_translation)),a.fs9p&&(this.devices.virtio_9p=new da(a.fs9p,this,b)),a.virtio_console&&(this.devices.virtio_console=new Wa(this,b)),this.devices.sb16=new Q(this,b));a.multiboot&&(a=this.load_multiboot_option_rom(a.multiboot,a.initrd,a.cmdline))&&(this.bios.main?this.option_roms.push(a):this.reg32[0]=this.io.port_read32(244))};E.prototype.load_multiboot=function(a){this.load_multiboot_option_rom(a,void 0,"")&&(this.reg32[0]=this.io.port_read32(244))};
E.prototype.load_multiboot_option_rom=function(a,b,c){if(8192>a.byteLength){var d=new Int32Array(2048);(new Uint8Array(d.buffer)).set(new Uint8Array(a))}else d=new Int32Array(a,0,2048);for(var e=0;8192>e;e+=4){if(464367618===d[e>>2]){var g=d[e+4>>2];if(464367618+g+d[e+8>>2]|0)continue}else continue;J("Multiboot magic found, flags: "+A(g>>>0,8),2);var f=this;this.io.register_read(244,this,function(){return 0},function(){return 0},function(){var n=31860,p=0;if(c){p|=4;f.write32(31760,n);c+="\x00";var t=
(new TextEncoder).encode(c);f.write_blob(t,n);n+=t.length}if(g&2){p|=64;t=0;f.write32(31788,0);f.write32(31792,n);var q=0;var z=!1;for(let u=0;4294967296>u;u+=131072)z&&void 0!==f.memory_map_read8[u>>>17]?(f.write32(n,20),f.write32(n+4,q),f.write32(n+8,0),f.write32(n+12,u-q),f.write32(n+16,0),f.write32(n+20,1),n+=24,t+=24,z=!1):z||void 0!==f.memory_map_read8[u>>>17]||(q=u,z=!0);f.write32(31788,t)}f.write32(31744,p);t=p=0;if(g&65536){z=d[e+12>>2];p=d[e+16>>2];var w=d[e+20>>2];t=d[e+24>>2];q=d[e+28>>
2];A(z,8);A(p,8);A(w,8);A(t,8);A(q,8);z=new Uint8Array(a,e-(z-p),0===w?void 0:w-p);f.write_blob(z,p);p=q|0;t=Math.max(w,t)}else if(1179403647===d[0]){q=new DataView(a);let [u,I]=$a(q,ab);console.assert(52===I);console.assert(1179403647===u.magic,"Bad magic");console.assert(1===u.class,"Unimplemented: 64 bit elf");console.assert(1===u.data,"Unimplemented: big endian");console.assert(1===u.version0,"Bad version0");console.assert(2===u.type,"Unimplemented type");console.assert(1===u.version1,"Bad version1");
console.assert(52===u.ehsize,"Bad header size");console.assert(32===u.phentsize,"Bad program header size");console.assert(40===u.shentsize,"Bad section header size");[p]=bb(new DataView(q.buffer,q.byteOffset+u.phoff,u.phentsize*u.phnum),cb,u.phnum);bb(new DataView(q.buffer,q.byteOffset+u.shoff,u.shentsize*u.shnum),gb,u.shnum);q=u;z=p;p=q.entry;for(w of z)0!==w.type&&(1===w.type?w.paddr+w.memsz<f.memory_size[0]?(w.filesz&&(z=new Uint8Array(a,w.offset,w.filesz),f.write_blob(z,w.paddr)),t=Math.max(t,
w.paddr+w.memsz),p===q.entry&&w.vaddr<=p&&w.vaddr+w.memsz>p&&(p=p-w.vaddr+w.paddr)):A(w.paddr):2===w.type||3===w.type||4===w.type||6===w.type||7===w.type||1685382480===w.type||1685382481===w.type||1685382482===w.type||1685382483===w.type||A(w.type))}b&&(f.write32(31764,1),f.write32(31768,n),w=t,0!==(w&4095)&&(w=(w&-4096)+4096),t=w+b.byteLength,f.write32(n,w),f.write32(n+4,t),f.write32(n+8,0),f.write32(n+12,0),f.write_blob(new Uint8Array(b),w));f.reg32[3]=31744;f.cr[0]=1;f.protected_mode[0]=1;f.flags[0]=
2;f.is_32[0]=1;f.stack_size_32[0]=1;for(n=0;6>n;n++)f.segment_is_null[n]=0,f.segment_offsets[n]=0,f.segment_limits[n]=4294967295,f.sreg[n]=45058;f.instruction_pointer[0]=f.get_seg_cs()+p|0;f.update_state_flags();f.debug.dump_state();f.debug.dump_regs();return 732803074});this.io.register_write_consecutive(244,this,function(n){console.log("Test exited with code "+A(n,2));throw"HALT";},function(){},function(){},function(){});for(let n=0;15>=n;n++){function p(t){A(n);A(t,2);t?this.device_raise_irq(n):
this.device_lower_irq(n)}this.io.register_write(8192+n,this,p,p,p)}const l=new Uint8Array(512);(new Uint16Array(l.buffer))[0]=43605;l[2]=1;var k=3;l[k++]=102;l[k++]=229;l[k++]=244;let m=l[k]=0;for(let n=0;n<l.length;n++)m+=l[n];l[k]=-m;return{name:"genroms/multiboot.bin",data:l}}};
E.prototype.fill_cmos=function(a,b){var c=b.boot_order||291;a.cmos_write(56,1|c>>4&240);a.cmos_write(61,c&255);a.cmos_write(21,128);a.cmos_write(22,2);c=0;1048576<=this.memory_size[0]&&(c=this.memory_size[0]-1048576>>10,c=Math.min(c,65535));a.cmos_write(23,c&255);a.cmos_write(24,c>>8&255);a.cmos_write(48,c&255);a.cmos_write(49,c>>8&255);c=0;16777216<=this.memory_size[0]&&(c=this.memory_size[0]-16777216>>16,c=Math.min(c,65535));a.cmos_write(52,c&255);a.cmos_write(53,c>>8&255);a.cmos_write(91,0);a.cmos_write(92,
0);a.cmos_write(93,0);a.cmos_write(20,47);a.cmos_write(95,0);b.fastboot&&a.cmos_write(63,1)};
E.prototype.load_bios=function(){var a=this.bios.main,b=this.bios.vga;if(a){var c=new Uint8Array(a);this.write_blob(c,1048576-a.byteLength);if(b){var d=new Uint8Array(b);this.write_blob(d,786432);this.io.mmap_register(4272947200,1048576,function(e){e=e-4272947200|0;return e<d.length?d[e]:0},function(){})}this.io.mmap_register(4293918720,1048576,function(e){return this.mem8[e&1048575]}.bind(this),function(e,g){this.mem8[e&1048575]=g}.bind(this))}};
E.prototype.codegen_finalize=function(a,b,c,d,e){const g=new Uint8Array(this.wasm_memory.buffer,d>>>0,e>>>0);WebAssembly.instantiate(g,{e:this.jit_imports}).then(f=>{this.wm.wasm_table.set(a+1024,f.instance.exports.f);this.codegen_finalize_finished(a,b,c);this.test_hook_did_finalize_wasm&&this.test_hook_did_finalize_wasm(g)})};E.prototype.log_uncompiled_code=function(){};E.prototype.dump_function_code=function(){};
E.prototype.run_hardware_timers=function(a,b){const c=this.devices.pit.timer(b,!1),d=this.devices.rtc.timer(b,!1);let e=100,g=100;a&&(e=this.devices.acpi.timer(b),g=this.devices.apic.timer(b));return Math.min(c,d,e,g)};E.prototype.device_raise_irq=function(a){this.pic_set_irq(a);this.devices.ioapic&&this.devices.ioapic.set_irq(a)};E.prototype.device_lower_irq=function(a){this.pic_clear_irq(a);this.devices.ioapic&&this.devices.ioapic.clear_irq(a)};
"undefined"!==typeof window?window.CPU=E:"undefined"!==typeof module&&"undefined"!==typeof module.exports?module.exports.CPU=E:"function"===typeof importScripts&&(self.CPU=E);E.prototype.debug_init=function(){var a=this,b={};this.debug=b;b.init=function(){};b.get_regs_short=function(){};b.dump_regs=function(){};b.get_state=function(){};b.dump_state=function(){};b.dump_stack=function(){};b.dump_page_structures=function(){if(a.cr[4]&32)for(var g=0;4>g;g++)a.read32s(a.cr[3]+8*g)};b.dump_gdt_ldt=function(){};b.dump_idt=function(){};b.get_memory_dump=function(){};b.memory_hex_dump=function(){};b.used_memory_dump=function(){};b.debug_interrupt=function(){};let c,d;b.dump_code=
function(g,f,k){if(!d){if(void 0===c&&(c="function"===typeof require?require("./capstone-x86.min.js"):window.cs,void 0===c))return;d=[new c.Capstone(c.ARCH_X86,c.MODE_16),new c.Capstone(c.ARCH_X86,c.MODE_32)]}try{d[g].disasm(f,k).forEach(function(l){J(A(l.address>>>0)+": "+r.pads(l.bytes.map(m=>A(m,2).slice(-2)).join(" "),20)+" "+l.mnemonic+" "+l.op_str)})}catch(l){J("Could not disassemble: "+Array.from(f).map(m=>A(m,2)).join(" "))}};let e;b.dump_wasm=function(g){if(void 0===e&&(e="function"===typeof require?
require("./libwabt.js"):new window.WabtModule,void 0===e))return;g=g.slice();try{var f=e.readWasm(g,{readDebugNames:!1});f.generateNames();f.applyNames();f.toText({foldExprs:!0,inlineExport:!0})}catch(m){var k=new Blob([g]),l=document.createElement("a");l.download="failed.wasm";l.href=window.URL.createObjectURL(k);l.dataset.downloadurl=["application/octet-stream",l.download,l.href].join(":");l.click();window.URL.revokeObjectURL(l.src);console.log(m.toString())}finally{f&&f.destroy()}}};let hb=DataView.prototype,ib={size:1,get:hb.getUint8,set:hb.setUint8},jb={size:2,get:hb.getUint16,set:hb.setUint16},X={size:4,get:hb.getUint32,set:hb.setUint32},ab=kb([{magic:X},{class:ib},{data:ib},{version0:ib},{osabi:ib},{abiversion:ib},{pad0:function(a){return{size:a,get:()=>-1}}(7)},{type:jb},{machine:jb},{version1:X},{entry:X},{phoff:X},{shoff:X},{flags:X},{ehsize:jb},{phentsize:jb},{phnum:jb},{shentsize:jb},{shnum:jb},{shstrndx:jb}]);console.assert(52===ab.reduce((a,b)=>a+b.size,0));
let cb=kb([{type:X},{offset:X},{vaddr:X},{paddr:X},{filesz:X},{memsz:X},{flags:X},{align:X}]);console.assert(32===cb.reduce((a,b)=>a+b.size,0));let gb=kb([{name:X},{type:X},{flags:X},{addr:X},{offset:X},{size:X},{link:X},{info:X},{addralign:X},{entsize:X}]);console.assert(40===gb.reduce((a,b)=>a+b.size,0));function kb(a){return a.map(function(b){var c=Object.keys(b);console.assert(1===c.length);c=c[0];b=b[c];console.assert(0<b.size);return{name:c,type:b,size:b.size,get:b.get,set:b.set}})}
function $a(a,b){let c={},d=0;for(let e of b)b=e.get.call(a,d,!0),console.assert(void 0===c[e.name]),c[e.name]=b,d+=e.size;return[c,d]}function bb(a,b,c){let d=[],e=0;for(var g=0;g<c;g++){let [f,k]=$a(new DataView(a.buffer,a.byteOffset+e,void 0),b);d.push(f);e+=k}return[d,e]};function Za(a,b,c,d){var e=new Uint8Array(b);const g=new Uint16Array(b);var f=new Uint32Array(b),k=e[497]||4,l=g[255];if(43605!==l)A(l);else if(l=g[257]|g[258]<<16,1400005704!==l)A(l);else{l=e[529];var m=g[283],n=f[139],p=f[140],t=e[565],q=f[142],z=f[146],w=f[147],u=f[150],I=f[151],U=f[152];A(g[259]);A(l);A(m);A(f[133]);A(n);A(p);A(t);A(q);A(z);A(w);A(I);A(u);A(U);e[528]=255;e[529]=l&-97|128;g[274]=56832;g[253]=65535;A(56832);d+="\x00";A(581632);f[138]=581632;for(e=0;e<d.length;e++)a[581632+e]=d.charCodeAt(e);
k=512*(k+1);A(k);d=new Uint8Array(b,0,k);b=new Uint8Array(b,k);e=k=0;c&&(k=67108864,e=c.byteLength,a.set(new Uint8Array(c),k));f[134]=k;f[135]=e;a.set(d,524288);a.set(b,1048576);a=new Uint8Array(512);(new Uint16Array(a.buffer))[0]=43605;a[2]=1;c=3;a[c++]=250;a[c++]=184;a[c++]=32768;a[c++]=128;a[c++]=142;a[c++]=192;a[c++]=142;a[c++]=216;a[c++]=142;a[c++]=224;a[c++]=142;a[c++]=232;a[c++]=142;a[c++]=208;a[c++]=188;a[c++]=57344;a[c++]=224;a[c++]=234;a[c++]=0;a[c++]=0;a[c++]=32800;a[c++]=128;f=a[c]=0;
for(b=0;b<a.length;b++)f+=a[b];a[c]=-f;return{name:"genroms/kernel.bin",data:a}}};function lb(a){function b(q){!q.altKey&&k[56]&&g(56,!1);return e(q,!1)}function c(q){!q.altKey&&k[56]&&g(56,!1);return e(q,!0)}function d(){for(var q=Object.keys(k),z,w=0;w<q.length;w++)z=+q[w],k[z]&&g(z,!1);k={}}function e(q,z){var w;if(w=l.bus)w=q.shiftKey&&q.ctrlKey&&(73===q.keyCode||74===q.keyCode||75===q.keyCode)||!l.emu_enabled?!1:q.target?q.target.classList.contains("phone_keyboard")||"INPUT"!==q.target.nodeName&&"TEXTAREA"!==q.target.nodeName:!0;if(w){a:{if(void 0!==q.code&&(w=t[q.code],void 0!==
w))break a;w=m[q.keyCode]}if(w)return g(w,z,q.repeat),q.preventDefault&&q.preventDefault(),!1;console.log("Missing char in map: keyCode="+(q.keyCode||-1).toString(16)+" code="+q.code)}}function g(q,z,w){if(z)k[q]&&!w&&g(q,!1);else if(!k[q])return;(k[q]=z)||(q|=128);255<q?(f(q>>8),f(q&255)):f(q)}function f(q){l.bus.send("keyboard-code",q)}var k={},l=this;this.emu_enabled=!0;var m=new Uint16Array([0,0,0,0,0,0,0,0,14,15,0,0,0,28,0,0,42,29,56,0,58,0,0,0,0,0,0,1,0,0,0,0,57,57417,57425,57423,57415,57419,
57416,57421,80,0,0,0,0,82,83,0,11,2,3,4,5,6,7,8,9,10,0,39,0,13,0,0,0,30,48,46,32,18,33,34,35,23,36,37,38,50,49,24,25,16,19,31,20,22,47,17,45,21,44,57435,57436,57437,0,0,82,79,80,81,75,76,77,71,72,73,0,0,0,0,0,0,59,60,61,62,63,64,65,66,67,68,87,88,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,69,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,39,13,51,12,52,53,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,43,27,40,0,57435,57400,0,0,0,0,0,0,0,0,0,0,0,0,0,0]),
n={8:8,10:13,32:32,39:222,44:188,45:189,46:190,47:191,48:48,49:49,50:50,51:51,52:52,53:53,54:54,55:55,56:56,57:57,59:186,61:187,91:219,92:220,93:221,96:192,97:65,98:66,99:67,100:68,101:69,102:70,103:71,104:72,105:73,106:74,107:75,108:76,109:77,110:78,111:79,112:80,113:81,114:82,115:83,116:84,117:85,118:86,119:87,120:88,121:89,122:90},p={33:49,34:222,35:51,36:52,37:53,38:55,40:57,41:48,42:56,43:187,58:186,60:188,62:190,63:191,64:50,65:65,66:66,67:67,68:68,69:69,70:70,71:71,72:72,73:73,74:74,75:75,
76:76,77:77,78:78,79:79,80:80,81:81,82:82,83:83,84:84,85:85,86:86,87:87,88:88,89:89,90:90,94:54,95:189,123:219,124:220,125:221,126:192},t={Escape:1,Digit1:2,Digit2:3,Digit3:4,Digit4:5,Digit5:6,Digit6:7,Digit7:8,Digit8:9,Digit9:10,Digit0:11,Minus:12,Equal:13,Backspace:14,Tab:15,KeyQ:16,KeyW:17,KeyE:18,KeyR:19,KeyT:20,KeyY:21,KeyU:22,KeyI:23,KeyO:24,KeyP:25,BracketLeft:26,BracketRight:27,Enter:28,ControlLeft:29,KeyA:30,KeyS:31,KeyD:32,KeyF:33,KeyG:34,KeyH:35,KeyJ:36,KeyK:37,KeyL:38,Semicolon:39,Quote:40,
Backquote:41,ShiftLeft:42,Backslash:43,KeyZ:44,KeyX:45,KeyC:46,KeyV:47,KeyB:48,KeyN:49,KeyM:50,Comma:51,Period:52,Slash:53,IntlRo:53,ShiftRight:54,NumpadMultiply:55,AltLeft:56,Space:57,CapsLock:58,F1:59,F2:60,F3:61,F4:62,F5:63,F6:64,F7:65,F8:66,F9:67,F10:68,NumLock:69,ScrollLock:70,Numpad7:71,Numpad8:72,Numpad9:73,NumpadSubtract:74,Numpad4:75,Numpad5:76,Numpad6:77,NumpadAdd:78,Numpad1:79,Numpad2:80,Numpad3:81,Numpad0:82,NumpadDecimal:83,IntlBackslash:86,F11:87,F12:88,NumpadEnter:57372,ControlRight:57373,
NumpadDivide:57397,AltRight:57400,Home:57415,ArrowUp:57416,PageUp:57417,ArrowLeft:57419,ArrowRight:57421,End:57423,ArrowDown:57424,PageDown:57425,Insert:57426,Delete:57427,OSLeft:57435,OSRight:57436,ContextMenu:57437};this.bus=a;this.destroy=function(){"undefined"!==typeof window&&(window.removeEventListener("keyup",b,!1),window.removeEventListener("keydown",c,!1),window.removeEventListener("blur",d,!1))};this.init=function(){"undefined"!==typeof window&&(this.destroy(),window.addEventListener("keyup",
b,!1),window.addEventListener("keydown",c,!1),window.addEventListener("blur",d,!1))};this.init();this.simulate_press=function(q){q={keyCode:q};e(q,!0);e(q,!1)};this.simulate_char=function(q){var z=q.charCodeAt(0);z in n?this.simulate_press(n[z]):z in p?(f(42),this.simulate_press(p[z]),f(170)):console.log("ascii -> keyCode not found: ",z,q)}};function mb(a,b){function c(u){if(!w.enabled||!w.emu_enabled)return!1;var I=b||document.body,U;if(!(U=document.pointerLockElement))a:{for(u=u.target;u.parentNode;){if(u===I){U=!0;break a}u=u.parentNode}U=!1}return U}function d(u){c(u)&&(u=u.changedTouches)&&u.length&&(u=u[u.length-1],q=u.clientX,z=u.clientY)}function e(){if(n||t||p)w.bus.send("mouse-click",[!1,!1,!1]),n=t=p=!1}function g(u){if(w.bus&&c(u)&&w.is_running){var I=0,U=0,ea=u.changedTouches;ea?ea.length&&(ea=ea[ea.length-1],I=ea.clientX-
q,U=ea.clientY-z,q=ea.clientX,z=ea.clientY,u.preventDefault()):"number"===typeof u.movementX?(I=u.movementX,U=u.movementY):"number"===typeof u.webkitMovementX?(I=u.webkitMovementX,U=u.webkitMovementY):"number"===typeof u.mozMovementX?(I=u.mozMovementX,U=u.mozMovementY):(I=u.clientX-q,U=u.clientY-z,q=u.clientX,z=u.clientY);w.bus.send("mouse-delta",[.15*I,-(.15*U)]);b&&w.bus.send("mouse-absolute",[u.pageX-b.offsetLeft,u.pageY-b.offsetTop,b.offsetWidth,b.offsetHeight])}}function f(u){c(u)&&l(u,!0)}function k(u){c(u)&&
l(u,!1)}function l(u,I){w.bus&&(1===u.which?n=I:2===u.which?t=I:3===u.which&&(p=I),w.bus.send("mouse-click",[n,t,p]),u.preventDefault())}function m(u){if(c(u)){var I=u.wheelDelta||-u.detail;0>I?I=-1:0<I&&(I=1);w.bus.send("mouse-wheel",[I,0]);u.preventDefault()}}var n=!1,p=!1,t=!1,q=0,z=0,w=this;this.enabled=!1;this.emu_enabled=!0;this.bus=a;this.bus.register("mouse-enable",function(u){this.enabled=u},this);this.is_running=!1;this.bus.register("emulator-stopped",function(){this.is_running=!1},this);
this.bus.register("emulator-started",function(){this.is_running=!0},this);this.destroy=function(){"undefined"!==typeof window&&(window.removeEventListener("touchstart",d,!1),window.removeEventListener("touchend",e,!1),window.removeEventListener("touchmove",g,!1),window.removeEventListener("mousemove",g,!1),window.removeEventListener("mousedown",f,!1),window.removeEventListener("mouseup",k,!1),window.removeEventListener("wheel",m,{passive:!1}))};this.init=function(){"undefined"!==typeof window&&(this.destroy(),
window.addEventListener("touchstart",d,!1),window.addEventListener("touchend",e,!1),window.addEventListener("touchmove",g,!1),window.addEventListener("mousemove",g,!1),window.addEventListener("mousedown",f,!1),window.addEventListener("mouseup",k,!1),window.addEventListener("wheel",m,{passive:!1}))};this.init()};function nb(a){if("undefined"!==typeof window)if(window.AudioContext||window.webkitAudioContext){var b=window.AudioWorklet?ob:pb;this.bus=a;this.audio_context=window.AudioContext?new AudioContext:new webkitAudioContext;this.mixer=new qb(a,this.audio_context);this.pcspeaker=new rb(a,this.audio_context,this.mixer);this.dac=new b(a,this.audio_context,this.mixer);this.pcspeaker.start();a.register("emulator-stopped",function(){this.audio_context.suspend()},this);a.register("emulator-started",function(){this.audio_context.resume()},
this);a.register("speaker-confirm-initialized",function(){a.send("speaker-has-initialized")},this);a.send("speaker-has-initialized")}else console.warn("Web browser doesn't support Web Audio API")}nb.prototype.destroy=function(){this.audio_context&&this.audio_context.close();this.audio_context=null;this.dac&&this.dac.node_processor&&this.dac.node_processor.port.close();this.dac=null};
function qb(a,b){function c(d){return function(e){d.gain.setValueAtTime(e,this.audio_context.currentTime)}}this.audio_context=b;this.sources=new Map;this.gain_right=this.gain_left=this.volume_right=this.volume_left=this.volume_both=1;this.node_treble_left=this.audio_context.createBiquadFilter();this.node_treble_right=this.audio_context.createBiquadFilter();this.node_treble_left.type="highshelf";this.node_treble_right.type="highshelf";this.node_treble_left.frequency.setValueAtTime(2E3,this.audio_context.currentTime);
this.node_treble_right.frequency.setValueAtTime(2E3,this.audio_context.currentTime);this.node_bass_left=this.audio_context.createBiquadFilter();this.node_bass_right=this.audio_context.createBiquadFilter();this.node_bass_left.type="lowshelf";this.node_bass_right.type="lowshelf";this.node_bass_left.frequency.setValueAtTime(200,this.audio_context.currentTime);this.node_bass_right.frequency.setValueAtTime(200,this.audio_context.currentTime);this.node_gain_left=this.audio_context.createGain();this.node_gain_right=
this.audio_context.createGain();this.node_merger=this.audio_context.createChannelMerger(2);this.input_left=this.node_treble_left;this.input_right=this.node_treble_right;this.node_treble_left.connect(this.node_bass_left);this.node_bass_left.connect(this.node_gain_left);this.node_gain_left.connect(this.node_merger,0,0);this.node_treble_right.connect(this.node_bass_right);this.node_bass_right.connect(this.node_gain_right);this.node_gain_right.connect(this.node_merger,0,1);this.node_merger.connect(this.audio_context.destination);
a.register("mixer-connect",function(d){this.connect_source(d[0],d[1])},this);a.register("mixer-disconnect",function(d){this.disconnect_source(d[0],d[1])},this);a.register("mixer-volume",function(d){var e=d[0],g=d[1];d=Math.pow(10,d[2]/20);e=0===e?this:this.sources.get(e);void 0===e||e.set_volume(d,g)},this);a.register("mixer-gain-left",function(d){this.gain_left=Math.pow(10,d/20);this.update()},this);a.register("mixer-gain-right",function(d){this.gain_right=Math.pow(10,d/20);this.update()},this);
a.register("mixer-treble-left",c(this.node_treble_left),this);a.register("mixer-treble-right",c(this.node_treble_right),this);a.register("mixer-bass-left",c(this.node_bass_left),this);a.register("mixer-bass-right",c(this.node_bass_right),this)}qb.prototype.add_source=function(a,b){a=new sb(this.audio_context,a,this.input_left,this.input_right);this.sources.has(b);this.sources.set(b,a);return a};qb.prototype.connect_source=function(a,b){a=this.sources.get(a);void 0===a||a.connect(b)};
qb.prototype.disconnect_source=function(a,b){a=this.sources.get(a);void 0===a||a.disconnect(b)};qb.prototype.set_volume=function(a,b){void 0===b&&(b=2);switch(b){case 0:this.volume_left=a;break;case 1:this.volume_right=a;break;case 2:this.volume_both=a;break;default:return}this.update()};
qb.prototype.update=function(){var a=this.volume_both*this.volume_right*this.gain_right;this.node_gain_left.gain.setValueAtTime(this.volume_both*this.volume_left*this.gain_left,this.audio_context.currentTime);this.node_gain_right.gain.setValueAtTime(a,this.audio_context.currentTime)};
function sb(a,b,c,d){this.audio_context=a;this.connected_right=this.connected_left=!0;this.volume_right=this.volume_left=this.volume_both=this.gain_hidden=1;this.node_splitter=a.createChannelSplitter(2);this.node_gain_left=a.createGain();this.node_gain_right=a.createGain();b.connect(this.node_splitter);this.node_splitter.connect(this.node_gain_left,0);this.node_gain_left.connect(c);this.node_splitter.connect(this.node_gain_right,1);this.node_gain_right.connect(d)}
sb.prototype.update=function(){var a=this.connected_right*this.gain_hidden*this.volume_both*this.volume_right;this.node_gain_left.gain.setValueAtTime(this.connected_left*this.gain_hidden*this.volume_both*this.volume_left,this.audio_context.currentTime);this.node_gain_right.gain.setValueAtTime(a,this.audio_context.currentTime)};sb.prototype.connect=function(a){var b=!a||2===a;if(b||0===a)this.connected_left=!0;if(b||1===a)this.connected_right=!0;this.update()};
sb.prototype.disconnect=function(a){var b=!a||2===a;if(b||0===a)this.connected_left=!1;if(b||1===a)this.connected_right=!1;this.update()};sb.prototype.set_volume=function(a,b){void 0===b&&(b=2);switch(b){case 0:this.volume_left=a;break;case 1:this.volume_right=a;break;case 2:this.volume_both=a;break;default:return}this.update()};sb.prototype.set_gain_hidden=function(a){this.gain_hidden=a};
function rb(a,b,c){this.node_oscillator=b.createOscillator();this.node_oscillator.type="square";this.node_oscillator.frequency.setValueAtTime(440,b.currentTime);this.mixer_connection=c.add_source(this.node_oscillator,1);this.mixer_connection.disconnect();a.register("pcspeaker-enable",function(){c.connect_source(1)},this);a.register("pcspeaker-disable",function(){c.disconnect_source(1)},this);a.register("pcspeaker-update",function(d){var e=d[1],g=0;3===d[0]&&(g=Math.min(1193181.6665999999/e,this.node_oscillator.frequency.maxValue),
g=Math.max(g,0));this.node_oscillator.frequency.setValueAtTime(g,b.currentTime)},this)}rb.prototype.start=function(){this.node_oscillator.start()};
function ob(a,b,c){this.bus=a;this.audio_context=b;this.enabled=!1;this.sampling_rate=48E3;b=function(){function f(m){if(0===m)return 1;m*=Math.PI;return Math.sin(m)/m}function k(){var m=Reflect.construct(AudioWorkletProcessor,[],k);m.kernel_size=3;m.queue_data=Array(1024);m.queue_start=0;m.queue_end=0;m.queue_length=0;m.queue_size=m.queue_data.length;m.queued_samples=0;m.source_buffer_previous=l;m.source_buffer_current=l;m.source_samples_per_destination=1;m.source_block_start=0;m.source_time=0;m.source_offset=
0;m.port.onmessage=n=>{switch(n.data.type){case "queue":m.queue_push(n.data.value);break;case "sampling-rate":m.source_samples_per_destination=n.data.value/sampleRate}};return m}var l=[new Float32Array(256),new Float32Array(256)];Reflect.setPrototypeOf(k.prototype,AudioWorkletProcessor.prototype);Reflect.setPrototypeOf(k,AudioWorkletProcessor);k.prototype.process=k.prototype.process=function(m,n){for(m=0;m<n[0][0].length;m++){for(var p=0,t=0,q=this.source_offset+this.kernel_size,z=this.source_offset-
this.kernel_size+1;z<=q;z++){var w=this.source_block_start+z;p+=this.get_sample(w,0)*this.kernel(this.source_time-z);t+=this.get_sample(w,1)*this.kernel(this.source_time-z)}if(isNaN(p)||isNaN(t))p=t=0,this.dbg_log("ERROR: NaN values! Ignoring for now.");n[0][0][m]=p;n[0][1][m]=t;this.source_time+=this.source_samples_per_destination;this.source_offset=Math.floor(this.source_time)}n=this.source_offset;n+=this.kernel_size+2;this.source_time-=this.source_offset;this.source_block_start+=this.source_offset;
this.source_offset=0;this.ensure_enough_data(n);return!0};k.prototype.kernel=function(m){return f(m)*f(m/this.kernel_size)};k.prototype.get_sample=function(m,n){return 0>m?(m+=this.source_buffer_previous[0].length,this.source_buffer_previous[n][m]):this.source_buffer_current[n][m]};k.prototype.ensure_enough_data=function(m){var n=this.source_buffer_current[0].length;n-this.source_block_start<m&&(this.prepare_next_buffer(),this.source_block_start-=n)};k.prototype.prepare_next_buffer=function(){256>
this.queued_samples&&this.queue_length&&this.dbg_log("Not enough samples - should not happen during midway of playback");this.source_buffer_previous=this.source_buffer_current;this.source_buffer_current=this.queue_shift();var m=this.source_buffer_current[0].length;if(256>m){for(var n=this.queue_start,p=0;256>m&&p<this.queue_length;)m+=this.queue_data[n][0].length,n=n+1&this.queue_size-1,p++;m=Math.max(m,256);m=[new Float32Array(m),new Float32Array(m)];m[0].set(this.source_buffer_current[0]);m[1].set(this.source_buffer_current[1]);
n=this.source_buffer_current[0].length;for(var t=0;t<p;t++){var q=this.queue_shift();m[0].set(q[0],n);m[1].set(q[1],n);n+=q[0].length}this.source_buffer_current=m}this.pump()};k.prototype.pump=function(){1024>this.queued_samples/this.source_samples_per_destination&&this.port.postMessage({type:"pump"})};k.prototype.queue_push=function(m){this.queue_length<this.queue_size&&(this.queue_data[this.queue_end]=m,this.queue_end=this.queue_end+1&this.queue_size-1,this.queue_length++,this.queued_samples+=m[0].length,
this.pump())};k.prototype.queue_shift=function(){if(!this.queue_length)return l;var m=this.queue_data[this.queue_start];this.queue_data[this.queue_start]=null;this.queue_start=this.queue_start+1&this.queue_size-1;this.queue_length--;this.queued_samples-=m[0].length;return m};k.prototype.dbg_log=function(){};registerProcessor("dac-processor",k)}.toString();var d=b.indexOf("{")+1,e=b.lastIndexOf("}");b=b.substring(d,e);b=new Blob([b],{type:"application/javascript"});var g=URL.createObjectURL(b);this.node_processor=
null;this.node_output=this.audio_context.createGain();this.audio_context.audioWorklet.addModule(g).then(()=>{URL.revokeObjectURL(g);this.node_processor=new AudioWorkletNode(this.audio_context,"dac-processor",{numberOfInputs:0,numberOfOutputs:1,outputChannelCount:[2],parameterData:{},processorOptions:{}});this.node_processor.port.postMessage({type:"sampling-rate",value:this.sampling_rate});this.node_processor.port.onmessage=f=>{switch(f.data.type){case "pump":this.pump()}};this.node_processor.connect(this.node_output)});
this.mixer_connection=c.add_source(this.node_output,2);this.mixer_connection.set_gain_hidden(3);a.register("dac-send-data",function(f){this.queue(f)},this);a.register("dac-enable",function(){this.enabled=!0},this);a.register("dac-disable",function(){this.enabled=!1},this);a.register("dac-tell-sampling-rate",function(f){this.sampling_rate=f;this.node_processor&&this.node_processor.port.postMessage({type:"sampling-rate",value:f})},this)}
ob.prototype.queue=function(a){this.node_processor&&this.node_processor.port.postMessage({type:"queue",value:a},[a[0].buffer,a[1].buffer])};ob.prototype.pump=function(){this.enabled&&this.bus.send("dac-request-data")};
function pb(a,b,c){this.bus=a;this.audio_context=b;this.enabled=!1;this.sampling_rate=22050;this.buffered_time=0;this.rate_ratio=1;this.node_lowpass=this.audio_context.createBiquadFilter();this.node_lowpass.type="lowpass";this.node_output=this.node_lowpass;this.mixer_connection=c.add_source(this.node_output,2);this.mixer_connection.set_gain_hidden(3);a.register("dac-send-data",function(d){this.queue(d)},this);a.register("dac-enable",function(){this.enabled=!0;this.pump()},this);a.register("dac-disable",
function(){this.enabled=!1},this);a.register("dac-tell-sampling-rate",function(d){this.sampling_rate=d;this.rate_ratio=Math.ceil(8E3/d);this.node_lowpass.frequency.setValueAtTime(d/2,this.audio_context.currentTime)},this)}
pb.prototype.queue=function(a){var b=a[0].length,c=b/this.sampling_rate;if(1<this.rate_ratio){var d=this.audio_context.createBuffer(2,b*this.rate_ratio,this.sampling_rate*this.rate_ratio);for(var e=d.getChannelData(0),g=d.getChannelData(1),f=0,k=0;k<b;k++)for(var l=0;l<this.rate_ratio;l++,f++)e[f]=a[0][k],g[f]=a[1][k]}else d=this.audio_context.createBuffer(2,b,this.sampling_rate),d.copyToChannel?(d.copyToChannel(a[0],0),d.copyToChannel(a[1],1)):(d.getChannelData(0).set(a[0]),d.getChannelData(1).set(a[1]));
a=this.audio_context.createBufferSource();a.buffer=d;a.connect(this.node_lowpass);a.addEventListener("ended",this.pump.bind(this));d=this.audio_context.currentTime;if(this.buffered_time<d)for(this.buffered_time=d,d=.2-c,b=0;b<=d;)b+=c,this.buffered_time+=c,setTimeout(()=>this.pump(),1E3*b);a.start(this.buffered_time);this.buffered_time+=c;setTimeout(()=>this.pump(),0)};pb.prototype.pump=function(){this.enabled&&(.2<this.buffered_time-this.audio_context.currentTime||this.bus.send("dac-request-data"))};function tb(a,b){function c(k){f.bus&&f.enabled&&(f.send_char(k.which),k.preventDefault())}function d(k){var l=k.which;8===l?(f.send_char(127),k.preventDefault()):9===l&&(f.send_char(9),k.preventDefault())}function e(k){if(f.enabled){for(var l=k.clipboardData.getData("text/plain"),m=0;m<l.length;m++)f.send_char(l.charCodeAt(m));k.preventDefault()}}function g(k){k.target!==a&&a.blur()}var f=this;this.enabled=!0;this.bus=b;this.text="";this.text_new_line=!1;this.last_update=0;this.bus.register("serial0-output-byte",
function(k){k=String.fromCharCode(k);this.show_char(k)},this);this.destroy=function(){a.removeEventListener("keypress",c,!1);a.removeEventListener("keydown",d,!1);a.removeEventListener("paste",e,!1);window.removeEventListener("mousedown",g,!1)};this.init=function(){this.destroy();a.style.display="block";a.addEventListener("keypress",c,!1);a.addEventListener("keydown",d,!1);a.addEventListener("paste",e,!1);window.addEventListener("mousedown",g,!1)};this.init();this.show_char=function(k){"\b"===k?(this.text=
this.text.slice(0,-1),this.update()):"\r"!==k&&(this.text+=k,"\n"===k&&(this.text_new_line=!0),this.update())};this.update=function(){var k=Date.now(),l=k-this.last_update;16>l?void 0===this.update_timer&&(this.update_timer=setTimeout(()=>{this.update_timer=void 0;this.last_update=Date.now();this.render()},16-l)):(void 0!==this.update_timer&&(clearTimeout(this.update_timer),this.update_timer=void 0),this.last_update=k,this.render())};this.render=function(){a.value=this.text;this.text_new_line&&(this.text_new_line=
!1,a.scrollTop=1E9)};this.send_char=function(k){f.bus&&f.bus.send("serial0-input",k)}}
function ub(a,b){this.element=a;if(window.Terminal){var c=this.term=new window.Terminal({logLevel:"off"});c.write("This is the serial console. Whatever you type or paste here will be sent to COM1");var d=c.onData(function(e){for(let g=0;g<e.length;g++)b.send("serial0-input",e.charCodeAt(g))});b.register("serial0-output-byte",function(e){c.write(Uint8Array.of(e))},this);this.destroy=function(){d.dispose();c.dispose()}}}ub.prototype.show=function(){this.term&&this.term.open(this.element)};function vb(a,b){this.bus=b;this.socket=void 0;this.send_queue=[];this.url=a;this.reconnect_interval=1E4;this.last_connect_attempt=Date.now()-this.reconnect_interval;this.send_queue_limit=64;this.bus.register("net0-send",function(c){this.send(c)},this)}vb.prototype.handle_message=function(a){this.bus&&this.bus.send("net0-receive",new Uint8Array(a.data))};vb.prototype.handle_close=function(){this.connect();setTimeout(this.connect.bind(this),this.reconnect_interval)};
vb.prototype.handle_open=function(){for(var a=0;a<this.send_queue.length;a++)this.send(this.send_queue[a]);this.send_queue=[]};vb.prototype.handle_error=function(){};vb.prototype.destroy=function(){this.socket&&this.socket.close()};
vb.prototype.connect=function(){if("undefined"!==typeof WebSocket){if(this.socket){var a=this.socket.readyState;if(0===a||1===a)return}a=Date.now();this.last_connect_attempt+this.reconnect_interval>a||(this.last_connect_attempt=Date.now(),this.socket=new WebSocket(this.url),this.socket.binaryType="arraybuffer",this.socket.onopen=this.handle_open.bind(this),this.socket.onmessage=this.handle_message.bind(this),this.socket.onclose=this.handle_close.bind(this),this.socket.onerror=this.handle_error.bind(this))}};
vb.prototype.send=function(a){this.socket&&1===this.socket.readyState?this.socket.send(a):(this.send_queue.push(a),this.send_queue.length>2*this.send_queue_limit&&(this.send_queue=this.send_queue.slice(-this.send_queue_limit)),this.connect())};vb.prototype.change_proxy=function(a){this.url=a;this.socket&&(this.socket.onclose=function(){},this.socket.onerror=function(){},this.socket.close(),this.socket=void 0)};function Y(a){this.cpu_is_running=!1;this.cpu_exception_hook=function(){};var b=Xa.create();this.bus=b[0];this.emulator_bus=b[1];var c,d;const e=new WebAssembly.Table({element:"anyfunc",initial:1924});b={cpu_exception_hook:f=>this.cpu_exception_hook(f),run_hardware_timers:function(f,k){return c.run_hardware_timers(f,k)},cpu_event_halt:()=>{this.emulator_bus.send("cpu-event-halt")},abort:function(){},microtick:D.microtick,get_rand_int:function(){return r.get_rand_int()},apic_acknowledge_irq:function(){return c.devices.apic.acknowledge_irq()},
io_port_read8:function(f){return c.io.port_read8(f)},io_port_read16:function(f){return c.io.port_read16(f)},io_port_read32:function(f){return c.io.port_read32(f)},io_port_write8:function(f,k){c.io.port_write8(f,k)},io_port_write16:function(f,k){c.io.port_write16(f,k)},io_port_write32:function(f,k){c.io.port_write32(f,k)},mmap_read8:function(f){return c.mmap_read8(f)},mmap_read16:function(f){return c.mmap_read16(f)},mmap_read32:function(f){return c.mmap_read32(f)},mmap_write8:function(f,k){c.mmap_write8(f,
k)},mmap_write16:function(f,k){c.mmap_write16(f,k)},mmap_write32:function(f,k){c.mmap_write32(f,k)},mmap_write64:function(f,k,l){c.mmap_write64(f,k,l)},mmap_write128:function(f,k,l,m,n){c.mmap_write128(f,k,l,m,n)},log_from_wasm:function(f,k){r.read_sized_string_from_mem(d,f,k)},console_log_from_wasm:function(f,k){f=r.read_sized_string_from_mem(d,f,k);console.error(f)},dbg_trace_from_wasm:function(){},codegen_finalize:(f,k,l,m,n)=>{c.codegen_finalize(f,k,l,m,n)},jit_clear_func:f=>c.jit_clear_func(f),
jit_clear_all_funcs:()=>c.jit_clear_all_funcs(),__indirect_function_table:e};let g=a.wasm_fn;g||(g=f=>new Promise(k=>{let l="v86.wasm",m="v86-fallback.wasm";if(a.wasm_path){l=a.wasm_path;const n=l.lastIndexOf("/");m=(-1===n?"":l.substr(0,n))+"/"+m}else"undefined"===typeof window&&"string"===typeof __dirname?(l=__dirname+"/"+l,m=__dirname+"/"+m):(l="build/"+l,m="build/"+m);r.load_file(l,{done:async n=>{try{const {instance:p}=await WebAssembly.instantiate(n,f);this.wasm_source=n;k(p.exports)}catch(p){r.load_file(m,
{done:async t=>{const {instance:q}=await WebAssembly.instantiate(t,f);this.wasm_source=t;k(q.exports)}})}},progress:n=>{this.emulator_bus.send("download-progress",{file_index:0,file_count:1,file_name:l,lengthComputable:n.lengthComputable,total:n.total,loaded:n.loaded})}})}));g({env:b}).then(f=>{d=f.memory;f.rust_init();f=this.v86=new D(this.emulator_bus,{exports:f,wasm_table:e});c=f.cpu;this.continue_init(f,a)});this.zstd_worker=null;this.zstd_worker_request_id=0}
Y.prototype.continue_init=async function(a,b){function c(t,q){switch(t){case "hda":e.hda=this.disk_images.hda=q;break;case "hdb":e.hdb=this.disk_images.hdb=q;break;case "cdrom":e.cdrom=this.disk_images.cdrom=q;break;case "fda":e.fda=this.disk_images.fda=q;break;case "fdb":e.fdb=this.disk_images.fdb=q;break;case "multiboot":e.multiboot=this.disk_images.multiboot=q.buffer;break;case "bzimage":e.bzimage=this.disk_images.bzimage=q.buffer;break;case "initrd":e.initrd=this.disk_images.initrd=q.buffer;break;
case "bios":e.bios=q.buffer;break;case "vga_bios":e.vga_bios=q.buffer;break;case "initial_state":e.initial_state=q.buffer;break;case "fs9p_json":e.fs9p_json=q}}async function d(){if(e.fs9p&&e.fs9p_json&&(e.initial_state||e.fs9p.load_from_json(e.fs9p_json),b.bzimage_initrd_from_filesystem)){const {bzimage_path:t,initrd_path:q}=this.get_bzimage_initrd_from_filesystem(e.fs9p),[z,w]=await Promise.all([e.fs9p.read_file(q),e.fs9p.read_file(t)]);c.call(this,"initrd",new r.SyncBuffer(z.buffer));c.call(this,
"bzimage",new r.SyncBuffer(w.buffer))}this.serial_adapter&&this.serial_adapter.show&&this.serial_adapter.show();this.bus.send("cpu-init",e);e.initial_state&&(a.restore_state(e.initial_state),e.initial_state=void 0);b.autostart&&this.bus.send("cpu-run");this.emulator_bus.send("emulator-loaded")}this.bus.register("emulator-stopped",function(){this.cpu_is_running=!1},this);this.bus.register("emulator-started",function(){this.cpu_is_running=!0},this);var e={};this.disk_images={fda:void 0,fdb:void 0,hda:void 0,
hdb:void 0,cdrom:void 0};var g=b.boot_order?b.boot_order:b.fda?801:b.hda?786:291;e.acpi=b.acpi;e.disable_jit=b.disable_jit;e.load_devices=!0;e.log_level=b.log_level;e.memory_size=b.memory_size||67108864;e.vga_memory_size=b.vga_memory_size||8388608;e.boot_order=g;e.fastboot=b.fastboot||!1;e.fda=void 0;e.fdb=void 0;e.uart1=b.uart1;e.uart2=b.uart2;e.uart3=b.uart3;e.cmdline=b.cmdline;e.preserve_mac_from_state_image=b.preserve_mac_from_state_image;e.mac_address_translation=b.mac_address_translation;e.cpuid_level=
b.cpuid_level;e.virtio_console=b.virtio_console;b.network_adapter?this.network_adapter=b.network_adapter(this.bus):b.network_relay_url&&(this.network_adapter=new vb(b.network_relay_url,this.bus));e.enable_ne2k=!0;b.disable_keyboard||(this.keyboard_adapter=new lb(this.bus));b.disable_mouse||(this.mouse_adapter=new mb(this.bus,b.screen_container));b.screen_container?this.screen_adapter=new ba(b.screen_container,this.bus):b.screen_dummy&&(this.screen_adapter=new wb(this.bus));b.serial_container&&(this.serial_adapter=
new tb(b.serial_container,this.bus));b.serial_container_xtermjs&&(this.serial_adapter=new ub(b.serial_container_xtermjs,this.bus));b.disable_speaker||(this.speaker_adapter=new nb(this.bus));var f=[];g=(t,q)=>{if(q)if(q.get&&q.set&&q.load)f.push({name:t,loadable:q});else{if("bios"===t||"vga_bios"===t||"initial_state"===t||"multiboot"===t||"bzimage"===t||"initrd"===t)q.async=!1;q.url&&!q.async?f.push({name:t,url:q.url,size:q.size}):f.push({name:t,loadable:r.buffer_from_object(q,this.zstd_decompress_worker.bind(this))})}};
b.state&&console.warn("Warning: Unknown option 'state'. Did you mean 'initial_state'?");g("bios",b.bios);g("vga_bios",b.vga_bios);g("cdrom",b.cdrom);g("hda",b.hda);g("hdb",b.hdb);g("fda",b.fda);g("fdb",b.fdb);g("initial_state",b.initial_state);g("multiboot",b.multiboot);g("bzimage",b.bzimage);g("initrd",b.initrd);if(b.filesystem){g=b.filesystem.basefs;var k=b.filesystem.baseurl;let t=new xb;k&&(t=new yb(t,k));e.fs9p=this.fs9p=new Z(t);if(g){if("object"===typeof g){var l=g.size;g=g.url}f.push({name:"fs9p_json",
url:g,size:l,as_json:!0})}}var m=this,n=f.length,p=function(t){if(t===n)setTimeout(d.bind(this),0);else{var q=f[t];q.loadable?(q.loadable.onload=function(){c.call(this,q.name,q.loadable);p(t+1)}.bind(this),q.loadable.load()):r.load_file(q.url,{done:function(z){q.url.endsWith(".zst")&&"initial_state"!==q.name&&(z=this.zstd_decompress(q.size,new Uint8Array(z)));c.call(this,q.name,q.as_json?z:new r.SyncBuffer(z));p(t+1)}.bind(this),progress:function(z){200===z.target.status?m.emulator_bus.send("download-progress",
{file_index:t,file_count:n,file_name:q.url,lengthComputable:z.lengthComputable,total:z.total||q.size,loaded:z.loaded}):m.emulator_bus.send("download-error",{file_index:t,file_count:n,file_name:q.url,request:z.target})},as_json:q.as_json})}}.bind(this);p(0)};
Y.prototype.zstd_decompress=function(a,b){const c=this.v86.cpu;this.zstd_context=c.zstd_create_ctx(b.length);(new Uint8Array(c.wasm_memory.buffer)).set(b,c.zstd_get_src_ptr(this.zstd_context));b=c.zstd_read(this.zstd_context,a);const d=c.wasm_memory.buffer.slice(b,b+a);c.zstd_read_free(b,a);c.zstd_free_ctx(this.zstd_context);this.zstd_context=null;return d};
Y.prototype.zstd_decompress_worker=async function(a,b){if(!this.zstd_worker){const c=URL.createObjectURL(new Blob(["("+function(){let d;globalThis.onmessage=function(e){if(d){var {src:g,decompressed_size:f,id:k}=e.data;e=d.exports;var l=e.zstd_create_ctx(g.length);(new Uint8Array(e.memory.buffer)).set(g,e.zstd_get_src_ptr(l));var m=e.zstd_read(l,f),n=e.memory.buffer.slice(m,m+f);e.zstd_read_free(m,f);e.zstd_free_ctx(l);postMessage({result:n,id:k},[n])}else l=Object.fromEntries("cpu_exception_hook run_hardware_timers cpu_event_halt microtick get_rand_int apic_acknowledge_irq io_port_read8 io_port_read16 io_port_read32 io_port_write8 io_port_write16 io_port_write32 mmap_read8 mmap_read16 mmap_read32 mmap_write8 mmap_write16 mmap_write32 mmap_write64 mmap_write128 codegen_finalize jit_clear_func jit_clear_all_funcs".split(" ").map(p=>
[p,()=>console.error("zstd worker unexpectedly called "+p)])),l.__indirect_function_table=new WebAssembly.Table({element:"anyfunc",initial:1024}),l.abort=()=>{throw Error("zstd worker aborted");},l.log_from_wasm=l.console_log_from_wasm=(p,t)=>{console.log(String.fromCharCode(...(new Uint8Array(d.exports.memory.buffer,p,t))))},l.dbg_trace_from_wasm=()=>console.trace(),d=new WebAssembly.Instance(new WebAssembly.Module(e.data),{env:l})}}.toString()+")()"],{type:"text/javascript"}));this.zstd_worker=
new Worker(c);URL.revokeObjectURL(c);this.zstd_worker.postMessage(this.wasm_source,[this.wasm_source])}return new Promise(c=>{const d=this.zstd_worker_request_id++,e=async g=>{g.data.id===d&&(this.zstd_worker.removeEventListener("message",e),c(g.data.result))};this.zstd_worker.addEventListener("message",e);this.zstd_worker.postMessage({src:b,decompressed_size:a,id:d},[b.buffer])})};
Y.prototype.get_bzimage_initrd_from_filesystem=function(a){const b=(a.read_dir("/")||[]).map(e=>"/"+e);a=(a.read_dir("/boot/")||[]).map(e=>"/boot/"+e);let c,d;for(let e of[].concat(b,a)){const g=/old/i.test(e)||/fallback/i.test(e),f=/vmlinuz/i.test(e)||/bzimage/i.test(e),k=/initrd/i.test(e)||/initramfs/i.test(e);!f||d&&g||(d=e);!k||c&&g||(c=e)}c&&d||(console.log("Failed to find bzimage or initrd in filesystem. Files:"),console.log(b.join(" ")),console.log(a.join(" ")));return{initrd_path:c,bzimage_path:d}};
Y.prototype.run=async function(){this.bus.send("cpu-run")};F.exportProperty(Y.prototype,"run",Y.prototype.run);Y.prototype.stop=async function(){this.cpu_is_running&&await new Promise(a=>{const b=()=>{this.remove_listener("emulator-stopped",b);a()};this.add_listener("emulator-stopped",b);this.bus.send("cpu-stop")})};F.exportProperty(Y.prototype,"stop",Y.prototype.stop);
Y.prototype.destroy=async function(){await this.stop();this.v86.destroy();this.keyboard_adapter&&this.keyboard_adapter.destroy();this.network_adapter&&this.network_adapter.destroy();this.mouse_adapter&&this.mouse_adapter.destroy();this.screen_adapter&&this.screen_adapter.destroy();this.serial_adapter&&this.serial_adapter.destroy();this.speaker_adapter&&this.speaker_adapter.destroy()};F.exportProperty(Y.prototype,"destroy",Y.prototype.destroy);Y.prototype.restart=function(){this.bus.send("cpu-restart")};
F.exportProperty(Y.prototype,"restart",Y.prototype.restart);Y.prototype.add_listener=function(a,b){this.bus.register(a,b,this)};F.exportProperty(Y.prototype,"add_listener",Y.prototype.add_listener);Y.prototype.remove_listener=function(a,b){this.bus.unregister(a,b)};F.exportProperty(Y.prototype,"remove_listener",Y.prototype.remove_listener);Y.prototype.restore_state=async function(a){this.v86.restore_state(a)};F.exportProperty(Y.prototype,"restore_state",Y.prototype.restore_state);
Y.prototype.save_state=async function(){return this.v86.save_state()};F.exportProperty(Y.prototype,"save_state",Y.prototype.save_state);Y.prototype.get_instruction_counter=function(){return this.v86?this.v86.cpu.instruction_counter[0]>>>0:0};F.exportProperty(Y.prototype,"get_instruction_counter",Y.prototype.get_instruction_counter);Y.prototype.is_running=function(){return this.cpu_is_running};F.exportProperty(Y.prototype,"is_running",Y.prototype.is_running);
Y.prototype.set_fda=async function(a){if(a.url&&!a.async)r.load_file(a.url,{done:b=>{this.v86.cpu.devices.fdc.set_fda(new r.SyncBuffer(b))}});else{const b=r.buffer_from_object(a,this.zstd_decompress_worker.bind(this));b.onload=()=>{this.v86.cpu.devices.fdc.set_fda(b)};await b.load()}};F.exportProperty(Y.prototype,"set_fda",Y.prototype.set_fda);Y.prototype.eject_fda=function(){this.v86.cpu.devices.fdc.eject_fda()};F.exportProperty(Y.prototype,"eject_fda",Y.prototype.eject_fda);
Y.prototype.keyboard_send_scancodes=function(a){for(var b=0;b<a.length;b++)this.bus.send("keyboard-code",a[b])};F.exportProperty(Y.prototype,"keyboard_send_scancodes",Y.prototype.keyboard_send_scancodes);Y.prototype.keyboard_send_keys=function(a){for(var b=0;b<a.length;b++)this.keyboard_adapter.simulate_press(a[b])};F.exportProperty(Y.prototype,"keyboard_send_keys",Y.prototype.keyboard_send_keys);Y.prototype.keyboard_send_text=function(a){for(var b=0;b<a.length;b++)this.keyboard_adapter.simulate_char(a[b])};
F.exportProperty(Y.prototype,"keyboard_send_text",Y.prototype.keyboard_send_text);Y.prototype.screen_make_screenshot=function(){return this.screen_adapter?this.screen_adapter.make_screenshot():null};F.exportProperty(Y.prototype,"screen_make_screenshot",Y.prototype.screen_make_screenshot);Y.prototype.screen_set_scale=function(a,b){this.screen_adapter&&this.screen_adapter.set_scale(a,b)};F.exportProperty(Y.prototype,"screen_set_scale",Y.prototype.screen_set_scale);
Y.prototype.screen_go_fullscreen=function(){if(this.screen_adapter){var a=document.getElementById("screen_container");if(a){var b=a.requestFullScreen||a.webkitRequestFullscreen||a.mozRequestFullScreen||a.msRequestFullScreen;b&&(b.call(a),(a=document.getElementsByClassName("phone_keyboard")[0])&&a.focus());try{navigator.keyboard.lock()}catch(c){}this.lock_mouse()}}};F.exportProperty(Y.prototype,"screen_go_fullscreen",Y.prototype.screen_go_fullscreen);
Y.prototype.lock_mouse=function(){var a=document.body,b=a.requestPointerLock||a.mozRequestPointerLock||a.webkitRequestPointerLock;b&&b.call(a)};F.exportProperty(Y.prototype,"lock_mouse",Y.prototype.lock_mouse);Y.prototype.mouse_set_status=function(a){this.mouse_adapter&&(this.mouse_adapter.emu_enabled=a)};Y.prototype.keyboard_set_status=function(a){this.keyboard_adapter&&(this.keyboard_adapter.emu_enabled=a)};F.exportProperty(Y.prototype,"keyboard_set_status",Y.prototype.keyboard_set_status);
Y.prototype.serial0_send=function(a){for(var b=0;b<a.length;b++)this.bus.send("serial0-input",a.charCodeAt(b))};F.exportProperty(Y.prototype,"serial0_send",Y.prototype.serial0_send);Y.prototype.serial_send_bytes=function(a,b){for(var c=0;c<b.length;c++)this.bus.send("serial"+a+"-input",b[c])};F.exportProperty(Y.prototype,"serial_send_bytes",Y.prototype.serial_send_bytes);Y.prototype.serial_set_modem_status=function(a,b){this.bus.send("serial"+a+"-modem-status-input",b)};
Y.prototype.serial_set_carrier_detect=function(a,b){this.bus.send("serial"+a+"-carrier-detect-input",b)};Y.prototype.serial_set_ring_indicator=function(a,b){this.bus.send("serial"+a+"-ring-indicator-input",b)};Y.prototype.serial_set_data_set_ready=function(a,b){this.bus.send("serial"+a+"-data-set-ready-input",b)};Y.prototype.serial_set_clear_to_send=function(a,b){this.bus.send("serial"+a+"-clear-to-send-input",b)};
Y.prototype.mount_fs=async function(a,b,c,d){let e=new xb;b&&(e=new yb(e,b));const g=new Z(e,this.fs9p.qidcounter),f=()=>{const k=this.fs9p.Mount(a,g);d&&(-2===k?d(new zb):-17===k?d(new Db):0>k?d(Error("Failed to mount. Error number: "+-k)):d(null))};b?g.load_from_json(c,()=>f()):f()};F.exportProperty(Y.prototype,"mount_fs",Y.prototype.mount_fs);
Y.prototype.create_file=async function(a,b){var c=this.fs9p;if(c){var d=a.split("/");d=d[d.length-1];a=c.SearchPath(a).parentid;if(""!==d&&-1!==a)await c.CreateBinaryFile(d,a,b);else return Promise.reject(new zb)}};F.exportProperty(Y.prototype,"create_file",Y.prototype.create_file);Y.prototype.read_file=async function(a){var b=this.fs9p;if(b)return(a=await b.read_file(a))?a:Promise.reject(new zb)};F.exportProperty(Y.prototype,"read_file",Y.prototype.read_file);
Y.prototype.automatically=function(a){const b=c=>{const d=c[0];if(d){var e=c.slice(1);if(d.sleep)setTimeout(()=>b(e),1E3*d.sleep);else if(d.vga_text){const g=this.screen_adapter.get_text_screen();for(let f of g)if(f.includes(d.vga_text)){b(e);return}setTimeout(()=>b(c),1E3)}else d.keyboard_send?(d.keyboard_send instanceof Array?this.keyboard_send_scancodes(d.keyboard_send):this.keyboard_send_text(d.keyboard_send),b(e)):d.call&&(d.call(),b(e))}};b(a)};
Y.prototype.read_memory=function(a,b){return this.v86.cpu.read_blob(a,b)};Y.prototype.write_memory=function(a,b){this.v86.cpu.write_blob(a,b)};Y.prototype.set_serial_container_xtermjs=function(a){this.serial_adapter&&this.serial_adapter.destroy&&this.serial_adapter.destroy();this.serial_adapter=new ub(a,this.bus);this.serial_adapter.show()};function Db(a){this.message=a||"File already exists"}Db.prototype=Error.prototype;function zb(a){this.message=a||"File not found"}zb.prototype=Error.prototype;
"undefined"!==typeof window?(window.V86Starter=Y,window.V86=Y):"undefined"!==typeof module&&"undefined"!==typeof module.exports?(module.exports.V86Starter=Y,module.exports.V86=Y):"function"===typeof importScripts&&(self.V86Starter=Y,self.V86=Y);var Eb={Connector:function(a){this.listeners={};this.pair=a;a.addEventListener("message",function(b){b=b.data;for(var c=this.listeners[b[0]],d=0;d<c.length;d++){var e=c[d];e.fn.call(e.this_value,b[1])}}.bind(this),!1)}};Eb.Connector.prototype.register=function(a,b,c){var d=this.listeners[a];void 0===d&&(d=this.listeners[a]=[]);d.push({fn:b,this_value:c})};Eb.Connector.prototype.send=function(a,b,c){this.pair&&this.pair.postMessage([a,b],c)};Eb.init=function(a){return new Eb.Connector(a)};function wb(a){var b,c,d,e,g;this.bus=a;a.register("screen-set-mode",function(f){this.set_mode(f)},this);a.register("screen-fill-buffer-end",function(f){this.update_buffer(f[0],f[1])},this);a.register("screen-put-char",function(f){this.put_char(f[0],f[1],f[2],f[3],f[4])},this);a.register("screen-text-scroll",function(f){console.log("scroll",f)},this);a.register("screen-update-cursor",function(f){this.update_cursor(f[0],f[1])},this);a.register("screen-update-cursor-scanline",function(f){this.update_cursor_scanline(f[0],
f[1])},this);a.register("screen-set-size-text",function(f){this.set_size_text(f[0],f[1])},this);a.register("screen-set-size-graphical",function(f){this.set_size_graphical(f[0],f[1])},this);this.put_char=function(f,k,l,m,n){f<g&&k<e&&(f=3*(f*e+k),d[f]=l,d[f+1]=m,d[f+2]=n)};this.destroy=function(){};this.set_mode=function(){};this.clear_screen=function(){};this.set_size_text=function(f,k){if(f!==e||k!==g)d=new Int32Array(f*k*3),e=f,g=k};this.set_size_graphical=function(){};this.set_scale=function(){};
this.update_cursor_scanline=function(){};this.update_cursor=function(f,k){if(f!==b||k!==c)b=f,c=k};this.update_buffer=function(){};this.get_text_screen=function(){for(var f=[],k=0;k<g;k++)f.push(this.get_text_row(k));return f};this.get_text_row=function(f){var k="";f=3*f*e;for(var l=0;l<e;l++)k+=String.fromCharCode(d[f+3*l]);return k}};const Fb={stats_to_string:function(a){return Fb.print_misc_stats(a)+Fb.print_instruction_counts(a)},print_misc_stats:function(a){let b="";var c="COMPILE COMPILE_SKIPPED_NO_NEW_ENTRY_POINTS COMPILE_WRONG_ADDRESS_SPACE COMPILE_CUT_OFF_AT_END_OF_PAGE COMPILE_WITH_LOOP_SAFETY COMPILE_PAGE COMPILE_PAGE/COMPILE COMPILE_BASIC_BLOCK COMPILE_DUPLICATED_BASIC_BLOCK COMPILE_WASM_BLOCK COMPILE_WASM_LOOP COMPILE_DISPATCHER COMPILE_ENTRY_POINT COMPILE_WASM_TOTAL_BYTES COMPILE_WASM_TOTAL_BYTES/COMPILE_PAGE RUN_INTERPRETED RUN_INTERPRETED_NEW_PAGE RUN_INTERPRETED_PAGE_HAS_CODE RUN_INTERPRETED_PAGE_HAS_ENTRY_AFTER_PAGE_WALK RUN_INTERPRETED_NEAR_END_OF_PAGE RUN_INTERPRETED_DIFFERENT_STATE RUN_INTERPRETED_DIFFERENT_STATE_CPL3 RUN_INTERPRETED_DIFFERENT_STATE_FLAT RUN_INTERPRETED_DIFFERENT_STATE_IS32 RUN_INTERPRETED_DIFFERENT_STATE_SS32 RUN_INTERPRETED_MISSED_COMPILED_ENTRY_RUN_INTERPRETED RUN_INTERPRETED_STEPS RUN_FROM_CACHE RUN_FROM_CACHE_STEPS RUN_FROM_CACHE_STEPS/RUN_FROM_CACHE RUN_FROM_CACHE_STEPS/RUN_INTERPRETED_STEPS DIRECT_EXIT INDIRECT_JUMP INDIRECT_JUMP_NO_ENTRY NORMAL_PAGE_CHANGE NORMAL_FALLTHRU NORMAL_FALLTHRU_WITH_TARGET_BLOCK NORMAL_BRANCH NORMAL_BRANCH_WITH_TARGET_BLOCK CONDITIONAL_JUMP CONDITIONAL_JUMP_PAGE_CHANGE CONDITIONAL_JUMP_EXIT CONDITIONAL_JUMP_FALLTHRU CONDITIONAL_JUMP_FALLTHRU_WITH_TARGET_BLOCK CONDITIONAL_JUMP_BRANCH CONDITIONAL_JUMP_BRANCH_WITH_TARGET_BLOCK DISPATCHER_SMALL DISPATCHER_LARGE LOOP LOOP_SAFETY CONDITION_OPTIMISED CONDITION_UNOPTIMISED CONDITION_UNOPTIMISED_PF CONDITION_UNOPTIMISED_UNHANDLED_L CONDITION_UNOPTIMISED_UNHANDLED_LE FAILED_PAGE_CHANGE SAFE_READ_FAST SAFE_READ_SLOW_PAGE_CROSSED SAFE_READ_SLOW_NOT_VALID SAFE_READ_SLOW_NOT_USER SAFE_READ_SLOW_IN_MAPPED_RANGE SAFE_WRITE_FAST SAFE_WRITE_SLOW_PAGE_CROSSED SAFE_WRITE_SLOW_NOT_VALID SAFE_WRITE_SLOW_NOT_USER SAFE_WRITE_SLOW_IN_MAPPED_RANGE SAFE_WRITE_SLOW_READ_ONLY SAFE_WRITE_SLOW_HAS_CODE SAFE_READ_WRITE_FAST SAFE_READ_WRITE_SLOW_PAGE_CROSSED SAFE_READ_WRITE_SLOW_NOT_VALID SAFE_READ_WRITE_SLOW_NOT_USER SAFE_READ_WRITE_SLOW_IN_MAPPED_RANGE SAFE_READ_WRITE_SLOW_READ_ONLY SAFE_READ_WRITE_SLOW_HAS_CODE PAGE_FAULT TLB_MISS MAIN_LOOP MAIN_LOOP_IDLE DO_MANY_CYCLES CYCLE_INTERNAL INVALIDATE_ALL_MODULES_NO_FREE_WASM_INDICES INVALIDATE_MODULE_WRITTEN_WHILE_COMPILED INVALIDATE_MODULE_UNUSED_AFTER_OVERWRITE INVALIDATE_MODULE_DIRTY_PAGE INVALIDATE_PAGE_HAD_CODE INVALIDATE_PAGE_HAD_ENTRY_POINTS DIRTY_PAGE_DID_NOT_HAVE_CODE RUN_FROM_CACHE_EXIT_SAME_PAGE RUN_FROM_CACHE_EXIT_NEAR_END_OF_PAGE RUN_FROM_CACHE_EXIT_DIFFERENT_PAGE CLEAR_TLB FULL_CLEAR_TLB TLB_FULL TLB_GLOBAL_FULL MODRM_SIMPLE_REG MODRM_SIMPLE_REG_WITH_OFFSET MODRM_SIMPLE_CONST_OFFSET MODRM_COMPLEX SEG_OFFSET_OPTIMISED SEG_OFFSET_NOT_OPTIMISED SEG_OFFSET_NOT_OPTIMISED_ES SEG_OFFSET_NOT_OPTIMISED_FS SEG_OFFSET_NOT_OPTIMISED_GS SEG_OFFSET_NOT_OPTIMISED_NOT_FLAT".split(" "),
d=0;const e={};for(let f=0;f<c.length;f++){const k=c[f];var g=void 0;if(k.includes("/")){d++;const [l,m]=k.split("/");g=e[l]/e[m]}else g=e[k]=a.wm.exports.profiler_stat_get(f-d),g=1E8<=g?Math.round(g/1E6)+"m":1E5<=g?Math.round(g/1E3)+"k":g;b+=k+"="+g+"\n"}b+="\n";c=a.wm.exports.get_valid_tlb_entries_count();d=a.wm.exports.get_valid_global_tlb_entries_count();b=b+("TLB_ENTRIES="+c+" ("+d+" global, "+(c-d)+" non-global)\nWASM_TABLE_FREE=")+(a.wm.exports.jit_get_wasm_table_index_free_list_count()+"\n");
b+="JIT_CACHE_SIZE="+a.wm.exports.jit_get_cache_size()+"\n";b+="FLAT_SEGMENTS="+a.wm.exports.has_flat_segmentation()+"\n";b+="wasm memory size: "+(a.wasm_memory.buffer.byteLength>>20)+"m\n";b=b+"Config:\nJIT_DISABLED="+(a.wm.exports.get_jit_config(0)+"\n");b+="MAX_PAGES="+a.wm.exports.get_jit_config(1)+"\n";b+="JIT_USE_LOOP_SAFETY="+!!a.wm.exports.get_jit_config(2)+"\n";return b+="MAX_EXTRA_BASIC_BLOCKS="+a.wm.exports.get_jit_config(3)+"\n"},print_instruction_counts:function(a){return[Fb.print_instruction_counts_offset(a,
!1,!1,!1,!1),Fb.print_instruction_counts_offset(a,!0,!1,!1,!1),Fb.print_instruction_counts_offset(a,!1,!0,!1,!1),Fb.print_instruction_counts_offset(a,!1,!1,!0,!1),Fb.print_instruction_counts_offset(a,!1,!1,!1,!0)].join("\n\n")},print_instruction_counts_offset:function(a,b,c,d,e){let g="";var f=[],k=b?"compiled":c?"jit exit":d?"unguarded register":e?"wasm size":"executed";for(let n=0;256>n;n++)for(let p=0;8>p;p++)for(let t of[!1,!0]){var l=a.wm.exports.get_opstats_buffer(b,c,d,e,n,!1,t,p);f.push({opcode:n,
count:l,is_mem:t,fixed_g:p});l=a.wm.exports.get_opstats_buffer(b,c,d,e,n,!0,t,p);f.push({opcode:3840|n,count:l,is_mem:t,fixed_g:p})}a=0;b=new Set([38,46,54,62,100,101,102,103,240,242,243]);for(let {count:n,opcode:p}of f)b.has(p)||(a+=n);if(0===a)return"";c=new Uint32Array(256);b=new Uint32Array(256);for(let {opcode:n,count:p}of f)3840==(n&65280)?b[n&255]+=p:c[n&255]+=p;g=g+"------------------\nTotal: "+(a+"\n");const m=1E7<a?1E3:1;d=Math.max.apply(Math,f.map(({count:n})=>Math.round(n/m)));d=String(d).length;
g+=`Instruction counts ${k} (in ${m}):\n`;for(e=0;256>e;e++)g+=e.toString(16).padStart(2,"0")+":"+r.pads(Math.round(c[e]/m),d),g=15==e%16?g+"\n":g+" ";g=g+"\n"+`Instruction counts ${k} (0f, in ${m}):\n`;for(k=0;256>k;k++)g+=(k&255).toString(16).padStart(2,"0")+":"+r.pads(Math.round(b[k]/m),d),g=15==k%16?g+"\n":g+" ";g+="\n";f=f.filter(({count:n})=>n).sort(({count:n},{count:p})=>p-n);for(let {opcode:n,is_mem:p,fixed_g:t,count:q}of f.slice(0,200))f=n.toString(16)+"_"+t+(p?"_m":"_r"),g+=f+":"+(q/a*100).toFixed(2)+
" ";return g+"\n"}};"undefined"!==typeof module&&"undefined"!==typeof module.exports&&(module.exports.print_stats=Fb);function xb(){this.filedata=new Map}xb.prototype.read=async function(a,b,c){return(a=this.filedata.get(a))?a.subarray(b,b+c):null};xb.prototype.cache=async function(a,b){this.filedata.set(a,b)};xb.prototype.uncache=function(a){this.filedata.delete(a)};function yb(a,b){this.storage=a;this.baseurl=b}yb.prototype.load_from_server=function(a){return new Promise(b=>{r.load_file(this.baseurl+a,{done:async c=>{c=new Uint8Array(c);await this.cache(a,c);b(c)}})})};
yb.prototype.read=async function(a,b,c){const d=await this.storage.read(a,b,c);return d?d:(await this.load_from_server(a)).subarray(b,b+c)};yb.prototype.cache=async function(a,b){return await this.storage.cache(a,b)};yb.prototype.uncache=function(a){this.storage.uncache(a)};
"undefined"!==typeof window?(window.MemoryFileStorage=xb,window.ServerFileStorageWrapper=yb):"undefined"!==typeof module&&"undefined"!==typeof module.exports?(module.exports.MemoryFileStorage=xb,module.exports.ServerFileStorageWrapper=yb):"function"===typeof importScripts&&(self.MemoryFileStorage=xb,self.ServerFileStorageWrapper=yb);var ha=16384,ia=4;function Z(a,b){this.inodes=[];this.events=[];this.storage=a;this.qidcounter=b||{last_qidnumber:0};this.inodedata={};this.total_size=274877906944;this.used_size=0;this.mounts=[];this.CreateDirectory("",-1)}Z.prototype.get_state=function(){let a=[];a[0]=this.inodes;a[1]=this.qidcounter.last_qidnumber;a[2]=[];for(const [b,c]of Object.entries(this.inodedata))0===(this.inodes[b].mode&ha)&&a[2].push([b,c]);a[3]=this.total_size;a[4]=this.used_size;return a=a.concat(this.mounts)};
Z.prototype.set_state=function(a){this.inodes=a[0].map(b=>{const c=new Gb(0);c.set_state(b);return c});this.qidcounter.last_qidnumber=a[1];this.inodedata={};for(let [b,c]of a[2])c.buffer.byteLength!==c.byteLength&&(c=c.slice()),this.inodedata[b]=c;this.total_size=a[3];this.used_size=a[4];this.mounts=a.slice(5)};Z.prototype.AddEvent=function(a,b){var c=this.inodes[a];0==c.status||2==c.status?b():this.is_forwarder(c)?this.follow_fs(c).AddEvent(c.foreign_id,b):this.events.push({id:a,OnEvent:b})};
Z.prototype.HandleEvent=function(a){var b=this.inodes[a];this.is_forwarder(b)&&this.follow_fs(b).HandleEvent(b.foreign_id);b=[];for(var c=0;c<this.events.length;c++)this.events[c].id==a?this.events[c].OnEvent():b.push(this.events[c]);this.events=b};
Z.prototype.load_from_json=function(a,b){if(3!==a.version)throw"The filesystem JSON format has changed. Please update your fs2json (https://github.com/copy/fs2json) and recreate the filesystem JSON.";var c=a.fsroot;this.used_size=a.size;for(a=0;a<c.length;a++)this.LoadRecursive(c[a],0);b&&b()};
Z.prototype.LoadRecursive=function(a,b){var c=this.CreateInode();const d=a[0];c.size=a[1];c.mtime=a[2];c.ctime=c.mtime;c.atime=c.mtime;c.mode=a[3];c.uid=a[4];c.gid=a[5];var e=c.mode&61440;e===ha?(this.PushInode(c,b,d),this.LoadDir(this.inodes.length-1,a[6])):32768===e?(c.status=2,c.sha256sum=a[6],this.PushInode(c,b,d)):40960===e?(c.symlink=a[6],this.PushInode(c,b,d)):49152!==e&&A(e)};Z.prototype.LoadDir=function(a,b){for(var c=0;c<b.length;c++)this.LoadRecursive(b[c],a)};
Z.prototype.should_be_linked=function(a){return!this.is_forwarder(a)||0===a.foreign_id};Z.prototype.link_under_dir=function(a,b,c){const d=this.inodes[b],e=this.inodes[a];this.is_forwarder(e);this.IsDirectory(a);this.should_be_linked(d);e.direntries.has(c);e.direntries.set(c,b);d.nlinks++;this.IsDirectory(b)&&(d.direntries.has(".."),d.direntries.has(".")||d.nlinks++,d.direntries.set(".",b),d.direntries.set("..",a),e.nlinks++)};
Z.prototype.unlink_from_dir=function(a,b){const c=this.Search(a,b),d=this.inodes[c],e=this.inodes[a];this.is_forwarder(e);this.IsDirectory(a);e.direntries.delete(b)&&(d.nlinks--,this.IsDirectory(c)&&(d.direntries.get(".."),d.direntries.delete(".."),e.nlinks--))};
Z.prototype.PushInode=function(a,b,c){-1!=b?(this.inodes.push(a),a.fid=this.inodes.length-1,this.link_under_dir(b,a.fid,c)):0==this.inodes.length?(this.inodes.push(a),a.direntries.set(".",0),a.direntries.set("..",0),a.nlinks=2):(y.Debug("Error in Filesystem: Pushed inode with name = "+c+" has no parent"),y.Abort())};
function Gb(a){this.direntries=new Map;this.minor=this.major=this.mtime=this.atime=this.ctime=this.fid=this.gid=this.uid=this.size=this.status=0;this.symlink="";this.mode=493;this.qid={type:0,version:0,path:a};this.caps=void 0;this.nlinks=0;this.sha256sum="";this.locks=[];this.foreign_id=this.mount_id=-1}
Gb.prototype.get_state=function(){const a=[];a[0]=this.mode;a[1]=(this.mode&61440)===ha?[...this.direntries]:32768===(this.mode&61440)?this.sha256sum:40960===(this.mode&61440)?this.symlink:49152===(this.mode&61440)?[this.minor,this.major]:null;a[2]=this.locks;a[3]=this.status;a[4]=this.size;a[5]=this.uid;a[6]=this.gid;a[7]=this.fid;a[8]=this.ctime;a[9]=this.atime;a[10]=this.mtime;a[11]=this.qid.version;a[12]=this.qid.path;a[13]=this.nlinks;return a};
Gb.prototype.set_state=function(a){this.mode=a[0];if((this.mode&61440)===ha){this.direntries=new Map;for(const [b,c]of a[1])this.direntries.set(b,c)}else 32768===(this.mode&61440)?this.sha256sum=a[1]:40960===(this.mode&61440)?this.symlink=a[1]:49152===(this.mode&61440)&&([this.minor,this.major]=a[1]);this.locks=[];for(const b of a[2]){const c=new Hb;c.set_state(b);this.locks.push(c)}this.status=a[3];this.size=a[4];this.uid=a[5];this.gid=a[6];this.fid=a[7];this.ctime=a[8];this.atime=a[9];this.mtime=
a[10];this.qid.type=(this.mode&61440)>>8;this.qid.version=a[11];this.qid.path=a[12];this.nlinks=a[13]};
Z.prototype.divert=function(a,b){const c=this.Search(a,b),d=this.inodes[c],e=new Gb(-1);this.IsDirectory(c);Object.assign(e,d);const g=this.inodes.length;this.inodes.push(e);e.fid=g;this.is_forwarder(d)&&this.mounts[d.mount_id].backtrack.set(d.foreign_id,g);this.should_be_linked(d)&&(this.unlink_from_dir(a,b),this.link_under_dir(a,g,b));if(this.IsDirectory(c)&&!this.is_forwarder(d))for(const [f,k]of e.direntries)"."!==f&&".."!==f&&this.IsDirectory(k)&&this.inodes[k].direntries.set("..",g);this.inodedata[g]=
this.inodedata[c];delete this.inodedata[c];d.direntries=new Map;d.nlinks=0;return g};Z.prototype.copy_inode=function(a,b){Object.assign(b,a,{fid:b.fid,direntries:b.direntries,nlinks:b.nlinks})};Z.prototype.CreateInode=function(){const a=Math.round(Date.now()/1E3),b=new Gb(++this.qidcounter.last_qidnumber);b.atime=b.ctime=b.mtime=a;return b};
Z.prototype.CreateDirectory=function(a,b){var c=this.inodes[b];if(0<=b&&this.is_forwarder(c))return b=c.foreign_id,a=this.follow_fs(c).CreateDirectory(a,b),this.create_forwarder(c.mount_id,a);c=this.CreateInode();c.mode=511|ha;0<=b&&(c.uid=this.inodes[b].uid,c.gid=this.inodes[b].gid,c.mode=this.inodes[b].mode&511|ha);c.qid.type=ha>>8;this.PushInode(c,b,a);this.NotifyListeners(this.inodes.length-1,"newdir");return this.inodes.length-1};
Z.prototype.CreateFile=function(a,b){var c=this.inodes[b];if(this.is_forwarder(c))return b=c.foreign_id,a=this.follow_fs(c).CreateFile(a,b),this.create_forwarder(c.mount_id,a);c=this.CreateInode();c.uid=this.inodes[b].uid;c.gid=this.inodes[b].gid;c.qid.type=128;c.mode=this.inodes[b].mode&438|32768;this.PushInode(c,b,a);this.NotifyListeners(this.inodes.length-1,"newfile");return this.inodes.length-1};
Z.prototype.CreateNode=function(a,b,c,d){var e=this.inodes[b];if(this.is_forwarder(e))return b=e.foreign_id,a=this.follow_fs(e).CreateNode(a,b,c,d),this.create_forwarder(e.mount_id,a);e=this.CreateInode();e.major=c;e.minor=d;e.uid=this.inodes[b].uid;e.gid=this.inodes[b].gid;e.qid.type=192;e.mode=this.inodes[b].mode&438;this.PushInode(e,b,a);return this.inodes.length-1};
Z.prototype.CreateSymlink=function(a,b,c){var d=this.inodes[b];if(this.is_forwarder(d))return b=d.foreign_id,a=this.follow_fs(d).CreateSymlink(a,b,c),this.create_forwarder(d.mount_id,a);d=this.CreateInode();d.uid=this.inodes[b].uid;d.gid=this.inodes[b].gid;d.qid.type=160;d.symlink=c;d.mode=40960;this.PushInode(d,b,a);return this.inodes.length-1};
Z.prototype.CreateTextFile=async function(a,b,c){var d=this.inodes[b];if(this.is_forwarder(d))return b=d.foreign_id,c=await this.follow_fs(d).CreateTextFile(a,b,c),this.create_forwarder(d.mount_id,c);d=this.CreateFile(a,b);b=this.inodes[d];a=new Uint8Array(c.length);b.size=c.length;for(b=0;b<c.length;b++)a[b]=c.charCodeAt(b);await this.set_data(d,a);return d};
Z.prototype.CreateBinaryFile=async function(a,b,c){var d=this.inodes[b];if(this.is_forwarder(d))return b=d.foreign_id,c=await this.follow_fs(d).CreateBinaryFile(a,b,c),this.create_forwarder(d.mount_id,c);d=this.CreateFile(a,b);a=this.inodes[d];b=new Uint8Array(c.length);b.set(c);await this.set_data(d,b);a.size=c.length;return d};
Z.prototype.OpenInode=function(a,b){var c=this.inodes[a];if(this.is_forwarder(c))return this.follow_fs(c).OpenInode(c.foreign_id,b);(c.mode&61440)==ha&&this.FillDirectory(a);return!0};Z.prototype.CloseInode=async function(a){var b=this.inodes[a];if(this.is_forwarder(b))return await this.follow_fs(b).CloseInode(b.foreign_id);2===b.status&&this.storage.uncache(b.sha256sum);b.status==ia&&(b.status=-1,await this.DeleteData(a))};
Z.prototype.Rename=async function(a,b,c,d){if(a==c&&b==d)return 0;var e=this.Search(a,b);if(-1===e)return-2;var g=this.GetFullPath(a)+"/"+b;if(-1!=this.Search(c,d)){var f=this.Unlink(c,d);if(0>f)return f}var k=this.inodes[e],l=this.inodes[a];f=this.inodes[c];if(this.is_forwarder(l)||this.is_forwarder(f))if(this.is_forwarder(l)&&l.mount_id===f.mount_id){if(a=await this.follow_fs(l).Rename(l.foreign_id,b,f.foreign_id,d),0>a)return a}else{if(this.is_a_root(e)||!this.IsDirectory(e)&&1<this.GetInode(e).nlinks)return-1;
l=this.divert(a,b);const m=this.GetInode(e),n=await this.Read(l,0,m.size);this.is_forwarder(f)?(c=this.follow_fs(f),d=this.IsDirectory(l)?c.CreateDirectory(d,f.foreign_id):c.CreateFile(d,f.foreign_id),c=c.GetInode(d),this.copy_inode(m,c),this.set_forwarder(e,f.mount_id,d)):(this.delete_forwarder(k),this.copy_inode(m,k),this.link_under_dir(c,e,d));await this.ChangeSize(e,m.size);n&&n.length&&await this.Write(e,0,n.length,n);if(this.IsDirectory(e))for(const p of this.GetChildren(l))if(f=await this.Rename(l,
p,e,p),0>f)return f;await this.DeleteData(l);a=this.Unlink(a,b);if(0>a)return a}else this.unlink_from_dir(a,b),this.link_under_dir(c,e,d),k.qid.version++;this.NotifyListeners(e,"rename",{oldpath:g});return 0};
Z.prototype.Write=async function(a,b,c,d){this.NotifyListeners(a,"write");var e=this.inodes[a];if(this.is_forwarder(e))a=e.foreign_id,await this.follow_fs(e).Write(a,b,c,d);else{var g=await this.get_buffer(a);!g||g.length<b+c?(await this.ChangeSize(a,Math.floor(3*(b+c)/2)),e.size=b+c,g=await this.get_buffer(a)):e.size<b+c&&(e.size=b+c);d&&g.set(d.subarray(0,c),b);await this.set_data(a,g)}};
Z.prototype.Read=async function(a,b,c){const d=this.inodes[a];return this.is_forwarder(d)?(a=d.foreign_id,await this.follow_fs(d).Read(a,b,c)):await this.get_data(a,b,c)};Z.prototype.Search=function(a,b){a=this.inodes[a];if(this.is_forwarder(a)){const c=a.foreign_id;b=this.follow_fs(a).Search(c,b);return-1===b?-1:this.get_forwarder(a.mount_id,b)}b=a.direntries.get(b);return void 0===b?-1:b};
Z.prototype.CountUsedInodes=function(){let a=this.inodes.length;for(const {fs:b,backtrack:c}of this.mounts)a+=b.CountUsedInodes(),a-=c.size;return a};Z.prototype.CountFreeInodes=function(){let a=1048576;for(const {fs:b}of this.mounts)a+=b.CountFreeInodes();return a};Z.prototype.GetTotalSize=function(){let a=this.used_size;for(const {fs:b}of this.mounts)a+=b.GetTotalSize();return a};Z.prototype.GetSpace=function(){let a=this.total_size;for(const {fs:b}of this.mounts)a+=b.GetSpace();return this.total_size};
Z.prototype.GetDirectoryName=function(a){const b=this.inodes[this.GetParent(a)];if(this.is_forwarder(b))return this.follow_fs(b).GetDirectoryName(this.inodes[a].foreign_id);if(!b)return"";for(const [c,d]of b.direntries)if(d===a)return c;return""};Z.prototype.GetFullPath=function(a){this.IsDirectory(a);for(var b="";0!=a;)b="/"+this.GetDirectoryName(a)+b,a=this.GetParent(a);return b.substring(1)};
Z.prototype.Link=function(a,b,c){if(this.IsDirectory(b))return-1;const d=this.inodes[a],e=this.inodes[b];if(this.is_forwarder(d))return this.is_forwarder(e)&&e.mount_id===d.mount_id?this.follow_fs(d).Link(d.foreign_id,e.foreign_id,c):-1;if(this.is_forwarder(e))return-1;this.link_under_dir(a,b,c);return 0};
Z.prototype.Unlink=function(a,b){if("."===b||".."===b)return-1;const c=this.Search(a,b),d=this.inodes[c],e=this.inodes[a];if(this.is_forwarder(e))return this.is_forwarder(d),a=e.foreign_id,this.follow_fs(e).Unlink(a,b);if(this.IsDirectory(c)&&!this.IsEmpty(c))return-39;this.unlink_from_dir(a,b);0===d.nlinks&&(d.status=ia,this.NotifyListeners(c,"delete"));return 0};
Z.prototype.DeleteData=async function(a){const b=this.inodes[a];this.is_forwarder(b)?await this.follow_fs(b).DeleteData(b.foreign_id):(b.size=0,delete this.inodedata[a])};Z.prototype.get_buffer=async function(a){const b=this.inodes[a];return this.inodedata[a]?this.inodedata[a]:2===b.status?await this.storage.read(b.sha256sum,0,b.size):null};
Z.prototype.get_data=async function(a,b,c){const d=this.inodes[a];return this.inodedata[a]?this.inodedata[a].subarray(b,b+c):2===d.status?await this.storage.read(d.sha256sum,b,c):null};Z.prototype.set_data=async function(a,b){this.inodedata[a]=b;2===this.inodes[a].status&&(this.inodes[a].status=0,this.storage.uncache(this.inodes[a].sha256sum))};Z.prototype.GetInode=function(a){isNaN(a);a=this.inodes[a];return this.is_forwarder(a)?this.follow_fs(a).GetInode(a.foreign_id):a};
Z.prototype.ChangeSize=async function(a,b){var c=this.GetInode(a),d=await this.get_data(a,0,c.size);if(b!=c.size){var e=new Uint8Array(b);c.size=b;d&&e.set(d.subarray(0,Math.min(d.length,c.size)),0);await this.set_data(a,e)}};
Z.prototype.SearchPath=function(a){a=a.replace("//","/");a=a.split("/");0<a.length&&0===a[a.length-1].length&&a.pop();0<a.length&&0===a[0].length&&a.shift();const b=a.length;var c=-1,d=0;let e=null;for(var g=0;g<b;g++)if(c=d,d=this.Search(c,a[g]),!e&&this.is_forwarder(this.inodes[c])&&(e="/"+a.slice(g).join("/")),-1==d)return g<b-1?{id:-1,parentid:-1,name:a[g],forward_path:e}:{id:-1,parentid:c,name:a[g],forward_path:e};return{id:d,parentid:c,name:a[g],forward_path:e}};
Z.prototype.GetRecursiveList=function(a,b){if(this.is_forwarder(this.inodes[a])){const c=this.follow_fs(this.inodes[a]),d=this.inodes[a].mount_id,e=b.length;c.GetRecursiveList(this.inodes[a].foreign_id,b);for(a=e;a<b.length;a++)b[a].parentid=this.get_forwarder(d,b[a].parentid)}else for(const [c,d]of this.inodes[a].direntries)"."!==c&&".."!==c&&(b.push({parentid:a,name:c}),this.IsDirectory(d)&&this.GetRecursiveList(d,b))};
Z.prototype.RecursiveDelete=function(a){var b=[];a=this.SearchPath(a);if(-1!==a.id)for(this.GetRecursiveList(a.id,b),a=b.length-1;0<=a;a--)this.Unlink(b[a].parentid,b[a].name)};Z.prototype.DeleteNode=function(a){var b=this.SearchPath(a);-1!=b.id&&(32768==(this.inodes[b.id].mode&61440)?this.Unlink(b.parentid,b.name):(this.inodes[b.id].mode&61440)==ha&&(this.RecursiveDelete(a),this.Unlink(b.parentid,b.name)))};Z.prototype.NotifyListeners=function(){};
Z.prototype.Check=function(){for(var a=1;a<this.inodes.length;a++)if(-1!=this.inodes[a].status){var b=this.GetInode(a);0>b.nlinks&&y.Debug("Error in filesystem: negative nlinks="+b.nlinks+" at id ="+a);if(this.IsDirectory(a)){b=this.GetInode(a);this.IsDirectory(a)&&0>this.GetParent(a)&&y.Debug("Error in filesystem: negative parent id "+a);for(const [c,d]of b.direntries){0===c.length&&y.Debug("Error in filesystem: inode with no name and id "+d);for(const e of c)32>e&&y.Debug("Error in filesystem: Unallowed char in filename")}}}};
Z.prototype.FillDirectory=function(a){var b=this.inodes[a];if(this.is_forwarder(b))this.follow_fs(b).FillDirectory(b.foreign_id);else{var c=0;for(const d of b.direntries.keys())c+=24+Ib.UTF8Length(d);a=this.inodedata[a]=new Uint8Array(c);b.size=c;c=0;for(const [d,e]of b.direntries)b=this.GetInode(e),c+=v.Marshall(["Q","d","b","s"],[b.qid,c+13+8+1+2+Ib.UTF8Length(d),b.mode>>12,d],a,c)}};
Z.prototype.RoundToDirentry=function(a,b){a=this.inodedata[a];if(b>=a.length)return a.length;let c=0;for(;;){const d=v.Unmarshall(["Q","d"],a,{offset:c})[1];if(d>b)break;c=d}return c};Z.prototype.IsDirectory=function(a){a=this.inodes[a];return this.is_forwarder(a)?this.follow_fs(a).IsDirectory(a.foreign_id):(a.mode&61440)===ha};
Z.prototype.IsEmpty=function(a){a=this.inodes[a];if(this.is_forwarder(a))return this.follow_fs(a).IsDirectory(a.foreign_id);for(const b of a.direntries.keys())if("."!==b&&".."!==b)return!1;return!0};Z.prototype.GetChildren=function(a){this.IsDirectory(a);a=this.inodes[a];if(this.is_forwarder(a))return this.follow_fs(a).GetChildren(a.foreign_id);const b=[];for(const c of a.direntries.keys())"."!==c&&".."!==c&&b.push(c);return b};
Z.prototype.GetParent=function(a){this.IsDirectory(a);a=this.inodes[a];if(this.should_be_linked(a))return a.direntries.get("..");const b=this.follow_fs(a).GetParent(a.foreign_id);return this.get_forwarder(a.mount_id,b)};
Z.prototype.PrepareCAPs=function(a){a=this.GetInode(a);if(a.caps)return a.caps.length;a.caps=new Uint8Array(20);a.caps[0]=0;a.caps[1]=0;a.caps[2]=0;a.caps[3]=2;a.caps[4]=255;a.caps[5]=255;a.caps[6]=255;a.caps[7]=255;a.caps[8]=255;a.caps[9]=255;a.caps[10]=255;a.caps[11]=255;a.caps[12]=63;a.caps[13]=0;a.caps[14]=0;a.caps[15]=0;a.caps[16]=63;a.caps[17]=0;a.caps[18]=0;a.caps[19]=0;return a.caps.length};function Jb(a){this.fs=a;this.backtrack=new Map}
Jb.prototype.get_state=function(){const a=[];a[0]=this.fs;a[1]=[...this.backtrack];return a};Jb.prototype.set_state=function(a){this.fs=a[0];this.backtrack=new Map(a[1])};Z.prototype.set_forwarder=function(a,b,c){const d=this.inodes[a];this.is_forwarder(d)&&this.mounts[d.mount_id].backtrack.delete(d.foreign_id);d.status=5;d.mount_id=b;d.foreign_id=c;this.mounts[b].backtrack.set(c,a)};
Z.prototype.create_forwarder=function(a,b){const c=this.CreateInode(),d=this.inodes.length;this.inodes.push(c);c.fid=d;this.set_forwarder(d,a,b);return d};Z.prototype.is_forwarder=function(a){return 5===a.status};Z.prototype.is_a_root=function(a){return 0===this.GetInode(a).fid};Z.prototype.get_forwarder=function(a,b){const c=this.mounts[a].backtrack.get(b);return void 0===c?this.create_forwarder(a,b):c};Z.prototype.delete_forwarder=function(a){this.is_forwarder(a);a.status=-1;this.mounts[a.mount_id].backtrack.delete(a.foreign_id)};
Z.prototype.follow_fs=function(a){const b=this.mounts[a.mount_id];this.is_forwarder(a);return b.fs};Z.prototype.Mount=function(a,b){a=this.SearchPath(a);if(-1===a.parentid)return-2;if(-1!==a.id)return-17;if(a.forward_path){var c=this.inodes[a.parentid];b=this.follow_fs(c).Mount(a.forward_path,b);return 0>b?b:this.get_forwarder(c.mount_id,b)}c=this.mounts.length;this.mounts.push(new Jb(b));b=this.create_forwarder(c,0);this.link_under_dir(a.parentid,b,a.name);return b};
function Hb(){this.type=2;this.start=0;this.length=Infinity;this.proc_id=-1;this.client_id=""}Hb.prototype.get_state=function(){const a=[];a[0]=this.type;a[1]=this.start;a[2]=Infinity===this.length?0:this.length;a[3]=this.proc_id;a[4]=this.client_id;return a};Hb.prototype.set_state=function(a){this.type=a[0];this.start=a[1];this.length=0===a[2]?Infinity:a[2];this.proc_id=a[3];this.client_id=a[4]};Hb.prototype.clone=function(){const a=new Hb;a.set_state(this.get_state());return a};
Hb.prototype.conflicts_with=function(a){return this.proc_id===a.proc_id&&this.client_id===a.client_id||2===this.type||2===a.type||1!==this.type&&1!==a.type||this.start+this.length<=a.start||a.start+a.length<=this.start?!1:!0};Hb.prototype.is_alike=function(a){return a.proc_id===this.proc_id&&a.client_id===this.client_id&&a.type===this.type};Hb.prototype.may_merge_after=function(a){return this.is_alike(a)&&a.start+a.length===this.start};
Z.prototype.DescribeLock=function(a,b,c,d,e){const g=new Hb;g.type=a;g.start=b;g.length=c;g.proc_id=d;g.client_id=e;return g};Z.prototype.GetLock=function(a,b){a=this.inodes[a];if(this.is_forwarder(a)){var c=a.foreign_id;return this.follow_fs(a).GetLock(c,b)}for(c of a.locks)if(b.conflicts_with(c))return c.clone();return null};
Z.prototype.Lock=function(a,b,c){const d=this.inodes[a];if(this.is_forwarder(d))return a=d.foreign_id,this.follow_fs(d).Lock(a,b,c);b=b.clone();if(2!==b.type&&this.GetLock(a,b))return 1;for(c=0;c<d.locks.length;c++){a=d.locks[c];if(a.start+a.length<=b.start)continue;if(b.start+b.length<=a.start)break;if(a.proc_id!==b.proc_id||a.client_id!==b.client_id){a.conflicts_with(b);continue}var e=b.start+b.length;const g=b.start-a.start,f=a.start+a.length-e;if(0<g&&0<f&&a.type===b.type)return 0;0<g&&(a.length=
g);if(0>=g&&0<f)a.start=e,a.length=f;else if(0<f){for(;c<d.locks.length&&d.locks[c].start<e;)c++;d.locks.splice(c,0,this.DescribeLock(a.type,e,f,a.proc_id,a.client_id))}else 0>=g&&(d.locks.splice(c,1),c--)}if(2!==b.type){c=b;a=!1;for(e=0;e<d.locks.length&&!(c.may_merge_after(d.locks[e])&&(d.locks[e].length+=b.length,c=d.locks[e],a=!0),b.start<=d.locks[e].start);e++);a||(d.locks.splice(e,0,c),e++);for(;e<d.locks.length;e++)if(d.locks[e].is_alike(c)){d.locks[e].may_merge_after(c)&&(c.length+=d.locks[e].length,
d.locks.splice(e,1));break}}return 0};Z.prototype.read_dir=function(a){a=this.SearchPath(a);if(-1!==a.id)return a=this.GetInode(a.id),Array.from(a.direntries.keys()).filter(b=>"."!==b&&".."!==b)};Z.prototype.read_file=function(a){a=this.SearchPath(a);if(-1===a.id)return Promise.resolve(null);const b=this.GetInode(a.id);return this.Read(a.id,0,b.size)};var y={Debug:function(a){[].slice.apply(arguments).join(" ")},Abort:function(){}};var v={Marshall:function(a,b,c,d){for(var e,g=0,f=0;f<a.length;f++)switch(e=b[f],a[f]){case "w":c[d++]=e&255;c[d++]=e>>8&255;c[d++]=e>>16&255;c[d++]=e>>24&255;g+=4;break;case "d":c[d++]=e&255;c[d++]=e>>8&255;c[d++]=e>>16&255;c[d++]=e>>24&255;c[d++]=0;c[d++]=0;c[d++]=0;c[d++]=0;g+=8;break;case "h":c[d++]=e&255;c[d++]=e>>8;g+=2;break;case "b":c[d++]=e;g+=1;break;case "s":var k=d,l=0;c[d++]=0;c[d++]=0;g+=2;for(var m of e)Kb(m.charCodeAt(0)).forEach(function(n){c[d++]=n;g+=1;l++});c[k+0]=l&255;c[k+1]=
l>>8&255;break;case "Q":v.Marshall(["b","w","d"],[e.type,e.version,e.path],c,d);d+=13;g+=13;break;default:y.Debug("Marshall: Unknown type="+a[f])}return g},Unmarshall:function(a,b,c){let d=c.offset;for(var e=[],g=0;g<a.length;g++)switch(a[g]){case "w":var f=b[d++];f+=b[d++]<<8;f+=b[d++]<<16;f+=b[d++]<<24>>>0;e.push(f);break;case "d":f=b[d++];f+=b[d++]<<8;f+=b[d++]<<16;f+=b[d++]<<24>>>0;d+=4;e.push(f);break;case "h":f=b[d++];e.push(f+(b[d++]<<8));break;case "b":e.push(b[d++]);break;case "s":f=b[d++];
f+=b[d++]<<8;for(var k="",l=new Lb,m=0;m<f;m++){var n=l.Put(b[d++]);-1!=n&&(k+=String.fromCharCode(n))}e.push(k);break;case "Q":c.offset=d;f=v.Unmarshall(["b","w","d"],b,c);d=c.offset;e.push({type:f[0],version:f[1],path:f[2]});break;default:y.Debug("Error in Unmarshall: Unknown type="+a[g])}c.offset=d;return e}};var Ib={};function Lb(){this.stream=new Uint8Array(5);this.ofs=0;this.Put=function(a){this.stream[this.ofs]=a;this.ofs++;switch(this.ofs){case 1:if(128>this.stream[0])return this.ofs=0,this.stream[0];break;case 2:if(192==(this.stream[0]&224)&&128==(this.stream[1]&192))return this.ofs=0,(this.stream[0]&31)<<6|this.stream[1]&63}return-1}}function Kb(a){if(128>a)return[a];if(2048>a)return[192|a>>6&31,128|a&63]}
Ib.UTF8Length=function(a){for(var b=0,c=0;c<a.length;c++){var d=a.charCodeAt(c);b+=128>d?1:2}return b};}).call(this);
File diff suppressed because it is too large. Load diff
+236
View File
@@ -0,0 +1,236 @@
/*
* Copyright (C) 2024 Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* Copyright (c) 2014 The xterm.js authors. All rights reserved.
* Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
* https://github.com/chjj/term.js
* @license MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* Originally forked from (with the author's permission):
* Fabrice Bellard's javascript vt100 for jslinux:
* http://bellard.org/jslinux/
* Copyright (c) 2011 Fabrice Bellard
* The original design remains. The terminal itself
* has been extended to include xterm CSI codes, among
* other features.
*/
/**
* Default styles for xterm.js
*/
.xterm {
cursor: text;
position: relative;
user-select: none;
-ms-user-select: none;
-webkit-user-select: none;
}
.xterm.focus,
.xterm:focus {
outline: none;
}
.xterm .xterm-helpers {
position: absolute;
top: 0;
/**
* The z-index of the helpers must be higher than the canvases in order for
* IMEs to appear on top.
*/
z-index: 5;
}
.xterm .xterm-helper-textarea {
padding: 0;
border: 0;
margin: 0;
/* Move textarea out of the screen to the far left, so that the cursor is not visible */
position: absolute;
opacity: 0;
left: -9999em;
top: 0;
width: 0;
height: 0;
z-index: -5;
/** Prevent wrapping so the IME appears against the textarea at the correct position */
white-space: nowrap;
overflow: hidden;
resize: none;
}
.xterm .composition-view {
/* TODO: Composition position got messed up somewhere */
background: #000;
color: #FFF;
display: none;
position: absolute;
white-space: nowrap;
z-index: 1;
}
.xterm .composition-view.active {
display: block;
}
.xterm .xterm-viewport {
/* On OS X this is required in order for the scroll bar to appear fully opaque */
background-color: #000;
overflow-y: scroll;
cursor: default;
position: absolute;
right: 0;
left: 0;
top: 0;
bottom: 0;
}
.xterm .xterm-screen {
position: relative;
}
.xterm .xterm-screen canvas {
position: absolute;
left: 0;
top: 0;
}
.xterm .xterm-scroll-area {
visibility: hidden;
}
.xterm-char-measure-element {
display: inline-block;
visibility: hidden;
position: absolute;
top: 0;
left: -9999em;
line-height: normal;
}
.xterm.enable-mouse-events {
/* When mouse events are enabled (eg. tmux), revert to the standard pointer cursor */
cursor: default;
}
.xterm.xterm-cursor-pointer,
.xterm .xterm-cursor-pointer {
cursor: pointer;
}
.xterm.column-select.focus {
/* Column selection mode */
cursor: crosshair;
}
.xterm .xterm-accessibility:not(.debug),
.xterm .xterm-message {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: 10;
color: transparent;
pointer-events: none;
}
.xterm .xterm-accessibility-tree:not(.debug) *::selection {
color: transparent;
}
.xterm .xterm-accessibility-tree {
user-select: text;
white-space: pre;
}
.xterm .live-region {
position: absolute;
left: -9999px;
width: 1px;
height: 1px;
overflow: hidden;
}
.xterm-dim {
/* Dim should not apply to background, so the opacity of the foreground color is applied
* explicitly in the generated class and reset to 1 here */
opacity: 1 !important;
}
.xterm-underline-1 { text-decoration: underline; }
.xterm-underline-2 { text-decoration: double underline; }
.xterm-underline-3 { text-decoration: wavy underline; }
.xterm-underline-4 { text-decoration: dotted underline; }
.xterm-underline-5 { text-decoration: dashed underline; }
.xterm-overline {
text-decoration: overline;
}
.xterm-overline.xterm-underline-1 { text-decoration: overline underline; }
.xterm-overline.xterm-underline-2 { text-decoration: overline double underline; }
.xterm-overline.xterm-underline-3 { text-decoration: overline wavy underline; }
.xterm-overline.xterm-underline-4 { text-decoration: overline dotted underline; }
.xterm-overline.xterm-underline-5 { text-decoration: overline dashed underline; }
.xterm-strikethrough {
text-decoration: line-through;
}
.xterm-screen .xterm-decoration-container .xterm-decoration {
z-index: 6;
position: absolute;
}
.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer {
z-index: 7;
}
.xterm-decoration-overview-ruler {
z-index: 8;
position: absolute;
top: 0;
right: 0;
pointer-events: none;
}
.xterm-decoration-top {
z-index: 2;
position: relative;
}
+20
View File
@@ -0,0 +1,20 @@
/*
* Copyright (C) 2024 Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var i=t();for(var s in i)("object"==typeof exports?exports:e)[s]=i[s]}}(globalThis,(()=>(()=>{"use strict";var e={4567:function(e,t,i){var s=this&&this.__decorate||function(e,t,i,s){var r,n=arguments.length,o=n<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,s);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(o=(n<3?r(o):n>3?r(t,i,o):r(t,i))||o);return n>3&&o&&Object.defineProperty(t,i,o),o},r=this&&this.__param||function(e,t){return function(i,s){t(i,s,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.AccessibilityManager=void 0;const n=i(9042),o=i(9924),a=i(844),h=i(4725),c=i(2585),l=i(3656);let d=t.AccessibilityManager=class extends a.Disposable{constructor(e,t,i,s){super(),this._terminal=e,this._coreBrowserService=i,this._renderService=s,this._rowColumns=new WeakMap,this._liveRegionLineCount=0,this._charsToConsume=[],this._charsToAnnounce="",this._accessibilityContainer=this._coreBrowserService.mainDocument.createElement("div"),this._accessibilityContainer.classList.add("xterm-accessibility"),this._rowContainer=this._coreBrowserService.mainDocument.createElement("div"),this._rowContainer.setAttribute("role","list"),this._rowContainer.classList.add("xterm-accessibility-tree"),this._rowElements=[];for(let e=0;e<this._terminal.rows;e++)this._rowElements[e]=this._createAccessibilityTreeNode(),this._rowContainer.appendChild(this._rowElements[e]);if(this._topBoundaryFocusListener=e=>this._handleBoundaryFocus(e,0),this._bottomBoundaryFocusListener=e=>this._handleBoundaryFocus(e,1),this._rowElements[0].addEventListener("focus",this._topBoundaryFocusListener),this._rowElements[this._rowElements.length-1].addEventListener("focus",this._bottomBoundaryFocusListener),this._refreshRowsDimensions(),this._accessibilityContainer.appendChild(this._rowContainer),this._liveRegion=this._coreBrowserService.mainDocument.createElement("div"),this._liveRegion.classList.add("live-region"),this._liveRegion.setAttribute("aria-live","assertive"),this._accessibilityContainer.appendChild(this._liveRegion),this._liveRegionDebouncer=this.register(new o.TimeBasedDebouncer(this._renderRows.bind(this))),!this._terminal.element)throw new Error("Cannot enable accessibility before Terminal.open");this._terminal.element.insertAdjacentElement("afterbegin",this._accessibilityContainer),this.register(this._terminal.onResize((e=>this._handleResize(e.rows)))),this.register(this._terminal.onRender((e=>this._refreshRows(e.start,e.end)))),this.register(this._terminal.onScroll((()=>this._refreshRows()))),this.register(this._terminal.onA11yChar((e=>this._handleChar(e)))),this.register(this._terminal.onLineFeed((()=>this._handleChar("\n")))),this.register(this._terminal.onA11yTab((e=>this._handleTab(e)))),this.register(this._terminal.onKey((e=>this._handleKey(e.key)))),this.register(this._terminal.onBlur((()=>this._clearLiveRegion()))),this.register(this._renderService.onDimensionsChange((()=>this._refreshRowsDimensions()))),this.register((0,l.addDisposableDomListener)(document,"selectionchange",(()=>this._handleSelectionChange()))),this.register(this._coreBrowserService.onDprChange((()=>this._refreshRowsDimensions()))),this._refreshRows(),this.register((0,a.toDisposable)((()=>{this._accessibilityContainer.remove(),this._rowElements.length=0})))}_handleTab(e){for(let t=0;t<e;t++)this._handleChar(" ")}_handleChar(e){this._liveRegionLineCount<21&&(this._charsToConsume.length>0?this._charsToConsume.shift()!==e&&(this._charsToAnnounce+=e):this._charsToAnnounce+=e,"\n"===e&&(this._liveRegionLineCount++,21===this._liveRegionLineCount&&(this._liveRegion.textContent+=n.tooMuchOutput)))}_clearLiveRegion(){this._liveRegion.textContent="",this._liveRegionLineCount=0}_handleKey(e){this._clearLiveRegion(),/\p{Control}/u.test(e)||this._charsToConsume.push(e)}_refreshRows(e,t){this._liveRegionDebouncer.refresh(e,t,this._terminal.rows)}_renderRows(e,t){const i=this._terminal.buffer,s=i.lines.length.toString();for(let r=e;r<=t;r++){const e=i.lines.get(i.ydisp+r),t=[],n=e?.translateToString(!0,void 0,void 0,t)||"",o=(i.ydisp+r+1).toString(),a=this._rowElements[r];a&&(0===n.length?(a.innerText=" ",this._rowColumns.set(a,[0,1])):(a.textContent=n,this._rowColumns.set(a,t)),a.setAttribute("aria-posinset",o),a.setAttribute("aria-setsize",s))}this._announceCharacters()}_announceCharacters(){0!==this._charsToAnnounce.length&&(this._liveRegion.textContent+=this._charsToAnnounce,this._charsToAnnounce="")}_handleBoundaryFocus(e,t){const i=e.target,s=this._rowElements[0===t?1:this._rowElements.length-2];if(i.getAttribute("aria-posinset")===(0===t?"1":`${this._terminal.buffer.lines.length}`))return;if(e.relatedTarget!==s)return;let r,n;if(0===t?(r=i,n=this._rowElements.pop(),this._rowContainer.removeChild(n)):(r=this._rowElements.shiftLine truncated
//# sourceMappingURL=xterm.js.map
+18
View File
@@ -1,2 +1,20 @@
/*
* Copyright (C) 2024 Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import backend from '@heyputer/backend';
export default backend;
+13
View File
@@ -0,0 +1,13 @@
# Puter Mods
A list of Puter mods which may be expanded in the future.
**Contributions of new mods are welcome.**
## kdmod
- **location:** [./kdmod](./kdmod)
- **description:**
> "kernel dev mod"; specifically for the devex needs of
> GitHub user KernelDeimos and provided in case anyone else
> finds it of any use.
@@ -0,0 +1,78 @@
/*
* Copyright (C) 2024 Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const path = require('path');
class CustomPuterService extends use.Service {
async _init () {
const svc_commands = this.services.get('commands');
this._register_commands(svc_commands);
const svc_puterHomepage = this.services.get('puter-homepage');
svc_puterHomepage.register_script('/custom-gui/main.js');
}
['__on_install.routes'] (_, { app }) {
const require = this.require;
const express = require('express');
const path_ = require('path');
app.use('/custom-gui',
express.static(path.join(__dirname, 'gui')));
}
async ['__on_boot.consolidation'] () {
const then = Date.now();
this.tod_widget = () => {
const s = 5 - Math.floor(
(Date.now() - then) / 1000);
const lines = [
"\x1B[36;1mKDMOD ENABLED\x1B[0m" +
` (👁️ ${s}s)`
];
// It would be super cool to be able to use this here
// surrounding_box('33;1', lines);
return lines;
}
const svc_devConsole = this.services.get('dev-console', { optional: true });
if ( ! svc_devConsole ) return;
svc_devConsole.add_widget(this.tod_widget);
setTimeout(() => {
svc_devConsole.remove_widget(this.tod_widget);
}, 5000)
}
_register_commands (commands) {
commands.registerCommands('o', [
{
id: 'k',
description: '',
handler: async (_, log) => {
const svc_devConsole = this.services.get('dev-console', { optional: true });
if ( ! svc_devConsole ) return;
svc_devConsole.remove_widget(this.tod_widget);
const lines = this.tod_widget();
for ( const line of lines ) log.log(line);
this.tod_widget = null;
}
}
]);
}
}
module.exports = { CustomPuterService };
+7
View File
@@ -0,0 +1,7 @@
# Kernel Dev Mod
This mod makes testing and debugging easier.
## Current Features:
- A service-script adds `reqex` to the `window` object in the client,
which contains a bunch of example requests to internal API endpoints.
@@ -0,0 +1,251 @@
/*
* Copyright (C) 2024 Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// TODO: accessing these imports directly from a mod is not really
// the way mods are intended to work; this is temporary until
// we have these things registered in "useapi".
const {
get_user,
generate_system_fsentries,
invalidate_cached_user,
deleteUser,
} = require('../../../packages/backend/src/helpers');
const { HLWrite } = require('../../../packages/backend/src/filesystem/hl_operations/hl_write');
const { LLRead } = require('../../../packages/backend/src/filesystem/ll_operations/ll_read');
const { Actor, UserActorType }
= require('../../../packages/backend/src/services/auth/Actor');
const { DB_WRITE } = require('../../../packages/backend/src/services/database/consts');
const {
RootNodeSelector,
NodeChildSelector,
NodePathSelector,
} = require('../../../packages/backend/src/filesystem/node/selectors');
const { Context } = require('../../../packages/backend/src/util/context');
class ShareTestService extends use.Service {
static MODULES = {
uuidv4: require('uuid').v4,
}
async _init () {
const svc_commands = this.services.get('commands');
this._register_commands(svc_commands);
this.scenarios = require('./data/sharetest_scenarios');
const svc_db = this.services.get('database');
this.db = svc_db.get(svc_db.DB_WRITE, 'share-test');
}
_register_commands (commands) {
commands.registerCommands('share-test', [
{
id: 'start',
description: '',
handler: async (_, log) => {
const results = await this.runit();
for ( const result of results ) {
log.log(`=== ${result.title} ===`);
if ( ! result.report ) {
log.log(`\x1B[32;1mSUCCESS\x1B[0m`);
continue;
}
log.log(
`\x1B[31;1mSTOPPED\x1B[0m at ` +
`${result.report.step}: ` +
result.report.report.message,
);
}
}
}
]);
}
async runit () {
await this.teardown_();
await this.setup_();
const results = [];
for ( const scenario of this.scenarios ) {
if ( ! scenario.title ) {
scenario.title = scenario.sequence.map(
step => step.title).join('; ')
}
results.push({
title: scenario.title,
report: await this.run_scenario_(scenario)
});
}
await this.teardown_();
return results;
}
async setup_ () {
await this.create_test_user_('testuser_eric');
await this.create_test_user_('testuser_stan');
await this.create_test_user_('testuser_kyle');
await this.create_test_user_('testuser_kenny');
}
async run_scenario_ (scenario) {
let error;
// Run sequence
for ( const step of scenario.sequence ) {
const method = this[`__scenario:${step.call}`];
const user = await get_user({ username: step.as })
const actor = await Actor.create(UserActorType, { user });
const generated = { user, actor };
const report = await Context.get().sub({ user, actor })
.arun(async () => {
return await method.call(this, generated, step.with);
});
if ( report ) {
error = { step: step.title, report };
break;
}
}
return error;
}
async teardown_ () {
await this.delete_test_user_('testuser_eric');
await this.delete_test_user_('testuser_stan');
await this.delete_test_user_('testuser_kyle');
await this.delete_test_user_('testuser_kenny');
}
async create_test_user_ (username) {
await this.db.write(
`
INSERT INTO user (uuid, username, email, free_storage, password)
VALUES (?, ?, ?, ?, ?)
`,
[
this.modules.uuidv4(),
username,
username + '@example.com',
1024 * 1024 * 500, // 500 MiB
this.modules.uuidv4(),
],
);
const user = await get_user({ username });
await generate_system_fsentries(user);
invalidate_cached_user(user);
return user;
}
async delete_test_user_ (username) {
const user = await get_user({ username });
if ( ! user ) return;
await deleteUser(user.id);
}
// API for scenarios
async ['__scenario:create-example-file'] (
{ actor, user },
{ name, contents },
) {
const svc_fs = this.services.get('filesystem');
const parent = await svc_fs.node(new NodePathSelector(
`/${user.username}/Desktop`
));
console.log('test -> create-example-file',
user, name, contents);
const buffer = Buffer.from(contents);
const file = {
size: buffer.length,
name: name,
type: 'application/octet-stream',
buffer,
};
const hl_write = new HLWrite();
await hl_write.run({
actor,
user,
destination_or_parent: parent,
specified_name: name,
file,
});
}
async ['__scenario:assert-no-access'] (
{ actor, user },
{ path },
) {
const svc_fs = this.services.get('filesystem');
const node = await svc_fs.node(new NodePathSelector(path));
const ll_read = new LLRead();
let expected_e; try {
const stream = await ll_read.run({
fsNode: node,
actor,
})
} catch (e) {
expected_e = e;
}
if ( ! expected_e ) {
return { message: 'expected error, got none' };
}
}
async ['__scenario:grant'] (
{ actor, user },
{ to, permission },
) {
const svc_permission = this.services.get('permission');
await svc_permission.grant_user_user_permission(
actor, to, permission, {}, {},
);
}
async ['__scenario:assert-access'] (
{ actor, user },
{ path, level }
) {
const svc_fs = this.services.get('filesystem');
const svc_acl = this.services.get('acl');
const node = await svc_fs.node(new NodePathSelector(path));
const has_read = await svc_acl.check(actor, node, 'read');
const has_write = await svc_acl.check(actor, node, 'write');
if ( level !== 'write' && level !== 'read' ) {
return {
message: 'unexpected value for "level" parameter'
};
}
if ( level === 'read' && has_write ) {
return {
message: 'expected read-only but actor can write'
};
}
if ( level === 'read' && !has_read ) {
return {
message: 'expected read access but no read access'
};
}
if ( level === 'write' && (!has_write || !has_read) ) {
return {
message: 'expected write access but no write access'
};
}
}
}
module.exports = {
ShareTestService,
};
@@ -0,0 +1,93 @@
/*
* Copyright (C) 2024 Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
module.exports = [
{
sequence: [
{
title: 'Kyle creates a file',
call: 'create-example-file',
as: 'testuser_kyle',
with: {
name: 'example.txt',
contents: 'secret file',
}
},
{
title: 'Eric tries to access it',
call: 'assert-no-access',
as: 'testuser_eric',
with: {
path: '/testuser_kyle/Desktop/example.txt'
}
},
]
},
{
sequence: [
{
title: 'Stan creates a file',
call: 'create-example-file',
as: 'testuser_stan',
with: {
name: 'example.txt',
contents: 'secret file',
}
},
{
title: 'Stan grants permission to Eric',
call: 'grant',
as: 'testuser_stan',
with: {
to: 'testuser_eric',
permission: 'fs:/testuser_stan/Desktop/example.txt:read'
}
},
{
title: 'Eric tries to access it',
call: 'assert-access',
as: 'testuser_eric',
with: {
path: '/testuser_stan/Desktop/example.txt',
level: 'read'
}
},
]
},
{
sequence: [
{
title: 'Stan grants Kyle\'s file to Eric',
call: 'grant',
as: 'testuser_stan',
with: {
to: 'testuser_eric',
permission: 'fs:/testuser_kyle/Desktop/example.txt:read'
}
},
{
title: 'Eric tries to access it',
call: 'assert-no-access',
as: 'testuser_eric',
with: {
path: '/testuser_kyle/Desktop/example.txt',
}
},
]
},
];
+125
View File
@@ -0,0 +1,125 @@
/*
* Copyright (C) 2024 Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const request_examples = [
{
name: 'entity storage app read',
fetch: async (args) => {
return await fetch(`${window.api_origin}/drivers/call`, {
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
body: JSON.stringify({
interface: 'puter-apps',
method: 'read',
args,
}),
method: "POST",
});
},
out: async (resp) => {
const data = await resp.json();
if ( ! data.success ) return data;
return data.result;
},
exec: async function exec (...a) {
const resp = await this.fetch(...a);
return await this.out(resp);
},
},
{
name: 'entity storage app select all',
fetch: async () => {
return await fetch(`${window.api_origin}/drivers/call`, {
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
body: JSON.stringify({
interface: 'puter-apps',
method: 'select',
args: { predicate: [] },
}),
method: "POST",
});
},
out: async (resp) => {
const data = await resp.json();
if ( ! data.success ) return data;
return data.result;
},
exec: async function exec (...a) {
const resp = await this.fetch(...a);
return await this.out(resp);
},
},
{
name: 'grant permission from a user to a user',
fetch: async (user, perm) => {
return await fetch(`${window.api_origin}/auth/grant-user-user`, {
"headers": {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
"body": JSON.stringify({
target_username: user,
permission: perm,
}),
"method": "POST",
});
},
out: async (resp) => {
const data = await resp.json();
return data;
},
exec: async function exec (...a) {
const resp = await this.fetch(...a);
return await this.out(resp);
},
},
{
name: 'write file',
fetch: async (path, str) => {
const endpoint = `${window.api_origin}/write`;
const token = puter.authToken;
const blob = new Blob([str], { type: 'text/plain' });
const formData = new FormData();
formData.append('create_missing_ancestors', true);
formData.append('path', path);
formData.append('size', 8);
formData.append('overwrite', true);
formData.append('file', blob, 'something.txt');
const response = await fetch(endpoint, {
method: 'POST',
headers: { 'Authorization': `Bearer ${token}` },
body: formData
});
return await response.json();
},
}
];
globalThis.reqex = request_examples;
globalThis.service_script(api => {
api.on_ready(() => {
});
});
+29
View File
@@ -0,0 +1,29 @@
/*
* Copyright (C) 2024 Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
module.exports = class BillingModule extends use.Module {
install (context) {
const services = context.get('services');
const { CustomPuterService } = require('./CustomPuterService.js');
services.registerService('__custom-puter', CustomPuterService);
const { ShareTestService } = require('./ShareTestService.js');
services.registerService('__share-test', ShareTestService);
}
}
+12
View File
@@ -0,0 +1,12 @@
{
"name": "custom-puter-mod",
"version": "1.0.0",
"description": "",
"main": "module.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
+2
View File
@@ -0,0 +1,2 @@
*
!.gitignore
+5036 -1505
View File
File diff suppressed because it is too large. Load diff
+15 -5
View File
@@ -1,6 +1,6 @@
{
"name": "puter.com",
"version": "1.0.0",
"version": "2.4.1",
"author": "Puter Technologies Inc.",
"license": "AGPL-3.0-only",
"description": "Desktop environment in the browser!",
@@ -11,25 +11,32 @@
"lib": "lib"
},
"devDependencies": {
"@eslint/js": "^9.1.1",
"chalk": "^4.1.0",
"clean-css": "^5.3.2",
"dotenv": "^16.4.5",
"eslint": "^9.1.1",
"express": "^4.18.2",
"globals": "^15.0.0",
"html-entities": "^2.3.3",
"license-check-and-add": "^4.0.5",
"mocha": "^10.6.0",
"nodemon": "^3.1.0",
"uglify-js": "^3.17.4",
"webpack": "^5.88.2",
"webpack-cli": "^5.1.1"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"test": "npx mocha src/phoenix/test src/contextlink/test",
"start=gui": "nodemon --exec \"node dev-server.js\" ",
"start": "node run-selfhosted.js",
"build": "node ./build.js",
"start": "node ./tools/run-selfhosted.js",
"build": "cd src/gui; node ./build.js",
"check-translations": "node tools/check-translations.js"
},
"workspaces": [
"packages/*"
"src/*",
"tools/*",
"experiments/js-parse-and-output"
],
"nodemonConfig": {
"ext": "js, json, mjs, jsx, svg, css",
@@ -39,6 +46,9 @@
]
},
"dependencies": {
"json-colorizer": "^3.0.1",
"simple-git": "^3.25.0",
"string-template": "^1.0.0",
"uuid": "^9.0.1"
}
}
@@ -1,32 +0,0 @@
const { TeePromise } = require('../util/promise');
const es_import_promise = new TeePromise();
let stringLength;
(async () => {
stringLength = (await import('string-length')).default;
es_import_promise.resolve();
// console.log('STRING LENGTH', stringLength);
// process.exit(0);
})();
const surrounding_box = (col, lines, lengths) => {
if ( ! lengths ) {
lengths = lines.map(line => stringLength(line));
}
const max_length = Math.max(...lengths);
const c = str => `\x1b[${col}m${str}\x1b[0m`;
const bar = c(Array(max_length + 4).fill('━').join(''));
for ( let i = 0 ; i < lines.length ; i++ ) {
while ( stringLength(lines[i]) < max_length ) {
lines[i] += ' ';
}
lines[i] = `${c('┃ ')} ${lines[i]} ${c(' ┃')}`;
}
lines.unshift(`${c('┏')}${bar}${c('┓')}`);
lines.push(`${c('┗')}${bar}${c('┛')}`);
};
module.exports = {
surrounding_box,
es_import_promise,
};
@@ -1,105 +0,0 @@
/*
* Copyright (C) 2024 Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
"use strict"
const validator = require('validator');
const crypto = require('crypto');
const eggspress = require('../api/eggspress.js');
const APIError = require('../api/APIError.js');
const { DB_READ, DB_WRITE } = require('../services/database/consts.js');
const CHANGE_EMAIL_START = eggspress('/change_email/start', {
subdomain: 'api',
auth: true,
verified: true,
allowedMethods: ['POST'],
}, async (req, res, next) => {
const user = req.user;
const new_email = req.body.new_email;
// TODO: DRY: signup.js
// validation
if( ! new_email ) {
throw APIError.create('field_missing', null, { key: 'new_email' });
}
if ( typeof new_email !== 'string' ) {
throw APIError.create('field_invalid', null, {
key: 'new_email', expected: 'a valid email address' });
}
if ( ! validator.isEmail(new_email) ) {
throw APIError.create('field_invalid', null, {
key: 'new_email', expected: 'a valid email address' });
}
// check if email is already in use
const svc_mysql = req.services.get('mysql');
const db = req.services.get('database').get(DB_WRITE, 'auth');
const rows = await db.read(
'SELECT COUNT(*) AS `count` FROM `user` WHERE `email` = ?',
[new_email]
);
if ( rows[0].count > 0 ) {
throw APIError.create('email_already_in_use', null, { email: new_email });
}
// generate confirmation token
const token = crypto.randomBytes(4).toString('hex');
// update user
await db.write(
'UPDATE `user` SET `unconfirmed_change_email` = ?, `change_email_confirm_token` = ? WHERE `id` = ?',
[new_email, token, user.id]
);
});
const CHANGE_EMAIL_CONFIRM = eggspress('/change_email/confirm', {
subdomain: 'api',
auth: true,
verified: true,
allowedMethods: ['POST'],
}, async (req, res, next) => {
const user = req.user;
const token = req.body.token;
if ( ! token ) {
throw APIError.create('field_missing', null, { key: 'token' });
}
const svc_mysql = req.services.get('mysql');
const dbrr = svc_mysql.get(DB_MODE_READ, 'change-email-confirm');
const [rows] = await dbrr.promise().query(
'SELECT `unconfirmed_change_email` FROM `user` WHERE `id` = ? AND `change_email_confirm_token` = ?',
[user.id, token]
);
if ( rows.length === 0 ) {
throw APIError.create('token_invalid');
}
const new_email = rows[0].unconfirmed_change_email;
const db = req.services.get('database').get(DB_WRITE, 'auth');
await db.write(
'UPDATE `user` SET `email` = ?, `unconfirmed_change_email` = NULL, `change_email_confirm_token` = NULL WHERE `id` = ?',
[new_email, user.id]
);
});
module.exports = app => {
app.use(CHANGE_EMAIL_START);
app.use(CHANGE_EMAIL_CONFIRM);
}
-121
View File
@@ -1,121 +0,0 @@
/*
* Copyright (C) 2024 Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
"use strict"
const express = require('express');
const router = new express.Router();
const { get_user, body_parser_error_handler } = require('../helpers');
const config = require('../config');
// -----------------------------------------------------------------------//
// POST /file
// -----------------------------------------------------------------------//
router.post('/login', express.json(), body_parser_error_handler, async (req, res, next)=>{
// either api. subdomain or no subdomain
if(require('../helpers').subdomain(req) !== 'api' && require('../helpers').subdomain(req) !== '')
next();
// modules
const bcrypt = require('bcrypt')
const jwt = require('jsonwebtoken')
const validator = require('validator')
// either username or email must be provided
if(!req.body.username && !req.body.email)
return res.status(400).send('Username or email is required.')
// password is required
else if(!req.body.password)
return res.status(400).send('Password is required.')
// password must be a string
else if (typeof req.body.password !== 'string' && !(req.body.password instanceof String))
return res.status(400).send('Password must be a string.')
// if password is too short it's invalid, no need to do a db lookup
else if(req.body.password.length < config.min_pass_length)
return res.status(400).send('Invalid password.')
// username, if present, must be a string
else if (req.body.username && typeof req.body.username !== 'string' && !(req.body.username instanceof String))
return res.status(400).send('username must be a string.')
// if username doesn't pass regex test it's invalid anyway, no need to do DB lookup
else if(req.body.username && !req.body.username.match(config.username_regex))
return res.status(400).send('Invalid username.')
// email, if present, must be a string
else if (req.body.email && typeof req.body.email !== 'string' && !(req.body.email instanceof String))
return res.status(400).send('email must be a string.')
// if email is invalid, no need to do DB lookup anyway
else if(req.body.email && !validator.isEmail(req.body.email))
return res.status(400).send('Invalid email.')
// Increment & check rate limit
if(kv.incr(`login|${req.ip}|${req.body.email ?? req.body.username}`) > 10)
return res.status(429).send('Too many requests.');
// Set expiry for rate limit
kv.expire(`login|${req.ip}|${req.body.email ?? req.body.username}`, 60*10, 'NX')
try{
let user;
// log in using username
if(req.body.username){
user = await get_user({ username: req.body.username, cached: false });
if(!user)
return res.status(400).send('Username not found.')
}
// log in using email
else if(validator.isEmail(req.body.email)){
user = await get_user({ email: req.body.email, cached: false });
if(!user)
return res.status(400).send('Email not found.')
}
// is user suspended?
if(user.suspended)
return res.status(401).send('This account is suspended.')
// pseudo user?
// todo make this better, maybe ask them to create an account or send them an activation link
if(user.password === null)
return res.status(400).send('Incorrect password.')
// check password
if(await bcrypt.compare(req.body.password, user.password)){
const token = await jwt.sign({uuid: user.uuid}, config.jwt_secret)
//set cookie
// res.cookie(config.cookie_name, token);
res.cookie(config.cookie_name, token, {
sameSite: 'none',
secure: true,
httpOnly: true,
});
// send response
return res.send({
token: token,
user:{
username: user.username,
uuid: user.uuid,
email: user.email,
email_confirmed: user.email_confirmed,
is_temp: (user.password === null && user.email === null),
}
})
}else{
return res.status(400).send('Incorrect password.')
}
}catch(e){
return res.status(400).send(e);
}
})
module.exports = router
@@ -1,196 +0,0 @@
/*
* Copyright (C) 2024 Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
"use strict"
const express = require('express');
const router = new express.Router();
const {get_taskbar_items, username_exists, send_email_verification_code, send_email_verification_token, invalidate_cached_user} = require('../helpers');
const auth = require('../middleware/auth.js');
const config = require('../config');
const { Context } = require('../util/context');
const { DB_WRITE } = require('../services/database/consts');
// -----------------------------------------------------------------------//
// POST /save_account
// -----------------------------------------------------------------------//
router.post('/save_account', auth, express.json(), async (req, res, next)=>{
// either api. subdomain or no subdomain
if(require('../helpers').subdomain(req) !== 'api' && require('../helpers').subdomain(req) !== '')
next();
// modules
const db = req.services.get('database').get(DB_WRITE, 'auth');
const validator = require('validator')
const bcrypt = require('bcrypt')
const jwt = require('jsonwebtoken')
const { v4: uuidv4 } = require('uuid');
// validation
if(req.user.password !== null)
return res.status(400).send('User account already saved.');
else if(!req.body.username)
return res.status(400).send('Username is required');
// username must be a string
else if (typeof req.body.username !== 'string')
return res.status(400).send('username must be a string.')
else if(!req.body.username.match(config.username_regex))
return res.status(400).send('Username can only contain letters, numbers and underscore (_).')
else if(req.body.username.length > config.username_max_length)
return res.status(400).send(`Username cannot have more than ${config.username_max_length} characters.`)
// check if username matches any reserved words
else if(config.reserved_words.includes(req.body.username))
return res.status(400).send({message: 'This username is not available.'});
else if(!req.body.email)
return res.status(400).send('Email is required')
// email must be a string
else if (typeof req.body.email !== 'string')
return res.status(400).send('email must be a string.')
else if(!validator.isEmail(req.body.email))
return res.status(400).send('Please enter a valid email address.')
else if(!req.body.password)
return res.status(400).send('Password is required')
// password must be a string
else if (typeof req.body.password !== 'string')
return res.status(400).send('password must be a string.')
else if(req.body.password.length < config.min_pass_length)
return res.status(400).send(`Password must be at least ${config.min_pass_length} characters long.`)
// duplicate username check, do this only if user has supplied a new username
if(req.body.username !== req.user.username && await username_exists(req.body.username))
return res.status(400).send('This username already exists in our database. Please use another one.');
// duplicate email check (pseudo-users don't count)
let rows2 = await db.read(`SELECT EXISTS(SELECT 1 FROM user WHERE email=? AND password IS NOT NULL) AS email_exists`, [req.body.email]);
if(rows2[0].email_exists)
return res.status(400).send('This email already exists in our database. Please use another one.');
// get pseudo user, if exists
let pseudo_user = await db.read(`SELECT * FROM user WHERE email = ? AND password IS NULL`, [req.body.email]);
pseudo_user = pseudo_user[0];
// get uuid user, if exists
if(req.body.uuid){
uuid_user = await db.read(`SELECT * FROM user WHERE uuid = ? LIMIT 1`, [req.body.uuid]);
uuid_user = uuid_user[0];
}
// send_confirmation_code
req.body.send_confirmation_code = req.body.send_confirmation_code ?? true;
// todo email confirmation is required by default unless:
// Pseudo user converting and matching uuid is provided
let email_confirmation_required = 0;
// -----------------------------------
// Get referral user
// -----------------------------------
let referred_by_user = undefined;
if ( req.body.referral_code ) {
referred_by_user = await get_user({ referral_code: req.body.referral_code });
if ( ! referred_by_user ) {
return res.status(400).send('Referral code not found');
}
}
// -----------------------------------
// New User
// -----------------------------------
const user_uuid = req.user.uuid;
let email_confirm_code = Math.floor(100000 + Math.random() * 900000);
const email_confirm_token = uuidv4();
if(pseudo_user === undefined){
await db.write(
`UPDATE user
SET
username = ?, email = ?, password = ?, email_confirm_code = ?, email_confirm_token = ?${
referred_by_user ? ', referred_by = ?' : '' }
WHERE
id = ?`,
[
// username
req.body.username,
// email
req.body.email,
// password
await bcrypt.hash(req.body.password, 8),
// email_confirm_code
email_confirm_code,
//email_confirm_token
email_confirm_token,
// referred_by
...(referred_by_user ? [referred_by_user.id] : []),
// id
req.user.id
]
);
invalidate_cached_user(req.user);
// Update root directory name
await db.write(
`UPDATE fsentries SET name = ? WHERE user_id = ? and parent_uid IS NULL`,
[
// name
req.body.username,
// id
req.user.id,
]
);
const filesystem = req.services.get('filesystem');
await filesystem.update_child_paths(`/${req.user.username}`, `/${req.body.username}`, req.user.id);
if(req.body.send_confirmation_code)
send_email_verification_code(email_confirm_code, req.body.email);
else
send_email_verification_token(email_confirm_token, req.body.email, user_uuid);
}
// create token for login
const token = await jwt.sign({uuid: user_uuid}, config.jwt_secret);
// user id
// todo if pseudo user, assign directly no need to do another DB lookup
const user_id = req.user.id;
const user_res = await db.read('SELECT * FROM `user` WHERE `id` = ? LIMIT 1', [user_id]);
const user = user_res[0];
// todo send LINK-based verification email
//set cookie
res.cookie(config.cookie_name, token);
{
const svc_event = req.services.get('event');
svc_event.emit('user.save_account', { user });
}
// return results
return res.send({
token: token,
user:{
username: user.username,
uuid: user.uuid,
email: user.email,
is_temp: false,
requires_email_confirmation: user.requires_email_confirmation,
email_confirmed: user.email_confirmed,
email_confirmation_required: email_confirmation_required,
taskbar_items: await get_taskbar_items(user),
referral_code: user.referral_code,
}
})
})
module.exports = router
@@ -1,100 +0,0 @@
/*
* Copyright (C) 2024 Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const { AdvancedBase } = require("puter-js-common");
class Emailservice extends AdvancedBase {
static MODULES = {
nodemailer: require('nodemailer'),
handlebars: require('handlebars'),
};
constructor ({ services, config }) {
super();
this.config = config;
this.templates = {
'new-referral': {
subject: `You've made a referral!`,
html: `<p>Hi there,</p>
<p>A new user has used your referral code. Enjoy an extra {{storage_increase}} of storage, on the house!</p>
<p>Sincerely,</p>
<p>Puter</p>
`,
},
'approved-for-listing': {
subject: '\u{1f389} Your app has been approved for listing!',
html: `
<p>Hi there,</p>
<p>
Exciting news! <a href="https://puter.com/app/{{app_name}}">{{app_title}}</a> is now approved and live on <a href="https://puter.com/app/app-center" target="_blank">Puter App Center</a>. It's now ready for users worldwide to discover and enjoy.
</p>
<p>
<strong>Next Step</strong>: As your app begins to gain traction with more users, we will conduct periodic reviews to assess its performance and user engagement. Once your app meets our criteria, we'll invite you to our Incentive Program. This exclusive program will allow you to earn revenue each time users open your app. So, keep an eye out for updates and stay tuned for this exciting opportunity! Make sure to share your app with your fans, friends and family to help it gain traction: <a href="https://puter.com/app/{{app_name}}">https://puter.com/app/{{app_name}}</a>
</p>
<p>Best,<br />
The Puter Team
</p>
`,
},
};
this.template_fns = {};
for ( const k in this.templates ) {
const template = this.templates[k];
this.template_fns[k] = values => {
const html = this.modules.handlebars.compile(template.html);
return {
...template,
html: html(values),
};
}
}
}
async send_email (user, template, values) {
const config = this.config;
const nodemailer = this.modules.nodemailer;
let transporter = nodemailer.createTransport({
host: config.smtp_server,
port: config.smpt_port,
secure: true, // STARTTLS
auth: {
user: config.smtp_username,
pass: config.smtp_password,
},
});
const email = user.email;
const template_fn = this.template_fns[template];
const { subject, html } = template_fn(values);
transporter.sendMail({
from: '"Puter" [email protected]', // sender address
to: email, // list of receivers
subject, html,
});
}
}
module.exports = {
Emailservice
};
@@ -1,93 +0,0 @@
/*
* Copyright (C) 2024 Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const { AdvancedBase } = require("puter-js-common");
const { NodeUIDSelector } = require("../filesystem/node/selectors");
const { get_user } = require("../helpers");
const { TeePromise } = require("../util/promise");
const { StreamBuffer } = require("../util/streamutil");
class PuterVersionService extends AdvancedBase {
static MODULES = {
_path: require('path'),
fs: require('fs'),
_exec: require('child_process').execSync,
axios: require('axios'),
}
constructor ({ services, config }) {
super();
this.fs = services.get('filesystem');
this.config = config;
this._init({ config });
this.ready_ = new TeePromise();
}
async _init ({ config }) {
// this.node = await this.fs.node(new NodeUIDSelector(config.puter_hosted_data.puter_versions));
// this.user = await get_user({ username: 'puter' });
// await this._poll_versions({ config });
// setInterval(async () => {
// await this._poll_versions({ config });
// }, 60 * 1000);
}
// not used anymore - this was for getting version numbers from a file hosted on puter
async _poll_versions ({ config }) {
const resp = await this.modules.axios.get(
config.puter_hosted_data.puter_versions
);
this.versions_ = resp.data.versions;
this.ready_.resolve();
}
get_version () {
let git_version;
let deploy_timestamp;
if ( this.config.env === 'dev' ) {
// get commit hash from git
git_version = this.modules._exec('git describe --tags', {
cwd: this.modules._path.join(__dirname, '../../'),
encoding: 'utf8',
}).trim();
deploy_timestamp = Date.now();
} else {
// get git version from file
const path = this.modules._path.join(__dirname, '../../git_version');
git_version = this.modules.fs.readFileSync(path, 'utf8').trim();
deploy_timestamp = Number.parseInt((this.modules.fs.readFileSync(
this.modules._path.join(__dirname, '../../deploy_timestamp'),
'utf8'
)).trim());
}
return {
version: git_version,
environment: this.config.env,
location: this.config.server_id,
deploy_timestamp,
};
}
}
module.exports = {
PuterVersionService,
};
@@ -1,430 +0,0 @@
/*
* Copyright (C) 2024 Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const { get_user, get_app } = require("../../helpers");
const BaseService = require("../BaseService");
const { DB_WRITE } = require("../database/consts");
const { UserActorType, Actor, AppUnderUserActorType, AccessTokenActorType } = require("./Actor");
const default_implicit_user_app_permissions = {
'driver:helloworld:greet': {},
'driver:puter-kvstore': {},
'driver:puter-ocr:recognize': {},
'driver:puter-chat-completion': {},
'driver:puter-image-generation': {},
'driver:puter-tts': {},
'driver:puter-apps': {},
'driver:puter-subdomains': {},
};
const implicit_user_app_permissions = [
{
id: 'builtin-apps',
apps: [
'app-0bef044f-918f-4cbf-a0c0-b4a17ee81085', // about
'app-838dfbc4-bf8b-48c2-b47b-c4adc77fab58', // editor
'app-58282b08-990a-4906-95f7-fa37ff92452b', // draw
'app-0087b701-da09-4f49-a37d-2d6bcabc81ee', // minipaint
'app-3fea7529-266e-47d9-8776-31649cd06557', // terminal
'app-5584fbf7-ed69-41fc-99cd-85da21b1ef51', // camera
'app-7bdca1a4-6373-4c98-ad97-03ff2d608ca1', // recorder
'app-240a43f4-43b1-49bc-b9fc-c8ae719dab77', // dev-center
'app-a2ae72a4-1ba3-4a29-b5c0-6de1be5cf178', // app-center
'app-74378e84-b9cd-5910-bcb1-3c50fa96d6e7', // https://nj.puter.site
'app-13a38aeb-f9f6-54f0-9bd3-9d4dd655ccfe', // https://cdpn.io
'app-dce8f797-82b0-5d95-a2f8-ebe4d71b9c54', // https://null.jsbin.com
'app-93005ce0-80d1-50d9-9b1e-9c453c375d56', // https://markus.puter.com
],
permissions: {
'driver:helloworld:greet': {},
'driver:puter-ocr:recognize': {},
'driver:puter-kvstore:get': {},
'driver:puter-kvstore:set': {},
'driver:puter-kvstore:del': {},
'driver:puter-kvstore:list': {},
'driver:puter-kvstore:flush': {},
'driver:puter-chat-completion:complete': {},
'driver:puter-image-generation:generate': {},
'driver:puter-analytics:create_trace': {},
'driver:puter-analytics:record': {},
},
},
{
id: 'local-testing',
apps: [
'app-a392f3e5-35ca-5dac-ae10-785696cc7dec', // https://localhost
'app-a6263561-6a84-5d52-9891-02956f9fac65', // https://127.0.0.1
'app-26149f0b-8304-5228-b995-772dadcf410e', // http://localhost
'app-c2e27728-66d9-54dd-87cd-6f4e9b92e3e3', // http://127.0.0.1
],
permissions: {
'driver:helloworld:greet': {},
'driver:puter-ocr:recognize': {},
'driver:puter-kvstore:get': {},
'driver:puter-kvstore:set': {},
'driver:puter-kvstore:del': {},
'driver:puter-kvstore:list': {},
'driver:puter-kvstore:flush': {},
},
},
];
class PermissionRewriter {
static create ({ id, matcher, rewriter }) {
return new PermissionRewriter({ id, matcher, rewriter });
}
constructor ({ id, matcher, rewriter }) {
this.id = id;
this.matcher = matcher;
this.rewriter = rewriter;
}
matches (permission) {
return this.matcher(permission);
}
async rewrite (permission) {
return await this.rewriter(permission);
}
}
class PermissionUtil {
static unescape_permission_component (component) {
let unescaped_str = '';
const STATE_NORMAL = {};
const STATE_ESCAPE = {};
let state = STATE_NORMAL;
const const_escapes = { C: ':' };
for ( let i = 0 ; i < component.length ; i++ ) {
const c = component[i];
if ( state === STATE_NORMAL ) {
if ( c === '\\' ) {
state = STATE_ESCAPE;
} else {
unescaped_str += c;
}
} else if ( state === STATE_ESCAPE ) {
unescaped_str += const_escapes.hasOwnProperty(c)
? const_escapes[c] : c;
state = STATE_NORMAL;
}
}
return unescaped_str;
}
static split (permission) {
return permission
.split(':')
.map(PermissionUtil.unescape_permission_component)
;
}
}
class PermissionService extends BaseService {
async _init () {
this.db = this.services.get('database').get(DB_WRITE, 'permissions');
this._register_commands(this.services.get('commands'));
this._permission_rewriters = [];
}
async _rewrite_permission (permission) {
for ( const rewriter of this._permission_rewriters ) {
if ( ! rewriter.matches(permission) ) continue;
permission = await rewriter.rewrite(permission);
}
return permission;
}
async check (actor, permission) {
permission = await this._rewrite_permission(permission);
this.log.info(`checking permission ${permission} for actor ${actor.uid}`, {
actor: actor.uid,
permission,
});
// For now we're only checking driver permissions, and users have all of them
if ( actor.type instanceof UserActorType ) {
return {};
}
if ( actor.type instanceof AccessTokenActorType ) {
return await this.check_access_token_permission(
actor.type.authorizer, actor.type.token, permission
);
}
// Prevent undefined behaviour
if ( ! (actor.type instanceof AppUnderUserActorType) ) {
throw new Error('actor must be an app under a user');
}
// Now it's an app under a user
const app_uid = actor.type.app.uid;
return await this.check_user_app_permission(actor, app_uid, permission);
}
async check_access_token_permission (authorizer, token, permission) {
// Authorizer must have permission
const authorizer_permission = await this.check(authorizer, permission);
if ( ! authorizer_permission ) return false;
const rows = await this.db.read(
'SELECT * FROM `access_token_permissions` ' +
'WHERE `token_uid` = ? AND `permission` = ?',
[
token,
permission,
]
);
// Token must have permission
if ( ! rows[0] ) return undefined;
return rows[0].extra;
}
async check_user_app_permission (actor, app_uid, permission) {
permission = await this._rewrite_permission(permission);
let app = await get_app({ uid: app_uid });
if ( ! app ) app = await get_app({ name: app_uid });
const app_id = app.id;
const parent_perms = [];
{
// We don't use PermissionUtil.split here because it unescapes
// components; we want to keep the components escaped for matching.
const parts = permission.split(':');
// Add sub-permissions
for ( let i = 1 ; i < parts.length ; i++ ) {
parent_perms.push(parts.slice(0, i + 1).join(':'));
}
}
parent_perms.reverse();
for ( const permission of parent_perms ) {
// Check hardcoded permissions
if ( default_implicit_user_app_permissions[permission] ) {
return default_implicit_user_app_permissions[permission];
}
// Check implicit permissions
const implicit_permissions = {};
for ( const implicit_permission of implicit_user_app_permissions ) {
if ( implicit_permission.apps.includes(app_uid) ) {
implicit_permissions[permission] = implicit_permission.permissions[permission];
}
}
if ( implicit_permissions[permission] ) {
return implicit_permissions[permission];
}
}
// My biggest gripe with SQL is doing string manipulation for queries.
// If the grammar for SQL was simpler we could model it, write this as
// data, and even implement macros for common patterns.
let sql_perm = parent_perms.map((perm) =>
`\`permission\` = ?`).join(' OR ');
if ( parent_perms.length > 1 ) sql_perm = '(' + sql_perm + ')';
// SELECT permission
const rows = await this.db.read(
'SELECT * FROM `user_to_app_permissions` ' +
'WHERE `user_id` = ? AND `app_id` = ? AND ' +
sql_perm,
[
actor.type.user.id,
app_id,
...parent_perms,
]
);
if ( ! rows[0] ) return undefined;
return rows[0].extra;
}
async grant_user_app_permission (actor, app_uid, permission, extra = {}, meta) {
permission = await this._rewrite_permission(permission);
let app = await get_app({ uid: app_uid });
if ( ! app ) app = await get_app({ name: app_uid });
const app_id = app.id;
// UPSERT permission
await this.db.write(
'INSERT INTO `user_to_app_permissions` (`user_id`, `app_id`, `permission`, `extra`) ' +
'VALUES (?, ?, ?, ?) ' +
this.db.case({
mysql: 'ON DUPLICATE KEY UPDATE `extra` = ?',
otherwise: 'ON CONFLICT(`user_id`, `app_id`, `permission`) DO UPDATE SET `extra` = ?',
}),
[
actor.type.user.id,
app_id,
permission,
JSON.stringify(extra),
JSON.stringify(extra),
]
);
// INSERT audit table
const audit_values = {
user_id: actor.type.user.id,
user_id_keep: actor.type.user.id,
app_id: app_id,
app_id_keep: app_id,
permission,
action: 'grant',
reason: meta?.reason || 'granted via PermissionService',
};
const sql_cols = Object.keys(audit_values).map((key) => `\`${key}\``).join(', ');
const sql_vals = Object.keys(audit_values).map((key) => `?`).join(', ');
await this.db.write(
'INSERT INTO `audit_user_to_app_permissions` (' + sql_cols + ') ' +
'VALUES (' + sql_vals + ')',
Object.values(audit_values)
);
}
async revoke_user_app_permission (actor, app_uid, permission, meta) {
permission = await this._rewrite_permission(permission);
// For now, actor MUST be a user
if ( ! (actor.type instanceof UserActorType) ) {
throw new Error('actor must be a user');
}
let app = await get_app({ uid: app_uid });
if ( ! app ) app = await get_app({ name: app_uid });
const app_id = app.id;
// DELETE permission
await this.db.write(
'DELETE FROM `user_to_app_permissions` ' +
'WHERE `user_id` = ? AND `app_id` = ? AND `permission` = ?',
[
actor.type.user.id,
app_id,
permission,
]
);
// INSERT audit table
const audit_values = {
user_id: actor.type.user.id,
user_id_keep: actor.type.user.id,
app_id: app_id,
app_id_keep: app_id,
permission,
action: 'revoke',
reason: meta?.reason || 'revoked via PermissionService',
};
const sql_cols = Object.keys(audit_values).map((key) => `\`${key}\``).join(', ');
const sql_vals = Object.keys(audit_values).map((key) => `?`).join(', ');
await this.db.write(
'INSERT INTO `audit_user_to_app_permissions` (' + sql_cols + ') ' +
'VALUES (' + sql_vals + ')',
Object.values(audit_values)
);
}
async revoke_user_app_all (actor, app_uid, meta) {
// For now, actor MUST be a user
if ( ! (actor.type instanceof UserActorType) ) {
throw new Error('actor must be a user');
}
let app = await get_app({ uid: app_uid });
if ( ! app ) app = await get_app({ name: app_uid });
const app_id = app.id;
// DELETE permissions
await this.db.write(
'DELETE FROM `user_to_app_permissions` ' +
'WHERE `user_id` = ? AND `app_id` = ?',
[
actor.type.user.id,
app_id,
]
);
// INSERT audit table
const audit_values = {
user_id: actor.type.user.id,
user_id_keep: actor.type.user.id,
app_id: app_id,
app_id_keep: app_id,
permission: '*',
action: 'revoke',
reason: meta?.reason || 'revoked all via PermissionService',
};
const sql_cols = Object.keys(audit_values).map((key) => `\`${key}\``).join(', ');
const sql_vals = Object.keys(audit_values).map((key) => `?`).join(', ');
await this.db.write(
'INSERT INTO `audit_user_to_app_permissions` (' + sql_cols + ') ' +
'VALUES (' + sql_vals + ')',
Object.values(audit_values)
);
}
register_rewriter (translator) {
if ( ! (translator instanceof PermissionRewriter) ) {
throw new Error('translator must be a PermissionRewriter');
}
this._permission_rewriters.push(translator);
}
_register_commands (commands) {
commands.registerCommands('perms', [
{
id: 'grant-user-app',
handler: async (args, log) => {
const [ username, app_uid, permission, extra ] = args;
// actor from username
const actor = new Actor({
type: new UserActorType({
user: await get_user({ username }),
}),
})
await this.grant_user_app_permission(actor, app_uid, permission, extra);
}
}
]);
}
}
module.exports = {
PermissionRewriter,
PermissionUtil,
PermissionService,
};
@@ -1,157 +0,0 @@
/*
* Copyright (C) 2024 Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const { BaseDatabaseAccessService } = require("./BaseDatabaseAccessService");
class SqliteDatabaseAccessService extends BaseDatabaseAccessService {
static ENGINE_NAME = 'sqlite';
static MODULES = {
// Documentation calls it 'Database'; it's new-able so
// I'll stick with their convention over ours.
Database: require('better-sqlite3'),
};
async _init () {
const require = this.require;
const Database = require('better-sqlite3');
this._register_commands(this.services.get('commands'));
const fs = require('fs');
const path_ = require('path');
const do_setup = ! fs.existsSync(this.config.path);
this.db = new Database(this.config.path);
if ( do_setup ) {
const sql_files = [
'0001_create-tables.sql',
'0002_add-default-apps.sql',
].map(p => path_.join(__dirname, 'sqlite_setup', p));
const fs = require('fs');
for ( const filename of sql_files ) {
const contents = fs.readFileSync(filename, 'utf8');
this.db.exec(contents);
}
}
// Create the tables if they don't exist.
const check =
`SELECT name FROM sqlite_master WHERE type='table' AND name='fsentries'`;
const rows = await this.db.prepare(check).all();
if ( rows.length === 0 ) {
throw new Error('it works');
}
}
async _read (query, params = []) {
query = this.sqlite_transform_query_(query);
params = this.sqlite_transform_params_(params);
return this.db.prepare(query).all(...params);
}
async _requireRead (query, params) {
return this._read(query, params);
}
async _write (query, params) {
query = this.sqlite_transform_query_(query);
params = this.sqlite_transform_params_(params);
try {
const stmt = this.db.prepare(query);
const info = stmt.run(...params);
return {
insertId: info.lastInsertRowid,
anyRowsAffected: info.changes > 0,
};
} catch ( e ) {
console.error(e);
console.log('everything', {
query, params,
})
console.log(params.map(p => typeof p));
// throw e;
}
}
async _batch_write (entries) {
this.db.transaction(() => {
for ( let { statement, values } of entries ) {
statement = this.sqlite_transform_query_(statement);
values = this.sqlite_transform_params_(values);
this.db.prepare(statement).run(values);
}
})();
}
sqlite_transform_query_ (query) {
// replace `now()` with `datetime('now')`
query = query.replace(/now\(\)/g, 'datetime(\'now\')');
return query;
}
sqlite_transform_params_ (params) {
return params.map(p => {
if ( typeof p === 'boolean' ) {
return p ? 1 : 0;
}
return p;
});
}
_register_commands (commands) {
commands.registerCommands('sqlite', [
{
id: 'execfile',
description: 'execute a file',
handler: async (args, log) => {
try {
const [filename] = args;
const fs = require('fs');
const contents = fs.readFileSync(filename, 'utf8');
this.db.exec(contents);
} catch (err) {
log.error(err.message);
}
}
},
{
id: 'read',
description: 'read a query',
handler: async (args, log) => {
try {
const [query] = args;
const rows = this._read(query, []);
log.log(rows);
} catch (err) {
log.error(err.message);
}
}
},
])
}
}
module.exports = {
SqliteDatabaseAccessService,
};
@@ -1,55 +0,0 @@
/*
* Copyright (C) 2024 Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const { AdvancedBase } = require("puter-js-common");
const ENDPOINT = 'https://api.puter.com/drivers/call';
/*
Fetch example:
await fetch("https://api.puter.local/drivers/call", {
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer <actor token>",
},
"body": JSON.stringify({ interface: '...', method: '...', args: { ... } }),
"method": "POST",
});
*/
class PuterDriverProxy extends AdvancedBase {
static MODULES = {
axios: require('axios'),
}
constructor ({ target }) {
this.target = target;
}
async call (method, args) {
const require = this.require;
const axios = require('axios');
// TODO: We need the BYOK feature before we can implement this
}
}
module.exports = PuterDriverProxy;
@@ -1,161 +0,0 @@
/*
* Copyright (C) 2024 Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const {encode} = require('html-entities');
const path_ = require('path');
const fs_ = require('fs');
const generate_puter_page_html = ({
manifest,
gui_path,
app_origin,
api_origin,
meta,
gui_params,
}) => {
const e = encode;
const {
title,
description,
short_description,
company,
canonical_url,
} = meta;
gui_params = {
...meta,
...gui_params,
app_origin,
api_origin,
gui_origin: app_origin,
};
return `<!DOCTYPE html>
<html lang="en">
<head>
<title>${e(title)}</title>
<meta name="author" content="${e(company)}">
<meta name="description" content="${e((description).replace(/\n/g, " "))}">
<meta name="facebook-domain-verification" content="e29w3hjbnnnypf4kzk2cewcdaxym1y" />
<link rel="canonical" href="${e(canonical_url)}">
<!-- Meta meta tags -->
<meta property="og:url" content="${app_origin}">
<meta property="og:type" content="website">
<meta property="og:title" content="${e(title)}">
<meta property="og:description" content="${e((short_description).replace(/\n/g, " "))}">
<meta property="og:image" content="/dist/images/screenshot.png">
<!-- Twitter meta tags -->
<meta name="twitter:card" content="summary_large_image">
<meta property="twitter:domain" content="puter.com">
<meta property="twitter:url" content="${app_origin}">
<meta name="twitter:title" content="${e(title)}">
<meta name="twitter:description" content="${e((short_description).replace(/\n/g, " "))}">
<meta name="twitter:image" content="/dist/images/screenshot.png">
<!-- favicons -->
<link rel="apple-touch-icon" sizes="57x57" href="/dist/favicons/apple-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/dist/favicons/apple-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/dist/favicons/apple-icon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="/dist/favicons/apple-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="/dist/favicons/apple-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="/dist/favicons/apple-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/dist/favicons/apple-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/dist/favicons/apple-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/dist/favicons/apple-icon-180x180.png">
<link rel="icon" type="image/png" sizes="192x192" href="/dist/favicons/android-icon-192x192.png">
<link rel="icon" type="image/png" sizes="32x32" href="/dist/favicons/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="/dist/favicons/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="16x16" href="/dist/favicons/favicon-16x16.png">
<link rel="manifest" href="/dist/manifest.json">
<meta name="msapplication-TileColor" content="#ffffff">
<meta name="msapplication-TileImage" content="/dist/favicons/ms-icon-144x144.png">
<meta name="theme-color" content="#ffffff">
<!-- Preload images when applicable -->
<link rel="preload" as="image" href="/dist/images/wallpaper.webp">
<!-- Files from JSON (may be empty) -->
${
(manifest?.css_paths
? manifest.css_paths.map(path => `<link rel="stylesheet" href="${path}">\n`)
: []).join('')
}
<!-- END Files from JSON -->
</head>
<body>
<script>window.puter_gui_enabled = true;</script>
${
(manifest?.lib_paths
? manifest.lib_paths.map(path => `<script type="text/javascript" src="${path}"></script>\n`)
: []).join('')
}
<script>
window.icons = {};
${(() => {
if ( ! manifest ) return '';
const html = [];
fs_.readdirSync(path_.join(gui_path, 'src/icons')).forEach(file => {
// skip dotfiles
if(file.startsWith('.'))
return;
// load image
let buff = new Buffer.from(fs_.readFileSync(path_.join(gui_path, 'src/icons') + '/' + file));
// convert to base64
let base64data = buff.toString('base64');
// add to `window.icons`
if(file.endsWith('.png'))
html.push(`window.icons['${file}'] = "data:image/png;base64,${base64data}";\n`);
else if(file.endsWith('.svg'))
html.push(`window.icons['${file}'] = "data:image/svg+xml;base64,${base64data}";\n`);
})
return html.join('');
})()}
</script>
${
(manifest?.js_paths
? manifest.js_paths.map(path => `<script type="module" src="${path}"></script>\n`)
: []).join('')
}
<!-- Load the GUI script -->
<script ${ manifest.index ? ' type="module"' : ''} src="${manifest?.index ?? '/dist/gui.js'}"></script>
<!-- Initialize GUI when document is loaded -->
<script>
window.addEventListener('load', function() {
gui(${JSON.stringify(gui_params)});
});
</script>
<div id="templates" style="display: none;"></div>
</body>
</html>`;
};
module.exports = {
generate_puter_page_html,
};
-5
View File
@@ -1,5 +0,0 @@
const { AdvancedBase } = require('./src/AdvancedBase');
module.exports = {
AdvancedBase,
};
@@ -1,15 +0,0 @@
// This doesn't go in ./bases because it logically depends on
// both ./bases and ./traits, and ./traits depends on ./bases.
const { TraitBase } = require("./bases/TraitBase");
class AdvancedBase extends TraitBase {
static TRAITS = [
require('./traits/NodeModuleDITrait'),
require('./traits/PropertiesTrait'),
]
}
module.exports = {
AdvancedBase,
};
@@ -1,37 +0,0 @@
class BasicBase {
_get_inheritance_chain () {
const chain = [];
let cls = this.constructor;
while ( cls && cls !== BasicBase ) {
chain.push(cls);
cls = cls.__proto__;
}
return chain.reverse();
}
_get_merged_static_array (key) {
const chain = this._get_inheritance_chain();
const values = [];
for ( const cls of chain ) {
if ( cls[key] ) {
values.push(...cls[key]);
}
}
return values;
}
_get_merged_static_object (key) {
const chain = this._get_inheritance_chain();
const values = {};
for ( const cls of chain ) {
if ( cls[key] ) {
Object.assign(values, cls[key]);
}
}
return values;
}
}
module.exports = {
BasicBase,
};
@@ -1,23 +0,0 @@
const { BasicBase } = require("./BasicBase");
class TraitBase extends BasicBase {
constructor (parameters, ...a) {
super(parameters, ...a);
for ( const trait of this.traits ) {
trait.install_in_instance(
this,
{
parameters: parameters || {},
}
)
}
}
get traits () {
return this._get_merged_static_array('TRAITS');
}
}
module.exports = {
TraitBase,
};
@@ -1,41 +0,0 @@
/**
* This trait allows dependency injection of node modules.
* This is incredibly useful for passing mock implementations
* of modules for unit testing.
*
* @example
* class MyClass extends AdvancedBase {
* static MODULES = {
* axios,
* };
* }
*
* const my_class = new MyClass({
* modules: {
* axios: MY_AXIOS_MOCK,
* }
* });
*/
module.exports = {
install_in_instance: (instance, { parameters }) => {
const modules = instance._get_merged_static_object('MODULES');
if ( parameters.modules ) {
for ( const k in parameters.modules ) {
modules[k] = parameters.modules[k];
}
}
instance.modules = modules;
// This "require" function can shadow the real one so
// that editor tools are aware of the modules that
// are being used.
instance.require = (name) => {
if ( modules[name] ) {
return modules[name];
}
return require(name);
}
},
};
@@ -1,20 +0,0 @@
module.exports = {
install_in_instance: (instance) => {
const properties = instance._get_merged_static_object('PROPERTIES');
for ( const k in properties ) {
if ( typeof properties[k] === 'function' ) {
instance[k] = properties[k]();
continue;
}
if ( typeof properties[k] === 'object' ) {
// This will be supported in the future.
throw new Error(`Property ${k} in ${instance.constructor.name} ` +
`is not a supported property specification.`);
}
instance[k] = properties[k];
}
}
}
-54
View File
@@ -1,54 +0,0 @@
const { expect } = require('chai');
const { BasicBase } = require('../src/bases/BasicBase');
const { AdvancedBase } = require('../src/AdvancedBase');
class ClassA extends BasicBase {
static STATIC_OBJ = {
a: 1,
b: 2,
};
static STATIC_ARR = ['a', 'b'];
}
class ClassB extends ClassA {
static STATIC_OBJ = {
c: 3,
d: 4,
};
static STATIC_ARR = ['c', 'd'];
}
describe('testing', () => {
it('does a thing', () => {
const b = new ClassB();
console.log(b._get_inheritance_chain());
console.log([ClassA, ClassB]);
expect(b._get_inheritance_chain()).deep.equal([ClassA, ClassB]);
expect(b._get_merged_static_array('STATIC_ARR'))
.deep.equal(['a', 'b', 'c', 'd']);
expect(b._get_merged_static_object('STATIC_OBJ'))
.deep.equal({ a: 1, b: 2, c: 3, d: 4 });
});
});
class ClassWithModule extends AdvancedBase {
static MODULES = {
axios: 'axios',
};
}
describe('AdvancedBase', () => {
it('passes DI modules to instance', () => {
const c1 = new ClassWithModule();
expect(c1.modules.axios).to.equal('axios');
const c2 = new ClassWithModule({
modules: {
axios: 'my-axios',
},
});
expect(c2.modules.axios).to.equal('my-axios');
});
});
-31
View File
@@ -1,31 +0,0 @@
{
"index": "/src/index.js",
"lib_paths": [
"/lib/jquery-3.6.1/jquery-3.6.1.min.js",
"/lib/viselect.min.js",
"/lib/FileSaver.min.js",
"/lib/socket.io/socket.io.min.js",
"/lib/qrcode.min.js",
"/lib/jquery-ui-1.13.2/jquery-ui.min.js",
"/lib/[email protected]",
"/lib/jquery.dragster.js",
"/lib/jquery.menu-aim.js",
"/lib/html-entities.js",
"/lib/timeago.min.js",
"/lib/iro.min.js",
"/lib/isMobile.min.js",
"/lib/jszip-3.10.1.min.js"
],
"css_paths": [
"/css/normalize.css",
"/lib/jquery-ui-1.13.2/jquery-ui.min.css",
"/css/style.css"
],
"js_paths": [
"/src/initgui.js",
"/src/helpers.js",
"/src/IPC.js",
"/src/globals.js",
"/src/i18n/i18n.js"
]
}
-16
View File
@@ -1,16 +0,0 @@
import backend from '@heyputer/backend';
const {
Kernel,
CoreModule,
DatabaseModule,
PuterDriversModule,
LocalDiskStorageModule,
} = backend;
const k = new Kernel();
k.add_module(new CoreModule());
k.add_module(new DatabaseModule());
k.add_module(new PuterDriversModule());
k.add_module(new LocalDiskStorageModule());
k.boot();
-96
View File
@@ -1,96 +0,0 @@
/**
* Copyright (C) 2024 Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// About
function UITabAbout(){
let h = ``;
h += `<div class="settings-content active" data-settings="about">`;
h += `<div class="about-container">`
h += `<div class="about">
<a href="https://puter.com" target="_blank" class="logo"><img src="/images/logo.png"></a>
<p class="description">${i18n('puter_description')}</p>
<p class="links">
<a href="mailto:[email protected]" target="_blank">hey@puter.com</a>
<span style="color: #CCC;">•</span>
<a href="https://docs.puter.com" target="_blank">${i18n('developers')}</a>
<span style="color: #CCC;">•</span>
<a href="https://status.puter.com" target="_blank">${i18n('status')}</a>
<span style="color: #CCC;">•</span>
<a href="https://puter.com/terms" target="_blank">${i18n('terms')}</a>
<span style="color: #CCC;">•</span>
<a href="https://puter.com/privacy" target="_blank">${i18n('privacy')}</a>
<span style="color: #CCC;">•</span>
<a href="#" class="show-credits">${i18n('credits')}</a>
</p>
<div class="social-links">
<a href="https://twitter.com/HeyPuter/" target="_blank">
<svg viewBox="0 0 24 24" aria-hidden="true" style="opacity: 0.7;"><g><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"></path></g></svg>
</a>
<a href="https://github.com/HeyPuter/" target="_blank">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="48px" height="48px" viewBox="0 0 48 48">
<g transform="translate(0, 0)">
<path fill-rule="evenodd" clip-rule="evenodd" fill="#5a606b" d="M24,0.6c-13.3,0-24,10.7-24,24c0,10.6,6.9,19.6,16.4,22.8 c1.2,0.2,1.6-0.5,1.6-1.2c0-0.6,0-2.1,0-4.1c-6.7,1.5-8.1-3.2-8.1-3.2c-1.1-2.8-2.7-3.5-2.7-3.5c-2.2-1.5,0.2-1.5,0.2-1.5 c2.4,0.2,3.7,2.5,3.7,2.5c2.1,3.7,5.6,2.6,7,2c0.2-1.6,0.8-2.6,1.5-3.2c-5.3-0.6-10.9-2.7-10.9-11.9c0-2.6,0.9-4.8,2.5-6.4 c-0.2-0.6-1.1-3,0.2-6.4c0,0,2-0.6,6.6,2.5c1.9-0.5,4-0.8,6-0.8c2,0,4.1,0.3,6,0.8c4.6-3.1,6.6-2.5,6.6-2.5c1.3,3.3,0.5,5.7,0.2,6.4 c1.5,1.7,2.5,3.8,2.5,6.4c0,9.2-5.6,11.2-11,11.8c0.9,0.7,1.6,2.2,1.6,4.4c0,3.2,0,5.8,0,6.6c0,0.6,0.4,1.4,1.7,1.2 C41.1,44.2,48,35.2,48,24.6C48,11.3,37.3,0.6,24,0.6z">
</path>
</g>
</svg>
</a>
<a href="https://discord.gg/PQcx7Teh8u" target="_blank">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="48px" height="48px" viewBox="0 0 48 48"><g transform="translate(0, 0)"><path d="M19.837,20.3a2.562,2.562,0,0,0,0,5.106,2.562,2.562,0,0,0,0-5.106Zm8.4,0a2.562,2.562,0,1,0,2.346,2.553A2.45,2.45,0,0,0,28.232,20.3Z" fill="#444444" data-color="color-2"></path> <path d="M39.41,1H8.59A4.854,4.854,0,0,0,4,6V37a4.482,4.482,0,0,0,4.59,4.572H34.672l-1.219-4.255L36.4,40.054,39.18,42.63,44,47V6A4.854,4.854,0,0,0,39.41,1ZM30.532,31.038s-.828-.989-1.518-1.863a7.258,7.258,0,0,0,4.163-2.737A13.162,13.162,0,0,1,30.532,27.8a15.138,15.138,0,0,1-3.335.989,16.112,16.112,0,0,1-5.957-.023,19.307,19.307,0,0,1-3.381-.989,13.112,13.112,0,0,1-2.622-1.357,7.153,7.153,0,0,0,4.025,2.714c-.69.874-1.541,1.909-1.541,1.909-5.083-.161-7.015-3.5-7.015-3.5a30.8,30.8,0,0,1,3.312-13.409,11.374,11.374,0,0,1,6.463-2.415l.23.276a15.517,15.517,0,0,0-6.049,3.013s.506-.276,1.357-.667a17.272,17.272,0,0,1,5.221-1.449,2.266,2.266,0,0,1,.391-.046,19.461,19.461,0,0,1,4.646-.046A18.749,18.749,0,0,1,33.2,15.007a15.307,15.307,0,0,0-5.727-2.921l.322-.368a11.374,11.374,0,0,1,6.463,2.415A30.8,30.8,0,0,1,37.57,27.542S35.615,30.877,30.532,31.038Z" fill="#444444"></path></g></svg> </a>
<a href="https://www.linkedin.com/company/puter/" target="_blank">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="48px" height="48px" viewBox="0 0 48 48">
<g transform="translate(0, 0)">
<path fill="#5a606b" d="M46,0H2C0.9,0,0,0.9,0,2v44c0,1.1,0.9,2,2,2h44c1.1,0,2-0.9,2-2V2C48,0.9,47.1,0,46,0z M14.2,40.9H7.1V18 h7.1V40.9z M10.7,14.9c-2.3,0-4.1-1.8-4.1-4.1c0-2.3,1.8-4.1,4.1-4.1c2.3,0,4.1,1.8,4.1,4.1C14.8,13,13,14.9,10.7,14.9z M40.9,40.9 h-7.1V29.8c0-2.7,0-6.1-3.7-6.1c-3.7,0-4.3,2.9-4.3,5.9v11.3h-7.1V18h6.8v3.1h0.1c0.9-1.8,3.3-3.7,6.7-3.7c7.2,0,8.5,4.7,8.5,10.9 V40.9z">
</path>
</g>
</svg>
</a>
</div>
</div>
<div class="version"></div>
<dialog class="credits">
<div class="credit-content">
<p style="margin: 0; font-size: 18px; text-align: center;">${i18n('oss_code_and_content')}</p>
<div style="max-height: 300px; overflow-y: scroll;">
<ul style="padding-left: 25px; padding-top:15px;">
<li>FileSaver.js <a target="_blank" href="https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md">${i18n('license')}</a></li>
<li>html-entities <a target="_blank" href="https://github.com/mdevils/html-entities/blob/master/LICENSE">${i18n('license')}</a></li>
<li>iro.js <a target="_blank" href="https://github.com/jaames/iro.js/blob/master/LICENSE.txt">${i18n('license')}</a></li>
<li>jQuery <a target="_blank" href="https://jquery.org/license/">${i18n('license')}</a></li>
<li>jQuery-dragster <a target="_blank" href="https://github.com/catmanjan/jquery-dragster/blob/master/LICENSE">${i18n('license')}</a></li>
<li>jQuery-menu-aim <a target="_blank" href="https://github.com/kamens/jQuery-menu-aim?tab=readme-ov-file#faq">${i18n('license')}</a></li>
<li>jQuery UI <a target="_blank" href="https://jquery.org/license/">${i18n('license')}</a></li>
<li>lodash <a target="_blank" href="https://lodash.com/license">${i18n('license')}</a></li>
<li>mime <a target="_blank" href="https://github.com/broofa/mime/blob/main/LICENSE">${i18n('license')}</a></li>
<li>qrcodejs <a target="_blank" href="https://github.com/davidshimjs/qrcodejs/blob/master/LICENSE">${i18n('license')}</a></li>
<li>Selection <a target="_blank" href="https://github.com/simonwep/selection/blob/master/LICENSE">${i18n('license')}</a></li>
<li>socket.io <a target="_blank" href="https://github.com/socketio/socket.io/blob/main/LICENSE">${i18n('license')}</a></li>
<li>Wallpaper by <a target="_blank" href="https://unsplash.com/@fakurian?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash">Milad Fakurian</a> on <a target="_blank" href="https://unsplash.com/photos/blue-orange-and-yellow-wallpaper-E8Ufcyxz514?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash">Unsplash</a></li>
</ul>
</div>
</div>
</dialog>
`;
h += `</div>`;
h += `</div>`;
return h;
}
export default UITabAbout;
Loaded 100 of 1290 files, more files were not shown because too many files have changed in this diff. Show more