@ibgib/web-gib 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.ibgibignore +30 -0
- package/.vscode/ibgib-snippets.code-snippets +309 -0
- package/.vscode/launch.json +25 -0
- package/.vscode/settings.json +68 -0
- package/.vscode/tasks.json +38 -0
- package/CHANGELOG.md +427 -0
- package/README.md +66 -0
- package/dist/agent-texts/common-agent-texts.d.mts +14 -0
- package/dist/agent-texts/common-agent-texts.d.mts.map +1 -0
- package/dist/agent-texts/common-agent-texts.mjs +51 -0
- package/dist/agent-texts/common-agent-texts.mjs.map +1 -0
- package/dist/agent-texts/primary-agent-texts.d.mts +16 -0
- package/dist/agent-texts/primary-agent-texts.d.mts.map +1 -0
- package/dist/agent-texts/primary-agent-texts.mjs +27 -0
- package/dist/agent-texts/primary-agent-texts.mjs.map +1 -0
- package/dist/agent-texts/project-agent-texts.d.mts +8 -0
- package/dist/agent-texts/project-agent-texts.d.mts.map +1 -0
- package/dist/agent-texts/project-agent-texts.mjs +29 -0
- package/dist/agent-texts/project-agent-texts.mjs.map +1 -0
- package/dist/agent-texts/project-child-text-agent-texts.d.mts +5 -0
- package/dist/agent-texts/project-child-text-agent-texts.d.mts.map +1 -0
- package/dist/agent-texts/project-child-text-agent-texts.mjs +26 -0
- package/dist/agent-texts/project-child-text-agent-texts.mjs.map +1 -0
- package/dist/agent-texts/projects-agent-texts.d.mts +4 -0
- package/dist/agent-texts/projects-agent-texts.d.mts.map +1 -0
- package/dist/agent-texts/projects-agent-texts.mjs +15 -0
- package/dist/agent-texts/projects-agent-texts.mjs.map +1 -0
- package/dist/agent-texts/raw-agent-texts.d.mts +4 -0
- package/dist/agent-texts/raw-agent-texts.d.mts.map +1 -0
- package/dist/agent-texts/raw-agent-texts.mjs +17 -0
- package/dist/agent-texts/raw-agent-texts.mjs.map +1 -0
- package/dist/agent-texts/text-editor-agent-texts.d.mts +6 -0
- package/dist/agent-texts/text-editor-agent-texts.d.mts.map +1 -0
- package/dist/agent-texts/text-editor-agent-texts.mjs +19 -0
- package/dist/agent-texts/text-editor-agent-texts.mjs.map +1 -0
- package/dist/api/api-constants.d.mts +9 -0
- package/dist/api/api-constants.d.mts.map +1 -0
- package/dist/api/api-constants.mjs +9 -0
- package/dist/api/api-constants.mjs.map +1 -0
- package/dist/api/api-index.d.mts +10 -0
- package/dist/api/api-index.d.mts.map +1 -0
- package/dist/api/api-index.mjs +121 -0
- package/dist/api/api-index.mjs.map +1 -0
- package/dist/api/api-types.d.mts +36 -0
- package/dist/api/api-types.d.mts.map +1 -0
- package/dist/api/api-types.mjs +2 -0
- package/dist/api/api-types.mjs.map +1 -0
- package/dist/api/commands/chat/chat-index.d.mts +3 -0
- package/dist/api/commands/chat/chat-index.d.mts.map +1 -0
- package/dist/api/commands/chat/chat-index.mjs +9 -0
- package/dist/api/commands/chat/chat-index.mjs.map +1 -0
- package/dist/api/commands/chat/get-context-info.d.mts +71 -0
- package/dist/api/commands/chat/get-context-info.d.mts.map +1 -0
- package/dist/api/commands/chat/get-context-info.mjs +130 -0
- package/dist/api/commands/chat/get-context-info.mjs.map +1 -0
- package/dist/api/commands/chat/hello-world.d.mts +63 -0
- package/dist/api/commands/chat/hello-world.d.mts.map +1 -0
- package/dist/api/commands/chat/hello-world.mjs +132 -0
- package/dist/api/commands/chat/hello-world.mjs.map +1 -0
- package/dist/api/commands/chat/tell-user.d.mts +57 -0
- package/dist/api/commands/chat/tell-user.d.mts.map +1 -0
- package/dist/api/commands/chat/tell-user.mjs +199 -0
- package/dist/api/commands/chat/tell-user.mjs.map +1 -0
- package/dist/api/commands/command-constants.d.mts +22 -0
- package/dist/api/commands/command-constants.d.mts.map +1 -0
- package/dist/api/commands/command-constants.mjs +17 -0
- package/dist/api/commands/command-constants.mjs.map +1 -0
- package/dist/api/commands/command-helpers.d.mts +47 -0
- package/dist/api/commands/command-helpers.d.mts.map +1 -0
- package/dist/api/commands/command-helpers.mjs +76 -0
- package/dist/api/commands/command-helpers.mjs.map +1 -0
- package/dist/api/commands/command-service-v1.d.mts +28 -0
- package/dist/api/commands/command-service-v1.d.mts.map +1 -0
- package/dist/api/commands/command-service-v1.mjs +122 -0
- package/dist/api/commands/command-service-v1.mjs.map +1 -0
- package/dist/api/commands/command-service.respec.d.mts +7 -0
- package/dist/api/commands/command-service.respec.d.mts.map +1 -0
- package/dist/api/commands/command-service.respec.mjs +66 -0
- package/dist/api/commands/command-service.respec.mjs.map +1 -0
- package/dist/api/commands/command-types.d.mts +48 -0
- package/dist/api/commands/command-types.d.mts.map +1 -0
- package/dist/api/commands/command-types.mjs +12 -0
- package/dist/api/commands/command-types.mjs.map +1 -0
- package/dist/api/commands/ibgib/get-ibgibs.d.mts +94 -0
- package/dist/api/commands/ibgib/get-ibgibs.d.mts.map +1 -0
- package/dist/api/commands/ibgib/get-ibgibs.mjs +219 -0
- package/dist/api/commands/ibgib/get-ibgibs.mjs.map +1 -0
- package/dist/api/commands/ibgib/ibgib-index.d.mts +3 -0
- package/dist/api/commands/ibgib/ibgib-index.d.mts.map +1 -0
- package/dist/api/commands/ibgib/ibgib-index.mjs +7 -0
- package/dist/api/commands/ibgib/ibgib-index.mjs.map +1 -0
- package/dist/api/commands/ibgib/mut8-ibgib.d.mts +135 -0
- package/dist/api/commands/ibgib/mut8-ibgib.d.mts.map +1 -0
- package/dist/api/commands/ibgib/mut8-ibgib.mjs +318 -0
- package/dist/api/commands/ibgib/mut8-ibgib.mjs.map +1 -0
- package/dist/api/commands/templates/api-function-info.template.d.mts +73 -0
- package/dist/api/commands/templates/api-function-info.template.d.mts.map +1 -0
- package/dist/api/commands/templates/api-function-info.template.mjs +161 -0
- package/dist/api/commands/templates/api-function-info.template.mjs.map +1 -0
- package/dist/api/commands/text/text-edit.d.mts +54 -0
- package/dist/api/commands/text/text-edit.d.mts.map +1 -0
- package/dist/api/commands/text/text-edit.mjs +170 -0
- package/dist/api/commands/text/text-edit.mjs.map +1 -0
- package/dist/api/commands/text/text-index.d.mts +3 -0
- package/dist/api/commands/text/text-index.d.mts.map +1 -0
- package/dist/api/commands/text/text-index.mjs +5 -0
- package/dist/api/commands/text/text-index.mjs.map +1 -0
- package/dist/api/commands/ui/ui-index.d.mts +3 -0
- package/dist/api/commands/ui/ui-index.d.mts.map +1 -0
- package/dist/api/commands/ui/ui-index.mjs +5 -0
- package/dist/api/commands/ui/ui-index.mjs.map +1 -0
- package/dist/api/commands/ui/update-css-variables.d.mts +48 -0
- package/dist/api/commands/ui/update-css-variables.d.mts.map +1 -0
- package/dist/api/commands/ui/update-css-variables.mjs +145 -0
- package/dist/api/commands/ui/update-css-variables.mjs.map +1 -0
- package/dist/api/function-infos.web.d.mts +15 -0
- package/dist/api/function-infos.web.d.mts.map +1 -0
- package/dist/api/function-infos.web.mjs +63 -0
- package/dist/api/function-infos.web.mjs.map +1 -0
- package/dist/assumptions.respec.d.mts +2 -0
- package/dist/assumptions.respec.d.mts.map +1 -0
- package/dist/assumptions.respec.mjs +41 -0
- package/dist/assumptions.respec.mjs.map +1 -0
- package/dist/common/project/project-constants.d.mts +38 -0
- package/dist/common/project/project-constants.d.mts.map +1 -0
- package/dist/common/project/project-constants.mjs +71 -0
- package/dist/common/project/project-constants.mjs.map +1 -0
- package/dist/common/project/project-helper.d.mts +127 -0
- package/dist/common/project/project-helper.d.mts.map +1 -0
- package/dist/common/project/project-helper.mjs +683 -0
- package/dist/common/project/project-helper.mjs.map +1 -0
- package/dist/common/project/project-types.d.mts +91 -0
- package/dist/common/project/project-types.d.mts.map +1 -0
- package/dist/common/project/project-types.mjs +31 -0
- package/dist/common/project/project-types.mjs.map +1 -0
- package/dist/common/prompt-functions.web.d.mts +90 -0
- package/dist/common/prompt-functions.web.d.mts.map +1 -0
- package/dist/common/prompt-functions.web.mjs +426 -0
- package/dist/common/prompt-functions.web.mjs.map +1 -0
- package/dist/common/settings/settings-constants.d.mts +33 -0
- package/dist/common/settings/settings-constants.d.mts.map +1 -0
- package/dist/common/settings/settings-constants.mjs +54 -0
- package/dist/common/settings/settings-constants.mjs.map +1 -0
- package/dist/common/settings/settings-helpers.d.mts +59 -0
- package/dist/common/settings/settings-helpers.d.mts.map +1 -0
- package/dist/common/settings/settings-helpers.mjs +253 -0
- package/dist/common/settings/settings-helpers.mjs.map +1 -0
- package/dist/common/settings/settings-types.d.mts +118 -0
- package/dist/common/settings/settings-types.d.mts.map +1 -0
- package/dist/common/settings/settings-types.mjs +13 -0
- package/dist/common/settings/settings-types.mjs.map +1 -0
- package/dist/constants.d.mts +34 -0
- package/dist/constants.d.mts.map +1 -0
- package/dist/constants.mjs +35 -0
- package/dist/constants.mjs.map +1 -0
- package/dist/foo.d.mts +2 -0
- package/dist/foo.d.mts.map +1 -0
- package/dist/foo.mjs +19 -0
- package/dist/foo.mjs.map +1 -0
- package/dist/helpers.d.mts +137 -0
- package/dist/helpers.d.mts.map +1 -0
- package/dist/helpers.mjs +514 -0
- package/dist/helpers.mjs.map +1 -0
- package/dist/helpers.web.d.mts +324 -0
- package/dist/helpers.web.d.mts.map +1 -0
- package/dist/helpers.web.mjs +1133 -0
- package/dist/helpers.web.mjs.map +1 -0
- package/dist/helpers.web.respec.d.mts +2 -0
- package/dist/helpers.web.respec.d.mts.map +1 -0
- package/dist/helpers.web.respec.mjs +12 -0
- package/dist/helpers.web.respec.mjs.map +1 -0
- package/dist/index.d.mts +2 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +3 -0
- package/dist/index.mjs.map +1 -0
- package/dist/respec-gib.node.d.mts +2 -0
- package/dist/respec-gib.node.d.mts.map +1 -0
- package/dist/respec-gib.node.mjs +211 -0
- package/dist/respec-gib.node.mjs.map +1 -0
- package/dist/spec-helper.node.respec.d.mts +13 -0
- package/dist/spec-helper.node.respec.d.mts.map +1 -0
- package/dist/spec-helper.node.respec.mjs +50 -0
- package/dist/spec-helper.node.respec.mjs.map +1 -0
- package/dist/storage/storage-helpers.web.d.mts +108 -0
- package/dist/storage/storage-helpers.web.d.mts.map +1 -0
- package/dist/storage/storage-helpers.web.mjs +757 -0
- package/dist/storage/storage-helpers.web.mjs.map +1 -0
- package/dist/storage/storage-types.web.d.mts +30 -0
- package/dist/storage/storage-types.web.d.mts.map +1 -0
- package/dist/storage/storage-types.web.mjs +2 -0
- package/dist/storage/storage-types.web.mjs.map +1 -0
- package/dist/types.web.d.mts +42 -0
- package/dist/types.web.d.mts.map +1 -0
- package/dist/types.web.mjs +2 -0
- package/dist/types.web.mjs.map +1 -0
- package/dist/ui/component/component-types.d.mts +225 -0
- package/dist/ui/component/component-types.d.mts.map +1 -0
- package/dist/ui/component/component-types.mjs +2 -0
- package/dist/ui/component/component-types.mjs.map +1 -0
- package/dist/ui/component/ibgib-component-service.d.mts +70 -0
- package/dist/ui/component/ibgib-component-service.d.mts.map +1 -0
- package/dist/ui/component/ibgib-component-service.mjs +201 -0
- package/dist/ui/component/ibgib-component-service.mjs.map +1 -0
- package/dist/ui/component/ibgib-dynamic-component-bases.d.mts +338 -0
- package/dist/ui/component/ibgib-dynamic-component-bases.d.mts.map +1 -0
- package/dist/ui/component/ibgib-dynamic-component-bases.mjs +1304 -0
- package/dist/ui/component/ibgib-dynamic-component-bases.mjs.map +1 -0
- package/dist/ui/ui-constants.d.mts +12 -0
- package/dist/ui/ui-constants.d.mts.map +1 -0
- package/dist/ui/ui-constants.mjs +93 -0
- package/dist/ui/ui-constants.mjs.map +1 -0
- package/dist/ui/ui-helpers.d.mts +42 -0
- package/dist/ui/ui-helpers.d.mts.map +1 -0
- package/dist/ui/ui-helpers.mjs +198 -0
- package/dist/ui/ui-helpers.mjs.map +1 -0
- package/dist/ui/ui-types.d.mts +13 -0
- package/dist/ui/ui-types.d.mts.map +1 -0
- package/dist/ui/ui-types.mjs +2 -0
- package/dist/ui/ui-types.mjs.map +1 -0
- package/dist/witness/agent/agent-constants.d.mts +97 -0
- package/dist/witness/agent/agent-constants.d.mts.map +1 -0
- package/dist/witness/agent/agent-constants.mjs +98 -0
- package/dist/witness/agent/agent-constants.mjs.map +1 -0
- package/dist/witness/agent/agent-helpers.d.mts +106 -0
- package/dist/witness/agent/agent-helpers.d.mts.map +1 -0
- package/dist/witness/agent/agent-helpers.mjs +601 -0
- package/dist/witness/agent/agent-helpers.mjs.map +1 -0
- package/dist/witness/agent/agent-one-file.app.d.mts +2 -0
- package/dist/witness/agent/agent-one-file.app.d.mts.map +1 -0
- package/dist/witness/agent/agent-one-file.app.mjs +8 -0
- package/dist/witness/agent/agent-one-file.app.mjs.map +1 -0
- package/dist/witness/agent/agent-one-file.d.mts +478 -0
- package/dist/witness/agent/agent-one-file.d.mts.map +1 -0
- package/dist/witness/agent/agent-one-file.mjs +1462 -0
- package/dist/witness/agent/agent-one-file.mjs.map +1 -0
- package/dist/witness/agent/agent-types.d.mts +83 -0
- package/dist/witness/agent/agent-types.d.mts.map +1 -0
- package/dist/witness/agent/agent-types.mjs +2 -0
- package/dist/witness/agent/agent-types.mjs.map +1 -0
- package/dist/witness/agent/agents-service-v1.d.mts +99 -0
- package/dist/witness/agent/agents-service-v1.d.mts.map +1 -0
- package/dist/witness/agent/agents-service-v1.mjs +453 -0
- package/dist/witness/agent/agents-service-v1.mjs.map +1 -0
- package/dist/witness/agent/function-info/function-info-one-file.d.mts +192 -0
- package/dist/witness/agent/function-info/function-info-one-file.d.mts.map +1 -0
- package/dist/witness/agent/function-info/function-info-one-file.mjs +192 -0
- package/dist/witness/agent/function-info/function-info-one-file.mjs.map +1 -0
- package/dist/witness/agent/gemini/agent-witness-gemini-v1.d.mts +51 -0
- package/dist/witness/agent/gemini/agent-witness-gemini-v1.d.mts.map +1 -0
- package/dist/witness/agent/gemini/agent-witness-gemini-v1.mjs +928 -0
- package/dist/witness/agent/gemini/agent-witness-gemini-v1.mjs.map +1 -0
- package/dist/witness/agent/gemini/gemini-agent-factory.d.mts +27 -0
- package/dist/witness/agent/gemini/gemini-agent-factory.d.mts.map +1 -0
- package/dist/witness/agent/gemini/gemini-agent-factory.mjs +144 -0
- package/dist/witness/agent/gemini/gemini-agent-factory.mjs.map +1 -0
- package/dist/witness/agent/gemini/gemini-constants.d.mts +36 -0
- package/dist/witness/agent/gemini/gemini-constants.d.mts.map +1 -0
- package/dist/witness/agent/gemini/gemini-constants.mjs +47 -0
- package/dist/witness/agent/gemini/gemini-constants.mjs.map +1 -0
- package/dist/witness/agent/gemini/gemini-helpers.d.mts +58 -0
- package/dist/witness/agent/gemini/gemini-helpers.d.mts.map +1 -0
- package/dist/witness/agent/gemini/gemini-helpers.mjs +210 -0
- package/dist/witness/agent/gemini/gemini-helpers.mjs.map +1 -0
- package/dist/witness/agent/gemini/gemini-types.d.mts +82 -0
- package/dist/witness/agent/gemini/gemini-types.d.mts.map +1 -0
- package/dist/witness/agent/gemini/gemini-types.mjs +3 -0
- package/dist/witness/agent/gemini/gemini-types.mjs.map +1 -0
- package/dist/witness/live-proxy-ibgib/live-proxy-ibgib-one-file.d.mts +136 -0
- package/dist/witness/live-proxy-ibgib/live-proxy-ibgib-one-file.d.mts.map +1 -0
- package/dist/witness/live-proxy-ibgib/live-proxy-ibgib-one-file.mjs +334 -0
- package/dist/witness/live-proxy-ibgib/live-proxy-ibgib-one-file.mjs.map +1 -0
- package/dist/witness/space/metaspace/metaspace-webspace/metaspace-webspace-helper.d.mts +35 -0
- package/dist/witness/space/metaspace/metaspace-webspace/metaspace-webspace-helper.d.mts.map +1 -0
- package/dist/witness/space/metaspace/metaspace-webspace/metaspace-webspace-helper.mjs +267 -0
- package/dist/witness/space/metaspace/metaspace-webspace/metaspace-webspace-helper.mjs.map +1 -0
- package/dist/witness/space/metaspace/metaspace-webspace/metaspace-webspace.d.mts +134 -0
- package/dist/witness/space/metaspace/metaspace-webspace/metaspace-webspace.d.mts.map +1 -0
- package/dist/witness/space/metaspace/metaspace-webspace/metaspace-webspace.mjs +389 -0
- package/dist/witness/space/metaspace/metaspace-webspace/metaspace-webspace.mjs.map +1 -0
- package/dist/witness/space/web-filesystem-space/web-filesystem-space-constants.d.mts +2 -0
- package/dist/witness/space/web-filesystem-space/web-filesystem-space-constants.d.mts.map +1 -0
- package/dist/witness/space/web-filesystem-space/web-filesystem-space-constants.mjs +2 -0
- package/dist/witness/space/web-filesystem-space/web-filesystem-space-constants.mjs.map +1 -0
- package/dist/witness/space/web-filesystem-space/web-filesystem-space-helper.d.mts +104 -0
- package/dist/witness/space/web-filesystem-space/web-filesystem-space-helper.d.mts.map +1 -0
- package/dist/witness/space/web-filesystem-space/web-filesystem-space-helper.mjs +457 -0
- package/dist/witness/space/web-filesystem-space/web-filesystem-space-helper.mjs.map +1 -0
- package/dist/witness/space/web-filesystem-space/web-filesystem-space-types.d.mts +93 -0
- package/dist/witness/space/web-filesystem-space/web-filesystem-space-types.d.mts.map +1 -0
- package/dist/witness/space/web-filesystem-space/web-filesystem-space-types.mjs +98 -0
- package/dist/witness/space/web-filesystem-space/web-filesystem-space-types.mjs.map +1 -0
- package/dist/witness/space/web-filesystem-space/web-filesystem-space-v1.d.mts +73 -0
- package/dist/witness/space/web-filesystem-space/web-filesystem-space-v1.d.mts.map +1 -0
- package/dist/witness/space/web-filesystem-space/web-filesystem-space-v1.mjs +650 -0
- package/dist/witness/space/web-filesystem-space/web-filesystem-space-v1.mjs.map +1 -0
- package/generate-version-file.js +29 -0
- package/package.json +60 -0
- package/src/agent-texts/common-agent-texts.mts +61 -0
- package/src/agent-texts/primary-agent-texts.mts +32 -0
- package/src/agent-texts/project-agent-texts.mts +29 -0
- package/src/agent-texts/project-child-text-agent-texts.mts +30 -0
- package/src/agent-texts/projects-agent-texts.mts +17 -0
- package/src/agent-texts/raw-agent-texts.mts +18 -0
- package/src/agent-texts/text-editor-agent-texts.mts +20 -0
- package/src/api/api-constants.mts +8 -0
- package/src/api/api-index.mts +110 -0
- package/src/api/api-types.mts +36 -0
- package/src/api/commands/chat/chat-index.mts +10 -0
- package/src/api/commands/chat/get-context-info.mts +196 -0
- package/src/api/commands/chat/hello-world.mts +183 -0
- package/src/api/commands/chat/tell-user.mts +241 -0
- package/src/api/commands/command-constants.mts +17 -0
- package/src/api/commands/command-helpers.mts +105 -0
- package/src/api/commands/command-service-v1.mts +136 -0
- package/src/api/commands/command-service.respec.mts +72 -0
- package/src/api/commands/command-types.mts +71 -0
- package/src/api/commands/ibgib/get-ibgibs.mts +269 -0
- package/src/api/commands/ibgib/ibgib-index.mts +8 -0
- package/src/api/commands/ibgib/mut8-ibgib.mts +418 -0
- package/src/api/commands/templates/api-function-info.template.mts +212 -0
- package/src/api/commands/text/text-edit.mts +217 -0
- package/src/api/commands/text/text-index.mts +6 -0
- package/src/api/commands/ui/ui-index.mts +6 -0
- package/src/api/commands/ui/update-css-variables.mts +187 -0
- package/src/api/function-infos.web.mts +66 -0
- package/src/assets/fullscreen-dialog.html +18 -0
- package/src/assumptions.respec.mts +51 -0
- package/src/common/project/project-constants.mts +83 -0
- package/src/common/project/project-helper.mts +730 -0
- package/src/common/project/project-types.mts +121 -0
- package/src/common/prompt-functions.web.mts +447 -0
- package/src/common/settings/settings-constants.mts +72 -0
- package/src/common/settings/settings-helpers.mts +280 -0
- package/src/common/settings/settings-types.mts +137 -0
- package/src/constants.mts +39 -0
- package/src/foo.mts +13 -0
- package/src/helpers.mts +574 -0
- package/src/helpers.web.mts +1277 -0
- package/src/helpers.web.respec.mts +16 -0
- package/src/index.mts +3 -0
- package/src/respec-gib.node.mts +199 -0
- package/src/spec-helper.node.respec.mts +50 -0
- package/src/storage/storage-helpers.web.mts +728 -0
- package/src/storage/storage-types.web.mts +29 -0
- package/src/types.web.mts +42 -0
- package/src/ui/component/component-types.mts +241 -0
- package/src/ui/component/ibgib-component-service.mts +201 -0
- package/src/ui/component/ibgib-dynamic-component-bases.mts +1369 -0
- package/src/ui/ui-constants.mts +101 -0
- package/src/ui/ui-helpers.mts +222 -0
- package/src/ui/ui-types.mts +11 -0
- package/src/witness/agent/agent-constants.mts +122 -0
- package/src/witness/agent/agent-helpers.mts +681 -0
- package/src/witness/agent/agent-one-file.app.mts +8 -0
- package/src/witness/agent/agent-one-file.mts +1665 -0
- package/src/witness/agent/agent-types.mts +92 -0
- package/src/witness/agent/agents-service-v1.mts +482 -0
- package/src/witness/agent/function-info/function-info-one-file.mts +362 -0
- package/src/witness/agent/gemini/agent-witness-gemini-v1.mts +910 -0
- package/src/witness/agent/gemini/gemini-agent-factory.mts +135 -0
- package/src/witness/agent/gemini/gemini-constants.mts +79 -0
- package/src/witness/agent/gemini/gemini-helpers.mts +216 -0
- package/src/witness/agent/gemini/gemini-types.mts +88 -0
- package/src/witness/live-proxy-ibgib/live-proxy-ibgib-one-file.mts +321 -0
- package/src/witness/space/metaspace/metaspace-webspace/metaspace-webspace-helper.mts +290 -0
- package/src/witness/space/metaspace/metaspace-webspace/metaspace-webspace.mts +407 -0
- package/src/witness/space/web-filesystem-space/web-filesystem-space-constants.mts +1 -0
- package/src/witness/space/web-filesystem-space/web-filesystem-space-helper.mts +491 -0
- package/src/witness/space/web-filesystem-space/web-filesystem-space-types.mts +172 -0
- package/src/witness/space/web-filesystem-space/web-filesystem-space-v1.mts +670 -0
- package/tsconfig.json +17 -0
- package/tsconfig.test.json +10 -0
|
@@ -0,0 +1,1277 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module helpers.web
|
|
3
|
+
*
|
|
4
|
+
* helper functions specific to the web version.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { delay, extractErrorMsg, pretty, } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
|
|
8
|
+
import { IbGib_V1 } from "@ibgib/ts-gib/dist/V1/types.mjs";
|
|
9
|
+
import { Gib, IbGibAddr } from "@ibgib/ts-gib/dist/types.mjs";
|
|
10
|
+
import { getIbAndGib, getIbGibAddr } from "@ibgib/ts-gib/dist/helper.mjs";
|
|
11
|
+
import { GIB } from "@ibgib/ts-gib/dist/V1/constants.mjs";
|
|
12
|
+
import { getGibInfo, isPrimitive } from "@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs";
|
|
13
|
+
import { validateIbGibIntrinsically } from "@ibgib/ts-gib/dist/V1/validate-helper.mjs";
|
|
14
|
+
import { MetaspaceService } from "@ibgib/core-gib/dist/witness/space/metaspace/metaspace-types.mjs";
|
|
15
|
+
import { RawExportIbGib_V1 } from "@ibgib/core-gib/dist/common/import-export/import-export-types.mjs";
|
|
16
|
+
import { FlatIbGibGraph } from "@ibgib/core-gib/dist/common/other/graph-types.mjs";
|
|
17
|
+
import { decompressIbGibGraphFromString, deserializeStringToGraph } from "@ibgib/core-gib/dist/common/other/other-helper.web.mjs";
|
|
18
|
+
import { getRawExportIbGib } from "@ibgib/core-gib/dist/common/import-export/import-export-helper.web.mjs";
|
|
19
|
+
import { IbGibSpaceAny } from "@ibgib/core-gib/dist/witness/space/space-base-v1.mjs";
|
|
20
|
+
import { ZERO_SPACE_ID } from "@ibgib/core-gib/dist/witness/space/space-constants.mjs";
|
|
21
|
+
|
|
22
|
+
import {
|
|
23
|
+
GLOBAL_LOG_A_LOT,
|
|
24
|
+
DEFAULT_IBGIB_COLOR, DEFAULT_IBGIB_COLOR_CONTRAST,
|
|
25
|
+
DEFAULT_IBGIB_TRANSLUCENT,
|
|
26
|
+
GEMINI_API_KEY_REGEXP,
|
|
27
|
+
CONFIG_OPTION_GEMINI_API_KEY_LOCATION_HELP
|
|
28
|
+
} from "./constants.mjs";
|
|
29
|
+
import { showFullscreenDialog } from "./ui/ui-helpers.mjs";
|
|
30
|
+
import { initializeStorage, storageCreateStoreIfNotExist, storageDBExists, storageGet, storagePut } from "./storage/storage-helpers.web.mjs";
|
|
31
|
+
import { GibColorInfo } from "./types.web.mjs";
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* used in verbose logging
|
|
36
|
+
*/
|
|
37
|
+
const logalot = GLOBAL_LOG_A_LOT;
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* converts string to Uint8Array.
|
|
42
|
+
* @param str to convert
|
|
43
|
+
* @returns array
|
|
44
|
+
*/
|
|
45
|
+
export function stringToUint8Array(str: string): Uint8Array {
|
|
46
|
+
const encoder = new TextEncoder();
|
|
47
|
+
return encoder.encode(str);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* converts Uint8Array to string.
|
|
52
|
+
* @param array to convert
|
|
53
|
+
* @returns string
|
|
54
|
+
*/
|
|
55
|
+
export function uint8ArrayToString(array: Uint8Array) {
|
|
56
|
+
const decoder = new TextDecoder();
|
|
57
|
+
return decoder.decode(array);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* I'm pulling out node from @ibgib/ibgib rcli code. This interface is just to
|
|
62
|
+
* aid in that transition.
|
|
63
|
+
*/
|
|
64
|
+
export interface PathUtilsHelper {
|
|
65
|
+
isAbsolute(path: string): boolean;
|
|
66
|
+
isRelative(path: string): boolean;
|
|
67
|
+
|
|
68
|
+
// for now I'm taking out resolve since it requires being stateful and isn't
|
|
69
|
+
// used AFAICT in the code I'm porting over
|
|
70
|
+
// resolve(path: string): string;
|
|
71
|
+
|
|
72
|
+
join(...paths: string[]): string;
|
|
73
|
+
dirname(path: string): string;
|
|
74
|
+
basename(path: string, ext?: string): string;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Helper class that exposes pathUtils functions. Note that this is relative to
|
|
79
|
+
* an individual space.
|
|
80
|
+
*/
|
|
81
|
+
export class PathUtilsHelper implements PathUtilsHelper {
|
|
82
|
+
/** class-level log context */
|
|
83
|
+
lc: string = `[${PathUtilsHelper.name}]`;
|
|
84
|
+
|
|
85
|
+
// /**
|
|
86
|
+
// * this path utils helper is per space, so this is the id of that space.
|
|
87
|
+
// */
|
|
88
|
+
// spaceId: SpaceId;
|
|
89
|
+
/**
|
|
90
|
+
*
|
|
91
|
+
*/
|
|
92
|
+
// constructor({ spaceId, initialCwd, }: { spaceId: SpaceId, initialCwd: string }) {
|
|
93
|
+
// const lc = `${this.lc}[ctor]`;
|
|
94
|
+
// this.spaceId = spaceId;
|
|
95
|
+
// let ibGibGlobalThis = getIbGibGlobalThis();
|
|
96
|
+
// if (!ibGibGlobalThis.spaceShim[spaceId]) {
|
|
97
|
+
// console.log(`${lc} initializing IbGibGlobalThis data`);
|
|
98
|
+
// // initialize
|
|
99
|
+
// ibGibGlobalThis.spaceShim[spaceId] = {
|
|
100
|
+
// cwd: initialCwd,
|
|
101
|
+
// initialCwd,
|
|
102
|
+
// };
|
|
103
|
+
// } else {
|
|
104
|
+
// if (logalot) { console.log(`${lc} ibgib global this already initialized (I: e48b0cb4075e536d150919e87ddc1f24)`); }
|
|
105
|
+
// }
|
|
106
|
+
// }
|
|
107
|
+
/**
|
|
108
|
+
*
|
|
109
|
+
*/
|
|
110
|
+
constructor() { }
|
|
111
|
+
|
|
112
|
+
isAbsolute(path: string): boolean {
|
|
113
|
+
if (!path) { throw new Error(`(UNEXPECTED) path falsy? (E: dcb92e11770ba06205c0afe3e6560b24)`); }
|
|
114
|
+
return path.startsWith('/');
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
isRelative(path: string): boolean {
|
|
118
|
+
return !this.isAbsolute(path);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// resolve(path: string): string {
|
|
122
|
+
// const lc = `${this.lc}[${this.resolve.name}]`;
|
|
123
|
+
// if (!path) { throw new Error(`(UNEXPECTED) path falsy? (E: 76161b12dbd446a0c2a9e18f4847fc24)`); }
|
|
124
|
+
|
|
125
|
+
// // for our implementation, we will throw if there is a relative path
|
|
126
|
+
// // specifier (. or ..) in the middle of the path. the proper
|
|
127
|
+
// // implementation probably resolves these concretely.
|
|
128
|
+
|
|
129
|
+
// if (this.isAbsolute(path)) {
|
|
130
|
+
// if (path.includes('/../') || path.endsWith('/..')) { throw new Error(`path is absolute but contains "/../" in it or ends with "../"? (E: 16145bf37d874abc886111c32c035124)`); }
|
|
131
|
+
// return path;
|
|
132
|
+
// }
|
|
133
|
+
|
|
134
|
+
// // we have a relative path. get the cwd from global for this particular space. If this space has no
|
|
135
|
+
// let ibGibGlobalThis = getIbGibGlobalThis();
|
|
136
|
+
// let info = ibGibGlobalThis.spaceShim[this.spaceId];
|
|
137
|
+
// if (!info) { throw new Error(`(UNEXPECTED) no info for spaceId in ibgibglobalthis? (E: c063f34ed784e70ccd19a6b2026eb924)`); }
|
|
138
|
+
|
|
139
|
+
// const { cwd } = info;
|
|
140
|
+
// if (!cwd) { throw new Error(`(UNEXPECTED) cwd falsy? (E: 91cbd7418a51d9d152ae53d4f87b3a24)`); }
|
|
141
|
+
// if (path.startsWith(cwd)) {
|
|
142
|
+
// console.log(`${lc} path already resolved (starts with cwd). path: ${path} (I: 1d99a4bad47398174fe127b85088fb24)`);
|
|
143
|
+
// }
|
|
144
|
+
// if (cwd.endsWith('/')) {
|
|
145
|
+
// // cwd does end with slash, so slice off initial if needed
|
|
146
|
+
// return cwd + (path.startsWith('/') ? path.slice(1) : path);
|
|
147
|
+
// } else {
|
|
148
|
+
// // cwd does NOT end with slash, so add if needed
|
|
149
|
+
// return cwd + (path.startsWith('/') ? path : `/${path}`);
|
|
150
|
+
// }
|
|
151
|
+
// }
|
|
152
|
+
|
|
153
|
+
join(...paths: string[]): string {
|
|
154
|
+
const lc = `${this.lc}[${this.join.name}]`;
|
|
155
|
+
|
|
156
|
+
if (paths.length === 0) {
|
|
157
|
+
console.log(`${lc} paths.length === 0. returning '.' per node convention. (I: 153da80765ff6160675fae895ebac225)`);
|
|
158
|
+
return '.'; /* <<<< returns early */
|
|
159
|
+
}
|
|
160
|
+
if (paths.length === 1 && paths[0] === '..') {
|
|
161
|
+
console.log(`${lc} paths.length === 1 && paths[0] === '..'. returning '..' per node convention. (I: 9af242b7615430a8c6899b1a332e9925)`);
|
|
162
|
+
return '..'; /* <<<< returns early */
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
let joined = '';
|
|
166
|
+
for (let i = 0; i < paths.length; i++) {
|
|
167
|
+
let path = paths[i];
|
|
168
|
+
if (path === '..') {
|
|
169
|
+
joined = joined.split('/').slice(0, -1).join('/');
|
|
170
|
+
} else {
|
|
171
|
+
if (path.startsWith('/')) { path = path.slice(1); }
|
|
172
|
+
if (path.endsWith('/')) {
|
|
173
|
+
path = path.slice(0, -1);
|
|
174
|
+
}
|
|
175
|
+
joined += (i > 0 ? '/' : '') + path;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return joined;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
dirname(path: string): string {
|
|
183
|
+
return path.split('/').slice(0, -1).join('/');
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
basename(path: string, ext?: string): string {
|
|
187
|
+
return path.split('/').pop() ?? '';
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
export async function copyToClipboard({
|
|
193
|
+
data,
|
|
194
|
+
logalot,
|
|
195
|
+
}: {
|
|
196
|
+
data: { title?: string, text?: string, url?: string },
|
|
197
|
+
logalot?: boolean,
|
|
198
|
+
}): Promise<void> {
|
|
199
|
+
const lc = `[${copyToClipboard.name}]`;
|
|
200
|
+
try {
|
|
201
|
+
if (logalot) { console.log(`${lc} starting... (I: 37d6a4e3c3ee9fa46a0b1cd5c8a5cf24)`); }
|
|
202
|
+
let { title, text, url } = data;
|
|
203
|
+
const textToCopy = [
|
|
204
|
+
`${data.title || ''}`,
|
|
205
|
+
`${data.text || ''}`,
|
|
206
|
+
`${data.url || ''}`,
|
|
207
|
+
].join('\n').trim();
|
|
208
|
+
await navigator.clipboard.writeText(textToCopy);
|
|
209
|
+
console.log('Content copied to clipboard!');
|
|
210
|
+
} catch (error) {
|
|
211
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
212
|
+
throw error;
|
|
213
|
+
} finally {
|
|
214
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* helper to trigger browser's share functionality (or fallback).
|
|
220
|
+
*/
|
|
221
|
+
export async function shareContent({
|
|
222
|
+
data,
|
|
223
|
+
logalot,
|
|
224
|
+
}: {
|
|
225
|
+
data: { title?: string, text?: string, url?: string },
|
|
226
|
+
logalot?: boolean,
|
|
227
|
+
}): Promise<void> {
|
|
228
|
+
const lc = `[${shareContent.name}]`;
|
|
229
|
+
try {
|
|
230
|
+
if (logalot) { console.log(`${lc} starting... (I: bfc7e484eba91f9126c3f5fc381e6424)`); }
|
|
231
|
+
|
|
232
|
+
if (navigator.share) {
|
|
233
|
+
await navigator.share(data);
|
|
234
|
+
console.log('Content shared successfully!');
|
|
235
|
+
} else {
|
|
236
|
+
console.warn('Web Share API not supported. Copying to clipboard instead.');
|
|
237
|
+
alert(`Share info copied to clipboard!`);
|
|
238
|
+
await copyToClipboard({ data, logalot });
|
|
239
|
+
}
|
|
240
|
+
} catch (error) {
|
|
241
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
242
|
+
throw error;
|
|
243
|
+
} finally {
|
|
244
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* useful for knowing if we are executing in our website or within an iframe.
|
|
250
|
+
*
|
|
251
|
+
* ## driving use case
|
|
252
|
+
*
|
|
253
|
+
* When we are loading an embedded iframe for link-gib, it is trying to trigger
|
|
254
|
+
* the router which is no bueno.
|
|
255
|
+
*
|
|
256
|
+
* This is causing a problem though when testing inside an iframe in Project
|
|
257
|
+
* IDX...I guess I'll have to whitelist embedded sites like link-gib
|
|
258
|
+
*
|
|
259
|
+
* @returns true if we are executing in an iframe, false otherwise.
|
|
260
|
+
*/
|
|
261
|
+
export function isExecutingInBlankGibWebAppProper({
|
|
262
|
+
metaName_appId,
|
|
263
|
+
metaContent_appId
|
|
264
|
+
}: {
|
|
265
|
+
/**
|
|
266
|
+
* this runs code:
|
|
267
|
+
*
|
|
268
|
+
* `const metaElement = document.querySelector(`meta[name=${metaName_appId}]`) as (HTMLMetaElement | null);`
|
|
269
|
+
*
|
|
270
|
+
* in the index, you should tag the meta tag with attribute of this.
|
|
271
|
+
*/
|
|
272
|
+
metaName_appId: string,
|
|
273
|
+
/**
|
|
274
|
+
* this is an appId on the `metaElement.content`
|
|
275
|
+
*/
|
|
276
|
+
metaContent_appId: string,
|
|
277
|
+
}): boolean {
|
|
278
|
+
const metaElement =
|
|
279
|
+
document.querySelector(`meta[name=${metaName_appId}]`) as (HTMLMetaElement | null);
|
|
280
|
+
return !!metaElement && metaElement.content === metaContent_appId;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Low-level plumbing for prompting the user for some text.
|
|
285
|
+
*
|
|
286
|
+
* ## notes
|
|
287
|
+
*
|
|
288
|
+
* * if an empty string is entered, confirm is automatic/always happens.
|
|
289
|
+
* * if confirm is true, will confirm on any entry
|
|
290
|
+
* * can just hit ENTER to confirm anything
|
|
291
|
+
* * this should be parameterized
|
|
292
|
+
*
|
|
293
|
+
* @returns the text the user entered.
|
|
294
|
+
*/
|
|
295
|
+
export async function promptForText({
|
|
296
|
+
msg,
|
|
297
|
+
title,
|
|
298
|
+
confirm,
|
|
299
|
+
noNewLine,
|
|
300
|
+
rl,
|
|
301
|
+
defaultValue,
|
|
302
|
+
dontCloseRl,
|
|
303
|
+
cancelable,
|
|
304
|
+
}: {
|
|
305
|
+
msg: string,
|
|
306
|
+
title?: string,
|
|
307
|
+
confirm?: boolean,
|
|
308
|
+
noNewLine?: boolean,
|
|
309
|
+
/**
|
|
310
|
+
* ignored in web version. used in node version. this is after all, a hack
|
|
311
|
+
* port
|
|
312
|
+
*/
|
|
313
|
+
rl?: any,
|
|
314
|
+
defaultValue?: string,
|
|
315
|
+
/**
|
|
316
|
+
* ignored in web version. used in node version. this is after all, a hack
|
|
317
|
+
* port
|
|
318
|
+
*/
|
|
319
|
+
dontCloseRl?: boolean,
|
|
320
|
+
/**
|
|
321
|
+
* if true, cancel will show and an empty string will be returned
|
|
322
|
+
*/
|
|
323
|
+
cancelable?: boolean,
|
|
324
|
+
}): Promise<string> {
|
|
325
|
+
const lc = `[${promptForText.name}]`;
|
|
326
|
+
try {
|
|
327
|
+
if (!msg) { throw new Error(`msg required (E: 7f4d67bca4cf98ea95fa110aabc98924)`); }
|
|
328
|
+
|
|
329
|
+
let result: string | undefined;
|
|
330
|
+
|
|
331
|
+
let attempts = 0;
|
|
332
|
+
let maxAttempts = 5;
|
|
333
|
+
do {
|
|
334
|
+
attempts++;
|
|
335
|
+
if (attempts >= maxAttempts) {
|
|
336
|
+
throw new Error(`max attempts reached (E: 1ef20ae955622d4b39479f3da91a1d25)`);
|
|
337
|
+
}
|
|
338
|
+
await delay(50);
|
|
339
|
+
result = await showFullscreenDialog({
|
|
340
|
+
title: title || 'Prompt for Info',
|
|
341
|
+
msg,
|
|
342
|
+
prompt: true,
|
|
343
|
+
showInput: true,
|
|
344
|
+
isPassword: false,
|
|
345
|
+
defaultValue,
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
} while (result === undefined && !cancelable);
|
|
349
|
+
|
|
350
|
+
return result ?? '';
|
|
351
|
+
|
|
352
|
+
// let userText: string | undefined = undefined;
|
|
353
|
+
// try {
|
|
354
|
+
// do {
|
|
355
|
+
// title = title ? `[${title}] ` : '';
|
|
356
|
+
// let promptMessage = `${title}${msg}${noNewLine ? ' ' : '\n'}`;
|
|
357
|
+
// let prompt = window.prompt;
|
|
358
|
+
|
|
359
|
+
// // Handle default value (Note: `prompt` can't pre-fill like readline.write)
|
|
360
|
+
// if (defaultValue) {
|
|
361
|
+
// if (defaultValue.includes('\n')) {
|
|
362
|
+
// if (logalot) { console.log(`defaultValue includes newline. (I: 147d4ea942995d0f92a19c3534c18a24)`); }
|
|
363
|
+
// // We can't pre-fill with newline in prompt, so we'll just inform if needed
|
|
364
|
+
// }
|
|
365
|
+
// promptMessage += ` (Default: ${defaultValue})`;
|
|
366
|
+
// }
|
|
367
|
+
|
|
368
|
+
// let userText1 = prompt(promptMessage);
|
|
369
|
+
|
|
370
|
+
// // Check for cancellation (prompt returns null on cancel)
|
|
371
|
+
// if (userText1 === null) {
|
|
372
|
+
// // return null; // User cancelled
|
|
373
|
+
// throw new Error(`user cancelled (E: bf3a221626f8cd14b2a945bfe661cb24)`);
|
|
374
|
+
// }
|
|
375
|
+
|
|
376
|
+
// if (userText1 === "") {
|
|
377
|
+
// let userText2 = prompt(`empty string entered. confirm:${noNewLine ? ' ' : '\n'}`);
|
|
378
|
+
// if (userText2 === userText1) {
|
|
379
|
+
// userText = userText1;
|
|
380
|
+
// break;
|
|
381
|
+
// } else {
|
|
382
|
+
// console.log(`confirm failed. please try again.`);
|
|
383
|
+
// }
|
|
384
|
+
// } else if (confirm) {
|
|
385
|
+
// let userText2 = prompt(`confirm by either hitting ENTER (empty string) or retype input:${noNewLine ? ' ' : '\n'}`);
|
|
386
|
+
// if (userText2 === '' || userText2 === userText1) {
|
|
387
|
+
// userText = userText1;
|
|
388
|
+
// } else {
|
|
389
|
+
// console.log(`confirm failed. please try again.`);
|
|
390
|
+
// }
|
|
391
|
+
// } else {
|
|
392
|
+
// userText = userText1;
|
|
393
|
+
// }
|
|
394
|
+
|
|
395
|
+
// } while (userText === undefined);
|
|
396
|
+
|
|
397
|
+
// return userText;
|
|
398
|
+
|
|
399
|
+
// } catch (error) {
|
|
400
|
+
// throw error;
|
|
401
|
+
// }
|
|
402
|
+
} catch (error) {
|
|
403
|
+
debugger; // in error block promptForText
|
|
404
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
405
|
+
throw error;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* not implemented atow (12/2024). I think we'll have perhaps a modal dialog
|
|
411
|
+
* with a known name and get at it that way.
|
|
412
|
+
*/
|
|
413
|
+
export async function promptForSecret({
|
|
414
|
+
msg,
|
|
415
|
+
confirm,
|
|
416
|
+
}: {
|
|
417
|
+
msg?: string,
|
|
418
|
+
confirm: boolean,
|
|
419
|
+
}): Promise<string> {
|
|
420
|
+
const lc = `[${promptForSecret.name}]`;
|
|
421
|
+
try {
|
|
422
|
+
if (logalot) { console.log(`${lc} starting... (I: 795a4ce348ddb9a5119770f4c572ac24)`); }
|
|
423
|
+
|
|
424
|
+
let result: string | undefined = undefined;
|
|
425
|
+
|
|
426
|
+
let firstTry = true;
|
|
427
|
+
let attempts = 0;
|
|
428
|
+
let maxAttempts = 5;
|
|
429
|
+
|
|
430
|
+
do {
|
|
431
|
+
attempts++;
|
|
432
|
+
if (attempts >= maxAttempts) {
|
|
433
|
+
throw new Error(`max attempts reached (E: d4166b4bf37aff0c6d44567792e9ad25)`);
|
|
434
|
+
}
|
|
435
|
+
await delay(50);
|
|
436
|
+
result = await showFullscreenDialog({
|
|
437
|
+
title: firstTry ? 'Shh...' : 'Secrets didn\'t match, try again...',
|
|
438
|
+
msg: msg || 'Enter Your Secret...',
|
|
439
|
+
prompt: true,
|
|
440
|
+
showInput: true,
|
|
441
|
+
isPassword: true,
|
|
442
|
+
defaultValue: undefined,
|
|
443
|
+
});
|
|
444
|
+
if (result === undefined) { throw new Error(`user cancelled (E: 91519d04378e84106f3df8eb36d99725)`); }
|
|
445
|
+
|
|
446
|
+
if (confirm) {
|
|
447
|
+
await delay(250);
|
|
448
|
+
let result2 = await showFullscreenDialog({
|
|
449
|
+
title: 'Shh...',
|
|
450
|
+
msg: 'Confirm...',
|
|
451
|
+
prompt: true,
|
|
452
|
+
showInput: true,
|
|
453
|
+
isPassword: true,
|
|
454
|
+
defaultValue: undefined,
|
|
455
|
+
});
|
|
456
|
+
if (result2 === undefined) { result = undefined; }
|
|
457
|
+
if (result !== result2) {
|
|
458
|
+
result = undefined;
|
|
459
|
+
firstTry = false;
|
|
460
|
+
await delay(250);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
} while (result === undefined);
|
|
466
|
+
|
|
467
|
+
return result;
|
|
468
|
+
} catch (error) {
|
|
469
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
470
|
+
throw error;
|
|
471
|
+
} finally {
|
|
472
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* prompt specifically looking to confirm something. if "cancelled", returns
|
|
478
|
+
* false.
|
|
479
|
+
*/
|
|
480
|
+
export async function promptForConfirm({
|
|
481
|
+
msg,
|
|
482
|
+
yesLabel,
|
|
483
|
+
noLabel,
|
|
484
|
+
}: {
|
|
485
|
+
/**
|
|
486
|
+
* if provided, this is the message displayed when confirming.
|
|
487
|
+
*/
|
|
488
|
+
msg?: string,
|
|
489
|
+
yesLabel?: string,
|
|
490
|
+
noLabel?: string,
|
|
491
|
+
}): Promise<boolean> {
|
|
492
|
+
const lc = `[${promptForConfirm.name}]`;
|
|
493
|
+
try {
|
|
494
|
+
await delay(50);
|
|
495
|
+
let result = await showFullscreenDialog({
|
|
496
|
+
title: 'Confirm?',
|
|
497
|
+
msg: msg ?? 'Confirm?',
|
|
498
|
+
okButtonTitle: yesLabel || undefined,
|
|
499
|
+
cancelButtonTitle: noLabel || undefined,
|
|
500
|
+
prompt: true,
|
|
501
|
+
});
|
|
502
|
+
return !!result;
|
|
503
|
+
// msg ||= 'confirm?';
|
|
504
|
+
// yesLabel ||= '(y)es';
|
|
505
|
+
// noLabel ||= '(n)o';
|
|
506
|
+
// try {
|
|
507
|
+
// const fnAnswerMatchesLabel = (answer: string, label: string) => {
|
|
508
|
+
// if (answer === label.replace(/[\(\)]/g, '').toLowerCase()) {
|
|
509
|
+
// // matched full label
|
|
510
|
+
// return true; /* <<<< returns early */
|
|
511
|
+
// } else {
|
|
512
|
+
// // check for short answers
|
|
513
|
+
// const regexCaptureCharsInsideParens = /\((\w+)\)/;
|
|
514
|
+
// const shortLabel = label.match(regexCaptureCharsInsideParens);
|
|
515
|
+
// if ((shortLabel ?? []).length >= 2) {
|
|
516
|
+
// if (answer === shortLabel![1].toLowerCase()) {
|
|
517
|
+
// // matched short label
|
|
518
|
+
// return true; /* <<<< returns early */
|
|
519
|
+
// }
|
|
520
|
+
// }
|
|
521
|
+
// }
|
|
522
|
+
// // if got this far, nothing positive matched
|
|
523
|
+
// return false;
|
|
524
|
+
// };
|
|
525
|
+
|
|
526
|
+
// const prompt = window.prompt;
|
|
527
|
+
|
|
528
|
+
// // try up to three times. if match found, either way, return early.
|
|
529
|
+
// const maxTries = 3;
|
|
530
|
+
// for (let i = 0; i < maxTries; i++) {
|
|
531
|
+
// let answer = prompt(`${msg} [${yesLabel}, ${noLabel}]\n`);
|
|
532
|
+
// if (answer) {
|
|
533
|
+
// answer = answer.toLowerCase();
|
|
534
|
+
// const matchesYesLabel = fnAnswerMatchesLabel(answer, yesLabel);
|
|
535
|
+
// if (matchesYesLabel) { return true; /* <<<< returns early */ }
|
|
536
|
+
// const matchesNoLabel = fnAnswerMatchesLabel(answer, noLabel);
|
|
537
|
+
// if (matchesNoLabel) { return false; /* <<<< returns early */ }
|
|
538
|
+
// } else {
|
|
539
|
+
// `no answer provided. defaulting to no...`;
|
|
540
|
+
// console.log('huh?');
|
|
541
|
+
// }
|
|
542
|
+
// }
|
|
543
|
+
|
|
544
|
+
// // max tries reached
|
|
545
|
+
// throw new Error(`could not confirm (E: ebbd2f642bde103c41d0102cf7e38d24)`);
|
|
546
|
+
// } catch (error) {
|
|
547
|
+
// throw error;
|
|
548
|
+
// }
|
|
549
|
+
} catch (error) {
|
|
550
|
+
console.error(`${lc} ${error.message}`);
|
|
551
|
+
throw error;
|
|
552
|
+
} finally {
|
|
553
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
export async function alertUser({
|
|
558
|
+
msg,
|
|
559
|
+
title,
|
|
560
|
+
skipHitEnterToContinue,
|
|
561
|
+
}: {
|
|
562
|
+
msg: string,
|
|
563
|
+
title?: string,
|
|
564
|
+
/**
|
|
565
|
+
* ignored in web version atow (12/2024)
|
|
566
|
+
*/
|
|
567
|
+
skipHitEnterToContinue?: boolean,
|
|
568
|
+
}): Promise<void> {
|
|
569
|
+
const lc = `[${alertUser.name}]`;
|
|
570
|
+
try {
|
|
571
|
+
|
|
572
|
+
if (!msg) { throw new Error(`msg required (E: ffcf7dd00324df7cea2792223d229524)`); }
|
|
573
|
+
try {
|
|
574
|
+
title ??= '';
|
|
575
|
+
await delay(50);
|
|
576
|
+
await showFullscreenDialog({
|
|
577
|
+
title,
|
|
578
|
+
msg,
|
|
579
|
+
});
|
|
580
|
+
} catch (error) {
|
|
581
|
+
throw error;
|
|
582
|
+
}
|
|
583
|
+
} catch (error) {
|
|
584
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
585
|
+
throw error;
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
export function getUserPreferredColorScheme(): 'light' | 'dark' {
|
|
590
|
+
const lc = `[${getUserPreferredColorScheme.name}]`;
|
|
591
|
+
try {
|
|
592
|
+
if (logalot) { console.log(`${lc} starting... (I: 196286d17b656bce5ce16f358f386525)`); }
|
|
593
|
+
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
594
|
+
return prefersDark ? 'dark' : 'light';
|
|
595
|
+
} catch (error) {
|
|
596
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
597
|
+
throw error;
|
|
598
|
+
} finally {
|
|
599
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
/**
|
|
604
|
+
* helper function to get a query param in the current url.
|
|
605
|
+
*
|
|
606
|
+
* # ONLY IN BROWSER
|
|
607
|
+
*
|
|
608
|
+
* not for use in node.js
|
|
609
|
+
*
|
|
610
|
+
* @returns raw
|
|
611
|
+
*/
|
|
612
|
+
export function getQueryParam<TValue>({ paramName, parseJSON, logalot, }: {
|
|
613
|
+
paramName: string, parseJSON?: boolean, logalot?: boolean,
|
|
614
|
+
}): TValue | undefined {
|
|
615
|
+
const lc = `[${getQueryParam.name}]`;
|
|
616
|
+
try {
|
|
617
|
+
if (logalot) { console.log(`${lc} starting... (I: f1a61ecdbb52cff1b958d1ceaea85f24)`); }
|
|
618
|
+
|
|
619
|
+
const url = new URL(window.location.href);
|
|
620
|
+
const rawValue = url.searchParams.get(paramName);
|
|
621
|
+
if (rawValue) {
|
|
622
|
+
const decodedValue = decodeURIComponent(rawValue);
|
|
623
|
+
if (parseJSON) {
|
|
624
|
+
try {
|
|
625
|
+
return JSON.parse(decodedValue) as TValue;
|
|
626
|
+
} catch (parseError) {
|
|
627
|
+
console.error(`${lc} Error parsing JSON from query parameter ${paramName}: ${parseError} (E: fa8128dbe8ed41fc9fdf57a8146d88de)`);
|
|
628
|
+
throw parseError;
|
|
629
|
+
}
|
|
630
|
+
} else {
|
|
631
|
+
return decodedValue as TValue;
|
|
632
|
+
}
|
|
633
|
+
} else {
|
|
634
|
+
return undefined;
|
|
635
|
+
}
|
|
636
|
+
} catch (error) {
|
|
637
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
638
|
+
throw error;
|
|
639
|
+
} finally {
|
|
640
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
/**
|
|
645
|
+
* helper function to set a query param in the current url.
|
|
646
|
+
*
|
|
647
|
+
* # ONLY IN BROWSER
|
|
648
|
+
*
|
|
649
|
+
* not for use in node.js
|
|
650
|
+
*/
|
|
651
|
+
export function setQueryParam<TValue>({
|
|
652
|
+
paramName, paramValue, rmParam, logalot,
|
|
653
|
+
}: {
|
|
654
|
+
paramName: string,
|
|
655
|
+
paramValue?: TValue,
|
|
656
|
+
/**
|
|
657
|
+
* if true, we will remove the param from the URL.
|
|
658
|
+
*/
|
|
659
|
+
rmParam?: boolean,
|
|
660
|
+
logalot?: boolean,
|
|
661
|
+
}): void {
|
|
662
|
+
const lc = `[${setQueryParam.name}]`;
|
|
663
|
+
try {
|
|
664
|
+
if (logalot) { console.log(`${lc} starting... (I: f3c557d19f5b3a723611c59aa4a20324)`); }
|
|
665
|
+
const url = new URL(window.location.href);
|
|
666
|
+
|
|
667
|
+
if (rmParam) {
|
|
668
|
+
url.searchParams.delete(paramName);
|
|
669
|
+
} else {
|
|
670
|
+
const actualValue = typeof paramValue === 'string' ?
|
|
671
|
+
paramValue :
|
|
672
|
+
JSON.stringify(paramValue);
|
|
673
|
+
url.searchParams.set(paramName, actualValue);
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
// Update the URL without reloading the page
|
|
677
|
+
window.history.replaceState({}, '', url.toString());
|
|
678
|
+
} catch (error) {
|
|
679
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
680
|
+
throw error;
|
|
681
|
+
} finally {
|
|
682
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
/**
|
|
687
|
+
* helper to highlight an element with border/background.
|
|
688
|
+
*
|
|
689
|
+
* ## requires
|
|
690
|
+
*
|
|
691
|
+
* .highlight and .unhighlight classes
|
|
692
|
+
*
|
|
693
|
+
* The unhighlight is for correctly showing the transition/animation.
|
|
694
|
+
*
|
|
695
|
+
* ## intent
|
|
696
|
+
*
|
|
697
|
+
* Just making this to make highlighting things (drawing the user's eye)
|
|
698
|
+
* easier and more consistent.
|
|
699
|
+
*
|
|
700
|
+
* @see {@link unhighlightElement}
|
|
701
|
+
*/
|
|
702
|
+
export async function highlightElement({
|
|
703
|
+
el,
|
|
704
|
+
magicHighlightTimingMs,
|
|
705
|
+
scrollIntoView,
|
|
706
|
+
}: {
|
|
707
|
+
el: HTMLElement,
|
|
708
|
+
/**
|
|
709
|
+
* if provided, will unhighlight the element after this delay in ms
|
|
710
|
+
*/
|
|
711
|
+
magicHighlightTimingMs?: number,
|
|
712
|
+
scrollIntoView?: boolean,
|
|
713
|
+
}): Promise<void> {
|
|
714
|
+
const lc = `[${highlightElement.name}]`;
|
|
715
|
+
try {
|
|
716
|
+
if (logalot) { console.log(`${lc} starting... (I: 1820329f88bb937b21ff98e624c03e25)`); }
|
|
717
|
+
|
|
718
|
+
if (scrollIntoView) { el.scrollIntoView({ behavior: 'smooth' }); }
|
|
719
|
+
|
|
720
|
+
el.classList.add('highlight');
|
|
721
|
+
if (magicHighlightTimingMs) {
|
|
722
|
+
await delay(magicHighlightTimingMs);
|
|
723
|
+
el.classList.add('unhighlight');
|
|
724
|
+
el.classList.remove('highlight');
|
|
725
|
+
await delay(magicHighlightTimingMs);
|
|
726
|
+
el.classList.remove('unhighlight');
|
|
727
|
+
}
|
|
728
|
+
} catch (error) {
|
|
729
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
730
|
+
throw error;
|
|
731
|
+
} finally {
|
|
732
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
/**
|
|
737
|
+
* @see {@link highlightElement}
|
|
738
|
+
*/
|
|
739
|
+
export async function unhighlightElement({
|
|
740
|
+
el,
|
|
741
|
+
}: {
|
|
742
|
+
el: HTMLElement,
|
|
743
|
+
}): Promise<void> {
|
|
744
|
+
const lc = `[${unhighlightElement.name}]`;
|
|
745
|
+
try {
|
|
746
|
+
if (logalot) { console.log(`${lc} starting... (I: ee5894b05ec31085883098cc512e1c25)`); }
|
|
747
|
+
|
|
748
|
+
el.classList.add('unhighlight');
|
|
749
|
+
el.classList.remove('highlight');
|
|
750
|
+
await delay(500);
|
|
751
|
+
el.classList.remove('unhighlight');
|
|
752
|
+
} catch (error) {
|
|
753
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
754
|
+
throw error;
|
|
755
|
+
} finally {
|
|
756
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
/**
|
|
761
|
+
* builds a color schema based on the gib.
|
|
762
|
+
*
|
|
763
|
+
* note that the alpha drives the translucent property, but the solid color is
|
|
764
|
+
* always built
|
|
765
|
+
*/
|
|
766
|
+
export function getDeterministicColorInfo({
|
|
767
|
+
ibGibAddr,
|
|
768
|
+
gib,
|
|
769
|
+
ibGib,
|
|
770
|
+
translucentAlpha = 10,
|
|
771
|
+
}: {
|
|
772
|
+
ibGibAddr?: IbGibAddr,
|
|
773
|
+
gib?: Gib,
|
|
774
|
+
ibGib?: IbGib_V1,
|
|
775
|
+
/**
|
|
776
|
+
* drives the translucent color.
|
|
777
|
+
*
|
|
778
|
+
* @default 10
|
|
779
|
+
*/
|
|
780
|
+
translucentAlpha?: number
|
|
781
|
+
}): GibColorInfo {
|
|
782
|
+
const lc = `[${getDeterministicColorInfo.name}]`;
|
|
783
|
+
try {
|
|
784
|
+
if (logalot) { console.log(`${lc} starting... (I: 3b70af42d1c4f6ae91870f3a15c6c625)`); }
|
|
785
|
+
if (!ibGibAddr && !gib && !ibGib) { gib = GIB; }
|
|
786
|
+
gib ??= ibGib?.gib ?? getIbAndGib({ ibGibAddr }).gib;
|
|
787
|
+
const gibInfo = getGibInfo({ gib });
|
|
788
|
+
translucentAlpha ??= 10;
|
|
789
|
+
/**
|
|
790
|
+
* we want to color coordinate according to timeline if possible, i.e.,
|
|
791
|
+
* by tjpGib.
|
|
792
|
+
*/
|
|
793
|
+
let drivingHash = '';
|
|
794
|
+
if (gibInfo.isPrimitive) {
|
|
795
|
+
return {
|
|
796
|
+
gib,
|
|
797
|
+
gibInfo,
|
|
798
|
+
punctiliarColor: DEFAULT_IBGIB_COLOR,
|
|
799
|
+
punctiliarColorTranslucent: DEFAULT_IBGIB_TRANSLUCENT,
|
|
800
|
+
punctiliarColorContrast: DEFAULT_IBGIB_COLOR_CONTRAST,
|
|
801
|
+
}; /* <<<< returns early */
|
|
802
|
+
} else {
|
|
803
|
+
drivingHash = gibInfo.tjpGib ?? gibInfo.punctiliarHash ?? gib; // hmm, gib should be punctiliar but meh
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
|
|
807
|
+
|
|
808
|
+
/**
|
|
809
|
+
* gets the color string
|
|
810
|
+
*/
|
|
811
|
+
// const fnGetColorStr = (drivingHash: string) => {
|
|
812
|
+
// function getContrastColor(hexcolor: string) {
|
|
813
|
+
// const c = hexcolor.concat().replace("#", "");
|
|
814
|
+
// var r = parseInt(c.substr(0, 2), 16);
|
|
815
|
+
// var g = parseInt(c.substr(2, 2), 16);
|
|
816
|
+
// var b = parseInt(c.substr(4, 2), 16);
|
|
817
|
+
// var yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;
|
|
818
|
+
// return (yiq >= 128) ? '#000000' : '#FFFFFF';
|
|
819
|
+
// }
|
|
820
|
+
// let alphaStr = '';
|
|
821
|
+
// if (translucentAlpha || translucentAlpha === 0) {
|
|
822
|
+
// if (translucentAlpha < 0 || translucentAlpha > 100) {
|
|
823
|
+
// throw new Error(`alpha must be between 0 and 100 (E: c78faeb1477482c739b03dd32d2e1825)`);
|
|
824
|
+
// }
|
|
825
|
+
// if (translucentAlpha === 100) {
|
|
826
|
+
// alphaStr = '';
|
|
827
|
+
// } else if (translucentAlpha >= 0 && translucentAlpha < 10) {
|
|
828
|
+
// // single digit
|
|
829
|
+
// alphaStr = `0${translucentAlpha}`;
|
|
830
|
+
// } else {
|
|
831
|
+
// alphaStr = translucentAlpha.toString();
|
|
832
|
+
// }
|
|
833
|
+
// }
|
|
834
|
+
// const color = `#${drivingHash.substring(0, 6)}`;
|
|
835
|
+
// const colorTranslucent = `#${drivingHash.substring(0, 6)}${alphaStr}`;
|
|
836
|
+
// const colorContrast = getContrastColor(color);
|
|
837
|
+
// return [color, colorTranslucent, colorContrast];
|
|
838
|
+
// };
|
|
839
|
+
|
|
840
|
+
const [punctiliarColor, punctiliarColorTranslucent, punctiliarColorContrast] = getColorStrings(translucentAlpha, gibInfo.punctiliarHash ?? gib);
|
|
841
|
+
const [tjpColor, tjpColorTranslucent, tjpColorContrast] = !!gibInfo.tjpGib ?
|
|
842
|
+
getColorStrings(translucentAlpha, gibInfo.tjpGib) :
|
|
843
|
+
[undefined, undefined, undefined];
|
|
844
|
+
|
|
845
|
+
return {
|
|
846
|
+
gib,
|
|
847
|
+
gibInfo,
|
|
848
|
+
punctiliarColor, punctiliarColorTranslucent, punctiliarColorContrast,
|
|
849
|
+
tjpColor, tjpColorTranslucent, tjpColorContrast,
|
|
850
|
+
};
|
|
851
|
+
} catch (error) {
|
|
852
|
+
const errorMsg = `${lc} ${extractErrorMsg(error)}`;
|
|
853
|
+
console.error(errorMsg);
|
|
854
|
+
return {
|
|
855
|
+
gib: gib ?? GIB,
|
|
856
|
+
gibInfo: { isPrimitive: true },
|
|
857
|
+
punctiliarColor: '#ff0000', // red
|
|
858
|
+
punctiliarColorTranslucent: '#ff000010', // translucent red
|
|
859
|
+
punctiliarColorContrast: '#ffffff', // black
|
|
860
|
+
errorMsg,
|
|
861
|
+
};
|
|
862
|
+
} finally {
|
|
863
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
/**
|
|
868
|
+
* gets the color, colorTranslucent and colorContrast
|
|
869
|
+
*/
|
|
870
|
+
export function getColorStrings(translucentAlpha: number, drivingHash: string): [string, string, string] {
|
|
871
|
+
function getContrastColor(hexcolor: string) {
|
|
872
|
+
const c = hexcolor.concat().replace("#", "");
|
|
873
|
+
var r = parseInt(c.substr(0, 2), 16);
|
|
874
|
+
var g = parseInt(c.substr(2, 2), 16);
|
|
875
|
+
var b = parseInt(c.substr(4, 2), 16);
|
|
876
|
+
var yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;
|
|
877
|
+
return (yiq >= 128) ? '#000000' : '#FFFFFF';
|
|
878
|
+
}
|
|
879
|
+
let alphaStr = '';
|
|
880
|
+
if (translucentAlpha || translucentAlpha === 0) {
|
|
881
|
+
if (translucentAlpha < 0 || translucentAlpha > 100) {
|
|
882
|
+
throw new Error(`alpha must be between 0 and 100 (E: c78faeb1477482c739b03dd32d2e1825)`);
|
|
883
|
+
}
|
|
884
|
+
if (translucentAlpha === 100) {
|
|
885
|
+
alphaStr = '';
|
|
886
|
+
} else if (translucentAlpha >= 0 && translucentAlpha < 10) {
|
|
887
|
+
// single digit
|
|
888
|
+
alphaStr = `0${translucentAlpha}`;
|
|
889
|
+
} else {
|
|
890
|
+
alphaStr = translucentAlpha.toString();
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
const color = `#${drivingHash.substring(0, 6)}`;
|
|
894
|
+
const colorTranslucent = `#${drivingHash.substring(0, 6)}${alphaStr}`;
|
|
895
|
+
const colorContrast = getContrastColor(color);
|
|
896
|
+
return [color, colorTranslucent, colorContrast];
|
|
897
|
+
};
|
|
898
|
+
|
|
899
|
+
/**
|
|
900
|
+
* Takes an incoming string. Assumes it's invalid. Does best effort at validating this.
|
|
901
|
+
* Gets the raw export ibgib if it can. If so, and if it is compressed, decompresses the
|
|
902
|
+
* compressed graph contained in the export ibgib.
|
|
903
|
+
*
|
|
904
|
+
* @returns RawExportIbGib_V1 and its decompressed graph
|
|
905
|
+
*/
|
|
906
|
+
export async function getRawExportIbGibAndGraphFromJsonString({
|
|
907
|
+
exportIbGibJsonString,
|
|
908
|
+
metaspace,
|
|
909
|
+
}: {
|
|
910
|
+
exportIbGibJsonString: string,
|
|
911
|
+
metaspace: MetaspaceService,
|
|
912
|
+
}): Promise<[RawExportIbGib_V1, FlatIbGibGraph]> {
|
|
913
|
+
const lc = `[${getRawExportIbGibAndGraphFromJsonString.name}]`;
|
|
914
|
+
try {
|
|
915
|
+
debugger; // walk thru getRawExportIbGibAndGraphFromJsonString
|
|
916
|
+
if (logalot) { console.log(`${lc} starting... (I: genuuid)`); }
|
|
917
|
+
if (!metaspace) { throw new Error(`(UNEXPECTED) metaspace falsy? (E: genuuid)`); }
|
|
918
|
+
|
|
919
|
+
const space = await metaspace.getLocalUserSpace({ lock: false });
|
|
920
|
+
if (!space) { throw new Error(`(UNEXPECTED) couldn't get default local user space? (E: genuuid)`); }
|
|
921
|
+
|
|
922
|
+
let parsedIbGib_notYetValidated: IbGib_V1;
|
|
923
|
+
let parsedExportIbGib_dependenciesNotValidated: RawExportIbGib_V1;
|
|
924
|
+
try {
|
|
925
|
+
parsedIbGib_notYetValidated = JSON.parse(exportIbGibJsonString) as IbGib_V1;
|
|
926
|
+
} catch (error) {
|
|
927
|
+
const emsg = `Error during parse JSON. error: ${extractErrorMsg(error)} (E: genuuid)`;
|
|
928
|
+
const errorHack = new Error(emsg);
|
|
929
|
+
(errorHack as any).cause = error;
|
|
930
|
+
throw errorHack;
|
|
931
|
+
}
|
|
932
|
+
try {
|
|
933
|
+
const validationErrors = await validateIbGibIntrinsically({ ibGib: parsedIbGib_notYetValidated }) ?? [];
|
|
934
|
+
if (validationErrors.length > 0) {
|
|
935
|
+
throw new Error(`validation errors when validating the parsed ibgib that should be a RawExportIbGib_V1: ${validationErrors} (E: 8ba178d3b26e8eca28a67c182fe16825)`);
|
|
936
|
+
}
|
|
937
|
+
// todo: other validation raw export ibgib, maybe to see if it's a full dependency graph, etc.
|
|
938
|
+
|
|
939
|
+
parsedExportIbGib_dependenciesNotValidated = parsedIbGib_notYetValidated as RawExportIbGib_V1;
|
|
940
|
+
if (!parsedExportIbGib_dependenciesNotValidated.data) { throw new Error(`(UNEXPECTED) rawExportIbGib.data falsy? (E: ef1824d1cca5584ab8e34288346e9825)`); }
|
|
941
|
+
} catch (error) {
|
|
942
|
+
const emsg = `Error during parse JSON. error: ${extractErrorMsg(error)} (E: genuuid)`;
|
|
943
|
+
const errorHack = new Error(emsg);
|
|
944
|
+
(errorHack as any).cause = error;
|
|
945
|
+
throw errorHack;
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
|
|
949
|
+
|
|
950
|
+
// at this point, we have a possibly quite large ibGib whose data
|
|
951
|
+
// includes a dependencyGraphAsString. this could possibly be
|
|
952
|
+
// compressed.
|
|
953
|
+
let payloadGraph: FlatIbGibGraph;
|
|
954
|
+
if (!!parsedExportIbGib_dependenciesNotValidated.data.compression) {
|
|
955
|
+
switch (parsedExportIbGib_dependenciesNotValidated.data.compression) {
|
|
956
|
+
case 'gzip':
|
|
957
|
+
payloadGraph = await decompressIbGibGraphFromString({
|
|
958
|
+
compressedBase64: parsedExportIbGib_dependenciesNotValidated.data.dependencyGraphAsString,
|
|
959
|
+
});
|
|
960
|
+
break;
|
|
961
|
+
default:
|
|
962
|
+
throw new Error(`unknown value of rawExportIbGib.data.compression: ${parsedExportIbGib_dependenciesNotValidated.data.compression} (E: 784672fae568312d887ddbb841199925)`);
|
|
963
|
+
}
|
|
964
|
+
} else {
|
|
965
|
+
payloadGraph = await deserializeStringToGraph({
|
|
966
|
+
jsonString: parsedExportIbGib_dependenciesNotValidated.data.dependencyGraphAsString
|
|
967
|
+
});
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
const validationErrorMap: { [addr: string]: string[] } = {};
|
|
971
|
+
for (const [addr, payloadIbGib] of Object.entries(payloadGraph)) {
|
|
972
|
+
const validationErrors = await validateIbGibIntrinsically({ ibGib: payloadIbGib }) ?? [];
|
|
973
|
+
if (validationErrors.length > 0) { validationErrorMap[addr] = validationErrors; }
|
|
974
|
+
}
|
|
975
|
+
if (Object.keys(validationErrorMap).length > 0) {
|
|
976
|
+
throw new Error(`there were validation errors for the RawExportIbGib_V1.data payload (contained in data.dependencyGraphAsString). Here is the validationErrorMap:\n${pretty({ validationErrorMap })} (E: e63f38b182a84122d83a55befb369825)`);
|
|
977
|
+
}
|
|
978
|
+
const exportIbGib_validated = parsedExportIbGib_dependenciesNotValidated;
|
|
979
|
+
|
|
980
|
+
return [exportIbGib_validated, payloadGraph];
|
|
981
|
+
} catch (error) {
|
|
982
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
983
|
+
throw error;
|
|
984
|
+
} finally {
|
|
985
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
/**
|
|
990
|
+
* exports a given ibgib to the default local userspace in the metaspace.
|
|
991
|
+
*/
|
|
992
|
+
export async function exportIbGib({
|
|
993
|
+
ibGib,
|
|
994
|
+
compress,
|
|
995
|
+
// downloadAnchorEl,
|
|
996
|
+
metaspace,
|
|
997
|
+
space,
|
|
998
|
+
}: {
|
|
999
|
+
ibGib: IbGib_V1,
|
|
1000
|
+
compress: boolean,
|
|
1001
|
+
// downloadAnchorEl: HTMLAnchorElement,
|
|
1002
|
+
metaspace: MetaspaceService,
|
|
1003
|
+
space: IbGibSpaceAny,
|
|
1004
|
+
}): Promise<void> {
|
|
1005
|
+
const lc = `[${exportIbGib.name}]`;
|
|
1006
|
+
try {
|
|
1007
|
+
if (logalot) { console.log(`${lc} starting... (I: 623d9463d919683be81f749821a95825)`); }
|
|
1008
|
+
if (isPrimitive({ ibGib })) { throw new Error(`ibGib is primitive. Can't export primitive. (E: dd42c42e9fda0707e81c692af1a2a225)`); }
|
|
1009
|
+
|
|
1010
|
+
const resGetExport = await getRawExportIbGib({
|
|
1011
|
+
ibGib,
|
|
1012
|
+
live: true,
|
|
1013
|
+
compress,
|
|
1014
|
+
metaspace: metaspace,
|
|
1015
|
+
space,
|
|
1016
|
+
});
|
|
1017
|
+
|
|
1018
|
+
const { rawExportIbGib: exportIbGib, errors: exportErrors } = resGetExport;
|
|
1019
|
+
if ((exportErrors ?? []).length > 0) { throw new Error(`Export had errors: ${exportErrors!} (E: 05faf83f25d3449ab809dfd24eeaf825)`); }
|
|
1020
|
+
|
|
1021
|
+
// at this point, we have a possibly quite large ibGib whose data includes
|
|
1022
|
+
// every single other ibgib that ibGib relates to (its dependency graph). This
|
|
1023
|
+
// so now we can save this file and later import from it.
|
|
1024
|
+
|
|
1025
|
+
/**
|
|
1026
|
+
* exportIbGib is guaranteed to have a serializable structure, i.e.,
|
|
1027
|
+
* the data has only primitives. (there are no Uint8Array)
|
|
1028
|
+
*/
|
|
1029
|
+
const exportIbGibAsString = JSON.stringify(exportIbGib);
|
|
1030
|
+
|
|
1031
|
+
// thank you SO, OP and volzotan at https://stackoverflow.com/questions/19721439/download-json-object-as-a-file-from-browser
|
|
1032
|
+
// set the anchor's href to a data stream
|
|
1033
|
+
const dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(exportIbGibAsString);
|
|
1034
|
+
|
|
1035
|
+
// get the filename for the anchor to suggest for the "download"
|
|
1036
|
+
const exportAddr = getIbGibAddr({ ibGib: exportIbGib });
|
|
1037
|
+
const filename = `${exportAddr}.json`;
|
|
1038
|
+
|
|
1039
|
+
// trigger the click
|
|
1040
|
+
const downloadAnchorEl = document.createElement('a');
|
|
1041
|
+
downloadAnchorEl.setAttribute("style", "none");
|
|
1042
|
+
downloadAnchorEl.setAttribute("href", dataStr);
|
|
1043
|
+
downloadAnchorEl.setAttribute("download", filename);
|
|
1044
|
+
const div = document.getElementsByTagName('div')[0]; // just append to the first div then remove it
|
|
1045
|
+
div.appendChild(downloadAnchorEl);
|
|
1046
|
+
downloadAnchorEl.click();
|
|
1047
|
+
div.removeChild(downloadAnchorEl);
|
|
1048
|
+
} catch (error) {
|
|
1049
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
1050
|
+
throw error;
|
|
1051
|
+
} finally {
|
|
1052
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
export async function promptForAPIKey({
|
|
1057
|
+
msg,
|
|
1058
|
+
}: {
|
|
1059
|
+
/**
|
|
1060
|
+
* msg to tell the user when prompting for the API key (secret)
|
|
1061
|
+
*
|
|
1062
|
+
* originally in blankgib, this is CHAT_WITH_AGENT_NEED_API_KEY
|
|
1063
|
+
*/
|
|
1064
|
+
msg: string,
|
|
1065
|
+
}): Promise<string | undefined> {
|
|
1066
|
+
const lc = `[${promptForAPIKey.name}]`;
|
|
1067
|
+
try {
|
|
1068
|
+
if (logalot) { console.log(`${lc} starting... (I: genuuid)`); }
|
|
1069
|
+
let resAPIKey = '';
|
|
1070
|
+
let tryAgain = false;
|
|
1071
|
+
let attempts = 0;
|
|
1072
|
+
let maxAttempts = 5;
|
|
1073
|
+
do {
|
|
1074
|
+
attempts++;
|
|
1075
|
+
if (attempts >= maxAttempts) { throw new Error(`too many attempts (E: genuuid)`); }
|
|
1076
|
+
resAPIKey = await promptForSecret({
|
|
1077
|
+
msg,
|
|
1078
|
+
confirm: false,
|
|
1079
|
+
});
|
|
1080
|
+
if (resAPIKey) {
|
|
1081
|
+
if (resAPIKey.match(GEMINI_API_KEY_REGEXP)) {
|
|
1082
|
+
tryAgain = false;
|
|
1083
|
+
// return resAPIKey; /* <<<< returns early */
|
|
1084
|
+
} else {
|
|
1085
|
+
await alertUser({
|
|
1086
|
+
title: `That's an API Key?`,
|
|
1087
|
+
msg: `That doesn't look like a valid API key, please try again, or hit cancel if you don't want to at this time.`,
|
|
1088
|
+
});
|
|
1089
|
+
tryAgain = true;
|
|
1090
|
+
}
|
|
1091
|
+
} else {
|
|
1092
|
+
console.log(`${lc} user cancelled entering API key. (I: genuuid)`);
|
|
1093
|
+
tryAgain = false;
|
|
1094
|
+
}
|
|
1095
|
+
} while (tryAgain);
|
|
1096
|
+
|
|
1097
|
+
return resAPIKey;
|
|
1098
|
+
} catch (error) {
|
|
1099
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
1100
|
+
throw error;
|
|
1101
|
+
} finally {
|
|
1102
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
/**
|
|
1107
|
+
* updates the given {@link apiKey}. if {@link force} is true and `apiKey` is
|
|
1108
|
+
* empty, then this will set an empty string for the apiKey, effectively
|
|
1109
|
+
* deleting it.
|
|
1110
|
+
*/
|
|
1111
|
+
export async function updateAPIKeyInStorage({
|
|
1112
|
+
dbName,
|
|
1113
|
+
storeName,
|
|
1114
|
+
key,
|
|
1115
|
+
apiKey,
|
|
1116
|
+
force,
|
|
1117
|
+
}: {
|
|
1118
|
+
dbName: string,
|
|
1119
|
+
storeName: string,
|
|
1120
|
+
key: string,
|
|
1121
|
+
apiKey: string,
|
|
1122
|
+
force: boolean,
|
|
1123
|
+
}): Promise<void> {
|
|
1124
|
+
const lc = `[${updateAPIKeyInStorage.name}]`;
|
|
1125
|
+
try {
|
|
1126
|
+
if (logalot) { console.log(`${lc} starting... (I: 64951b38da35ec5ff847004d53b2d425)`); }
|
|
1127
|
+
|
|
1128
|
+
const matches = apiKey.match(GEMINI_API_KEY_REGEXP);
|
|
1129
|
+
if (matches || force) {
|
|
1130
|
+
await storagePut({
|
|
1131
|
+
dbName, storeName,
|
|
1132
|
+
key,
|
|
1133
|
+
value: apiKey,
|
|
1134
|
+
});
|
|
1135
|
+
if (apiKey) {
|
|
1136
|
+
// set a new truthy key
|
|
1137
|
+
await alertUser({ title: `need to reload...`, msg: `Cool! We successfully SAVED your Gemini API key in your browser's IndexedDB.\n\nIf you'd like to remove it later, you can clear it out by using the ${CONFIG_OPTION_GEMINI_API_KEY_LOCATION_HELP}.\n\nWe must now reload the page to use the new API key... (investment would be a good thing to improve this UX workflow!)` });
|
|
1138
|
+
} else {
|
|
1139
|
+
// cleared out the key
|
|
1140
|
+
await alertUser({ title: `need to reload...`, msg: `Cool! We successfully CLEARED your Gemini API key from your browser's IndexedDB.\n\nIf you'd like to set a new key, use the ${CONFIG_OPTION_GEMINI_API_KEY_LOCATION_HELP}.\n\nThe API key is already removed, but we must now reload the page for this to propagate throughout the web page... (investment would be a good thing to improve this UX workflow!)` });
|
|
1141
|
+
}
|
|
1142
|
+
window.location.reload();
|
|
1143
|
+
} else {
|
|
1144
|
+
throw new Error(`apiKey does not match apiKeyRegex (${GEMINI_API_KEY_REGEXP.source}) and force is false. (E: 2d6c798803e6b71bf6aa70bd60170825)`);
|
|
1145
|
+
}
|
|
1146
|
+
} catch (error) {
|
|
1147
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
1148
|
+
throw error;
|
|
1149
|
+
} finally {
|
|
1150
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
/**
|
|
1156
|
+
* wrapper for simplifying/asserting an element that is expected to exist.
|
|
1157
|
+
*
|
|
1158
|
+
* ## intent
|
|
1159
|
+
*
|
|
1160
|
+
* This avoids using TypeScript truthy assertions (!) or excessive
|
|
1161
|
+
* falsy/exception checks.
|
|
1162
|
+
*/
|
|
1163
|
+
export function getElementById_throwsIfFalsy<TElement extends Element>({
|
|
1164
|
+
id,
|
|
1165
|
+
shadowRoot,
|
|
1166
|
+
}: {
|
|
1167
|
+
id: string;
|
|
1168
|
+
/**
|
|
1169
|
+
* If set, will get element here, else will use document
|
|
1170
|
+
*/
|
|
1171
|
+
shadowRoot?: ShadowRoot;
|
|
1172
|
+
}): TElement {
|
|
1173
|
+
const lc = `[${getElementById_throwsIfFalsy.name}]`;
|
|
1174
|
+
try {
|
|
1175
|
+
if (logalot) { console.log(`${lc} starting... (I: 18a338c6dab8690c72b8759b8d952925)`); }
|
|
1176
|
+
let resElement = !!shadowRoot ?
|
|
1177
|
+
shadowRoot.getElementById(id) as TElement | null :
|
|
1178
|
+
document.getElementById(id) as TElement | null;
|
|
1179
|
+
|
|
1180
|
+
if (resElement) {
|
|
1181
|
+
return resElement;
|
|
1182
|
+
} else {
|
|
1183
|
+
throw new Error(`${!!shadowRoot ? 'shadowRoot' : 'document'}.getElementById(${id}) returned null. So...Element was not found. (E: 5e501f6835cc74cd4c2faf0d9e387825)`);
|
|
1184
|
+
}
|
|
1185
|
+
} catch (error) {
|
|
1186
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
1187
|
+
throw error;
|
|
1188
|
+
} finally {
|
|
1189
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
/**
|
|
1194
|
+
* wrapper that throws if element not found.
|
|
1195
|
+
* @param id of Element
|
|
1196
|
+
* @returns Element of type TElement or throws.
|
|
1197
|
+
* @see {@link shadowRoot_getElementById}
|
|
1198
|
+
*
|
|
1199
|
+
* ## intent
|
|
1200
|
+
*
|
|
1201
|
+
* This avoids using TypeScript truthy assertions (!) or excessive
|
|
1202
|
+
* falsy/exception checks.
|
|
1203
|
+
*/
|
|
1204
|
+
export function document_getElementById<TElement extends Element = HTMLElement>(id: string): TElement {
|
|
1205
|
+
return getElementById_throwsIfFalsy<TElement>({ id });
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
/**
|
|
1209
|
+
* wrapper that throws if element not found.
|
|
1210
|
+
* @param shadowRoot in which the element MUST be truthy or throws
|
|
1211
|
+
* @param id of Element
|
|
1212
|
+
* @returns Element of type TElement or throws.
|
|
1213
|
+
* @see {@link document_getElementById}
|
|
1214
|
+
*
|
|
1215
|
+
* ## intent
|
|
1216
|
+
*
|
|
1217
|
+
* This avoids using TypeScript truthy assertions (!) or excessive
|
|
1218
|
+
* falsy/exception checks.
|
|
1219
|
+
*/
|
|
1220
|
+
export function shadowRoot_getElementById<TElement extends Element = HTMLElement>(shadowRoot: ShadowRoot, id: string): TElement {
|
|
1221
|
+
return getElementById_throwsIfFalsy<TElement>({ id, shadowRoot });
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
|
|
1225
|
+
export function getGlobalMetaspace_waitIfNeeded(): Promise<MetaspaceService> {
|
|
1226
|
+
const lc = `[${getGlobalMetaspace_waitIfNeeded.name}]`;
|
|
1227
|
+
try {
|
|
1228
|
+
if (logalot) { console.log(`${lc} starting... (I: 96e9b89ef4986c33e819340ec7d05325)`); }
|
|
1229
|
+
throw new Error(`not implemented (E: eb1258f32cb543ce684812845dd28c25)`);
|
|
1230
|
+
} catch (error) {
|
|
1231
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
1232
|
+
throw error;
|
|
1233
|
+
} finally {
|
|
1234
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
export function getGlobalStoreName(): Promise<string> {
|
|
1239
|
+
const lc = `[${getGlobalStoreName.name}]`;
|
|
1240
|
+
try {
|
|
1241
|
+
if (logalot) { console.log(`${lc} starting... (I: 62a29f9982b4b5ecd91ff58ca4dd6825)`); }
|
|
1242
|
+
// ARMY_STORE
|
|
1243
|
+
throw new Error(`not implemented (E: 33bc38b63bb8ab5244c6a0388aadaa25)`);
|
|
1244
|
+
} catch (error) {
|
|
1245
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
1246
|
+
throw error;
|
|
1247
|
+
} finally {
|
|
1248
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
export function getGlobalDbName(): string {
|
|
1253
|
+
const lc = `[${getGlobalDbName.name}]`;
|
|
1254
|
+
try {
|
|
1255
|
+
if (logalot) { console.log(`${lc} starting... (I: 8c8f08728fc7384f87697377358cc825)`); }
|
|
1256
|
+
// BLANK_GIB_DB_NAME
|
|
1257
|
+
throw new Error(`not implemented (E: 6586f8982de8bcea91f922982c3ea825)`);
|
|
1258
|
+
} catch (error) {
|
|
1259
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
1260
|
+
throw error;
|
|
1261
|
+
} finally {
|
|
1262
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1266
|
+
export function getGlobalIndexedDbKey_APIKey(): Promise<string> {
|
|
1267
|
+
const lc = `[${getGlobalIndexedDbKey_APIKey.name}]`;
|
|
1268
|
+
try {
|
|
1269
|
+
if (logalot) { console.log(`${lc} starting... (I: 59a2510a85051f97ed15fbc8825b6825)`); }
|
|
1270
|
+
throw new Error(`not implemented (E: 7e05c81caed719f2a6dcf7824e948825)`);
|
|
1271
|
+
} catch (error) {
|
|
1272
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
1273
|
+
throw error;
|
|
1274
|
+
} finally {
|
|
1275
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
1276
|
+
}
|
|
1277
|
+
}
|