From ac7ae9fade4a3f8a0de1e58eef9a0067bfd5ce18 Mon Sep 17 00:00:00 2001 From: patnorris Date: Tue, 15 Aug 2023 23:41:09 +0200 Subject: [PATCH 01/17] Add option for space environment --- .../components/EnvironmentLibrary.svelte | 69 ++++++++++++++++ .../components/EnvironmentPreview.svelte | 28 +++++++ .../helpers/space_helpers.js | 18 ++++ .../pages/Space.svelte | 82 ++++++++++++++++++- 4 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 src/PersonalWebSpace_frontend/components/EnvironmentLibrary.svelte create mode 100644 src/PersonalWebSpace_frontend/components/EnvironmentPreview.svelte diff --git a/src/PersonalWebSpace_frontend/components/EnvironmentLibrary.svelte b/src/PersonalWebSpace_frontend/components/EnvironmentLibrary.svelte new file mode 100644 index 0000000..a33a862 --- /dev/null +++ b/src/PersonalWebSpace_frontend/components/EnvironmentLibrary.svelte @@ -0,0 +1,69 @@ + + +
+ {#each environments as item (item.name)} +
+ {item.name} + +
+ {/each} +
+ + + + + + + diff --git a/src/PersonalWebSpace_frontend/components/EnvironmentPreview.svelte b/src/PersonalWebSpace_frontend/components/EnvironmentPreview.svelte new file mode 100644 index 0000000..6c07316 --- /dev/null +++ b/src/PersonalWebSpace_frontend/components/EnvironmentPreview.svelte @@ -0,0 +1,28 @@ + +
+ +
+ + + + + + + diff --git a/src/PersonalWebSpace_frontend/helpers/space_helpers.js b/src/PersonalWebSpace_frontend/helpers/space_helpers.js index 28cdbdb..7e9b840 100644 --- a/src/PersonalWebSpace_frontend/helpers/space_helpers.js +++ b/src/PersonalWebSpace_frontend/helpers/space_helpers.js @@ -63,6 +63,24 @@ export const initiateCollapsibles = () => { }; }; +export const getStringForSpaceWithEnvironment = (envToPreview) => { + return ` + + + + + + + + + + + + + + `; +}; + export const getStringForSpaceFromModel = (modelUrl) => { return ` diff --git a/src/PersonalWebSpace_frontend/pages/Space.svelte b/src/PersonalWebSpace_frontend/pages/Space.svelte index 1f7153c..11bdac8 100644 --- a/src/PersonalWebSpace_frontend/pages/Space.svelte +++ b/src/PersonalWebSpace_frontend/pages/Space.svelte @@ -14,7 +14,9 @@ import SpaceInfo from "../components/SpaceInfo.svelte"; import GlbModelPreview from "../components/GlbModelPreview.svelte"; import ItemLibrary from "../components/ItemLibrary.svelte"; + import EnvironmentLibrary from "../components/EnvironmentLibrary.svelte"; import MediaContentPreview from "../components/MediaContentPreview.svelte"; + import EnvironmentPreview from "../components/EnvironmentPreview.svelte"; import { getEntityClipboardRepresentation } from '../helpers/entity.js'; import { extractSpaceMetadata } from '../helpers/space_helpers.js'; @@ -244,6 +246,8 @@ // Close all option popups openUploadModelFilePopup = false; openItemsToAddLibraryPopup = false; + openAddMediaContentPopup = false; + openEnvironmentOptionPopup = false; // Toggle whether the Edit Mode popup is open openEditModelPopup = !openEditModelPopup; resetUploadVariables(); @@ -395,7 +399,7 @@ aScene.appendChild(imageEntity); } else { aScene.replaceChild(imageEntity, aScene.querySelector('#imageFromUserFile')); - } + }; } else { aScene.addEventListener('loaded', function () { // Create a new A-Frame entity for the image @@ -609,6 +613,37 @@ }; }; +// Add environment option + let openEnvironmentOptionPopup = false; + let userSelectedEnvironmentOption = "default"; + let isAddingEnvironmentInProgress = false; + let wasEnvironmentAddedSuccessfully = false; + + const addEnvironmentToSpace = () => { + if (!isAddingEnvironmentInProgress) { + isAddingEnvironmentInProgress = true; + wasEnvironmentAddedSuccessfully = false; + try { + let scene = document.querySelector('a-scene'); + var environmentEntity = scene.ownerDocument.createElement('a-entity'); + environmentEntity.setAttribute('environment', `preset: ${userSelectedEnvironmentOption}`); + environmentEntity.setAttribute('id', 'presetEnvironmentSelectedByUser'); + // Ensure that only one environment is added to the scene + var existingEnvironment = document.body.querySelector("#presetEnvironmentSelectedByUser"); + if (existingEnvironment) { + scene.replaceChild(environmentEntity, existingEnvironment); + } else { + scene.appendChild(environmentEntity); + }; + } catch (error) { + console.error("Adding Environment to Space Error:", error); + }; + wasEnvironmentAddedSuccessfully = true; + isAddingEnvironmentInProgress = false; + }; + }; + +// Prepare dropdown menu const addDropdownMenuForNewElements = () => { var elements = document.body.getElementsByClassName("button fa fa-plus"); var addEntityButton = elements.item(0); @@ -699,6 +734,21 @@ }, 1000); }; + // Create "Environment" option + const addEnvironmentOption = document.createElement("a"); + addEnvironmentOption.href = "javascript:;"; // "empty" behavior, i.e. shouldn't do anything + addEnvironmentOption.id = "addEnvironment"; + addEnvironmentOption.classList.add("dropdownOption"); + addEnvironmentOption.innerHTML = "Environment"; + addEnvironmentOption.onclick = function() { + toggleOpenEditModePopup(); + // Handle add environment action + openEnvironmentOptionPopup = true; + setTimeout(() => { + window.addEventListener("click", closePopupsOnClickOutside , false); + }, 1000); + }; + // Create "Add New Entity" option (from the + button ("Add Entity"), i.e. it keeps the onclick behavior of adding a new a-entity) const addNewEntityOption = addEntityButton; // @ts-ignore @@ -714,6 +764,7 @@ dropdownMenuContent.appendChild(libraryOption); dropdownMenuContent.appendChild(mediaContentOption); dropdownMenuContent.appendChild(uploadFileOption); + dropdownMenuContent.appendChild(addEnvironmentOption); dropdownMenuContent.appendChild(addNewEntityOption); // Add button and dropdown menu to div @@ -1393,6 +1444,35 @@

{/if} + + {:else if openEnvironmentOptionPopup} +
+ + {#if isViewerSpaceOwner()} +

Add an Environment to Your Space

+
addEnvironmentToSpace()}> +

Select an envrionment from the list:

+ {#key userSelectedEnvironmentOption} + + {#if isAddingEnvironmentInProgress} + +

{inProgressSubtext}

+ {:else if wasEnvironmentAddedSuccessfully} + +

{createdSubtext}

+ {:else} + +

{clickFileUploadSubtext}

+ {/if} + {/key} + + + {:else} +

+ You need to be the space's owner to use this feature. +

+ {/if} +
{/if} {/if} From 3e7e1496beca7fac5d97f7a71eef1905af361a0f Mon Sep 17 00:00:00 2001 From: patnorris Date: Wed, 16 Aug 2023 00:23:10 +0200 Subject: [PATCH 02/17] Add code for 360-degree content --- .../components/MediaContentPreview.svelte | 14 ++++- .../helpers/space_helpers.js | 40 ++++++++++++ .../pages/Space.svelte | 62 +++++++++++++++---- 3 files changed, 102 insertions(+), 14 deletions(-) diff --git a/src/PersonalWebSpace_frontend/components/MediaContentPreview.svelte b/src/PersonalWebSpace_frontend/components/MediaContentPreview.svelte index 28b11a5..d1793c7 100644 --- a/src/PersonalWebSpace_frontend/components/MediaContentPreview.svelte +++ b/src/PersonalWebSpace_frontend/components/MediaContentPreview.svelte @@ -1,8 +1,14 @@ + + + + + + + + + + + + + + `; +}; + export const getStringForSpaceFromImageFile = (imageUrl) => { return ` @@ -177,6 +197,26 @@ export const getStringForSpaceFromImageFile = (imageUrl) => { `; }; +export const getStringForSpaceFrom360ImageFile = (imageUrl) => { + return ` + + + + + + + + + + + + + + + + `; +}; + // Extract metadata fields from Space NFT export const extractSpaceMetadata = (spaceNft, targetObject, forUpdatingSpace = false) => { if (spaceNft && spaceNft.metadata && spaceNft.metadata.length > 0) { diff --git a/src/PersonalWebSpace_frontend/pages/Space.svelte b/src/PersonalWebSpace_frontend/pages/Space.svelte index 11bdac8..14c3deb 100644 --- a/src/PersonalWebSpace_frontend/pages/Space.svelte +++ b/src/PersonalWebSpace_frontend/pages/Space.svelte @@ -305,6 +305,7 @@ // Upload model file let openUploadModelFilePopup = false; let files; + let is360Degree = false; // This will store the state of the checkbox let userUploadedFileURL; let fileSizeToUpload; let fileSizeUploadLimit = 2000000; // 2 MB @@ -542,6 +543,8 @@ console.error("File Upload Error:", fileUploadResult); }; } else if (sourceType === "UserUploadedMediaContent") { + // Capture 360-degree toggle + const set360DegreeContent = is360Degree ? true : false; // Store file for user const arrayBuffer = await files[0].arrayBuffer(); const uint8Array = new Uint8Array(arrayBuffer); @@ -570,11 +573,25 @@ var assets = document.querySelector('a-assets'); assets.appendChild(newImageAsset); function loaded() { - contentEntity = scene.ownerDocument.createElement('a-image'); - contentEntity.setAttribute('src', '#userUploadedImageAsset_' + fileUploadResult.Ok.FileId); - contentEntity.setAttribute('position', '0 3 -6'); - contentEntity.setAttribute('id', 'userUploadedImage_' + fileUploadResult.Ok.FileId); - scene.appendChild(contentEntity); + // Determine whether the image is 360 degree and set the appropriate attribute + if (set360DegreeContent) { + contentEntity = scene.ownerDocument.createElement('a-sky'); + contentEntity.setAttribute('src', '#userUploadedImageAsset_' + fileUploadResult.Ok.FileId); + contentEntity.setAttribute('id', 'userUploaded360Image_' + fileUploadResult.Ok.FileId); + contentEntity.setAttribute('rotation', '0 -130 0'); + const existingSky = scene.querySelector('a-sky'); + if (existingSky) { + scene.replaceChild(contentEntity, existingSky); + } else { + scene.appendChild(contentEntity); + }; + } else { + contentEntity = scene.ownerDocument.createElement('a-image'); + contentEntity.setAttribute('src', '#userUploadedImageAsset_' + fileUploadResult.Ok.FileId); + contentEntity.setAttribute('position', '0 3 -6'); + contentEntity.setAttribute('id', 'userUploadedImage_' + fileUploadResult.Ok.FileId); + scene.appendChild(contentEntity); + }; }; newImageAsset.addEventListener('load', loaded); } else if (fileName.endsWith('.mp4') || fileName.endsWith('.mov')) { @@ -587,12 +604,26 @@ var assets = document.querySelector('a-assets'); assets.appendChild(newVideoAsset); function loaded() { - contentEntity = scene.ownerDocument.createElement('a-video'); - contentEntity.setAttribute('src', '#userUploadedVideoAsset_' + fileUploadResult.Ok.FileId); - contentEntity.setAttribute('position', '0 3 -6'); - contentEntity.setAttribute('id', 'userUploadedVideo_' + fileUploadResult.Ok.FileId); - contentEntity.setAttribute('video-play-on-click', true); // Add component to play video on click - scene.appendChild(contentEntity); + // Determine whether the video is 360 degree and set the appropriate attribute + if (set360DegreeContent) { + contentEntity = scene.ownerDocument.createElement('a-videosphere'); + contentEntity.setAttribute('src', '#userUploadedVideoAsset_' + fileUploadResult.Ok.FileId); + contentEntity.setAttribute('id', 'userUploaded360Video_' + fileUploadResult.Ok.FileId); + contentEntity.setAttribute('rotation', '0 -130 0'); + const existingVideosphere = scene.querySelector('a-videosphere'); + if (existingVideosphere) { + scene.replaceChild(contentEntity, existingVideosphere); + } else { + scene.appendChild(contentEntity); + }; + } else { + contentEntity = scene.ownerDocument.createElement('a-video'); + contentEntity.setAttribute('src', '#userUploadedVideoAsset_' + fileUploadResult.Ok.FileId); + contentEntity.setAttribute('position', '0 3 -6'); + contentEntity.setAttribute('id', 'userUploadedVideo_' + fileUploadResult.Ok.FileId); + contentEntity.setAttribute('video-play-on-click', true); // Add component to play video on click + scene.appendChild(contentEntity); + }; }; newVideoAsset.addEventListener('loadeddata', loaded); } else { @@ -1373,6 +1404,11 @@ {#if isViewerSpaceOwner()}

Upload an Image or Video

+ +
+ + +
createNewItemInSpace("UserUploadedMediaContent")}> {#if userFileInputHandler(files)} - + {#key is360Degree} + + {/key} {#if isFileUploadInProgress}

{inProgressSubtext}

From 5d61e61392af33003d5a614da08b460aa8d324f8 Mon Sep 17 00:00:00 2001 From: patnorris Date: Wed, 16 Aug 2023 15:37:41 +0200 Subject: [PATCH 03/17] Play 360 degree video --- src/PersonalWebSpace_frontend/pages/Space.svelte | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/PersonalWebSpace_frontend/pages/Space.svelte b/src/PersonalWebSpace_frontend/pages/Space.svelte index 14c3deb..5023986 100644 --- a/src/PersonalWebSpace_frontend/pages/Space.svelte +++ b/src/PersonalWebSpace_frontend/pages/Space.svelte @@ -610,6 +610,8 @@ contentEntity.setAttribute('src', '#userUploadedVideoAsset_' + fileUploadResult.Ok.FileId); contentEntity.setAttribute('id', 'userUploaded360Video_' + fileUploadResult.Ok.FileId); contentEntity.setAttribute('rotation', '0 -130 0'); + contentEntity.setAttribute('autoplay', true); + contentEntity.setAttribute('loop', true); const existingVideosphere = scene.querySelector('a-videosphere'); if (existingVideosphere) { scene.replaceChild(contentEntity, existingVideosphere); From 452d0e6ba06c5b7c9ca6c9dac8d2be73a7fa0c42 Mon Sep 17 00:00:00 2001 From: patnorris Date: Wed, 16 Aug 2023 16:46:34 +0200 Subject: [PATCH 04/17] Add media upload as creation option --- .../components/MediaContentPreview.svelte | 6 +- .../helpers/space_helpers.js | 19 ++++ .../helpers/utils.js | 4 + .../pages/CreateSpace.svelte | 107 ++++++++++++++---- .../pages/Space.svelte | 7 +- 5 files changed, 116 insertions(+), 27 deletions(-) diff --git a/src/PersonalWebSpace_frontend/components/MediaContentPreview.svelte b/src/PersonalWebSpace_frontend/components/MediaContentPreview.svelte index d1793c7..c284ccb 100644 --- a/src/PersonalWebSpace_frontend/components/MediaContentPreview.svelte +++ b/src/PersonalWebSpace_frontend/components/MediaContentPreview.svelte @@ -6,14 +6,16 @@ getStringForSpaceFromVideoFile } from "../helpers/space_helpers"; + import { supportedImageExtensions, supportedVideoExtensions } from "../helpers/utils"; + export let contentUrl; export let contentFiles; export let is360Degree = false; contentFiles = contentFiles; // Note: HTML as string in Svelte needs the ending script tag to be escaped (see https://github.com/sveltejs/svelte/issues/5810) - const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.svg']; - const videoExtensions = ['.mp4', '.mov']; + const imageExtensions = supportedImageExtensions; + const videoExtensions = supportedVideoExtensions; const fileName = contentFiles[0].name; const isImage = imageExtensions.some(ext => fileName.endsWith(ext)); diff --git a/src/PersonalWebSpace_frontend/helpers/space_helpers.js b/src/PersonalWebSpace_frontend/helpers/space_helpers.js index b16a76d..601f411 100644 --- a/src/PersonalWebSpace_frontend/helpers/space_helpers.js +++ b/src/PersonalWebSpace_frontend/helpers/space_helpers.js @@ -1,4 +1,5 @@ import { canisterId as PersonalWebSpace_frontend_canister_id } from "canisters/PersonalWebSpace_frontend"; +import { supportedImageExtensions, supportedVideoExtensions } from "./utils"; export const formatUserSpaces = (userSpaces) => { // transform userSpaces list to string holding HTML ready to be displayed @@ -217,6 +218,24 @@ export const getStringForSpaceFrom360ImageFile = (imageUrl) => { `; }; +export const getStringForSpaceFromMediaFile = (mediaUrl, fileName, is360Degree) => { + if (supportedImageExtensions.some(ext => fileName.endsWith(ext))) { + if (is360Degree) { + return getStringForSpaceFrom360ImageFile(mediaUrl); + } else { + return getStringForSpaceFromImageFile(mediaUrl); + }; + } else if (supportedVideoExtensions.some(ext => fileName.endsWith(ext))) { + if (is360Degree) { + return getStringForSpaceFrom360VideoFile(mediaUrl); + } else { + return getStringForSpaceFromVideoFile(mediaUrl); + }; + } else { + return getStringForSpaceFromImageFile(mediaUrl); + } +}; + // Extract metadata fields from Space NFT export const extractSpaceMetadata = (spaceNft, targetObject, forUpdatingSpace = false) => { if (spaceNft && spaceNft.metadata && spaceNft.metadata.length > 0) { diff --git a/src/PersonalWebSpace_frontend/helpers/utils.js b/src/PersonalWebSpace_frontend/helpers/utils.js index 982ef16..ac90641 100644 --- a/src/PersonalWebSpace_frontend/helpers/utils.js +++ b/src/PersonalWebSpace_frontend/helpers/utils.js @@ -9,6 +9,10 @@ export async function submitEmailSignUpForm(emailAddress, pageSubmittedFrom) { return result; } +export const supportedImageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.svg']; +export const supportedVideoExtensions = ['.mp4', '.mov']; +export const supported3dModelExtensions = ['.glb', '.gltf']; + export function getNumber(value) { return parseFloat(value.toFixed(3)); } diff --git a/src/PersonalWebSpace_frontend/pages/CreateSpace.svelte b/src/PersonalWebSpace_frontend/pages/CreateSpace.svelte index 52bbda8..3c53ecb 100644 --- a/src/PersonalWebSpace_frontend/pages/CreateSpace.svelte +++ b/src/PersonalWebSpace_frontend/pages/CreateSpace.svelte @@ -6,11 +6,13 @@ import Footer from "../components/Footer.svelte"; import GlbModelPreview from "../components/GlbModelPreview.svelte"; - import { getStringForSpaceFromModel } from "../helpers/space_helpers"; + import { getStringForSpaceFromMediaFile, getStringForSpaceFromModel } from "../helpers/space_helpers"; + import { supportedImageExtensions, supportedVideoExtensions } from "../helpers/utils"; import { canisterId as backendCanisterId } from "canisters/PersonalWebSpace_backend"; import { canisterId as PersonalWebSpace_frontend_canister_id } from "canisters/PersonalWebSpace_frontend"; import type { EntityInitiationObject } from "src/integrations/BebbProtocol/bebb.did"; + import MediaContentPreview from "../components/MediaContentPreview.svelte"; let webHostedGlbModelUrl : string = ""; @@ -57,10 +59,14 @@ let files; let userUploadedFileURL; + let fileType; let fileSizeToUpload; let fileSizeUploadLimit = 2000000; // 2 MB + + const supportedMediaExtensions = supportedVideoExtensions.concat(supportedImageExtensions); + let is360Degree = false; - const userFileInputHandler = function(userFiles = files) { + const userFileInputHandler = function(userFiles = files, preCreation=false) { if (!userFiles || userFiles.length === 0) { return false; }; @@ -68,16 +74,24 @@ let fileName = userFile.name; // get the name of the file if (fileName.endsWith('.glb')) { try { + fileType = "glbModel"; userUploadedFileURL = URL.createObjectURL(userFile); fileSizeToUpload = userFile.size; - addUserFileToScene(files); + if (!preCreation) { + addUserFileToScene(files); + }; return true; } catch (e) { console.error(e); return false; } + } else if (supportedMediaExtensions.some(ext => fileName.endsWith(ext))) { + fileType = "mediaContent"; + userUploadedFileURL = URL.createObjectURL(userFile); + fileSizeToUpload = userFile.size; + return true; } else { - console.log('The uploaded file is not a .glb file.'); + console.log('The uploaded file is not a supported file.'); return false; } }; @@ -137,7 +151,9 @@ const createSpace = async (spaceHtml) => { try { const spaceResponse = await $store.backendActor.createSpace(spaceHtml); + // @ts-ignore if (spaceResponse && spaceResponse.Ok) { + // @ts-ignore const spaceId = spaceResponse.Ok.id; setSpaceWasCreated(); // Protocol integration: create Space as Entity in Protocol @@ -151,8 +167,11 @@ entitySpecificFields: [externalId], }; const spaceEntityIdResponse = await $store.protocolActor.create_entity(entityInitiationObject); + // @ts-ignore if (spaceEntityIdResponse && spaceEntityIdResponse.Ok) { + // @ts-ignore const spaceEntityIdUpdateResponse = await $store.backendActor.updateSpaceEntityId(spaceId, spaceEntityIdResponse.Ok); + // @ts-ignore if (!spaceEntityIdUpdateResponse || !spaceEntityIdUpdateResponse.Ok) { console.error("Update Space Error:", spaceEntityIdUpdateResponse); }; @@ -168,13 +187,13 @@ }; const createNewUserSpaceFromModel = async (modelType) => { - setCreationInProgress(modelType); if (modelType === "WebHostedGlbModel" && urlInputHandler(webHostedGlbModelUrl)) { + setCreationInProgress(modelType); const spaceHtml = getStringForSpaceFromModel(webHostedGlbModelUrl); await createSpace(spaceHtml); }; // Upload the user's file to the backend canister and create a new space for the user including the uploaded model - if (modelType === "UserUploadedGlbModel" && userFileInputHandler(files) && (fileSizeToUpload <= fileSizeUploadLimit)) { + if (modelType === "UserUploadedGlbModel" && userFileInputHandler(files, true) && (fileSizeToUpload <= fileSizeUploadLimit)) { // Store file for user const arrayBuffer = await files[0].arrayBuffer(); const uint8Array = new Uint8Array(arrayBuffer); @@ -197,6 +216,35 @@ }; }; + const createNewUserSpaceFromFile = async () => { + setCreationInProgress("UserUploadedFile"); + if (fileType === "glbModel") { + await createNewUserSpaceFromModel("UserUploadedGlbModel") + }; + // Upload the user's file to the backend canister and create a new space for the user including the uploaded file + if (fileType === "mediaContent" && userFileInputHandler(files, true) && (fileSizeToUpload <= fileSizeUploadLimit)) { + // Store file for user + const arrayBuffer = await files[0].arrayBuffer(); + const uint8Array = new Uint8Array(arrayBuffer); + const byteArray = Array.from(uint8Array); + let fileUploadResult; + try { + fileUploadResult = await $store.backendActor.uploadUserFile(files[0].name, byteArray); + } catch (error) { + console.error("File Upload Error:", error); + }; + if (fileUploadResult.Ok) { + const url = process.env.DFX_NETWORK === "local" + ? `http://127.0.0.1:4943/file/fileId=${fileUploadResult.Ok.FileId}?canisterId=${backendCanisterId}` // e.g. http://127.0.0.1:4943/file/fileId=888?canisterId=bkyz2-fmaaa-aaaaa-qaaaq-cai + : `https://${backendCanisterId}.raw${appDomain}/file/fileId=${fileUploadResult.Ok.FileId}`; // e.g. https://vee64-zyaaa-aaaai-acpta-cai.raw.ic0.app/file/fileId=777 + const spaceHtml = getStringForSpaceFromMediaFile(url, files[0].name, is360Degree); + await createSpace(spaceHtml); + } else { + console.error("File Upload Error:", fileUploadResult); + }; + }; + }; + // Helper functions to check whether a valid URL was provided in the form const isValidUrl = (url) => { try { @@ -304,12 +352,14 @@

{clickDefaultSubtext}

{/if} {/if} - -

Create Your Space From an Existing Model:

- -

Upload a GLB Model File

- createNewUserSpaceFromModel("UserUploadedGlbModel")}> - + +

Create Your Space With an Uploaded Item:

+ +

Upload a File

+

It can be a 3D model, image or video (incl. 360-degree).

+

Supported File Types: .glb, .gltf, .mp4, .mov, .jpg, .jpeg, .png, .svg, .gif

+ createNewUserSpaceFromFile()}> + {#if files} {#key files} - {#if userFileInputHandler(files)} + {#if fileType === "glbModel"} + + + {:else if fileType === "mediaContent"} + + +
+ + +
+ {#key is360Degree} + + {/key} + {/if} {#if !$store.isAuthed} -

{loginSubtext}

+

{loginSubtext}

{:else} {#if isSpaceCreationInProgress} - {#if spaceToCreate === "UserUploadedGlbModel"} -

{inProgressSubtext}

+ {#if spaceToCreate === "UserUploadedFile"} +

{inProgressSubtext}

{/if} {:else if wasSpaceCreatedSuccessfully} - {#if spaceToCreate === "UserUploadedGlbModel"} -

{createdSubtext}

+ {#if spaceToCreate === "UserUploadedFile"} +

{createdSubtext}

{:else} -

{clickFromModelSubtext}

+

{clickFromModelSubtext}

{/if} {:else} {#if fileSizeToUpload <= fileSizeUploadLimit} -

{clickFromModelSubtext}

+

{clickFromModelSubtext}

{:else} -

{fileTooBigText}

+

{fileTooBigText}

{/if} {/if} {/if} {:else} -

Please provide a valid GLB Model File.

+

Please provide a valid File (with a supported file type).

{/if} {/key} {/if} diff --git a/src/PersonalWebSpace_frontend/pages/Space.svelte b/src/PersonalWebSpace_frontend/pages/Space.svelte index 5023986..9a04bb6 100644 --- a/src/PersonalWebSpace_frontend/pages/Space.svelte +++ b/src/PersonalWebSpace_frontend/pages/Space.svelte @@ -20,6 +20,7 @@ import { getEntityClipboardRepresentation } from '../helpers/entity.js'; import { extractSpaceMetadata } from '../helpers/space_helpers.js'; + import { supportedImageExtensions, supportedVideoExtensions } from "../helpers/utils"; import { canisterId as backendCanisterId } from "canisters/PersonalWebSpace_backend"; import type { Entity, EntityAttachedBridgesResult, Bridge } from "src/integrations/BebbProtocol/bebb.did"; @@ -345,7 +346,7 @@ console.error(e); return false; } - } else if (fileName.endsWith('.jpg') || fileName.endsWith('.jpeg') || fileName.endsWith('.png') || fileName.endsWith('.gif') || fileName.endsWith('.svg')) { + } else if (supportedImageExtensions.some(ext => fileName.endsWith(ext))) { try { userUploadedFileURL = URL.createObjectURL(userFile); fileSizeToUpload = userFile.size; @@ -354,7 +355,7 @@ console.error(e); return false; } - } else if (fileName.endsWith('.mp4') || fileName.endsWith('.mov')) { + } else if (supportedVideoExtensions.some(ext => fileName.endsWith(ext))) { try { userUploadedFileURL = URL.createObjectURL(userFile); fileSizeToUpload = userFile.size; @@ -364,7 +365,7 @@ return false; } } else { - console.log('The uploaded file is not a .glb file.'); + console.log('The uploaded file is not a supported file.'); return false; } }; From a6c038e5b8d4141a9354b49a8af8fcf935b54a56 Mon Sep 17 00:00:00 2001 From: patnorris Date: Wed, 16 Aug 2023 17:44:11 +0200 Subject: [PATCH 05/17] Enable animated glb models --- .../assets/DownloadFileExample.html | 8 ++--- .../assets/defaultRoom.html | 36 +++++++++---------- .../assets/defaultRoom_InternetIsland.html | 4 +-- .../assets/defaultRoom_NatureRetreat.html | 36 +++++++++---------- .../assets/defaultRoom_Web3Cockpit.html | 8 ++--- .../helpers/space_helpers.js | 2 +- .../pages/CreateSpace.svelte | 2 ++ .../pages/Space.svelte | 4 +++ 8 files changed, 53 insertions(+), 47 deletions(-) diff --git a/src/PersonalWebSpace_frontend/assets/DownloadFileExample.html b/src/PersonalWebSpace_frontend/assets/DownloadFileExample.html index 1bf911d..a7cf5f5 100644 --- a/src/PersonalWebSpace_frontend/assets/DownloadFileExample.html +++ b/src/PersonalWebSpace_frontend/assets/DownloadFileExample.html @@ -20,10 +20,10 @@ - - - - + + + + diff --git a/src/PersonalWebSpace_frontend/assets/defaultRoom.html b/src/PersonalWebSpace_frontend/assets/defaultRoom.html index b07f12e..a819c9a 100644 --- a/src/PersonalWebSpace_frontend/assets/defaultRoom.html +++ b/src/PersonalWebSpace_frontend/assets/defaultRoom.html @@ -36,27 +36,27 @@ - - - - + + + + - - - - - + + + + + - - - - + + + + - - - - - + + + + + diff --git a/src/PersonalWebSpace_frontend/assets/defaultRoom_InternetIsland.html b/src/PersonalWebSpace_frontend/assets/defaultRoom_InternetIsland.html index 20af0fd..62f8ffe 100644 --- a/src/PersonalWebSpace_frontend/assets/defaultRoom_InternetIsland.html +++ b/src/PersonalWebSpace_frontend/assets/defaultRoom_InternetIsland.html @@ -20,8 +20,8 @@ - - + + diff --git a/src/PersonalWebSpace_frontend/assets/defaultRoom_NatureRetreat.html b/src/PersonalWebSpace_frontend/assets/defaultRoom_NatureRetreat.html index f62264e..7b3fbd2 100644 --- a/src/PersonalWebSpace_frontend/assets/defaultRoom_NatureRetreat.html +++ b/src/PersonalWebSpace_frontend/assets/defaultRoom_NatureRetreat.html @@ -34,27 +34,27 @@ - - - - + + + + - - - - - + + + + + - - - - + + + + - - - - - + + + + + diff --git a/src/PersonalWebSpace_frontend/assets/defaultRoom_Web3Cockpit.html b/src/PersonalWebSpace_frontend/assets/defaultRoom_Web3Cockpit.html index 3a29724..c04fb44 100644 --- a/src/PersonalWebSpace_frontend/assets/defaultRoom_Web3Cockpit.html +++ b/src/PersonalWebSpace_frontend/assets/defaultRoom_Web3Cockpit.html @@ -24,10 +24,10 @@ - - - - + + + + diff --git a/src/PersonalWebSpace_frontend/helpers/space_helpers.js b/src/PersonalWebSpace_frontend/helpers/space_helpers.js index 601f411..581caae 100644 --- a/src/PersonalWebSpace_frontend/helpers/space_helpers.js +++ b/src/PersonalWebSpace_frontend/helpers/space_helpers.js @@ -100,7 +100,7 @@ export const getStringForSpaceFromModel = (modelUrl) => { - + `; diff --git a/src/PersonalWebSpace_frontend/pages/CreateSpace.svelte b/src/PersonalWebSpace_frontend/pages/CreateSpace.svelte index 3c53ecb..d09db75 100644 --- a/src/PersonalWebSpace_frontend/pages/CreateSpace.svelte +++ b/src/PersonalWebSpace_frontend/pages/CreateSpace.svelte @@ -115,6 +115,7 @@ modelEntity.setAttribute('gltf-model', `url(${fileURL})`); modelEntity.setAttribute('position', '0 3 -6'); modelEntity.setAttribute('id', 'modelFromUserFile'); + modelEntity.setAttribute('animation-mixer', true); if (!aScene.querySelector('#modelFromUserFile')) { aScene.appendChild(modelEntity); } else { @@ -126,6 +127,7 @@ modelEntity.setAttribute('gltf-model', `url(${fileURL})`); modelEntity.setAttribute('position', '0 3 -6'); modelEntity.setAttribute('id', 'modelFromUserFile'); + modelEntity.setAttribute('animation-mixer', true); if (!aScene.querySelector('#modelFromUserFile')) { aScene.appendChild(modelEntity); } else { diff --git a/src/PersonalWebSpace_frontend/pages/Space.svelte b/src/PersonalWebSpace_frontend/pages/Space.svelte index 9a04bb6..4d648ee 100644 --- a/src/PersonalWebSpace_frontend/pages/Space.svelte +++ b/src/PersonalWebSpace_frontend/pages/Space.svelte @@ -295,6 +295,7 @@ modelEntity.setAttribute('gltf-model', `url(${userSelectedLibraryItemURL})`); modelEntity.setAttribute('position', '0 3 -6'); modelEntity.setAttribute('id', 'userAddedLibraryItem_' + Math.random().toString(36).substr(2, 9)); + modelEntity.setAttribute('animation-mixer', true); scene.appendChild(modelEntity); } catch (error) { console.error("Adding Library Item to Space Error:", error); @@ -455,6 +456,7 @@ modelEntity.setAttribute('gltf-model', `url(${fileURL})`); modelEntity.setAttribute('position', '0 3 -6'); modelEntity.setAttribute('id', 'modelFromUserFile'); + modelEntity.setAttribute('animation-mixer', true); if (!aScene.querySelector('#modelFromUserFile')) { aScene.appendChild(modelEntity); } else { @@ -466,6 +468,7 @@ modelEntity.setAttribute('gltf-model', `url(${fileURL})`); modelEntity.setAttribute('position', '0 3 -6'); modelEntity.setAttribute('id', 'modelFromUserFile'); + modelEntity.setAttribute('animation-mixer', true); if (!aScene.querySelector('#modelFromUserFile')) { aScene.appendChild(modelEntity); } else { @@ -536,6 +539,7 @@ modelEntity.setAttribute('gltf-model', `url(${fileURL})`); modelEntity.setAttribute('position', '0 3 -6'); modelEntity.setAttribute('id', 'userUploadedModel_' + fileUploadResult.Ok.FileId); + modelEntity.setAttribute('animation-mixer', true); scene.appendChild(modelEntity); } catch (error) { console.error("Adding Uploaded Model to Space Error:", error); From 9066c9c99ac58a017e834805793e6aa2c097c35c Mon Sep 17 00:00:00 2001 From: patnorris Date: Wed, 16 Aug 2023 17:48:42 +0200 Subject: [PATCH 06/17] Clean code --- .../components/ProtocolEntity.svelte | 2 +- .../components/SpaceInfo.svelte | 2 +- .../components/SpaceNeighbors.svelte | 16 ++++++++-------- .../components/UserSpace.svelte | 2 +- .../pages/CreateSpace.svelte | 2 +- src/PersonalWebSpace_frontend/pages/Space.svelte | 12 ++++++------ .../pages/Spaces.svelte | 4 ++-- 7 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/PersonalWebSpace_frontend/components/ProtocolEntity.svelte b/src/PersonalWebSpace_frontend/components/ProtocolEntity.svelte index 8dbd0e5..d170e97 100644 --- a/src/PersonalWebSpace_frontend/components/ProtocolEntity.svelte +++ b/src/PersonalWebSpace_frontend/components/ProtocolEntity.svelte @@ -36,7 +36,7 @@ errorDeletingLink = true; } } catch(err) { - console.log("Delete Link err", err); + console.error("Delete Link err", err); errorDeletingLink = true; }; }; diff --git a/src/PersonalWebSpace_frontend/components/SpaceInfo.svelte b/src/PersonalWebSpace_frontend/components/SpaceInfo.svelte index f972ebc..137ed60 100644 --- a/src/PersonalWebSpace_frontend/components/SpaceInfo.svelte +++ b/src/PersonalWebSpace_frontend/components/SpaceInfo.svelte @@ -34,7 +34,7 @@ // @ts-ignore await $store.backendActor.updateUserSpace(updateInput); // Authenticated call; only space owner may update it } catch (error) { - console.log("Error in updateUserSpace", error); + console.error("Error in updateUserSpace", error); } spaceInfoUpdateInProgress = false; }; diff --git a/src/PersonalWebSpace_frontend/components/SpaceNeighbors.svelte b/src/PersonalWebSpace_frontend/components/SpaceNeighbors.svelte index 1936908..e2cb3b9 100644 --- a/src/PersonalWebSpace_frontend/components/SpaceNeighbors.svelte +++ b/src/PersonalWebSpace_frontend/components/SpaceNeighbors.svelte @@ -108,7 +108,7 @@ errorAddingNeighbor = true; }; } catch(err) { - console.log("Create Neighbor err", err); + console.error("Create Neighbor err", err); errorAddingNeighbor = true; }; @@ -134,7 +134,7 @@ try { getBridgesResponse = await $store.protocolActor.get_from_bridge_ids_by_entity_id(spaceEntityId); } catch (error) { - console.log("Error Getting Bridges", error); + console.error("Error Getting Bridges", error); return null; }; // @ts-ignore @@ -152,7 +152,7 @@ const bridgesBetweenEntities : Bridge[] = []; for (var j = 0; j < getBridgeResponses.length; j++) { if (getBridgeResponses[j].Err) { - console.log("Error retrieving Bridge", getBridgeResponses[j].Err); + console.error("Error retrieving Bridge", getBridgeResponses[j].Err); } else { const bridge : Bridge = getBridgeResponses[j].Ok; if (bridge && bridge.id && bridge.toEntityId === neighborProtocolEntityId) { @@ -185,7 +185,7 @@ const deletionResponses = await Promise.all(requestPromises); for (var j = 0; j < deletionResponses.length; j++) { if (deletionResponses[j].Err) { - console.log("Error deleting Space Neighbor", deletionResponses[j].Err); + console.error("Error deleting Space Neighbor", deletionResponses[j].Err); return null; }; }; @@ -234,7 +234,7 @@ try { spaceNeighborsResponse = await $store.protocolActor.get_from_bridge_ids_by_entity_id(spaceEntityId); } catch (error) { - console.log("Error Getting Bridges", error); + console.error("Error Getting Bridges", error); return null; }; // @ts-ignore @@ -253,7 +253,7 @@ let getConnectedEntityRequestPromises = []; for (var j = 0; j < getBridgeResponses.length; j++) { if (getBridgeResponses[j].Err) { - console.log("Error retrieving Bridge", getBridgeResponses[j].Err); + console.error("Error retrieving Bridge", getBridgeResponses[j].Err); } else { const bridge : Bridge = getBridgeResponses[j].Ok; getConnectedEntityRequestPromises.push($store.protocolActor.get_entity(bridge.toEntityId)); // Send requests in parallel and then await all to speed up @@ -262,7 +262,7 @@ const getConnectedEntityResponses = await Promise.all(getConnectedEntityRequestPromises); for (var j = 0; j < getConnectedEntityResponses.length; j++) { if (getConnectedEntityResponses[j].Err) { - console.log("Error retrieving connected Entity", getConnectedEntityResponses[j].Err); + console.error("Error retrieving connected Entity", getConnectedEntityResponses[j].Err); } else { const connectedEntity : Entity = getConnectedEntityResponses[j].Ok; retrievedNeighborEntities.push(connectedEntity); @@ -270,7 +270,7 @@ }; }; } catch(err) { - console.log("Error getting SpaceNeighbors", err); + console.error("Error getting SpaceNeighbors", err); neighborsLoadingError = true; }; loadingInProgress = false; diff --git a/src/PersonalWebSpace_frontend/components/UserSpace.svelte b/src/PersonalWebSpace_frontend/components/UserSpace.svelte index 2ba6de2..64dcab1 100644 --- a/src/PersonalWebSpace_frontend/components/UserSpace.svelte +++ b/src/PersonalWebSpace_frontend/components/UserSpace.svelte @@ -64,7 +64,7 @@ errorCreatingLink = true; }; } catch(err) { - console.log("Link Space err", err); + console.error("Link Space err", err); errorCreatingLink = true; }; }; diff --git a/src/PersonalWebSpace_frontend/pages/CreateSpace.svelte b/src/PersonalWebSpace_frontend/pages/CreateSpace.svelte index d09db75..ca3ba7d 100644 --- a/src/PersonalWebSpace_frontend/pages/CreateSpace.svelte +++ b/src/PersonalWebSpace_frontend/pages/CreateSpace.svelte @@ -91,7 +91,7 @@ fileSizeToUpload = userFile.size; return true; } else { - console.log('The uploaded file is not a supported file.'); + console.error('The uploaded file is not a supported file.'); return false; } }; diff --git a/src/PersonalWebSpace_frontend/pages/Space.svelte b/src/PersonalWebSpace_frontend/pages/Space.svelte index 4d648ee..f7c8b0c 100644 --- a/src/PersonalWebSpace_frontend/pages/Space.svelte +++ b/src/PersonalWebSpace_frontend/pages/Space.svelte @@ -366,7 +366,7 @@ return false; } } else { - console.log('The uploaded file is not a supported file.'); + console.error('The uploaded file is not a supported file.'); return false; } }; @@ -634,7 +634,7 @@ }; newVideoAsset.addEventListener('loadeddata', loaded); } else { - console.log('The uploaded file type is not supported.'); + console.error('The uploaded file type is not supported.'); return false; }; } catch (error) { @@ -1111,7 +1111,7 @@ try { spaceNeighborsResponse = await $store.protocolActor.get_from_bridge_ids_by_entity_id(spaceEntityId); } catch (error) { - console.log("Error Getting Bridges", error); + console.error("Error Getting Bridges", error); return null; }; // @ts-ignore @@ -1130,7 +1130,7 @@ let getConnectedEntityRequestPromises = []; for (var j = 0; j < getBridgeResponses.length; j++) { if (getBridgeResponses[j].Err) { - console.log("Error retrieving Bridge", getBridgeResponses[j].Err); + console.error("Error retrieving Bridge", getBridgeResponses[j].Err); } else { const bridge : Bridge = getBridgeResponses[j].Ok; getConnectedEntityRequestPromises.push($store.protocolActor.get_entity(bridge.toEntityId)); // Send requests in parallel and then await all to speed up @@ -1139,7 +1139,7 @@ const getConnectedEntityResponses = await Promise.all(getConnectedEntityRequestPromises); for (var j = 0; j < getConnectedEntityResponses.length; j++) { if (getConnectedEntityResponses[j].Err) { - console.log("Error retrieving connected Entity", getConnectedEntityResponses[j].Err); + console.error("Error retrieving connected Entity", getConnectedEntityResponses[j].Err); } else { const connectedEntity : Entity = getConnectedEntityResponses[j].Ok; retrievedNeighborEntities.push(connectedEntity); @@ -1147,7 +1147,7 @@ }; }; } catch(err) { - console.log("Error getting SpaceNeighbors", err); + console.error("Error getting SpaceNeighbors", err); }; // Only load Neighbors if they haven't been loaded yet or reload if new Neighbors have been added diff --git a/src/PersonalWebSpace_frontend/pages/Spaces.svelte b/src/PersonalWebSpace_frontend/pages/Spaces.svelte index 29b23ca..48a1211 100644 --- a/src/PersonalWebSpace_frontend/pages/Spaces.svelte +++ b/src/PersonalWebSpace_frontend/pages/Spaces.svelte @@ -89,7 +89,7 @@ // const loginButton = document.querySelector('#login-button'); if(!loginButton) { setTimeout(() => { - console.log("Login button - Delayed for 1 second."); + //console.log("Login button - Delayed for 1 second."); loadLoginButton(); }, 1000); } else { @@ -103,7 +103,7 @@ ); if(!editButton) { setTimeout(() => { - console.log("Edit button - Delayed for 1 second."); + //console.log("Edit button - Delayed for 1 second."); loadEditButton(); }, 1000); } else { From 6b9e6c08cde28cf12c1452e9ab3669783bb3457e Mon Sep 17 00:00:00 2001 From: patnorris Date: Wed, 16 Aug 2023 18:18:12 +0200 Subject: [PATCH 07/17] Enhance findings from testing --- src/PersonalWebSpace_backend/main.mo | 6 +-- .../pages/CreateSpace.svelte | 48 +++++++++---------- src/PersonalWebSpace_frontend/store.ts | 4 +- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/PersonalWebSpace_backend/main.mo b/src/PersonalWebSpace_backend/main.mo index 22ba71a..75c7e97 100644 --- a/src/PersonalWebSpace_backend/main.mo +++ b/src/PersonalWebSpace_backend/main.mo @@ -739,9 +739,9 @@ shared actor class PersonalWebSpace(custodian: Principal, init : Types.Dip721Non */ // 1 MB is the max size for a single file let oneMB : Nat = 1048576; // 1 MB -private let maxFileSize : Nat = oneMB; -private let maxTotalSize : Nat = 10 * oneMB; -private let maxFiles : Nat = 10; +private let maxFileSize : Nat = 2 * oneMB; +private let maxTotalSize : Nat = 25 * oneMB; +private let maxFiles : Nat = 15; // A simple file storage database which stores a unique file ID in the form of a 128 bit (16 byte) UUID as // defined by RFC 4122 diff --git a/src/PersonalWebSpace_frontend/pages/CreateSpace.svelte b/src/PersonalWebSpace_frontend/pages/CreateSpace.svelte index ca3ba7d..1ccbfcc 100644 --- a/src/PersonalWebSpace_frontend/pages/CreateSpace.svelte +++ b/src/PersonalWebSpace_frontend/pages/CreateSpace.svelte @@ -282,30 +282,6 @@

Spaces Ready For You:

- -

Your Web Space Station

- - {#if !$store.isAuthed} - -

{loginSubtext}

- {:else} - {#if isSpaceCreationInProgress} - - {#if spaceToCreate === "defaultspace/0"} -

{inProgressSubtext}

- {/if} - {:else if wasSpaceCreatedSuccessfully} - - {#if spaceToCreate === "defaultspace/0"} -

{createdSubtext}

- {:else} -

{clickDefaultSubtext}

- {/if} - {:else} - -

{clickDefaultSubtext}

- {/if} - {/if}

Your Nature Retreat

@@ -354,6 +330,30 @@

{clickDefaultSubtext}

{/if} {/if} + +

Your Web Space Station

+ + {#if !$store.isAuthed} + +

{loginSubtext}

+ {:else} + {#if isSpaceCreationInProgress} + + {#if spaceToCreate === "defaultspace/0"} +

{inProgressSubtext}

+ {/if} + {:else if wasSpaceCreatedSuccessfully} + + {#if spaceToCreate === "defaultspace/0"} +

{createdSubtext}

+ {:else} +

{clickDefaultSubtext}

+ {/if} + {:else} + +

{clickDefaultSubtext}

+ {/if} + {/if}

Create Your Space With an Uploaded Item:

diff --git a/src/PersonalWebSpace_frontend/store.ts b/src/PersonalWebSpace_frontend/store.ts index cc53509..30e1f9c 100644 --- a/src/PersonalWebSpace_frontend/store.ts +++ b/src/PersonalWebSpace_frontend/store.ts @@ -50,8 +50,8 @@ if (process.env.DFX_NETWORK === "ic") { }; let authClient : AuthClient; -const APPLICATION_NAME = "DeVinci"; -const APPLICATION_LOGO_URL = "https://vdfyi-uaaaa-aaaai-acptq-cai.ic0.app/favicon.ico"; //TODO: change to faviconFutureWebInitiative (once deployed with OIM) +const APPLICATION_NAME = "Open Internet Metaverse"; +const APPLICATION_LOGO_URL = "https://vdfyi-uaaaa-aaaai-acptq-cai.ic0.app/faviconFutureWebInitiative.ico"; //"https%3A%2F%2Fx6occ%2Dbiaaa%2Daaaai%2Dacqzq%2Dcai.icp0.io%2Ffavicon.ico" //"https%3A%2F%2Fx6occ-biaaa-aaaai-acqzq-cai.icp0.io%2FFutureWebInitiative%5Fimg.png"; const AUTH_PATH = "/authenticate/?applicationName="+APPLICATION_NAME+"&applicationLogo="+APPLICATION_LOGO_URL+"#authorize"; From eaba94b9da503e269b141c7f8581483b7e7aa328 Mon Sep 17 00:00:00 2001 From: patnorris Date: Tue, 22 Aug 2023 00:36:06 +0200 Subject: [PATCH 08/17] Rewrite Readme and restructure notes --- README.md | 108 ++++++++++-------- notes/CanisterCyclesNotes.md | 16 +++ .../DevelopmentNotes.md | 0 .../NotesOnLocalDev.md | 0 4 files changed, 74 insertions(+), 50 deletions(-) create mode 100644 notes/CanisterCyclesNotes.md rename DevelopmentNotes.md => notes/DevelopmentNotes.md (100%) rename NotesOnLocalDev.md => notes/NotesOnLocalDev.md (100%) diff --git a/README.md b/README.md index bf7e85f..67f1eca 100644 --- a/README.md +++ b/README.md @@ -1,43 +1,53 @@ -# PersonalWebSpace +# Open Internet Metaverse (OIM) +Welcome to the next frontier of the Internet: A decentralized, user-centric, 3D metaverse powered by the Internet Computer. -Welcome to your new PersonalWebSpace project and to the internet computer development community. By default, creating a new project adds this README and some template files to your project directory. You can edit these template files to customize your project and to include your own code to speed up the development cycle. +## Overview +The Open Internet Metaverse (OIM) is not just a vision; it's live and operational on the Internet Computer. Our platform derives its name from the foundational belief that the Internet itself is already a Metaverse. OIM takes this vision further, creating a 3D Web experience where users can build, own, and navigate "Webspaces" — 3D Web pages that render interactive scenes right from their browsers. -To get started, you might want to explore the project directory structure and the default configuration file. Working with this project in your development environment will not affect any production deployment or identity tokens. +### Try the OIM App +[Experience OIM Live!](https://vdfyi-uaaaa-aaaai-acptq-cai.ic0.app/) -To learn more before you start working with PersonalWebSpace, see the following documentation available online: +### As a user +If you like, take a look at our [User Guide](./resources/user_guide.md) -- [Quick Start](https://sdk.dfinity.org/docs/quickstart/quickstart-intro.html) -- [SDK Developer Tools](https://sdk.dfinity.org/docs/developers-guide/sdk-guide.html) -- [Motoko Programming Language Guide](https://sdk.dfinity.org/docs/language-guide/motoko.html) -- [Motoko Language Quick Reference](https://sdk.dfinity.org/docs/language-guide/language-manual.html) -- [JavaScript API Reference](https://erxue-5aaaa-aaaab-qaagq-cai.raw.ic0.app) +### As a developer +If you like, take a look at our [Integration Guide](./resources/integration_guide.md) -If you want to start working on your project right away, you might want to try the following commands: +## Features +- Fully Operational on the Internet Computer: Experience the metaverse today, live on the Internet Computer. -```bash -cd PersonalWebSpace/ -dfx help -dfx canister --help -``` +- User-centric Webspaces: Create your virtual spaces, host them like Websites on the Internet Computer, but in 3D. Embed objects, images, videos, and more. Make it your personal corner of the 3D Web. -## Running the project locally +- Virtual Neighborhoods: Link your space to others', forming a connected, expansive, and personalized virtual neighborhood within the greater Metaverse (or simply, as we like to think of it, the Internet). + +- Decentralized & Open: An environment that ensures the metaverse remains open, free, and not under the control of any one entity. + +- Compatibility: Seamlessly integrates with current Web technologies, ensuring developers have a familiar ground. +- Built with A-Frame: OIM leverages A-Frame, a Web framework for building 3D mixed reality experiences. + +# Development & Deployment +## Running the project locally If you want to test your project locally, you can use the following commands: +1. Install dependencies ```bash - -# 1. Install dependencies npm install +``` +2. Install Vessel which is a dependency: https://github.com/dfinity/vessel -# 2. Install Vessel which is a dependency -https://github.com/dfinity/vessel: - +3. Start the local replica +```bash npm run dev +``` Note: this starts a replica which includes the canisters state stored from previous sessions. -If you want to start a clean local IC replica (i.e. all canister state is erased) run instead: npm run erase-replica +If you want to start a clean local IC replica (i.e. all canister state is erased) run instead: +```bash +npm run erase-replica +``` -# 3. Deploys your canisters to the replica and generates your candid interface -Local: +4. Deploy your canisters to the replica +```bash dfx deploy --argument "( principal\"$(dfx identity get-principal)\", record { @@ -50,30 +60,35 @@ dfx deploy --argument "( maxLimit = 65535; } )" PersonalWebSpace_backend -dfx deploy ---> access frontend at http://localhost:4943/?canisterId=ryjl3-tyaaa-aaaaa-aaaba-cai -access routes like so http://localhost:4943/?canisterId=ryjl3-tyaaa-aaaaa-aaaba-cai#/testroom +dfx deploy +``` +--> Access frontend at http://localhost:4943/?canisterId=ryjl3-tyaaa-aaaaa-aaaba-cai +Access routes like so http://localhost:4943/?canisterId=ryjl3-tyaaa-aaaaa-aaaba-cai#/testroom or http://localhost:4943/?canisterId=ryjl3-tyaaa-aaaaa-aaaba-cai#/space/0 (for space with spaceid 0) -needs to be redeployed after every change to reflect changes +Needs to be redeployed after every change to reflect changes -# Alternative 3. Run a local vite UI (note that this had issues communicating to the backend canister for some setups in the past) +Alternative: Run a local vite UI (note that this had issues communicating to the backend canister for some setups in the past) +```bash npm run vite +``` --> runs on port 3000 -access routes like "http://172.30.141.44:3000/#/testroom" (same as on Mainnet) -hot reloads with every UI change +Access routes like "http://172.30.141.44:3000/#/testroom" (same as on Mainnet) +Hot reloads with every UI change For more detailed notes on running this locally, also see NotesOnLocalDev.md -# Production Deployment +## Deployment to the Internet Computer +```bash npm install dfx start --background +``` Deploy to Mainnet (live IC): Ensure that all changes needed for Mainnet deployment have been made (e.g. define HOST in store.ts) - +```bash dfx deploy --network ic --argument "( principal\"$(dfx identity get-principal)\", record { @@ -86,10 +101,13 @@ dfx deploy --network ic --argument "( maxLimit = 65535; } )" PersonalWebSpace_backend + dfx deploy --network ic +``` In case there are authentication issues, you could try this command -Note that only authorized identities which are set up as canister controllers may deploy the production canisters +(Note that only authorized identities which are set up as canister controllers may deploy the production canisters) +```bash dfx deploy --network ic --wallet "$(dfx identity --network ic get-wallet)" --argument "( principal\"$(dfx identity get-principal)\", record { @@ -102,16 +120,19 @@ dfx deploy --network ic --wallet "$(dfx identity --network ic get-wallet)" --arg maxLimit = 65535; } )" PersonalWebSpace_backend + dfx deploy --network ic --wallet "$(dfx identity --network ic get-wallet)" +``` -# Get and delete Email Subscribers +# Additional Notes +## Get and delete Email Subscribers dfx canister call PersonalWebSpace_backend getEmailSubscribers dfx canister call PersonalWebSpace_backend deleteEmailSubscriber 'j@g.com' dfx canister call PersonalWebSpace_backend getEmailSubscribers --network ic dfx canister call PersonalWebSpace_backend deleteEmailSubscriber 'j@g.com' --network ic -# Cycles for Production Canisters +## Cycles for Production Canisters Fund wallet with cycles (from ICP): https://medium.com/dfinity/internet-computer-basics-part-3-funding-a-cycles-wallet-a724efebd111 Top up cycles: @@ -122,22 +143,9 @@ dfx canister --network ic status PersonalWebSpace_frontend dfx canister --network ic --wallet 3v5vy-2aaaa-aaaai-aapla-cai deposit-cycles 3000000000000 PersonalWebSpace_backend dfx canister --network ic --wallet 3v5vy-2aaaa-aaaai-aapla-cai deposit-cycles 300000000000 PersonalWebSpace_frontend -2023-02-16: - topped up 7T cycles each for new balances: - PersonalWebSpace_backend Balance: 10_896_387_427_956 Cycles (2023-03-06: 10.895, 2023-07-05: 10_882_246_216_265) - PersonalWebSpace_frontend Balance: 10_220_358_949_308 Cycles (2023-03-06: 10.079, 2023-07-05: 9_481_199_655_794) - -### Note on frontend environment variables - -If you are hosting frontend code somewhere without using DFX, you may need to make one of the following adjustments to ensure your project does not fetch the root key in production: - -- set`NODE_ENV` to `production` if you are using Webpack -- use your own preferred method to replace `process.env.NODE_ENV` in the autogenerated declarations -- Write your own `createActor` constructor - ## Web Space NFT format For details, see Types.mo in PersonalWebSpace_backend - NFT looks like: + Space NFT looks like: { owner: Principal; id: TokenId; diff --git a/notes/CanisterCyclesNotes.md b/notes/CanisterCyclesNotes.md new file mode 100644 index 0000000..5a04466 --- /dev/null +++ b/notes/CanisterCyclesNotes.md @@ -0,0 +1,16 @@ +# Cycles for Mainnet Canisters +Fund wallet with cycles (from ICP): https://medium.com/dfinity/internet-computer-basics-part-3-funding-a-cycles-wallet-a724efebd111 + +## Top up cycles: +dfx identity --network=ic get-wallet +dfx wallet --network ic balance +dfx canister --network ic status PersonalWebSpace_backend +dfx canister --network ic status PersonalWebSpace_frontend +dfx canister --network ic --wallet 3v5vy-2aaaa-aaaai-aapla-cai deposit-cycles 3000000000000 PersonalWebSpace_backend +dfx canister --network ic --wallet 3v5vy-2aaaa-aaaai-aapla-cai deposit-cycles 300000000000 PersonalWebSpace_frontend + +## Top up history +2023-02-16: + topped up 7T cycles each for new balances: + PersonalWebSpace_backend Balance: 10_896_387_427_956 Cycles (2023-03-06: 10.895, 2023-07-05: 10_882_246_216_265) + PersonalWebSpace_frontend Balance: 10_220_358_949_308 Cycles (2023-03-06: 10.079, 2023-07-05: 9_481_199_655_794) \ No newline at end of file diff --git a/DevelopmentNotes.md b/notes/DevelopmentNotes.md similarity index 100% rename from DevelopmentNotes.md rename to notes/DevelopmentNotes.md diff --git a/NotesOnLocalDev.md b/notes/NotesOnLocalDev.md similarity index 100% rename from NotesOnLocalDev.md rename to notes/NotesOnLocalDev.md From 5d516774a40b98f01a14696f1cccd9b6eca51acd Mon Sep 17 00:00:00 2001 From: patnorris Date: Tue, 22 Aug 2023 00:40:19 +0200 Subject: [PATCH 09/17] Fix reference in Readme to notes --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 67f1eca..3da69b3 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ npm run vite Access routes like "http://172.30.141.44:3000/#/testroom" (same as on Mainnet) Hot reloads with every UI change -For more detailed notes on running this locally, also see NotesOnLocalDev.md +For more detailed notes on running this locally, also see [NotesOnLocalDev.md](./notes/NotesOnLocalDev.md) ## Deployment to the Internet Computer ```bash From dedaf3099fa940fce341ace8f2dc4ea59f865691 Mon Sep 17 00:00:00 2001 From: patnorris Date: Tue, 22 Aug 2023 00:42:54 +0200 Subject: [PATCH 10/17] Fix commands formatting --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 3da69b3..bccc62c 100644 --- a/README.md +++ b/README.md @@ -126,22 +126,26 @@ dfx deploy --network ic --wallet "$(dfx identity --network ic get-wallet)" # Additional Notes ## Get and delete Email Subscribers +```bash dfx canister call PersonalWebSpace_backend getEmailSubscribers dfx canister call PersonalWebSpace_backend deleteEmailSubscriber 'j@g.com' dfx canister call PersonalWebSpace_backend getEmailSubscribers --network ic dfx canister call PersonalWebSpace_backend deleteEmailSubscriber 'j@g.com' --network ic +``` ## Cycles for Production Canisters Fund wallet with cycles (from ICP): https://medium.com/dfinity/internet-computer-basics-part-3-funding-a-cycles-wallet-a724efebd111 Top up cycles: +```bash dfx identity --network=ic get-wallet dfx wallet --network ic balance dfx canister --network ic status PersonalWebSpace_backend dfx canister --network ic status PersonalWebSpace_frontend dfx canister --network ic --wallet 3v5vy-2aaaa-aaaai-aapla-cai deposit-cycles 3000000000000 PersonalWebSpace_backend dfx canister --network ic --wallet 3v5vy-2aaaa-aaaai-aapla-cai deposit-cycles 300000000000 PersonalWebSpace_frontend +``` ## Web Space NFT format For details, see Types.mo in PersonalWebSpace_backend From 208b99fa7a6bd4d8c8be6f92f9771a3efb4c7e63 Mon Sep 17 00:00:00 2001 From: patnorris Date: Fri, 25 Aug 2023 15:14:51 +0200 Subject: [PATCH 11/17] Add space metadata field --- src/PersonalWebSpace_backend/Types.mo | 1 + src/PersonalWebSpace_backend/main.mo | 13 +++++-------- .../components/SpaceInfo.svelte | 18 +++++++++++++----- .../helpers/space_helpers.js | 6 +++--- .../PersonalWebSpace_backend.did | 1 + .../PersonalWebSpace_backend.did.d.ts | 1 + .../PersonalWebSpace_backend.did.js | 1 + .../PersonalWebSpace_frontend.did | 16 ++++++++++++++++ .../PersonalWebSpace_frontend.did.d.ts | 13 +++++++++++++ .../PersonalWebSpace_frontend.did.js | 17 +++++++++++++++++ 10 files changed, 71 insertions(+), 16 deletions(-) diff --git a/src/PersonalWebSpace_backend/Types.mo b/src/PersonalWebSpace_backend/Types.mo index bdcbf75..aef16a7 100644 --- a/src/PersonalWebSpace_backend/Types.mo +++ b/src/PersonalWebSpace_backend/Types.mo @@ -107,6 +107,7 @@ module { updatedOwnerContactInfo: Text; updatedSpaceDescription: Text; updatedSpaceName: Text; + updatedAboutDescription : Text; updatedSpaceData: ?Text; }; diff --git a/src/PersonalWebSpace_backend/main.mo b/src/PersonalWebSpace_backend/main.mo index e022454..b0da1a4 100644 --- a/src/PersonalWebSpace_backend/main.mo +++ b/src/PersonalWebSpace_backend/main.mo @@ -446,10 +446,6 @@ shared actor class PersonalWebSpace(custodian: Principal, init : Types.Dip721Non }; // assemble updated space data, then update nfts list // create placeholder objects... - var aboutDescriptionObject = { - key = "aboutDescription"; - val: Types.MetadataVal = #TextContent "This is my flaming hot Personal Web Space. Enjoy!"; - }; var creatorObject = { key = "creator"; val: Types.MetadataVal = #PrincipalContent caller; @@ -464,9 +460,7 @@ shared actor class PersonalWebSpace(custodian: Principal, init : Types.Dip721Non }; // ... and fill them with space's current data for (i in token.metadata[0].key_val_data.keys()) { - if (token.metadata[0].key_val_data[i].key == "aboutDescription") { - aboutDescriptionObject := token.metadata[0].key_val_data[i]; // currently not used, thus remains unchanged - } else if (token.metadata[0].key_val_data[i].key == "creator") { + if (token.metadata[0].key_val_data[i].key == "creator") { creatorObject := token.metadata[0].key_val_data[i]; // should always remain unchanged } else if (token.metadata[0].key_val_data[i].key == "creationTime") { creationTimeObject := token.metadata[0].key_val_data[i]; // should always remain unchanged @@ -484,7 +478,10 @@ shared actor class PersonalWebSpace(custodian: Principal, init : Types.Dip721Non key = "ownerContactInfo"; val = #TextContent (updatedUserSpaceData.updatedOwnerContactInfo); }, - aboutDescriptionObject, + { + key = "aboutDescription"; + val = #TextContent (updatedUserSpaceData.updatedAboutDescription); + }, { key = "spaceDescription"; val = #TextContent (updatedUserSpaceData.updatedSpaceDescription); diff --git a/src/PersonalWebSpace_frontend/components/SpaceInfo.svelte b/src/PersonalWebSpace_frontend/components/SpaceInfo.svelte index 7df12bc..1974544 100644 --- a/src/PersonalWebSpace_frontend/components/SpaceInfo.svelte +++ b/src/PersonalWebSpace_frontend/components/SpaceInfo.svelte @@ -15,12 +15,13 @@ let updatedOwnerContactInfo : string = spaceMetadata.ownerContactInfo; let updatedSpaceDescription : string = spaceMetadata.spaceDescription; let updatedSpaceName : string = spaceMetadata.spaceName; + let updatedAboutDescription : string = spaceMetadata.aboutDescription; // User submitted form to update Space Info let spaceInfoUpdateInProgress = false; const submitUpdateSpaceInfoForm = async () => { - console.log("in submitUpdateSpaceInfoForm spaceMetadata", spaceMetadata); + console.log("Debug in submitUpdateSpaceInfoForm spaceMetadata", spaceMetadata); spaceInfoUpdateInProgress = true; // Write space's updated metadata to backend canister (HTML stays the same) let updateInput = { @@ -30,16 +31,17 @@ updatedOwnerContactInfo, updatedSpaceDescription, updatedSpaceName, + updatedAboutDescription, }; - console.log("in submitUpdateSpaceInfoForm updateInput", updateInput); + console.log("Debug in submitUpdateSpaceInfoForm updateInput", updateInput); try { // @ts-ignore await $store.backendActor.updateUserSpace(updateInput); // Authenticated call; only space owner may update it } catch (error) { - console.log("Error in updateUserSpace", error); + console.error("Error in updateUserSpace", error); } spaceInfoUpdateInProgress = false; - console.log("in submitUpdateSpaceInfoForm after"); + console.log("Debug in submitUpdateSpaceInfoForm after"); }; @@ -64,6 +66,12 @@ placeholder={updatedOwnerName} class="spaceInfoInput text-black font-bold" /> +

About Owner:

+

Owner Contact Info:

Space Creation Time: {spaceMetadata.creationTime}

Owner Principal: {spaceMetadata.spaceOwnerPrincipal}

Owner Name: {updatedOwnerName}

+

About Owner: {updatedAboutDescription}

Owner Contact Info: {updatedOwnerContactInfo}

- {/if} diff --git a/src/PersonalWebSpace_frontend/helpers/space_helpers.js b/src/PersonalWebSpace_frontend/helpers/space_helpers.js index 2101bfd..b17470f 100644 --- a/src/PersonalWebSpace_frontend/helpers/space_helpers.js +++ b/src/PersonalWebSpace_frontend/helpers/space_helpers.js @@ -123,9 +123,9 @@ export const extractSpaceMetadata = (spaceNft, targetObject, forUpdatingSpace = targetObject.updatedOwnerName = spaceNft.metadata[0].key_val_data[j].val.TextContent; } else if (fieldKey === "ownerContactInfo") { targetObject.updatedOwnerContactInfo = spaceNft.metadata[0].key_val_data[j].val.TextContent; - } /* else if (fieldKey === "aboutDescription") { - targetObject.updatedOwnerContactInfo = spaceNft.metadata[0].key_val_data[j].val.TextContent; - } */; + } else if (fieldKey === "aboutDescription") { + targetObject.updatedAboutDescription = spaceNft.metadata[0].key_val_data[j].val.TextContent; + }; }; } else { for (var j = 0; j < spaceNft.metadata[0].key_val_data.length; j++) { diff --git a/src/declarations/PersonalWebSpace_backend/PersonalWebSpace_backend.did b/src/declarations/PersonalWebSpace_backend/PersonalWebSpace_backend.did index 9359259..f179a62 100644 --- a/src/declarations/PersonalWebSpace_backend/PersonalWebSpace_backend.did +++ b/src/declarations/PersonalWebSpace_backend/PersonalWebSpace_backend.did @@ -6,6 +6,7 @@ type UserRecord = type UpdateMetadataValuesInput = record { id: TokenId; + updatedAboutDescription: text; updatedOwnerContactInfo: text; updatedOwnerName: text; updatedSpaceData: opt text; diff --git a/src/declarations/PersonalWebSpace_backend/PersonalWebSpace_backend.did.d.ts b/src/declarations/PersonalWebSpace_backend/PersonalWebSpace_backend.did.d.ts index fb9c558..c32734b 100644 --- a/src/declarations/PersonalWebSpace_backend/PersonalWebSpace_backend.did.d.ts +++ b/src/declarations/PersonalWebSpace_backend/PersonalWebSpace_backend.did.d.ts @@ -162,6 +162,7 @@ export interface UpdateMetadataValuesInput { 'id' : TokenId, 'updatedSpaceDescription' : string, 'updatedOwnerName' : string, + 'updatedAboutDescription' : string, 'updatedOwnerContactInfo' : string, 'updatedSpaceData' : [] | [string], 'updatedSpaceName' : string, diff --git a/src/declarations/PersonalWebSpace_backend/PersonalWebSpace_backend.did.js b/src/declarations/PersonalWebSpace_backend/PersonalWebSpace_backend.did.js index 82dbd77..fb1836a 100644 --- a/src/declarations/PersonalWebSpace_backend/PersonalWebSpace_backend.did.js +++ b/src/declarations/PersonalWebSpace_backend/PersonalWebSpace_backend.did.js @@ -130,6 +130,7 @@ export const idlFactory = ({ IDL }) => { 'id' : TokenId, 'updatedSpaceDescription' : IDL.Text, 'updatedOwnerName' : IDL.Text, + 'updatedAboutDescription' : IDL.Text, 'updatedOwnerContactInfo' : IDL.Text, 'updatedSpaceData' : IDL.Opt(IDL.Text), 'updatedSpaceName' : IDL.Text, diff --git a/src/declarations/PersonalWebSpace_frontend/PersonalWebSpace_frontend.did b/src/declarations/PersonalWebSpace_frontend/PersonalWebSpace_frontend.did index 508bda6..c4f659e 100644 --- a/src/declarations/PersonalWebSpace_frontend/PersonalWebSpace_frontend.did +++ b/src/declarations/PersonalWebSpace_frontend/PersonalWebSpace_frontend.did @@ -109,6 +109,18 @@ type SetAssetPropertiesArguments = record { is_aliased: opt opt bool; }; +type ConfigurationResponse = record { + max_batches: opt nat64; + max_chunks: opt nat64; + max_bytes: opt nat64; +}; + +type ConfigureArguments = record { + max_batches: opt opt nat64; + max_chunks: opt opt nat64; + max_bytes: opt opt nat64; +}; + type Permission = variant { Commit; ManagePermissions; @@ -221,8 +233,12 @@ service: { is_aliased: opt bool; } ) query; set_asset_properties: (SetAssetPropertiesArguments) -> (); + get_configuration: () -> (ConfigurationResponse); + configure: (ConfigureArguments) -> (); + validate_grant_permission: (GrantPermission) -> (ValidationResult); validate_revoke_permission: (RevokePermission) -> (ValidationResult); validate_take_ownership: () -> (ValidationResult); validate_commit_proposed_batch: (CommitProposedBatchArguments) -> (ValidationResult); + validate_configure: (ConfigureArguments) -> (ValidationResult); } diff --git a/src/declarations/PersonalWebSpace_frontend/PersonalWebSpace_frontend.did.d.ts b/src/declarations/PersonalWebSpace_frontend/PersonalWebSpace_frontend.did.d.ts index d5bc1a4..ad645fa 100644 --- a/src/declarations/PersonalWebSpace_frontend/PersonalWebSpace_frontend.did.d.ts +++ b/src/declarations/PersonalWebSpace_frontend/PersonalWebSpace_frontend.did.d.ts @@ -24,6 +24,16 @@ export interface ComputeEvidenceArguments { 'batch_id' : BatchId, 'max_iterations' : [] | [number], } +export interface ConfigurationResponse { + 'max_batches' : [] | [bigint], + 'max_bytes' : [] | [bigint], + 'max_chunks' : [] | [bigint], +} +export interface ConfigureArguments { + 'max_batches' : [] | [[] | [bigint]], + 'max_bytes' : [] | [[] | [bigint]], + 'max_chunks' : [] | [[] | [bigint]], +} export interface CreateAssetArguments { 'key' : Key, 'content_type' : string, @@ -114,6 +124,7 @@ export interface _SERVICE { [ComputeEvidenceArguments], [] | [Uint8Array | number[]] >, + 'configure' : ActorMethod<[ConfigureArguments], undefined>, 'create_asset' : ActorMethod<[CreateAssetArguments], undefined>, 'create_batch' : ActorMethod<[{}], { 'batch_id' : BatchId }>, 'create_chunk' : ActorMethod< @@ -153,6 +164,7 @@ export interface _SERVICE { ], { 'content' : Uint8Array | number[] } >, + 'get_configuration' : ActorMethod<[], ConfigurationResponse>, 'grant_permission' : ActorMethod<[GrantPermission], undefined>, 'http_request' : ActorMethod<[HttpRequest], HttpResponse>, 'http_request_streaming_callback' : ActorMethod< @@ -203,6 +215,7 @@ export interface _SERVICE { [CommitProposedBatchArguments], ValidationResult >, + 'validate_configure' : ActorMethod<[ConfigureArguments], ValidationResult>, 'validate_grant_permission' : ActorMethod< [GrantPermission], ValidationResult diff --git a/src/declarations/PersonalWebSpace_frontend/PersonalWebSpace_frontend.did.js b/src/declarations/PersonalWebSpace_frontend/PersonalWebSpace_frontend.did.js index d390f7c..31ef5ce 100644 --- a/src/declarations/PersonalWebSpace_frontend/PersonalWebSpace_frontend.did.js +++ b/src/declarations/PersonalWebSpace_frontend/PersonalWebSpace_frontend.did.js @@ -50,7 +50,17 @@ export const idlFactory = ({ IDL }) => { 'batch_id' : BatchId, 'max_iterations' : IDL.Opt(IDL.Nat16), }); + const ConfigureArguments = IDL.Record({ + 'max_batches' : IDL.Opt(IDL.Opt(IDL.Nat64)), + 'max_bytes' : IDL.Opt(IDL.Opt(IDL.Nat64)), + 'max_chunks' : IDL.Opt(IDL.Opt(IDL.Nat64)), + }); const DeleteBatchArguments = IDL.Record({ 'batch_id' : BatchId }); + const ConfigurationResponse = IDL.Record({ + 'max_batches' : IDL.Opt(IDL.Nat64), + 'max_bytes' : IDL.Opt(IDL.Nat64), + 'max_chunks' : IDL.Opt(IDL.Nat64), + }); const Permission = IDL.Variant({ 'Prepare' : IDL.Null, 'ManagePermissions' : IDL.Null, @@ -121,6 +131,7 @@ export const idlFactory = ({ IDL }) => { [IDL.Opt(IDL.Vec(IDL.Nat8))], [], ), + 'configure' : IDL.Func([ConfigureArguments], [], []), 'create_asset' : IDL.Func([CreateAssetArguments], [], []), 'create_batch' : IDL.Func( [IDL.Record({})], @@ -172,6 +183,7 @@ export const idlFactory = ({ IDL }) => { [IDL.Record({ 'content' : IDL.Vec(IDL.Nat8) })], ['query'], ), + 'get_configuration' : IDL.Func([], [ConfigurationResponse], []), 'grant_permission' : IDL.Func([GrantPermission], [], []), 'http_request' : IDL.Func([HttpRequest], [HttpResponse], ['query']), 'http_request_streaming_callback' : IDL.Func( @@ -229,6 +241,11 @@ export const idlFactory = ({ IDL }) => { [ValidationResult], [], ), + 'validate_configure' : IDL.Func( + [ConfigureArguments], + [ValidationResult], + [], + ), 'validate_grant_permission' : IDL.Func( [GrantPermission], [ValidationResult], From b34c84d55990ae56f1fecf2131beffc47ce7bac8 Mon Sep 17 00:00:00 2001 From: patnorris Date: Fri, 25 Aug 2023 15:38:51 +0200 Subject: [PATCH 12/17] Finalize merge --- README.md | 464 +- canister_ids.json | 26 +- dfx.json | 108 +- notes/NotesOnLocalDev.md | 129 +- NotesOnStages.md => notes/NotesOnStages.md | 34 +- package-lock.json | 5002 ++++++++--------- src/PersonalWebSpace_backend/main.mo | 2226 ++++---- .../components/BitfinityButton.svelte | 74 +- .../components/LoginModal.svelte | 40 +- .../components/NfidButton.svelte | 78 +- .../components/PlugButton.svelte | 74 +- .../components/ProtocolEntity.svelte | 168 +- .../components/SpaceInfo.svelte | 244 +- .../components/SpaceNeighbors.svelte | 750 +-- .../components/StoicButton.svelte | 78 +- .../components/UserSpace.svelte | 266 +- .../pages/CreateSpace.svelte | 810 +-- .../pages/Space.svelte | 2974 +++++----- .../pages/Spaces.svelte | 248 +- src/PersonalWebSpace_frontend/store.ts | 1088 ++-- .../PersonalWebSpace_backend.did | 488 +- .../PersonalWebSpace_backend.did.d.ts | 344 +- .../PersonalWebSpace_backend.did.js | 416 +- src/integrations/BebbProtocol/bebb.did | 372 +- src/integrations/BebbProtocol/bebb.did.d.ts | 280 +- src/integrations/BebbProtocol/bebb.did.js | 332 +- src/integrations/BebbProtocol/index.d.ts | 100 +- src/integrations/BebbProtocol/index.js | 124 +- .../BebbProtocol/index_newwave.d.ts | 100 +- .../BebbProtocol/index_newwave.js | 74 +- vite.config.ts | 226 +- 31 files changed, 8869 insertions(+), 8868 deletions(-) rename NotesOnStages.md => notes/NotesOnStages.md (99%) diff --git a/README.md b/README.md index 1be49f8..dd22658 100644 --- a/README.md +++ b/README.md @@ -1,231 +1,233 @@ -# Open Internet Metaverse (OIM) -Welcome to the next frontier of the Internet: A decentralized, user-centric, 3D metaverse powered by the Internet Computer. - -## Overview -The Open Internet Metaverse (OIM) is not just a vision; it's live and operational on the Internet Computer. Our platform derives its name from the foundational belief that the Internet itself is already a Metaverse. OIM takes this vision further, creating a 3D Web experience where users can build, own, and navigate "Webspaces" — 3D Web pages that render interactive scenes right from their browsers. - -### Try the OIM App -[Experience OIM Live!](https://vdfyi-uaaaa-aaaai-acptq-cai.ic0.app/) - -### As a user -If you like, take a look at our [User Guide](./resources/user_guide.md) - -### As a developer -If you like, take a look at our [Integration Guide](./resources/integration_guide.md) - -## Features -- Fully Operational on the Internet Computer: Experience the metaverse today, live on the Internet Computer. - -- User-centric Webspaces: Create your virtual spaces, host them like Websites on the Internet Computer, but in 3D. Embed objects, images, videos, and more. Make it your personal corner of the 3D Web. - -- Virtual Neighborhoods: Link your space to others', forming a connected, expansive, and personalized virtual neighborhood within the greater Metaverse (or simply, as we like to think of it, the Internet). - -- Decentralized & Open: An environment that ensures the metaverse remains open, free, and not under the control of any one entity. - -- Compatibility: Seamlessly integrates with current Web technologies, ensuring developers have a familiar ground. - -- Built with A-Frame: OIM leverages A-Frame, a Web framework for building 3D mixed reality experiences. - -# Development & Deployment -## Running the project locally -If you want to test your project locally, you can use the following commands: - -1. Install dependencies -```bash -npm install -``` -2. Install Vessel which is a dependency: https://github.com/dfinity/vessel - -3. Start the local replica -```bash -npm run dev -``` -Note: this starts a replica which includes the canisters state stored from previous sessions. -If you want to start a clean local IC replica (i.e. all canister state is erased) run instead: -```bash -npm run erase-replica -``` - -4. Deploy your canisters to the replica -```bash -dfx deploy --argument "( - principal\"$(dfx identity get-principal)\", - record { - logo = record { - logo_type = \"image/png\"; - data = \"\"; - }; - name = \"PersonalWebSpace\"; - symbol = \"PWS\"; - maxLimit = 65535; - } -)" PersonalWebSpace_backend - -dfx deploy -``` ---> Access frontend at http://localhost:4943/?canisterId=ryjl3-tyaaa-aaaaa-aaaba-cai -Access routes like so http://localhost:4943/?canisterId=ryjl3-tyaaa-aaaaa-aaaba-cai#/testroom -or http://localhost:4943/?canisterId=ryjl3-tyaaa-aaaaa-aaaba-cai#/space/0 (for space with spaceid 0) - -Needs to be redeployed after every change to reflect changes - -Alternative: Run a local vite UI (note that this had issues communicating to the backend canister for some setups in the past) -```bash -npm run vite -``` ---> runs on port 3000 -Access routes like "http://172.30.141.44:3000/#/testroom" (same as on Mainnet) -Hot reloads with every UI change - -For more detailed notes on running this locally, also see [NotesOnLocalDev.md](./notes/NotesOnLocalDev.md) - -## Deployment to the Internet Computer -```bash -npm install - -dfx start --background -``` - -Deploy to Mainnet (live IC): -Ensure that all changes needed for Mainnet deployment have been made (e.g. define HOST in store.ts) -```bash - -Development Canisters: -dfx deploy --network development --argument "( - principal\"$(dfx identity get-principal)\", - record { - logo = record { - logo_type = \"image/png\"; - data = \"\"; - }; - name = \"PersonalWebSpace\"; - symbol = \"PWS\"; - maxLimit = 65535; - } -)" PersonalWebSpace_backend -dfx deploy --network development PersonalWebSpace_frontend - -Testing Canisters: -dfx deploy --network testing --argument "( - principal\"$(dfx identity get-principal)\", - record { - logo = record { - logo_type = \"image/png\"; - data = \"\"; - }; - name = \"PersonalWebSpace\"; - symbol = \"PWS\"; - maxLimit = 65535; - } -)" PersonalWebSpace_backend -dfx deploy --network testing PersonalWebSpace_frontend - -Production Canisters: -dfx deploy --network ic --argument "( - principal\"$(dfx identity get-principal)\", - record { - logo = record { - logo_type = \"image/png\"; - data = \"\"; - }; - name = \"PersonalWebSpace\"; - symbol = \"PWS\"; - maxLimit = 65535; - } -)" PersonalWebSpace_backend - -dfx deploy --network ic -``` - -In case there are authentication issues, you could try this command -(Note that only authorized identities which are set up as canister controllers may deploy the production canisters) -```bash -dfx deploy --network ic --wallet "$(dfx identity --network ic get-wallet)" --argument "( - principal\"$(dfx identity get-principal)\", - record { - logo = record { - logo_type = \"image/png\"; - data = \"\"; - }; - name = \"PersonalWebSpace\"; - symbol = \"PWS\"; - maxLimit = 65535; - } -)" PersonalWebSpace_backend - -dfx deploy --network ic --wallet "$(dfx identity --network ic get-wallet)" -``` - -# Additional Notes -## Get and delete Email Subscribers -```bash -dfx canister call PersonalWebSpace_backend getEmailSubscribers -dfx canister call PersonalWebSpace_backend deleteEmailSubscriber 'j@g.com' - -dfx canister call PersonalWebSpace_backend getEmailSubscribers --network ic -dfx canister call PersonalWebSpace_backend deleteEmailSubscriber 'j@g.com' --network ic -``` - -## Cycles for Production Canisters -Fund wallet with cycles (from ICP): https://medium.com/dfinity/internet-computer-basics-part-3-funding-a-cycles-wallet-a724efebd111 - -Top up cycles: -```bash -dfx identity --network=ic get-wallet -dfx wallet --network ic balance -dfx canister --network ic status PersonalWebSpace_backend -dfx canister --network ic status PersonalWebSpace_frontend -dfx canister --network ic --wallet 3v5vy-2aaaa-aaaai-aapla-cai deposit-cycles 3000000000000 PersonalWebSpace_backend -dfx canister --network ic --wallet 3v5vy-2aaaa-aaaai-aapla-cai deposit-cycles 300000000000 PersonalWebSpace_frontend -``` - -## Web Space NFT format -For details, see Types.mo in PersonalWebSpace_backend - Space NFT looks like: - { - owner: Principal; - id: TokenId; - metadata: MetadataDesc; - } - - Types.MetadataDesc for this project looks like: - [ - { - purpose: #Rendered ; - data: spaceAsHtmlTextBlob // Text.encodeUtf8(spaceAsHtmlText) to get Blob from Text (probably change to spaceAsJsonFormattedTextBlob later) - key_val_data: [ - { - key = "ownerName"; - val = #TextContent ownerName; - }, - { - key = "ownerContactInfo"; - val = #TextContent ownerContactInfo; - }, - { - key = "aboutDescription"; - val = #TextContent aboutDescription; - }, - { - key = "spaceDescription"; - val = #TextContent spaceDescription; - }, - { - key = "spaceName"; - val = #TextContent spaceName; - }, - { - key = "creator"; - val: #PrincipalContent caller; - }, - { - key = "creationTime"; - val = #Nat64Content generatedTimestamp; - }, - { - key = "protocolEntityId"; - val = #TextContent protocolEntityId; - }, - ]; - } - ] +# Open Internet Metaverse (OIM) +Welcome to the next frontier of the Internet: A decentralized, user-centric, 3D metaverse powered by the Internet Computer. + +## Overview +The Open Internet Metaverse (OIM) is not just a vision; it's live and operational on the Internet Computer. Our platform derives its name from the foundational belief that the Internet itself is already a Metaverse. OIM takes this vision further, creating a 3D Web experience where users can build, own, and navigate "Webspaces" — 3D Web pages that render interactive scenes right from their browsers. + +### Try the OIM App +[Experience OIM Live!](https://vdfyi-uaaaa-aaaai-acptq-cai.ic0.app/) + +### As a user +If you like, take a look at our [User Guide](./resources/user_guide.md) + +### As a developer +If you like, take a look at our [Integration Guide](./resources/integration_guide.md) + +## Features +- Fully Operational on the Internet Computer: Experience the metaverse today, live on the Internet Computer. + +- User-centric Webspaces: Create your virtual spaces, host them like Websites on the Internet Computer, but in 3D. Embed objects, images, videos, and more. Make it your personal corner of the 3D Web. + +- Virtual Neighborhoods: Link your space to others', forming a connected, expansive, and personalized virtual neighborhood within the greater Metaverse (or simply, as we like to think of it, the Internet). + +- Decentralized & Open: An environment that ensures the metaverse remains open, free, and not under the control of any one entity. + +- Compatibility: Seamlessly integrates with current Web technologies, ensuring developers have a familiar ground. + +- Built with A-Frame: OIM leverages A-Frame, a Web framework for building 3D mixed reality experiences. + +# Development & Deployment +## Running the project locally +If you want to test your project locally, you can use the following commands: + +1. Install dependencies +```bash +npm install +``` +2. Install Vessel which is a dependency: https://github.com/dfinity/vessel + +3. Start the local replica +```bash +npm run dev +``` +Note: this starts a replica which includes the canisters state stored from previous sessions. +If you want to start a clean local IC replica (i.e. all canister state is erased) run instead: +```bash +npm run erase-replica +``` + +4. Deploy your canisters to the replica +```bash +dfx deploy --argument "( + principal\"$(dfx identity get-principal)\", + record { + logo = record { + logo_type = \"image/png\"; + data = \"\"; + }; + name = \"PersonalWebSpace\"; + symbol = \"PWS\"; + maxLimit = 65535; + } +)" PersonalWebSpace_backend + +dfx deploy +``` +--> Access frontend at http://localhost:4943/?canisterId=ryjl3-tyaaa-aaaaa-aaaba-cai +Access routes like so http://localhost:4943/?canisterId=ryjl3-tyaaa-aaaaa-aaaba-cai#/testroom +or http://localhost:4943/?canisterId=ryjl3-tyaaa-aaaaa-aaaba-cai#/space/0 (for space with spaceid 0) + +Needs to be redeployed after every change to reflect changes + +Alternative: Run a local vite UI (note that this had issues communicating to the backend canister for some setups in the past) +```bash +npm run vite +``` +--> runs on port 3000 +Access routes like "http://172.30.141.44:3000/#/testroom" (same as on Mainnet) +Hot reloads with every UI change + +For more detailed notes on running this locally, also see [NotesOnLocalDev.md](./notes/NotesOnLocalDev.md) + +## Deployment to the Internet Computer +```bash +npm install + +dfx start --background +``` + +Deploy to Mainnet (live IC): +Ensure that all changes needed for Mainnet deployment have been made (e.g. define HOST in store.ts) + +Development Canisters: +```bash +dfx deploy --network development --argument "( + principal\"$(dfx identity get-principal)\", + record { + logo = record { + logo_type = \"image/png\"; + data = \"\"; + }; + name = \"PersonalWebSpace\"; + symbol = \"PWS\"; + maxLimit = 65535; + } +)" PersonalWebSpace_backend +dfx deploy --network development PersonalWebSpace_frontend +``` +Testing Canisters: +```bash +dfx deploy --network testing --argument "( + principal\"$(dfx identity get-principal)\", + record { + logo = record { + logo_type = \"image/png\"; + data = \"\"; + }; + name = \"PersonalWebSpace\"; + symbol = \"PWS\"; + maxLimit = 65535; + } +)" PersonalWebSpace_backend +dfx deploy --network testing PersonalWebSpace_frontend +``` +Production Canisters: +```bash +dfx deploy --network ic --argument "( + principal\"$(dfx identity get-principal)\", + record { + logo = record { + logo_type = \"image/png\"; + data = \"\"; + }; + name = \"PersonalWebSpace\"; + symbol = \"PWS\"; + maxLimit = 65535; + } +)" PersonalWebSpace_backend + +dfx deploy --network ic +``` + +In case there are authentication issues, you could try this command +(Note that only authorized identities which are set up as canister controllers may deploy the production canisters) +```bash +dfx deploy --network ic --wallet "$(dfx identity --network ic get-wallet)" --argument "( + principal\"$(dfx identity get-principal)\", + record { + logo = record { + logo_type = \"image/png\"; + data = \"\"; + }; + name = \"PersonalWebSpace\"; + symbol = \"PWS\"; + maxLimit = 65535; + } +)" PersonalWebSpace_backend + +dfx deploy --network ic --wallet "$(dfx identity --network ic get-wallet)" +``` + +# Additional Notes +## Get and delete Email Subscribers +```bash +dfx canister call PersonalWebSpace_backend getEmailSubscribers +dfx canister call PersonalWebSpace_backend deleteEmailSubscriber 'j@g.com' + +dfx canister call PersonalWebSpace_backend getEmailSubscribers --network ic +dfx canister call PersonalWebSpace_backend deleteEmailSubscriber 'j@g.com' --network ic +``` + +## Cycles for Production Canisters +Fund wallet with cycles (from ICP): https://medium.com/dfinity/internet-computer-basics-part-3-funding-a-cycles-wallet-a724efebd111 + +Top up cycles: +```bash +dfx identity --network=ic get-wallet +dfx wallet --network ic balance +dfx canister --network ic status PersonalWebSpace_backend +dfx canister --network ic status PersonalWebSpace_frontend +dfx canister --network ic --wallet 3v5vy-2aaaa-aaaai-aapla-cai deposit-cycles 3000000000000 PersonalWebSpace_backend +dfx canister --network ic --wallet 3v5vy-2aaaa-aaaai-aapla-cai deposit-cycles 300000000000 PersonalWebSpace_frontend +``` + +## Web Space NFT format +For details, see Types.mo in PersonalWebSpace_backend + Space NFT looks like: + { + owner: Principal; + id: TokenId; + metadata: MetadataDesc; + } + + Types.MetadataDesc for this project looks like: + [ + { + purpose: #Rendered ; + data: spaceAsHtmlTextBlob // Text.encodeUtf8(spaceAsHtmlText) to get Blob from Text (probably change to spaceAsJsonFormattedTextBlob later) + key_val_data: [ + { + key = "ownerName"; + val = #TextContent ownerName; + }, + { + key = "ownerContactInfo"; + val = #TextContent ownerContactInfo; + }, + { + key = "aboutDescription"; + val = #TextContent aboutDescription; + }, + { + key = "spaceDescription"; + val = #TextContent spaceDescription; + }, + { + key = "spaceName"; + val = #TextContent spaceName; + }, + { + key = "creator"; + val: #PrincipalContent caller; + }, + { + key = "creationTime"; + val = #Nat64Content generatedTimestamp; + }, + { + key = "protocolEntityId"; + val = #TextContent protocolEntityId; + }, + ]; + } + ] diff --git a/canister_ids.json b/canister_ids.json index 3c94700..fa2555b 100644 --- a/canister_ids.json +++ b/canister_ids.json @@ -1,14 +1,14 @@ -{ - "PersonalWebSpace_backend": { - "ic": "vee64-zyaaa-aaaai-acpta-cai", - "local": "vee64-zyaaa-aaaai-acpta-cai", - "development": "5pd2u-2aaaa-aaaal-acv2a-cai", - "testing": "zmsq5-4yaaa-aaaap-qblra-cai" - }, - "PersonalWebSpace_frontend": { - "ic": "vdfyi-uaaaa-aaaai-acptq-cai", - "local": "vdfyi-uaaaa-aaaai-acptq-cai", - "development": "c5rfj-tqaaa-aaaan-qd5qq-cai", - "testing": "556gz-nyaaa-aaaak-qcjka-cai" - } +{ + "PersonalWebSpace_backend": { + "ic": "vee64-zyaaa-aaaai-acpta-cai", + "local": "vee64-zyaaa-aaaai-acpta-cai", + "development": "5pd2u-2aaaa-aaaal-acv2a-cai", + "testing": "zmsq5-4yaaa-aaaap-qblra-cai" + }, + "PersonalWebSpace_frontend": { + "ic": "vdfyi-uaaaa-aaaai-acptq-cai", + "local": "vdfyi-uaaaa-aaaai-acptq-cai", + "development": "c5rfj-tqaaa-aaaan-qd5qq-cai", + "testing": "556gz-nyaaa-aaaak-qcjka-cai" + } } \ No newline at end of file diff --git a/dfx.json b/dfx.json index 699334f..4cb1a3f 100644 --- a/dfx.json +++ b/dfx.json @@ -1,55 +1,55 @@ -{ - "canisters": { - "PersonalWebSpace_backend": { - "main": "src/PersonalWebSpace_backend/main.mo", - "type": "motoko" - }, - "bebbprotocol": { - "type": "custom", - "candid": "src/integrations/BebbProtocol/bebb.did", - "wasm": "src/integrations/BebbProtocol/bebb.wasm", - "remote": { - "candid": "src/integrations/BebbProtocol/bebb.did", - "id": { - "ic": "pzrof-pyaaa-aaaai-acnha-cai", - "local": "br5f7-7uaaa-aaaaa-qaaca-cai", - "development": "tsmol-tqaaa-aaaag-abt2a-cai", - "testing": "t6nyb-faaaa-aaaal-qcbaa-cai" - } - } - }, - "PersonalWebSpace_frontend": { - "dependencies": [ - "PersonalWebSpace_backend" - ], - "frontend": { - "entrypoint": "dist/index.html" - }, - "source": [ - "dist/" - ], - "type": "assets" - } - }, - "defaults": { - "build": { - "packtool": "vessel sources", - "args": "" - } - }, - "networks": { - "development": { - "providers": [ - "https://icp0.io" - ], - "type": "persistent" - }, - "testing": { - "providers": [ - "https://icp0.io" - ], - "type": "persistent" - } - }, - "version": 1 +{ + "canisters": { + "PersonalWebSpace_backend": { + "main": "src/PersonalWebSpace_backend/main.mo", + "type": "motoko" + }, + "bebbprotocol": { + "type": "custom", + "candid": "src/integrations/BebbProtocol/bebb.did", + "wasm": "src/integrations/BebbProtocol/bebb.wasm", + "remote": { + "candid": "src/integrations/BebbProtocol/bebb.did", + "id": { + "ic": "pzrof-pyaaa-aaaai-acnha-cai", + "local": "br5f7-7uaaa-aaaaa-qaaca-cai", + "development": "tsmol-tqaaa-aaaag-abt2a-cai", + "testing": "t6nyb-faaaa-aaaal-qcbaa-cai" + } + } + }, + "PersonalWebSpace_frontend": { + "dependencies": [ + "PersonalWebSpace_backend" + ], + "frontend": { + "entrypoint": "dist/index.html" + }, + "source": [ + "dist/" + ], + "type": "assets" + } + }, + "defaults": { + "build": { + "packtool": "vessel sources", + "args": "" + } + }, + "networks": { + "development": { + "providers": [ + "https://icp0.io" + ], + "type": "persistent" + }, + "testing": { + "providers": [ + "https://icp0.io" + ], + "type": "persistent" + } + }, + "version": 1 } \ No newline at end of file diff --git a/notes/NotesOnLocalDev.md b/notes/NotesOnLocalDev.md index 7ba8b42..6845e2c 100644 --- a/notes/NotesOnLocalDev.md +++ b/notes/NotesOnLocalDev.md @@ -1,65 +1,64 @@ -There are three files where I added a comment like Local vs Mainnet Development -For the two UI files, those parts are responsible for the UI communicating with the local backend (IC replica running the canisters including the backend canister) - -There might be issues with my setup as I'm running the Linux subsystem on Windows, so when I run npm run vite it gives me -Local: http://localhost:3000/ -Network: http://172.30.141.44:3000/ -but http://localhost:3000/ doesn't work for me -you could try uncommenting the block comment for the proxy in vite.config.ts (right under the comment with Local vs Mainnet Development) and see if that works for you - -Currently http://172.29.55.198:3000/ from the hot reloading npm run vite is able to access the backend cansiter. The system seems to be able to call the replica and load rooms from the canisters. To get it to work you need to run npm run dev which starts the backend canister, the downside is that the hot relating links will call the deployed canisters from npm run dev which means that those pages are not hot reloading. But at least the calls work - - -Working with the UI spun up by npm run vite has the advantage that it supports hot reloading for changes made to the UI so one doesn't need to redeploy on every UI change. -that's not the case for the UI canister spun up with -dfx deploy --argument "( - principal\"$(dfx identity get-principal)\", - record { - logo = record { - logo_type = \"image/png\"; - data = \"\"; - }; - name = \"PersonalWebSpace\"; - symbol = \"PWS\"; - maxLimit = 65535; - } -)" -after running that command you get sth like -Deployed canisters. -URLs: - Frontend canister via browser - PersonalWebSpace_frontend: http://127.0.0.1:4943/?canisterId=ryjl3-tyaaa-aaaaa-aaaba-cai - Backend canister via Candid interface: - PersonalWebSpace_backend: http://127.0.0.1:4943/?canisterId=r7inp-6aaaa-aaaaa-aaabq-cai&id=rrkah-fqaaa-aaaaa-aaaaq-cai -http://127.0.0.1:4943/?canisterId=ryjl3-tyaaa-aaaaa-aaaba-cai doesn't work properly for me either (calls to the backend are also rejected) but http://localhost:4943/?canisterId=ryjl3-tyaaa-aaaaa-aaaba-cai actually works (which usually should be the same as far as I know but it might be that my Linux subsystem setup messes this up) -thus, http://localhost:4943/?canisterId=ryjl3-tyaaa-aaaaa-aaaba-cai can also call the backend successfully -creating a space still fails though as the local IC replica doesn't have the protocol canister running (which our backend uses). We could comment out the call to the protocol canister from the backend canister though (see comment with Local vs Mainnet Development in main.mo). -After commenting out the protocol call, the call to create a space is successful. Note that the preview shown in the section My Spaces points to the mainnet UI canister (i.e. doesn't show the local canisters). To see the local canister go to http://localhost:4943/?canisterId=ryjl3-tyaaa-aaaaa-aaaba-cai#/space/0 (might need to refresh to work). -for accessing routes with this, one can use e.g. -http://localhost:4943/?canisterId=ryjl3-tyaaa-aaaaa-aaaba-cai#/testroom -the disadvantage here is that there isn't any hot reloading, so after every change one has to redeploy the canisters with -dfx deploy --argument "( - principal\"$(dfx identity get-principal)\", - record { - logo = record { - logo_type = \"image/png\"; - data = \"\"; - }; - name = \"PersonalWebSpace\"; - symbol = \"PWS\"; - maxLimit = 65535; - } -)" - -Running Bebb Protocol locally: -This project's dfx.json specifies Bebb Protocol as a remote canister (i.e. can be used by project's canisters locally but isn't built as it relies on the remote canister being deployed to the local replica from another project). It's canister bebbprotocol. The files for the integration (wasm, did, js, ts) need to be copied over to the integrations/BebbProtocol folder manually if changed. -Clone Bebb Protocol's repo: https://github.com/Bebb-Protocol-and-Apps/BebbProtocol -And use the latest version (e.g. 0.0.4 as of 2023-07) -Go to OIM's codebase (where the file you're reading is in) -Start a local replica in this project (OIM) -Deploy this project's canisters, PersonalWebSpace_backend and PersonalWebSpace_frontend, see deploy command in README (after these steps the following canister ids should be assigned: PersonalWebSpace_backend canister id: rrkah-fqaaa-aaaaa-aaaaq-cai; PersonalWebSpace_frontend canister id: ryjl3-tyaaa-aaaaa-aaaba-cai) -Go to the folder with Bebb Protocol's latest version and run dfx deploy there (this creates the local Bebb Protocol canister on the local replica started earlier which is thus the same replica this project's canisters are running on) -Make sure the local canister id for the deployed Bebb Protocol canister is br5f7-7uaaa-aaaaa-qaaca-cai (required by this project to make the calls on the local replica) -This project's canisters should now successfully call the locally deployed Bebb Protocol canister (i.e. all functionality works, same as on mainnet) -Test via npm run vite - +There are three files where I added a comment like Local vs Mainnet Development +For the two UI files, those parts are responsible for the UI communicating with the local backend (IC replica running the canisters including the backend canister) + +There might be issues with my setup as I'm running the Linux subsystem on Windows, so when I run npm run vite it gives me +Local: http://localhost:3000/ +Network: http://172.30.141.44:3000/ +but http://localhost:3000/ doesn't work for me +you could try uncommenting the block comment for the proxy in vite.config.ts (right under the comment with Local vs Mainnet Development) and see if that works for you + +Currently http://172.29.55.198:3000/ from the hot reloading npm run vite is able to access the backend cansiter. The system seems to be able to call the replica and load rooms from the canisters. To get it to work you need to run npm run dev which starts the backend canister, the downside is that the hot relating links will call the deployed canisters from npm run dev which means that those pages are not hot reloading. But at least the calls work + +Working with the UI spun up by npm run vite has the advantage that it supports hot reloading for changes made to the UI so one doesn't need to redeploy on every UI change. +that's not the case for the UI canister spun up with +dfx deploy --argument "( + principal\"$(dfx identity get-principal)\", + record { + logo = record { + logo_type = \"image/png\"; + data = \"\"; + }; + name = \"PersonalWebSpace\"; + symbol = \"PWS\"; + maxLimit = 65535; + } +)" +after running that command you get sth like +Deployed canisters. +URLs: + Frontend canister via browser + PersonalWebSpace_frontend: http://127.0.0.1:4943/?canisterId=ryjl3-tyaaa-aaaaa-aaaba-cai + Backend canister via Candid interface: + PersonalWebSpace_backend: http://127.0.0.1:4943/?canisterId=r7inp-6aaaa-aaaaa-aaabq-cai&id=rrkah-fqaaa-aaaaa-aaaaq-cai +http://127.0.0.1:4943/?canisterId=ryjl3-tyaaa-aaaaa-aaaba-cai doesn't work properly for me either (calls to the backend are also rejected) but http://localhost:4943/?canisterId=ryjl3-tyaaa-aaaaa-aaaba-cai actually works (which usually should be the same as far as I know but it might be that my Linux subsystem setup messes this up) +thus, http://localhost:4943/?canisterId=ryjl3-tyaaa-aaaaa-aaaba-cai can also call the backend successfully +creating a space still fails though as the local IC replica doesn't have the protocol canister running (which our backend uses). We could comment out the call to the protocol canister from the backend canister though (see comment with Local vs Mainnet Development in main.mo). +After commenting out the protocol call, the call to create a space is successful. Note that the preview shown in the section My Spaces points to the mainnet UI canister (i.e. doesn't show the local canisters). To see the local canister go to http://localhost:4943/?canisterId=ryjl3-tyaaa-aaaaa-aaaba-cai#/space/0 (might need to refresh to work). +for accessing routes with this, one can use e.g. +http://localhost:4943/?canisterId=ryjl3-tyaaa-aaaaa-aaaba-cai#/testroom +the disadvantage here is that there isn't any hot reloading, so after every change one has to redeploy the canisters with +dfx deploy --argument "( + principal\"$(dfx identity get-principal)\", + record { + logo = record { + logo_type = \"image/png\"; + data = \"\"; + }; + name = \"PersonalWebSpace\"; + symbol = \"PWS\"; + maxLimit = 65535; + } +)" + +Running Bebb Protocol locally: +This project's dfx.json specifies Bebb Protocol as a remote canister (i.e. can be used by project's canisters locally but isn't built as it relies on the remote canister being deployed to the local replica from another project). It's canister bebbprotocol. The files for the integration (wasm, did, js, ts) need to be copied over to the integrations/BebbProtocol folder manually if changed. +Clone Bebb Protocol's repo: https://github.com/Bebb-Protocol-and-Apps/BebbProtocol +And use the latest version (e.g. 0.0.4 as of 2023-07) +Go to OIM's codebase (where the file you're reading is in) +Start a local replica in this project (OIM) +Deploy this project's canisters, PersonalWebSpace_backend and PersonalWebSpace_frontend, see deploy command in README (after these steps the following canister ids should be assigned: PersonalWebSpace_backend canister id: rrkah-fqaaa-aaaaa-aaaaq-cai; PersonalWebSpace_frontend canister id: ryjl3-tyaaa-aaaaa-aaaba-cai) +Go to the folder with Bebb Protocol's latest version and run dfx deploy there (this creates the local Bebb Protocol canister on the local replica started earlier which is thus the same replica this project's canisters are running on) +Make sure the local canister id for the deployed Bebb Protocol canister is br5f7-7uaaa-aaaaa-qaaca-cai (required by this project to make the calls on the local replica) +This project's canisters should now successfully call the locally deployed Bebb Protocol canister (i.e. all functionality works, same as on mainnet) +Test via npm run vite + diff --git a/NotesOnStages.md b/notes/NotesOnStages.md similarity index 99% rename from NotesOnStages.md rename to notes/NotesOnStages.md index 1bbcd4c..654a200 100644 --- a/NotesOnStages.md +++ b/notes/NotesOnStages.md @@ -1,18 +1,18 @@ -For development and testing, additional stages have been created, i.e. canisters live on the mainnet. - -Process to create another stage: -Initial reference: https://medium.com/@Catalyze.One/working-with-environments-on-the-internet-computer-59ed3d2a5763 -Go to https://nns.ic0.app/ and log in -From the burger menu, choose My Canisters -Click on Create Canister and follow the creation flow (note that you need ICP to pay for the creation and charge the canister with cycles), you may start with 3T cycles (and can top up later) -Click on the new canister and then on Add Controller -Go to your local CLI and run: dfx identity get-principal -Copy the principal returned and paste it into the Add Controller field on the nns app, continue and confirm -Copy the id of the new canister -Paste the canister's id in the file canister_ids.json (under the new entry for the stage, the entry's ket needs to match the network name given in dfx.json) -Create a new networks entry in dfx.json (with the network's name being the same key as given in canister_ids.json) -If there are multiple canisters for a stage, create as many canisters as needed (e.g. PersonalWebSpace_backend and PersonalWebSpace_frontend) -Add the CLI command/s in Readme for the new stage (with the correct network name) -Make sure that all code relevant for stages/networks has been changed (e.g. search for network and check all relevant results in the project files) -Run the new CLI command/s in Readme and make sure everything works as expected (just just deploy the new canister/s) +For development and testing, additional stages have been created, i.e. canisters live on the mainnet. + +Process to create another stage: +Initial reference: https://medium.com/@Catalyze.One/working-with-environments-on-the-internet-computer-59ed3d2a5763 +Go to https://nns.ic0.app/ and log in +From the burger menu, choose My Canisters +Click on Create Canister and follow the creation flow (note that you need ICP to pay for the creation and charge the canister with cycles), you may start with 3T cycles (and can top up later) +Click on the new canister and then on Add Controller +Go to your local CLI and run: dfx identity get-principal +Copy the principal returned and paste it into the Add Controller field on the nns app, continue and confirm +Copy the id of the new canister +Paste the canister's id in the file canister_ids.json (under the new entry for the stage, the entry's ket needs to match the network name given in dfx.json) +Create a new networks entry in dfx.json (with the network's name being the same key as given in canister_ids.json) +If there are multiple canisters for a stage, create as many canisters as needed (e.g. PersonalWebSpace_backend and PersonalWebSpace_frontend) +Add the CLI command/s in Readme for the new stage (with the correct network name) +Make sure that all code relevant for stages/networks has been changed (e.g. search for network and check all relevant results in the project files) +Run the new CLI command/s in Readme and make sure everything works as expected (just just deploy the new canister/s) If you have any other projects depending on the canisters or that the canisters depend on, make sure to handle this accordingly (e.g. Bebb Protocol canisters: create a corresponding stage canister there and deploy it, make sure the canisters here reference that canister then for the correct stage, e.g. in dfx.json and look for Different Stages in motoko files) \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index ffcb9b1..4165b56 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,2501 +1,2501 @@ -{ - "name": "PersonalWebSpace_frontend", - "version": "0.1.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@alloc/quick-lru": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", - "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", - "dev": true - }, - "@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "requires": { - "@jridgewell/trace-mapping": "0.3.9" - } - }, - "@dfinity/agent": { - "version": "0.15.6", - "resolved": "https://registry.npmjs.org/@dfinity/agent/-/agent-0.15.6.tgz", - "integrity": "sha512-Ch+tXAszPap0zwRgr/oFEgJLDld4RDwBdFDqR1JUg38xhHWTFMrTkjMT6uQFvqf6d2wDXnh3zwhqbg5P7OCv7A==", - "requires": { - "base64-arraybuffer": "^0.2.0", - "bignumber.js": "^9.0.0", - "borc": "^2.1.1", - "js-sha256": "0.9.0", - "simple-cbor": "^0.4.1", - "ts-node": "^10.8.2" - } - }, - "@dfinity/auth-client": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/@dfinity/auth-client/-/auth-client-0.15.7.tgz", - "integrity": "sha512-f6cRqXayCf+7+9gNcDnAZZwJrgBYKIzfxjxeRLlpsueQeo+E/BX2yVSANxzTkCNc4U3p+ttHI1RNtasLunYTcA==", - "requires": { - "idb": "^7.0.2" - } - }, - "@dfinity/authentication": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/@dfinity/authentication/-/authentication-0.14.2.tgz", - "integrity": "sha512-kiZrRKUOnbseTQiAh4GDkAo5vCX6dUN1jkqJ5rLBYkIiGuK3jENxbu4G5oJPxq57F/cgnR4Hx/abSVHQfFRkEw==", - "requires": { - "@dfinity/identity": "^0.15.1" - } - }, - "@dfinity/candid": { - "version": "0.15.6", - "resolved": "https://registry.npmjs.org/@dfinity/candid/-/candid-0.15.6.tgz", - "integrity": "sha512-Q9PGvhTE/1dTLfSo0pu0+ifzA7NA4X1rgSy9TE6O1Glk6Kl8Nf+Pg2sCHS2hWt0RAiKfR2glEVlbUAm6S8vRxA==", - "requires": { - "ts-node": "^10.8.2" - } - }, - "@dfinity/identity": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/@dfinity/identity/-/identity-0.15.7.tgz", - "integrity": "sha512-kBAkx9wq78jSQf6T5aayLyWm8YgtOZw8bW6+OuzX6tR3hkAEa85A9TcKA7BjkmMWSIskjEDVQub4fFfKWS2vOQ==", - "requires": { - "borc": "^2.1.1", - "js-sha256": "^0.9.0", - "tweetnacl": "^1.0.1" - } - }, - "@dfinity/principal": { - "version": "0.15.6", - "resolved": "https://registry.npmjs.org/@dfinity/principal/-/principal-0.15.6.tgz", - "integrity": "sha512-eMsS5YofRk5Hm6LlhzyBvw1RzDxM5FWPtepQuYeZbZyD/ztq4TrUiScqoKBFw/LLODd0znt8rGnNgqtt+7JnQA==", - "requires": { - "js-sha256": "^0.9.0", - "ts-node": "^10.8.2" - } - }, - "@esbuild/android-arm": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.17.tgz", - "integrity": "sha512-wHsmJG/dnL3OkpAcwbgoBTTMHVi4Uyou3F5mf58ZtmUyIKfcdA7TROav/6tCzET4A3QW2Q2FC+eFneMU+iyOxg==", - "dev": true, - "optional": true - }, - "@esbuild/android-arm64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.17.tgz", - "integrity": "sha512-9np+YYdNDed5+Jgr1TdWBsozZ85U1Oa3xW0c7TWqH0y2aGghXtZsuT8nYRbzOMcl0bXZXjOGbksoTtVOlWrRZg==", - "dev": true, - "optional": true - }, - "@esbuild/android-x64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.17.tgz", - "integrity": "sha512-O+FeWB/+xya0aLg23hHEM2E3hbfwZzjqumKMSIqcHbNvDa+dza2D0yLuymRBQQnC34CWrsJUXyH2MG5VnLd6uw==", - "dev": true, - "optional": true - }, - "@esbuild/darwin-arm64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.17.tgz", - "integrity": "sha512-M9uJ9VSB1oli2BE/dJs3zVr9kcCBBsE883prage1NWz6pBS++1oNn/7soPNS3+1DGj0FrkSvnED4Bmlu1VAE9g==", - "dev": true, - "optional": true - }, - "@esbuild/darwin-x64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.17.tgz", - "integrity": "sha512-XDre+J5YeIJDMfp3n0279DFNrGCXlxOuGsWIkRb1NThMZ0BsrWXoTg23Jer7fEXQ9Ye5QjrvXpxnhzl3bHtk0g==", - "dev": true, - "optional": true - }, - "@esbuild/freebsd-arm64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.17.tgz", - "integrity": "sha512-cjTzGa3QlNfERa0+ptykyxs5A6FEUQQF0MuilYXYBGdBxD3vxJcKnzDlhDCa1VAJCmAxed6mYhA2KaJIbtiNuQ==", - "dev": true, - "optional": true - }, - "@esbuild/freebsd-x64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.17.tgz", - "integrity": "sha512-sOxEvR8d7V7Kw8QqzxWc7bFfnWnGdaFBut1dRUYtu+EIRXefBc/eIsiUiShnW0hM3FmQ5Zf27suDuHsKgZ5QrA==", - "dev": true, - "optional": true - }, - "@esbuild/linux-arm": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.17.tgz", - "integrity": "sha512-2d3Lw6wkwgSLC2fIvXKoMNGVaeY8qdN0IC3rfuVxJp89CRfA3e3VqWifGDfuakPmp90+ZirmTfye1n4ncjv2lg==", - "dev": true, - "optional": true - }, - "@esbuild/linux-arm64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.17.tgz", - "integrity": "sha512-c9w3tE7qA3CYWjT+M3BMbwMt+0JYOp3vCMKgVBrCl1nwjAlOMYzEo+gG7QaZ9AtqZFj5MbUc885wuBBmu6aADQ==", - "dev": true, - "optional": true - }, - "@esbuild/linux-ia32": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.17.tgz", - "integrity": "sha512-1DS9F966pn5pPnqXYz16dQqWIB0dmDfAQZd6jSSpiT9eX1NzKh07J6VKR3AoXXXEk6CqZMojiVDSZi1SlmKVdg==", - "dev": true, - "optional": true - }, - "@esbuild/linux-loong64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.17.tgz", - "integrity": "sha512-EvLsxCk6ZF0fpCB6w6eOI2Fc8KW5N6sHlIovNe8uOFObL2O+Mr0bflPHyHwLT6rwMg9r77WOAWb2FqCQrVnwFg==", - "dev": true, - "optional": true - }, - "@esbuild/linux-mips64el": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.17.tgz", - "integrity": "sha512-e0bIdHA5p6l+lwqTE36NAW5hHtw2tNRmHlGBygZC14QObsA3bD4C6sXLJjvnDIjSKhW1/0S3eDy+QmX/uZWEYQ==", - "dev": true, - "optional": true - }, - "@esbuild/linux-ppc64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.17.tgz", - "integrity": "sha512-BAAilJ0M5O2uMxHYGjFKn4nJKF6fNCdP1E0o5t5fvMYYzeIqy2JdAP88Az5LHt9qBoUa4tDaRpfWt21ep5/WqQ==", - "dev": true, - "optional": true - }, - "@esbuild/linux-riscv64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.17.tgz", - "integrity": "sha512-Wh/HW2MPnC3b8BqRSIme/9Zhab36PPH+3zam5pqGRH4pE+4xTrVLx2+XdGp6fVS3L2x+DrsIcsbMleex8fbE6g==", - "dev": true, - "optional": true - }, - "@esbuild/linux-s390x": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.17.tgz", - "integrity": "sha512-j/34jAl3ul3PNcK3pfI0NSlBANduT2UO5kZ7FCaK33XFv3chDhICLY8wJJWIhiQ+YNdQ9dxqQctRg2bvrMlYgg==", - "dev": true, - "optional": true - }, - "@esbuild/linux-x64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.17.tgz", - "integrity": "sha512-QM50vJ/y+8I60qEmFxMoxIx4de03pGo2HwxdBeFd4nMh364X6TIBZ6VQ5UQmPbQWUVWHWws5MmJXlHAXvJEmpQ==", - "dev": true, - "optional": true - }, - "@esbuild/netbsd-x64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.17.tgz", - "integrity": "sha512-/jGlhWR7Sj9JPZHzXyyMZ1RFMkNPjC6QIAan0sDOtIo2TYk3tZn5UDrkE0XgsTQCxWTTOcMPf9p6Rh2hXtl5TQ==", - "dev": true, - "optional": true - }, - "@esbuild/openbsd-x64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.17.tgz", - "integrity": "sha512-rSEeYaGgyGGf4qZM2NonMhMOP/5EHp4u9ehFiBrg7stH6BYEEjlkVREuDEcQ0LfIl53OXLxNbfuIj7mr5m29TA==", - "dev": true, - "optional": true - }, - "@esbuild/sunos-x64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.17.tgz", - "integrity": "sha512-Y7ZBbkLqlSgn4+zot4KUNYst0bFoO68tRgI6mY2FIM+b7ZbyNVtNbDP5y8qlu4/knZZ73fgJDlXID+ohY5zt5g==", - "dev": true, - "optional": true - }, - "@esbuild/win32-arm64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.17.tgz", - "integrity": "sha512-bwPmTJsEQcbZk26oYpc4c/8PvTY3J5/QK8jM19DVlEsAB41M39aWovWoHtNm78sd6ip6prilxeHosPADXtEJFw==", - "dev": true, - "optional": true - }, - "@esbuild/win32-ia32": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.17.tgz", - "integrity": "sha512-H/XaPtPKli2MhW+3CQueo6Ni3Avggi6hP/YvgkEe1aSaxw+AeO8MFjq8DlgfTd9Iz4Yih3QCZI6YLMoyccnPRg==", - "dev": true, - "optional": true - }, - "@esbuild/win32-x64": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.17.tgz", - "integrity": "sha512-fGEb8f2BSA3CW7riJVurug65ACLuQAzKq0SSqkY2b2yHHH0MzDfbLyKIGzHwOI/gkHcxM/leuSW6D5w/LMNitA==", - "dev": true, - "optional": true - }, - "@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==" - }, - "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" - }, - "@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@sveltejs/vite-plugin-svelte": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-2.4.3.tgz", - "integrity": "sha512-NY2h+B54KHZO3kDURTdARqthn6D4YSIebtfW75NvZ/fwyk4G+AJw3V/i0OBjyN4406Ht9yZcnNWMuRUFnDNNiA==", - "dev": true, - "requires": { - "@sveltejs/vite-plugin-svelte-inspector": "^1.0.3", - "debug": "^4.3.4", - "deepmerge": "^4.3.1", - "kleur": "^4.1.5", - "magic-string": "^0.30.1", - "svelte-hmr": "^0.15.2", - "vitefu": "^0.2.4" - } - }, - "@sveltejs/vite-plugin-svelte-inspector": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-1.0.3.tgz", - "integrity": "sha512-Khdl5jmmPN6SUsVuqSXatKpQTMIifoQPDanaxC84m9JxIibWvSABJyHpyys0Z+1yYrxY5TTEQm+6elh0XCMaOA==", - "dev": true, - "requires": { - "debug": "^4.3.4" - } - }, - "@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", - "dev": true - }, - "@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" - }, - "@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" - }, - "@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" - }, - "@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" - }, - "@tsconfig/svelte": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@tsconfig/svelte/-/svelte-3.0.0.tgz", - "integrity": "sha512-pYrtLtOwku/7r1i9AMONsJMVYAtk3hzOfiGNekhtq5tYBGA7unMve8RvUclKLMT3PrihvJqUmzsRGh0RP84hKg==", - "dev": true - }, - "@types/node": { - "version": "16.18.39", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.39.tgz", - "integrity": "sha512-8q9ZexmdYYyc5/cfujaXb4YOucpQxAV4RMG0himLyDUOEr8Mr79VrqsFI+cQ2M2h89YIuy95lbxuYjxT4Hk4kQ==", - "dev": true - }, - "@types/pug": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.6.tgz", - "integrity": "sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==", - "dev": true - }, - "acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==" - }, - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" - }, - "any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true - }, - "anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" - }, - "assert": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", - "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", - "dev": true, - "requires": { - "es6-object-assign": "^1.1.0", - "is-nan": "^1.2.1", - "object-is": "^1.0.1", - "util": "^0.12.0" - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "autoprefixer": { - "version": "10.4.14", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz", - "integrity": "sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==", - "dev": true, - "requires": { - "browserslist": "^4.21.5", - "caniuse-lite": "^1.0.30001464", - "fraction.js": "^4.2.0", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", - "postcss-value-parser": "^4.2.0" - } - }, - "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true - }, - "axios": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", - "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", - "requires": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "base64-arraybuffer": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.2.0.tgz", - "integrity": "sha512-7emyCsu1/xiBXgQZrscw/8KPRT44I4Yq9Pe6EGs3aPRTsWuggML1/1DTuZUuIaJPIm1FTDUVXl4x/yW8s0kQDQ==" - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "bignumber.js": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.1.tgz", - "integrity": "sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig==" - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true - }, - "borc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/borc/-/borc-2.1.2.tgz", - "integrity": "sha512-Sy9eoUi4OiKzq7VovMn246iTo17kzuyHJKomCfpWMlI6RpfN1gk95w7d7gH264nApVLg0HZfcpz62/g4VH1Y4w==", - "requires": { - "bignumber.js": "^9.0.0", - "buffer": "^5.5.0", - "commander": "^2.15.0", - "ieee754": "^1.1.13", - "iso-url": "~0.4.7", - "json-text-sequence": "~0.1.0", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - } - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true - }, - "browserslist": { - "version": "4.21.9", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", - "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001503", - "electron-to-chromium": "^1.4.431", - "node-releases": "^2.0.12", - "update-browserslist-db": "^1.0.11" - } - }, - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase-css": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "dev": true - }, - "caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "caniuse-lite": { - "version": "1.0.30001517", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001517.tgz", - "integrity": "sha512-Vdhm5S11DaFVLlyiKu4hiUTkpZu+y1KA/rZZqVQfOD5YdDT/eQKlkt7NaE0WGOFgX32diqt9MiP9CAiFeRklaA==", - "dev": true - }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, - "colord": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" - }, - "css-declaration-sorter": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", - "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", - "dev": true - }, - "css-line-break": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz", - "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==", - "requires": { - "utrie": "^1.0.2" - } - }, - "css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "dev": true, - "requires": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - } - }, - "css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "dev": true, - "requires": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - } - }, - "css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "dev": true - }, - "cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true - }, - "cssnano": { - "version": "5.1.15", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz", - "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", - "dev": true, - "requires": { - "cssnano-preset-default": "^5.2.14", - "lilconfig": "^2.0.3", - "yaml": "^1.10.2" - } - }, - "cssnano-preset-default": { - "version": "5.2.14", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", - "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", - "dev": true, - "requires": { - "css-declaration-sorter": "^6.3.1", - "cssnano-utils": "^3.1.0", - "postcss-calc": "^8.2.3", - "postcss-colormin": "^5.3.1", - "postcss-convert-values": "^5.1.3", - "postcss-discard-comments": "^5.1.2", - "postcss-discard-duplicates": "^5.1.0", - "postcss-discard-empty": "^5.1.1", - "postcss-discard-overridden": "^5.1.0", - "postcss-merge-longhand": "^5.1.7", - "postcss-merge-rules": "^5.1.4", - "postcss-minify-font-values": "^5.1.0", - "postcss-minify-gradients": "^5.1.1", - "postcss-minify-params": "^5.1.4", - "postcss-minify-selectors": "^5.2.1", - "postcss-normalize-charset": "^5.1.0", - "postcss-normalize-display-values": "^5.1.0", - "postcss-normalize-positions": "^5.1.1", - "postcss-normalize-repeat-style": "^5.1.1", - "postcss-normalize-string": "^5.1.0", - "postcss-normalize-timing-functions": "^5.1.0", - "postcss-normalize-unicode": "^5.1.1", - "postcss-normalize-url": "^5.1.0", - "postcss-normalize-whitespace": "^5.1.1", - "postcss-ordered-values": "^5.1.3", - "postcss-reduce-initial": "^5.1.2", - "postcss-reduce-transforms": "^5.1.0", - "postcss-svgo": "^5.1.0", - "postcss-unique-selectors": "^5.1.1" - } - }, - "cssnano-utils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", - "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", - "dev": true - }, - "csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", - "dev": true, - "requires": { - "css-tree": "^1.1.2" - } - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true - }, - "define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", - "dev": true, - "requires": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" - }, - "delimit-stream": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/delimit-stream/-/delimit-stream-0.1.0.tgz", - "integrity": "sha512-a02fiQ7poS5CnjiJBAsjGLPp5EwVoGHNeu9sziBd9huppRfsAFIpv5zNLv0V1gbop53ilngAf5Kf331AwcoRBQ==" - }, - "detect-indent": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", - "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", - "dev": true - }, - "didyoumean": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "dev": true - }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" - }, - "dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "dev": true - }, - "dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "dev": true, - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - } - }, - "domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true - }, - "domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dev": true, - "requires": { - "domelementtype": "^2.2.0" - } - }, - "domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dev": true, - "requires": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - } - }, - "electron-to-chromium": { - "version": "1.4.475", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.475.tgz", - "integrity": "sha512-mTye5u5P98kSJO2n7zYALhpJDmoSQejIGya0iR01GpoRady8eK3bw7YHHnjA1Rfi4ZSLdpuzlAC7Zw+1Zu7Z6A==", - "dev": true - }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true - }, - "es6-object-assign": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", - "integrity": "sha512-MEl9uirslVwqQU369iHNWZXsI8yaZYGg/D65aOgZkeyFJwHYSxilf7rQzXKI7DdDuBPrBXbfk3sl9hJhmd5AUw==", - "dev": true - }, - "es6-promise": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", - "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", - "dev": true - }, - "esbuild": { - "version": "0.18.17", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.17.tgz", - "integrity": "sha512-1GJtYnUxsJreHYA0Y+iQz2UEykonY66HNWOb0yXYZi9/kNrORUEHVg87eQsCtqh59PEJ5YVZJO98JHznMJSWjg==", - "dev": true, - "requires": { - "@esbuild/android-arm": "0.18.17", - "@esbuild/android-arm64": "0.18.17", - "@esbuild/android-x64": "0.18.17", - "@esbuild/darwin-arm64": "0.18.17", - "@esbuild/darwin-x64": "0.18.17", - "@esbuild/freebsd-arm64": "0.18.17", - "@esbuild/freebsd-x64": "0.18.17", - "@esbuild/linux-arm": "0.18.17", - "@esbuild/linux-arm64": "0.18.17", - "@esbuild/linux-ia32": "0.18.17", - "@esbuild/linux-loong64": "0.18.17", - "@esbuild/linux-mips64el": "0.18.17", - "@esbuild/linux-ppc64": "0.18.17", - "@esbuild/linux-riscv64": "0.18.17", - "@esbuild/linux-s390x": "0.18.17", - "@esbuild/linux-x64": "0.18.17", - "@esbuild/netbsd-x64": "0.18.17", - "@esbuild/openbsd-x64": "0.18.17", - "@esbuild/sunos-x64": "0.18.17", - "@esbuild/win32-arm64": "0.18.17", - "@esbuild/win32-ia32": "0.18.17", - "@esbuild/win32-x64": "0.18.17" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true - }, - "fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - } - }, - "fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "requires": { - "is-callable": "^1.1.3" - } - }, - "form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "fraction.js": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", - "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.3" - } - }, - "graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.1" - } - }, - "has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "dev": true - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "html2canvas": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz", - "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==", - "requires": { - "css-line-break": "^2.1.0", - "text-segmentation": "^1.0.3" - } - }, - "ic-stoic-identity": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ic-stoic-identity/-/ic-stoic-identity-2.0.0.tgz", - "integrity": "sha512-0lvtX+lWR0LaEo076SFTKYDds+WKByQZfn3iU8ap5iCgc+OEBt/g/0jHwsnH3e7tI46JLiNaxSQIp223BEj81Q==", - "dev": true, - "requires": { - "@dfinity/agent": "^0.10.0", - "@dfinity/identity": "^0.10.0", - "@dfinity/principal": "^0.10.0", - "buffer": "^6.0.3" - }, - "dependencies": { - "@dfinity/agent": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/@dfinity/agent/-/agent-0.10.4.tgz", - "integrity": "sha512-/O1443GWkQ6GngrXos/ShAbnF9IgUlWclzaQn/qEsGJIey6S7tty+iOa5yZqOS1BtOTnDe+TYh8GeERZZn7vvg==", - "dev": true, - "requires": { - "base64-arraybuffer": "^0.2.0", - "bignumber.js": "^9.0.0", - "borc": "^2.1.1", - "js-sha256": "0.9.0", - "simple-cbor": "^0.4.1" - } - }, - "@dfinity/identity": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/@dfinity/identity/-/identity-0.10.4.tgz", - "integrity": "sha512-b4WsaD70Ts75JlJcf4+E04B140hQN5u/GnCvjhaHqN2++bwWO56Paxtv0UfAc58LMwJZj4iOyZoahnT56LhC9A==", - "dev": true, - "requires": { - "borc": "^2.1.1", - "js-sha256": "^0.9.0", - "secp256k1": "^4.0.2", - "tweetnacl": "^1.0.1" - } - }, - "@dfinity/principal": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/@dfinity/principal/-/principal-0.10.4.tgz", - "integrity": "sha512-qwzpmq5wfyeKMBspRZmuYvTxu1dqN+IY0ThACHTRh6D58QjnVQNCD3Hq9d5eEDu0qyNcY22cJEWwzrzZaaoVmw==", - "dev": true - } - } - }, - "idb": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", - "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==" - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true - }, - "is-core-module": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", - "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-typed-array": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", - "dev": true, - "requires": { - "which-typed-array": "^1.1.11" - } - }, - "iso-url": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/iso-url/-/iso-url-0.4.7.tgz", - "integrity": "sha512-27fFRDnPAMnHGLq36bWTpKET+eiXct3ENlCcdcMdk+mjXrb2kw3mhBUg1B7ewAC0kVzlOPhADzQgz1SE6Tglog==" - }, - "jiti": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.19.1.tgz", - "integrity": "sha512-oVhqoRDaBXf7sjkll95LHVS6Myyyb1zaunVwk4Z0+WPSW4gjS0pl01zYKHScTuyEhQsFxV5L4DR5r+YqSyqyyg==", - "dev": true - }, - "js-sha256": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", - "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==" - }, - "json-text-sequence": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/json-text-sequence/-/json-text-sequence-0.1.1.tgz", - "integrity": "sha512-L3mEegEWHRekSHjc7+sc8eJhba9Clq1PZ8kMkzf8OxElhXc8O4TS5MwcVlj9aEbm5dr81N90WHC5nAz3UO971w==", - "requires": { - "delimit-stream": "0.1.0" - } - }, - "kleur": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", - "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", - "dev": true - }, - "lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "dev": true - }, - "lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true - }, - "lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", - "dev": true - }, - "magic-string": { - "version": "0.30.2", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.2.tgz", - "integrity": "sha512-lNZdu7pewtq/ZvWUp9Wpf/x7WzMTsR26TWV03BRZrXFsv+BI6dy8RAiKgm1uM/kyR0rCfUcqvOlXKG66KhIGug==", - "dev": true, - "requires": { - "@jridgewell/sourcemap-codec": "^1.4.15" - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" - }, - "mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", - "dev": true - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - } - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "requires": { - "mime-db": "1.52.0" - } - }, - "min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "dev": true - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true - }, - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "requires": { - "minimist": "^1.2.6" - } - }, - "mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dev": true, - "requires": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, - "nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", - "dev": true - }, - "node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", - "dev": true - }, - "node-gyp-build": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", - "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", - "dev": true - }, - "node-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", - "dev": true - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "dev": true - }, - "normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true - }, - "nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dev": true, - "requires": { - "boolbase": "^1.0.0" - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true - }, - "object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "dev": true - }, - "object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true - }, - "pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "dev": true - }, - "postcss": { - "version": "8.4.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.27.tgz", - "integrity": "sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==", - "dev": true, - "requires": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - } - }, - "postcss-calc": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", - "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", - "dev": true, - "requires": { - "postcss-selector-parser": "^6.0.9", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-colormin": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz", - "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", - "dev": true, - "requires": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0", - "colord": "^2.9.1", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-convert-values": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", - "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", - "dev": true, - "requires": { - "browserslist": "^4.21.4", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-discard-comments": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", - "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", - "dev": true - }, - "postcss-discard-duplicates": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", - "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", - "dev": true - }, - "postcss-discard-empty": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", - "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", - "dev": true - }, - "postcss-discard-overridden": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", - "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", - "dev": true - }, - "postcss-import": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", - "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.0.0", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - } - }, - "postcss-js": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", - "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", - "dev": true, - "requires": { - "camelcase-css": "^2.0.1" - } - }, - "postcss-load-config": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz", - "integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==", - "dev": true, - "requires": { - "lilconfig": "^2.0.5", - "yaml": "^2.1.1" - }, - "dependencies": { - "yaml": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz", - "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==", - "dev": true - } - } - }, - "postcss-merge-longhand": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", - "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0", - "stylehacks": "^5.1.1" - } - }, - "postcss-merge-rules": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", - "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", - "dev": true, - "requires": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0", - "cssnano-utils": "^3.1.0", - "postcss-selector-parser": "^6.0.5" - } - }, - "postcss-minify-font-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", - "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-minify-gradients": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", - "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", - "dev": true, - "requires": { - "colord": "^2.9.1", - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-minify-params": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", - "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", - "dev": true, - "requires": { - "browserslist": "^4.21.4", - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-minify-selectors": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", - "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", - "dev": true, - "requires": { - "postcss-selector-parser": "^6.0.5" - } - }, - "postcss-nested": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", - "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", - "dev": true, - "requires": { - "postcss-selector-parser": "^6.0.11" - } - }, - "postcss-normalize-charset": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", - "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", - "dev": true - }, - "postcss-normalize-display-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", - "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-positions": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", - "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-repeat-style": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", - "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-string": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", - "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-timing-functions": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", - "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-unicode": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", - "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", - "dev": true, - "requires": { - "browserslist": "^4.21.4", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", - "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", - "dev": true, - "requires": { - "normalize-url": "^6.0.1", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-whitespace": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", - "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-ordered-values": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", - "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", - "dev": true, - "requires": { - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-reduce-initial": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", - "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", - "dev": true, - "requires": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0" - } - }, - "postcss-reduce-transforms": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", - "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-selector-parser": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", - "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", - "dev": true, - "requires": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - } - }, - "postcss-svgo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", - "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0", - "svgo": "^2.7.0" - } - }, - "postcss-unique-selectors": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", - "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", - "dev": true, - "requires": { - "postcss-selector-parser": "^6.0.5" - } - }, - "postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true - }, - "proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dev": true, - "requires": { - "pify": "^2.3.0" - } - }, - "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "regexparam": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexparam/-/regexparam-2.0.1.tgz", - "integrity": "sha512-zRgSaYemnNYxUv+/5SeoHI0eJIgTL/A2pUtXUPLHQxUldagouJ9p+K6IbIZ/JiQuCEv2E2B1O11SjVQy3aMCkw==" - }, - "resolve": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", - "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", - "dev": true, - "requires": { - "is-core-module": "^2.11.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "rollup": { - "version": "3.27.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.27.0.tgz", - "integrity": "sha512-aOltLCrYZ0FhJDm7fCqwTjIUEVjWjcydKBV/Zeid6Mn8BWgDCUBBWT5beM5ieForYNo/1ZHuGJdka26kvQ3Gzg==", - "dev": true, - "requires": { - "fsevents": "~2.3.2" - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "sade": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", - "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", - "dev": true, - "requires": { - "mri": "^1.1.0" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "sander": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz", - "integrity": "sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==", - "dev": true, - "requires": { - "es6-promise": "^3.1.2", - "graceful-fs": "^4.1.3", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.2" - } - }, - "secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", - "dev": true, - "requires": { - "elliptic": "^6.5.4", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "simple-cbor": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/simple-cbor/-/simple-cbor-0.4.1.tgz", - "integrity": "sha512-rijcxtwx2b4Bje3sqeIqw5EeW7UlOIC4YfOdwqIKacpvRQ/D78bWg/4/0m5e0U91oKvlGh7LlJuZCu07ISCC7w==" - }, - "sorcery": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.11.0.tgz", - "integrity": "sha512-J69LQ22xrQB1cIFJhPfgtLuI6BpWRiWu1Y3vSsIwK/eAScqJxd/+CJlUuHQRdX2C9NGFamq+KqNywGgaThwfHw==", - "dev": true, - "requires": { - "@jridgewell/sourcemap-codec": "^1.4.14", - "buffer-crc32": "^0.2.5", - "minimist": "^1.2.0", - "sander": "^0.5.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "dev": true - }, - "stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "dev": true - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dev": true, - "requires": { - "min-indent": "^1.0.0" - } - }, - "stylehacks": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", - "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", - "dev": true, - "requires": { - "browserslist": "^4.21.4", - "postcss-selector-parser": "^6.0.4" - } - }, - "sucrase": { - "version": "3.34.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz", - "integrity": "sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.3.2", - "commander": "^4.0.0", - "glob": "7.1.6", - "lines-and-columns": "^1.1.6", - "mz": "^2.7.0", - "pirates": "^4.0.1", - "ts-interface-checker": "^0.1.9" - }, - "dependencies": { - "commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true - }, - "svelte": { - "version": "3.59.2", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.59.2.tgz", - "integrity": "sha512-vzSyuGr3eEoAtT/A6bmajosJZIUWySzY2CzB3w2pgPvnkUjGqlDnsNnA0PMO+mMAhuyMul6C2uuZzY6ELSkzyA==", - "dev": true - }, - "svelte-check": { - "version": "3.4.6", - "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.4.6.tgz", - "integrity": "sha512-OBlY8866Zh1zHQTkBMPS6psPi7o2umTUyj6JWm4SacnIHXpWFm658pG32m3dKvKFL49V4ntAkfFHKo4ztH07og==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "^0.3.17", - "chokidar": "^3.4.1", - "fast-glob": "^3.2.7", - "import-fresh": "^3.2.1", - "picocolors": "^1.0.0", - "sade": "^1.7.4", - "svelte-preprocess": "^5.0.4", - "typescript": "^5.0.3" - }, - "dependencies": { - "@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, - "@jridgewell/trace-mapping": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - } - }, - "typescript": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", - "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", - "dev": true - } - } - }, - "svelte-hamburgers": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/svelte-hamburgers/-/svelte-hamburgers-4.1.1.tgz", - "integrity": "sha512-tHgP17HP1xd+0IKA/rSrnEOiyvbsL74SK1LOwjoi8dTwa41usAeQuWaS90sC2VOw87tnHcafV3G+fh1gubiOdA==", - "dev": true - }, - "svelte-hmr": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.2.tgz", - "integrity": "sha512-q/bAruCvFLwvNbeE1x3n37TYFb3mTBJ6TrCq6p2CoFbSTNhDE9oAtEfpy+wmc9So8AG0Tja+X0/mJzX9tSfvIg==", - "dev": true - }, - "svelte-preprocess": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.0.4.tgz", - "integrity": "sha512-ABia2QegosxOGsVlsSBJvoWeXy1wUKSfF7SWJdTjLAbx/Y3SrVevvvbFNQqrSJw89+lNSsM58SipmZJ5SRi5iw==", - "dev": true, - "requires": { - "@types/pug": "^2.0.6", - "detect-indent": "^6.1.0", - "magic-string": "^0.27.0", - "sorcery": "^0.11.0", - "strip-indent": "^3.0.0" - }, - "dependencies": { - "magic-string": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", - "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", - "dev": true, - "requires": { - "@jridgewell/sourcemap-codec": "^1.4.13" - } - } - } - }, - "svelte-spa-router": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/svelte-spa-router/-/svelte-spa-router-3.3.0.tgz", - "integrity": "sha512-cwRNe7cxD43sCvSfEeaKiNZg3FCizGxeMcf7CPiWRP3jKXjEma3vxyyuDtPOam6nWbVxl9TNM3hlE/i87ZlqcQ==", - "requires": { - "regexparam": "2.0.1" - } - }, - "svgo": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", - "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", - "dev": true, - "requires": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^4.1.3", - "css-tree": "^1.1.3", - "csso": "^4.2.0", - "picocolors": "^1.0.0", - "stable": "^0.1.8" - }, - "dependencies": { - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true - } - } - }, - "tailwindcss": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.3.tgz", - "integrity": "sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==", - "dev": true, - "requires": { - "@alloc/quick-lru": "^5.2.0", - "arg": "^5.0.2", - "chokidar": "^3.5.3", - "didyoumean": "^1.2.2", - "dlv": "^1.1.3", - "fast-glob": "^3.2.12", - "glob-parent": "^6.0.2", - "is-glob": "^4.0.3", - "jiti": "^1.18.2", - "lilconfig": "^2.1.0", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "object-hash": "^3.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.4.23", - "postcss-import": "^15.1.0", - "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.1", - "postcss-nested": "^6.0.1", - "postcss-selector-parser": "^6.0.11", - "resolve": "^1.22.2", - "sucrase": "^3.32.0" - }, - "dependencies": { - "arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "dev": true - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - } - } - }, - "text-segmentation": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", - "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==", - "requires": { - "utrie": "^1.0.2" - } - }, - "thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dev": true, - "requires": { - "any-promise": "^1.0.0" - } - }, - "thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dev": true, - "requires": { - "thenify": ">= 3.1.0 < 4" - } - }, - "three": { - "version": "0.148.0", - "resolved": "https://registry.npmjs.org/three/-/three-0.148.0.tgz", - "integrity": "sha512-8uzVV+qhTPi0bOFs/3te3RW6hb3urL8jYEl6irjCWo/l6sr8MPNMcClFev/MMYeIxr0gmDcoXTy/8LXh/LXkfw==" - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "ts-interface-checker": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "dev": true - }, - "ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "requires": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - } - }, - "tslib": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", - "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==", - "dev": true - }, - "tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - }, - "typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "dev": true - }, - "update-browserslist-db": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", - "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", - "dev": true, - "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - } - }, - "util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "utrie": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz", - "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==", - "requires": { - "base64-arraybuffer": "^1.0.2" - }, - "dependencies": { - "base64-arraybuffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", - "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==" - } - } - }, - "v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" - }, - "vite": { - "version": "4.4.7", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.7.tgz", - "integrity": "sha512-6pYf9QJ1mHylfVh39HpuSfMPojPSKVxZvnclX1K1FyZ1PXDOcLBibdq5t1qxJSnL63ca8Wf4zts6mD8u8oc9Fw==", - "dev": true, - "requires": { - "esbuild": "^0.18.10", - "fsevents": "~2.3.2", - "postcss": "^8.4.26", - "rollup": "^3.25.2" - } - }, - "vitefu": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.4.tgz", - "integrity": "sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==", - "dev": true - }, - "which-typed-array": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", - "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" - } - } -} +{ + "name": "PersonalWebSpace_frontend", + "version": "0.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true + }, + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + } + }, + "@dfinity/agent": { + "version": "0.15.6", + "resolved": "https://registry.npmjs.org/@dfinity/agent/-/agent-0.15.6.tgz", + "integrity": "sha512-Ch+tXAszPap0zwRgr/oFEgJLDld4RDwBdFDqR1JUg38xhHWTFMrTkjMT6uQFvqf6d2wDXnh3zwhqbg5P7OCv7A==", + "requires": { + "base64-arraybuffer": "^0.2.0", + "bignumber.js": "^9.0.0", + "borc": "^2.1.1", + "js-sha256": "0.9.0", + "simple-cbor": "^0.4.1", + "ts-node": "^10.8.2" + } + }, + "@dfinity/auth-client": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/@dfinity/auth-client/-/auth-client-0.15.7.tgz", + "integrity": "sha512-f6cRqXayCf+7+9gNcDnAZZwJrgBYKIzfxjxeRLlpsueQeo+E/BX2yVSANxzTkCNc4U3p+ttHI1RNtasLunYTcA==", + "requires": { + "idb": "^7.0.2" + } + }, + "@dfinity/authentication": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/@dfinity/authentication/-/authentication-0.14.2.tgz", + "integrity": "sha512-kiZrRKUOnbseTQiAh4GDkAo5vCX6dUN1jkqJ5rLBYkIiGuK3jENxbu4G5oJPxq57F/cgnR4Hx/abSVHQfFRkEw==", + "requires": { + "@dfinity/identity": "^0.15.1" + } + }, + "@dfinity/candid": { + "version": "0.15.6", + "resolved": "https://registry.npmjs.org/@dfinity/candid/-/candid-0.15.6.tgz", + "integrity": "sha512-Q9PGvhTE/1dTLfSo0pu0+ifzA7NA4X1rgSy9TE6O1Glk6Kl8Nf+Pg2sCHS2hWt0RAiKfR2glEVlbUAm6S8vRxA==", + "requires": { + "ts-node": "^10.8.2" + } + }, + "@dfinity/identity": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/@dfinity/identity/-/identity-0.15.7.tgz", + "integrity": "sha512-kBAkx9wq78jSQf6T5aayLyWm8YgtOZw8bW6+OuzX6tR3hkAEa85A9TcKA7BjkmMWSIskjEDVQub4fFfKWS2vOQ==", + "requires": { + "borc": "^2.1.1", + "js-sha256": "^0.9.0", + "tweetnacl": "^1.0.1" + } + }, + "@dfinity/principal": { + "version": "0.15.6", + "resolved": "https://registry.npmjs.org/@dfinity/principal/-/principal-0.15.6.tgz", + "integrity": "sha512-eMsS5YofRk5Hm6LlhzyBvw1RzDxM5FWPtepQuYeZbZyD/ztq4TrUiScqoKBFw/LLODd0znt8rGnNgqtt+7JnQA==", + "requires": { + "js-sha256": "^0.9.0", + "ts-node": "^10.8.2" + } + }, + "@esbuild/android-arm": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.17.tgz", + "integrity": "sha512-wHsmJG/dnL3OkpAcwbgoBTTMHVi4Uyou3F5mf58ZtmUyIKfcdA7TROav/6tCzET4A3QW2Q2FC+eFneMU+iyOxg==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.17.tgz", + "integrity": "sha512-9np+YYdNDed5+Jgr1TdWBsozZ85U1Oa3xW0c7TWqH0y2aGghXtZsuT8nYRbzOMcl0bXZXjOGbksoTtVOlWrRZg==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.17.tgz", + "integrity": "sha512-O+FeWB/+xya0aLg23hHEM2E3hbfwZzjqumKMSIqcHbNvDa+dza2D0yLuymRBQQnC34CWrsJUXyH2MG5VnLd6uw==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.17.tgz", + "integrity": "sha512-M9uJ9VSB1oli2BE/dJs3zVr9kcCBBsE883prage1NWz6pBS++1oNn/7soPNS3+1DGj0FrkSvnED4Bmlu1VAE9g==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.17.tgz", + "integrity": "sha512-XDre+J5YeIJDMfp3n0279DFNrGCXlxOuGsWIkRb1NThMZ0BsrWXoTg23Jer7fEXQ9Ye5QjrvXpxnhzl3bHtk0g==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.17.tgz", + "integrity": "sha512-cjTzGa3QlNfERa0+ptykyxs5A6FEUQQF0MuilYXYBGdBxD3vxJcKnzDlhDCa1VAJCmAxed6mYhA2KaJIbtiNuQ==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.17.tgz", + "integrity": "sha512-sOxEvR8d7V7Kw8QqzxWc7bFfnWnGdaFBut1dRUYtu+EIRXefBc/eIsiUiShnW0hM3FmQ5Zf27suDuHsKgZ5QrA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.17.tgz", + "integrity": "sha512-2d3Lw6wkwgSLC2fIvXKoMNGVaeY8qdN0IC3rfuVxJp89CRfA3e3VqWifGDfuakPmp90+ZirmTfye1n4ncjv2lg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.17.tgz", + "integrity": "sha512-c9w3tE7qA3CYWjT+M3BMbwMt+0JYOp3vCMKgVBrCl1nwjAlOMYzEo+gG7QaZ9AtqZFj5MbUc885wuBBmu6aADQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.17.tgz", + "integrity": "sha512-1DS9F966pn5pPnqXYz16dQqWIB0dmDfAQZd6jSSpiT9eX1NzKh07J6VKR3AoXXXEk6CqZMojiVDSZi1SlmKVdg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.17.tgz", + "integrity": "sha512-EvLsxCk6ZF0fpCB6w6eOI2Fc8KW5N6sHlIovNe8uOFObL2O+Mr0bflPHyHwLT6rwMg9r77WOAWb2FqCQrVnwFg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.17.tgz", + "integrity": "sha512-e0bIdHA5p6l+lwqTE36NAW5hHtw2tNRmHlGBygZC14QObsA3bD4C6sXLJjvnDIjSKhW1/0S3eDy+QmX/uZWEYQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.17.tgz", + "integrity": "sha512-BAAilJ0M5O2uMxHYGjFKn4nJKF6fNCdP1E0o5t5fvMYYzeIqy2JdAP88Az5LHt9qBoUa4tDaRpfWt21ep5/WqQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.17.tgz", + "integrity": "sha512-Wh/HW2MPnC3b8BqRSIme/9Zhab36PPH+3zam5pqGRH4pE+4xTrVLx2+XdGp6fVS3L2x+DrsIcsbMleex8fbE6g==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.17.tgz", + "integrity": "sha512-j/34jAl3ul3PNcK3pfI0NSlBANduT2UO5kZ7FCaK33XFv3chDhICLY8wJJWIhiQ+YNdQ9dxqQctRg2bvrMlYgg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.17.tgz", + "integrity": "sha512-QM50vJ/y+8I60qEmFxMoxIx4de03pGo2HwxdBeFd4nMh364X6TIBZ6VQ5UQmPbQWUVWHWws5MmJXlHAXvJEmpQ==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.17.tgz", + "integrity": "sha512-/jGlhWR7Sj9JPZHzXyyMZ1RFMkNPjC6QIAan0sDOtIo2TYk3tZn5UDrkE0XgsTQCxWTTOcMPf9p6Rh2hXtl5TQ==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.17.tgz", + "integrity": "sha512-rSEeYaGgyGGf4qZM2NonMhMOP/5EHp4u9ehFiBrg7stH6BYEEjlkVREuDEcQ0LfIl53OXLxNbfuIj7mr5m29TA==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.17.tgz", + "integrity": "sha512-Y7ZBbkLqlSgn4+zot4KUNYst0bFoO68tRgI6mY2FIM+b7ZbyNVtNbDP5y8qlu4/knZZ73fgJDlXID+ohY5zt5g==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.17.tgz", + "integrity": "sha512-bwPmTJsEQcbZk26oYpc4c/8PvTY3J5/QK8jM19DVlEsAB41M39aWovWoHtNm78sd6ip6prilxeHosPADXtEJFw==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.17.tgz", + "integrity": "sha512-H/XaPtPKli2MhW+3CQueo6Ni3Avggi6hP/YvgkEe1aSaxw+AeO8MFjq8DlgfTd9Iz4Yih3QCZI6YLMoyccnPRg==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.17.tgz", + "integrity": "sha512-fGEb8f2BSA3CW7riJVurug65ACLuQAzKq0SSqkY2b2yHHH0MzDfbLyKIGzHwOI/gkHcxM/leuSW6D5w/LMNitA==", + "dev": true, + "optional": true + }, + "@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==" + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@sveltejs/vite-plugin-svelte": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-2.4.3.tgz", + "integrity": "sha512-NY2h+B54KHZO3kDURTdARqthn6D4YSIebtfW75NvZ/fwyk4G+AJw3V/i0OBjyN4406Ht9yZcnNWMuRUFnDNNiA==", + "dev": true, + "requires": { + "@sveltejs/vite-plugin-svelte-inspector": "^1.0.3", + "debug": "^4.3.4", + "deepmerge": "^4.3.1", + "kleur": "^4.1.5", + "magic-string": "^0.30.1", + "svelte-hmr": "^0.15.2", + "vitefu": "^0.2.4" + } + }, + "@sveltejs/vite-plugin-svelte-inspector": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-1.0.3.tgz", + "integrity": "sha512-Khdl5jmmPN6SUsVuqSXatKpQTMIifoQPDanaxC84m9JxIibWvSABJyHpyys0Z+1yYrxY5TTEQm+6elh0XCMaOA==", + "dev": true, + "requires": { + "debug": "^4.3.4" + } + }, + "@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "dev": true + }, + "@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + }, + "@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" + }, + "@tsconfig/svelte": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@tsconfig/svelte/-/svelte-3.0.0.tgz", + "integrity": "sha512-pYrtLtOwku/7r1i9AMONsJMVYAtk3hzOfiGNekhtq5tYBGA7unMve8RvUclKLMT3PrihvJqUmzsRGh0RP84hKg==", + "dev": true + }, + "@types/node": { + "version": "16.18.39", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.39.tgz", + "integrity": "sha512-8q9ZexmdYYyc5/cfujaXb4YOucpQxAV4RMG0himLyDUOEr8Mr79VrqsFI+cQ2M2h89YIuy95lbxuYjxT4Hk4kQ==", + "dev": true + }, + "@types/pug": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.6.tgz", + "integrity": "sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==", + "dev": true + }, + "acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==" + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" + }, + "any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "assert": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", + "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", + "dev": true, + "requires": { + "es6-object-assign": "^1.1.0", + "is-nan": "^1.2.1", + "object-is": "^1.0.1", + "util": "^0.12.0" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "autoprefixer": { + "version": "10.4.14", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz", + "integrity": "sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==", + "dev": true, + "requires": { + "browserslist": "^4.21.5", + "caniuse-lite": "^1.0.30001464", + "fraction.js": "^4.2.0", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + } + }, + "available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true + }, + "axios": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", + "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", + "requires": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "base64-arraybuffer": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.2.0.tgz", + "integrity": "sha512-7emyCsu1/xiBXgQZrscw/8KPRT44I4Yq9Pe6EGs3aPRTsWuggML1/1DTuZUuIaJPIm1FTDUVXl4x/yW8s0kQDQ==" + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "bignumber.js": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.1.tgz", + "integrity": "sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig==" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true + }, + "borc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/borc/-/borc-2.1.2.tgz", + "integrity": "sha512-Sy9eoUi4OiKzq7VovMn246iTo17kzuyHJKomCfpWMlI6RpfN1gk95w7d7gH264nApVLg0HZfcpz62/g4VH1Y4w==", + "requires": { + "bignumber.js": "^9.0.0", + "buffer": "^5.5.0", + "commander": "^2.15.0", + "ieee754": "^1.1.13", + "iso-url": "~0.4.7", + "json-text-sequence": "~0.1.0", + "readable-stream": "^3.6.0" + }, + "dependencies": { + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", + "dev": true + }, + "browserslist": { + "version": "4.21.9", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", + "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001503", + "electron-to-chromium": "^1.4.431", + "node-releases": "^2.0.12", + "update-browserslist-db": "^1.0.11" + } + }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true + }, + "caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "caniuse-lite": { + "version": "1.0.30001517", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001517.tgz", + "integrity": "sha512-Vdhm5S11DaFVLlyiKu4hiUTkpZu+y1KA/rZZqVQfOD5YdDT/eQKlkt7NaE0WGOFgX32diqt9MiP9CAiFeRklaA==", + "dev": true + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, + "css-declaration-sorter": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", + "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", + "dev": true + }, + "css-line-break": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz", + "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==", + "requires": { + "utrie": "^1.0.2" + } + }, + "css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + } + }, + "css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dev": true, + "requires": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + } + }, + "css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true + }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true + }, + "cssnano": { + "version": "5.1.15", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz", + "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", + "dev": true, + "requires": { + "cssnano-preset-default": "^5.2.14", + "lilconfig": "^2.0.3", + "yaml": "^1.10.2" + } + }, + "cssnano-preset-default": { + "version": "5.2.14", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", + "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", + "dev": true, + "requires": { + "css-declaration-sorter": "^6.3.1", + "cssnano-utils": "^3.1.0", + "postcss-calc": "^8.2.3", + "postcss-colormin": "^5.3.1", + "postcss-convert-values": "^5.1.3", + "postcss-discard-comments": "^5.1.2", + "postcss-discard-duplicates": "^5.1.0", + "postcss-discard-empty": "^5.1.1", + "postcss-discard-overridden": "^5.1.0", + "postcss-merge-longhand": "^5.1.7", + "postcss-merge-rules": "^5.1.4", + "postcss-minify-font-values": "^5.1.0", + "postcss-minify-gradients": "^5.1.1", + "postcss-minify-params": "^5.1.4", + "postcss-minify-selectors": "^5.2.1", + "postcss-normalize-charset": "^5.1.0", + "postcss-normalize-display-values": "^5.1.0", + "postcss-normalize-positions": "^5.1.1", + "postcss-normalize-repeat-style": "^5.1.1", + "postcss-normalize-string": "^5.1.0", + "postcss-normalize-timing-functions": "^5.1.0", + "postcss-normalize-unicode": "^5.1.1", + "postcss-normalize-url": "^5.1.0", + "postcss-normalize-whitespace": "^5.1.1", + "postcss-ordered-values": "^5.1.3", + "postcss-reduce-initial": "^5.1.2", + "postcss-reduce-transforms": "^5.1.0", + "postcss-svgo": "^5.1.0", + "postcss-unique-selectors": "^5.1.1" + } + }, + "cssnano-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", + "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", + "dev": true + }, + "csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "dev": true, + "requires": { + "css-tree": "^1.1.2" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true + }, + "define-properties": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", + "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "dev": true, + "requires": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, + "delimit-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/delimit-stream/-/delimit-stream-0.1.0.tgz", + "integrity": "sha512-a02fiQ7poS5CnjiJBAsjGLPp5EwVoGHNeu9sziBd9huppRfsAFIpv5zNLv0V1gbop53ilngAf5Kf331AwcoRBQ==" + }, + "detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true + }, + "didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + }, + "dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true + }, + "dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + } + }, + "domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true + }, + "domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "requires": { + "domelementtype": "^2.2.0" + } + }, + "domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + } + }, + "electron-to-chromium": { + "version": "1.4.475", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.475.tgz", + "integrity": "sha512-mTye5u5P98kSJO2n7zYALhpJDmoSQejIGya0iR01GpoRady8eK3bw7YHHnjA1Rfi4ZSLdpuzlAC7Zw+1Zu7Z6A==", + "dev": true + }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true + }, + "es6-object-assign": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", + "integrity": "sha512-MEl9uirslVwqQU369iHNWZXsI8yaZYGg/D65aOgZkeyFJwHYSxilf7rQzXKI7DdDuBPrBXbfk3sl9hJhmd5AUw==", + "dev": true + }, + "es6-promise": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", + "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", + "dev": true + }, + "esbuild": { + "version": "0.18.17", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.17.tgz", + "integrity": "sha512-1GJtYnUxsJreHYA0Y+iQz2UEykonY66HNWOb0yXYZi9/kNrORUEHVg87eQsCtqh59PEJ5YVZJO98JHznMJSWjg==", + "dev": true, + "requires": { + "@esbuild/android-arm": "0.18.17", + "@esbuild/android-arm64": "0.18.17", + "@esbuild/android-x64": "0.18.17", + "@esbuild/darwin-arm64": "0.18.17", + "@esbuild/darwin-x64": "0.18.17", + "@esbuild/freebsd-arm64": "0.18.17", + "@esbuild/freebsd-x64": "0.18.17", + "@esbuild/linux-arm": "0.18.17", + "@esbuild/linux-arm64": "0.18.17", + "@esbuild/linux-ia32": "0.18.17", + "@esbuild/linux-loong64": "0.18.17", + "@esbuild/linux-mips64el": "0.18.17", + "@esbuild/linux-ppc64": "0.18.17", + "@esbuild/linux-riscv64": "0.18.17", + "@esbuild/linux-s390x": "0.18.17", + "@esbuild/linux-x64": "0.18.17", + "@esbuild/netbsd-x64": "0.18.17", + "@esbuild/openbsd-x64": "0.18.17", + "@esbuild/sunos-x64": "0.18.17", + "@esbuild/win32-arm64": "0.18.17", + "@esbuild/win32-ia32": "0.18.17", + "@esbuild/win32-x64": "0.18.17" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true + }, + "fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "requires": { + "is-callable": "^1.1.3" + } + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "fraction.js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", + "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "get-intrinsic": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3" + } + }, + "graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.1" + } + }, + "has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "html2canvas": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz", + "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==", + "requires": { + "css-line-break": "^2.1.0", + "text-segmentation": "^1.0.3" + } + }, + "ic-stoic-identity": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ic-stoic-identity/-/ic-stoic-identity-2.0.0.tgz", + "integrity": "sha512-0lvtX+lWR0LaEo076SFTKYDds+WKByQZfn3iU8ap5iCgc+OEBt/g/0jHwsnH3e7tI46JLiNaxSQIp223BEj81Q==", + "dev": true, + "requires": { + "@dfinity/agent": "^0.10.0", + "@dfinity/identity": "^0.10.0", + "@dfinity/principal": "^0.10.0", + "buffer": "^6.0.3" + }, + "dependencies": { + "@dfinity/agent": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@dfinity/agent/-/agent-0.10.4.tgz", + "integrity": "sha512-/O1443GWkQ6GngrXos/ShAbnF9IgUlWclzaQn/qEsGJIey6S7tty+iOa5yZqOS1BtOTnDe+TYh8GeERZZn7vvg==", + "dev": true, + "requires": { + "base64-arraybuffer": "^0.2.0", + "bignumber.js": "^9.0.0", + "borc": "^2.1.1", + "js-sha256": "0.9.0", + "simple-cbor": "^0.4.1" + } + }, + "@dfinity/identity": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@dfinity/identity/-/identity-0.10.4.tgz", + "integrity": "sha512-b4WsaD70Ts75JlJcf4+E04B140hQN5u/GnCvjhaHqN2++bwWO56Paxtv0UfAc58LMwJZj4iOyZoahnT56LhC9A==", + "dev": true, + "requires": { + "borc": "^2.1.1", + "js-sha256": "^0.9.0", + "secp256k1": "^4.0.2", + "tweetnacl": "^1.0.1" + } + }, + "@dfinity/principal": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@dfinity/principal/-/principal-0.10.4.tgz", + "integrity": "sha512-qwzpmq5wfyeKMBspRZmuYvTxu1dqN+IY0ThACHTRh6D58QjnVQNCD3Hq9d5eEDu0qyNcY22cJEWwzrzZaaoVmw==", + "dev": true + } + } + }, + "idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==" + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true + }, + "is-core-module": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", + "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-nan": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-typed-array": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "dev": true, + "requires": { + "which-typed-array": "^1.1.11" + } + }, + "iso-url": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/iso-url/-/iso-url-0.4.7.tgz", + "integrity": "sha512-27fFRDnPAMnHGLq36bWTpKET+eiXct3ENlCcdcMdk+mjXrb2kw3mhBUg1B7ewAC0kVzlOPhADzQgz1SE6Tglog==" + }, + "jiti": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.19.1.tgz", + "integrity": "sha512-oVhqoRDaBXf7sjkll95LHVS6Myyyb1zaunVwk4Z0+WPSW4gjS0pl01zYKHScTuyEhQsFxV5L4DR5r+YqSyqyyg==", + "dev": true + }, + "js-sha256": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", + "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==" + }, + "json-text-sequence": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/json-text-sequence/-/json-text-sequence-0.1.1.tgz", + "integrity": "sha512-L3mEegEWHRekSHjc7+sc8eJhba9Clq1PZ8kMkzf8OxElhXc8O4TS5MwcVlj9aEbm5dr81N90WHC5nAz3UO971w==", + "requires": { + "delimit-stream": "0.1.0" + } + }, + "kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true + }, + "lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true + }, + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true + }, + "magic-string": { + "version": "0.30.2", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.2.tgz", + "integrity": "sha512-lNZdu7pewtq/ZvWUp9Wpf/x7WzMTsR26TWV03BRZrXFsv+BI6dy8RAiKgm1uM/kyR0rCfUcqvOlXKG66KhIGug==", + "dev": true, + "requires": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true + }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "requires": { + "minimist": "^1.2.6" + } + }, + "mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "requires": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "dev": true + }, + "node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", + "dev": true + }, + "node-gyp-build": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", + "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", + "dev": true + }, + "node-releases": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true + }, + "normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true + }, + "nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "requires": { + "boolbase": "^1.0.0" + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true + }, + "object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true + }, + "object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true + }, + "pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true + }, + "postcss": { + "version": "8.4.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.27.tgz", + "integrity": "sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==", + "dev": true, + "requires": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + }, + "postcss-calc": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", + "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", + "dev": true, + "requires": { + "postcss-selector-parser": "^6.0.9", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-colormin": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz", + "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", + "dev": true, + "requires": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0", + "colord": "^2.9.1", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-convert-values": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", + "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", + "dev": true, + "requires": { + "browserslist": "^4.21.4", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-discard-comments": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", + "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", + "dev": true + }, + "postcss-discard-duplicates": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", + "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", + "dev": true + }, + "postcss-discard-empty": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", + "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", + "dev": true + }, + "postcss-discard-overridden": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", + "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", + "dev": true + }, + "postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + } + }, + "postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, + "requires": { + "camelcase-css": "^2.0.1" + } + }, + "postcss-load-config": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz", + "integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==", + "dev": true, + "requires": { + "lilconfig": "^2.0.5", + "yaml": "^2.1.1" + }, + "dependencies": { + "yaml": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz", + "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==", + "dev": true + } + } + }, + "postcss-merge-longhand": { + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", + "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^5.1.1" + } + }, + "postcss-merge-rules": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", + "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", + "dev": true, + "requires": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^3.1.0", + "postcss-selector-parser": "^6.0.5" + } + }, + "postcss-minify-font-values": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", + "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-minify-gradients": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", + "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", + "dev": true, + "requires": { + "colord": "^2.9.1", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-minify-params": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", + "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", + "dev": true, + "requires": { + "browserslist": "^4.21.4", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-minify-selectors": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", + "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", + "dev": true, + "requires": { + "postcss-selector-parser": "^6.0.5" + } + }, + "postcss-nested": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", + "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "dev": true, + "requires": { + "postcss-selector-parser": "^6.0.11" + } + }, + "postcss-normalize-charset": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", + "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", + "dev": true + }, + "postcss-normalize-display-values": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", + "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-positions": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", + "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-repeat-style": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", + "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-string": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", + "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-timing-functions": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", + "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-unicode": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", + "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", + "dev": true, + "requires": { + "browserslist": "^4.21.4", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", + "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", + "dev": true, + "requires": { + "normalize-url": "^6.0.1", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-whitespace": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", + "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-ordered-values": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", + "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", + "dev": true, + "requires": { + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-reduce-initial": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", + "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", + "dev": true, + "requires": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0" + } + }, + "postcss-reduce-transforms": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", + "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-selector-parser": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", + "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "postcss-svgo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", + "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0", + "svgo": "^2.7.0" + } + }, + "postcss-unique-selectors": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", + "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", + "dev": true, + "requires": { + "postcss-selector-parser": "^6.0.5" + } + }, + "postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true + }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "requires": { + "pify": "^2.3.0" + } + }, + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "regexparam": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexparam/-/regexparam-2.0.1.tgz", + "integrity": "sha512-zRgSaYemnNYxUv+/5SeoHI0eJIgTL/A2pUtXUPLHQxUldagouJ9p+K6IbIZ/JiQuCEv2E2B1O11SjVQy3aMCkw==" + }, + "resolve": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "dev": true, + "requires": { + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "rollup": { + "version": "3.27.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.27.0.tgz", + "integrity": "sha512-aOltLCrYZ0FhJDm7fCqwTjIUEVjWjcydKBV/Zeid6Mn8BWgDCUBBWT5beM5ieForYNo/1ZHuGJdka26kvQ3Gzg==", + "dev": true, + "requires": { + "fsevents": "~2.3.2" + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dev": true, + "requires": { + "mri": "^1.1.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "sander": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz", + "integrity": "sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==", + "dev": true, + "requires": { + "es6-promise": "^3.1.2", + "graceful-fs": "^4.1.3", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.2" + } + }, + "secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", + "dev": true, + "requires": { + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + }, + "simple-cbor": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/simple-cbor/-/simple-cbor-0.4.1.tgz", + "integrity": "sha512-rijcxtwx2b4Bje3sqeIqw5EeW7UlOIC4YfOdwqIKacpvRQ/D78bWg/4/0m5e0U91oKvlGh7LlJuZCu07ISCC7w==" + }, + "sorcery": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.11.0.tgz", + "integrity": "sha512-J69LQ22xrQB1cIFJhPfgtLuI6BpWRiWu1Y3vSsIwK/eAScqJxd/+CJlUuHQRdX2C9NGFamq+KqNywGgaThwfHw==", + "dev": true, + "requires": { + "@jridgewell/sourcemap-codec": "^1.4.14", + "buffer-crc32": "^0.2.5", + "minimist": "^1.2.0", + "sander": "^0.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true + }, + "stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "requires": { + "min-indent": "^1.0.0" + } + }, + "stylehacks": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", + "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", + "dev": true, + "requires": { + "browserslist": "^4.21.4", + "postcss-selector-parser": "^6.0.4" + } + }, + "sucrase": { + "version": "3.34.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz", + "integrity": "sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "7.1.6", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "dependencies": { + "commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "svelte": { + "version": "3.59.2", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.59.2.tgz", + "integrity": "sha512-vzSyuGr3eEoAtT/A6bmajosJZIUWySzY2CzB3w2pgPvnkUjGqlDnsNnA0PMO+mMAhuyMul6C2uuZzY6ELSkzyA==", + "dev": true + }, + "svelte-check": { + "version": "3.4.6", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.4.6.tgz", + "integrity": "sha512-OBlY8866Zh1zHQTkBMPS6psPi7o2umTUyj6JWm4SacnIHXpWFm658pG32m3dKvKFL49V4ntAkfFHKo4ztH07og==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.17", + "chokidar": "^3.4.1", + "fast-glob": "^3.2.7", + "import-fresh": "^3.2.1", + "picocolors": "^1.0.0", + "sade": "^1.7.4", + "svelte-preprocess": "^5.0.4", + "typescript": "^5.0.3" + }, + "dependencies": { + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "typescript": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", + "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", + "dev": true + } + } + }, + "svelte-hamburgers": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/svelte-hamburgers/-/svelte-hamburgers-4.1.1.tgz", + "integrity": "sha512-tHgP17HP1xd+0IKA/rSrnEOiyvbsL74SK1LOwjoi8dTwa41usAeQuWaS90sC2VOw87tnHcafV3G+fh1gubiOdA==", + "dev": true + }, + "svelte-hmr": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.2.tgz", + "integrity": "sha512-q/bAruCvFLwvNbeE1x3n37TYFb3mTBJ6TrCq6p2CoFbSTNhDE9oAtEfpy+wmc9So8AG0Tja+X0/mJzX9tSfvIg==", + "dev": true + }, + "svelte-preprocess": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.0.4.tgz", + "integrity": "sha512-ABia2QegosxOGsVlsSBJvoWeXy1wUKSfF7SWJdTjLAbx/Y3SrVevvvbFNQqrSJw89+lNSsM58SipmZJ5SRi5iw==", + "dev": true, + "requires": { + "@types/pug": "^2.0.6", + "detect-indent": "^6.1.0", + "magic-string": "^0.27.0", + "sorcery": "^0.11.0", + "strip-indent": "^3.0.0" + }, + "dependencies": { + "magic-string": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", + "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", + "dev": true, + "requires": { + "@jridgewell/sourcemap-codec": "^1.4.13" + } + } + } + }, + "svelte-spa-router": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/svelte-spa-router/-/svelte-spa-router-3.3.0.tgz", + "integrity": "sha512-cwRNe7cxD43sCvSfEeaKiNZg3FCizGxeMcf7CPiWRP3jKXjEma3vxyyuDtPOam6nWbVxl9TNM3hlE/i87ZlqcQ==", + "requires": { + "regexparam": "2.0.1" + } + }, + "svgo": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", + "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", + "dev": true, + "requires": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^4.1.3", + "css-tree": "^1.1.3", + "csso": "^4.2.0", + "picocolors": "^1.0.0", + "stable": "^0.1.8" + }, + "dependencies": { + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true + } + } + }, + "tailwindcss": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.3.tgz", + "integrity": "sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==", + "dev": true, + "requires": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.2.12", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.18.2", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" + }, + "dependencies": { + "arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + } + } + }, + "text-segmentation": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", + "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==", + "requires": { + "utrie": "^1.0.2" + } + }, + "thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "requires": { + "any-promise": "^1.0.0" + } + }, + "thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "requires": { + "thenify": ">= 3.1.0 < 4" + } + }, + "three": { + "version": "0.148.0", + "resolved": "https://registry.npmjs.org/three/-/three-0.148.0.tgz", + "integrity": "sha512-8uzVV+qhTPi0bOFs/3te3RW6hb3urL8jYEl6irjCWo/l6sr8MPNMcClFev/MMYeIxr0gmDcoXTy/8LXh/LXkfw==" + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true + }, + "ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + } + }, + "tslib": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", + "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==", + "dev": true + }, + "tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, + "typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true + }, + "update-browserslist-db": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", + "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "dev": true, + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, + "util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "utrie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz", + "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==", + "requires": { + "base64-arraybuffer": "^1.0.2" + }, + "dependencies": { + "base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==" + } + } + }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + }, + "vite": { + "version": "4.4.7", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.7.tgz", + "integrity": "sha512-6pYf9QJ1mHylfVh39HpuSfMPojPSKVxZvnclX1K1FyZ1PXDOcLBibdq5t1qxJSnL63ca8Wf4zts6mD8u8oc9Fw==", + "dev": true, + "requires": { + "esbuild": "^0.18.10", + "fsevents": "~2.3.2", + "postcss": "^8.4.26", + "rollup": "^3.25.2" + } + }, + "vitefu": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.4.tgz", + "integrity": "sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==", + "dev": true + }, + "which-typed-array": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", + "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" + } + } +} diff --git a/src/PersonalWebSpace_backend/main.mo b/src/PersonalWebSpace_backend/main.mo index 99ea3e6..7b32aa5 100644 --- a/src/PersonalWebSpace_backend/main.mo +++ b/src/PersonalWebSpace_backend/main.mo @@ -1,1113 +1,1113 @@ -import List "mo:base/List"; -import Principal "mo:base/Principal"; -import Text "mo:base/Text"; -import Iter "mo:base/Iter"; -import Nat "mo:base/Nat"; -import Nat16 "mo:base/Nat16"; -import Nat32 "mo:base/Nat32"; -import Nat64 "mo:base/Nat64"; -import Time "mo:base/Time"; -import Int "mo:base/Int"; -import Char "mo:base/Char"; -import AssocList "mo:base/AssocList"; -import Buffer "mo:base/Buffer"; -import Random "mo:base/Random"; -import RBTree "mo:base/RBTree"; -import HashMap "mo:base/HashMap"; -import Array "mo:base/Array"; - -import FileTypes "./types/FileStorageTypes"; -import Utils "./Utils"; - -import Types "./Types"; -import HTTP "./Http"; - -import Stoic "./EXT/Stoic"; - -import Protocol "./Protocol"; -import Testable "mo:matchers/Testable"; -import Blob "mo:base/Blob"; - - - -shared actor class PersonalWebSpace(custodian: Principal, init : Types.Dip721NonFungibleToken) = Self { -// TODO: instead add functions to manage cycles balance and gather stats - public func greet(name : Text) : async Text { - return "Hello, " # name # "!"; - }; - - // DIP721 standard: https://github.com/dfinity/examples/blob/master/motoko/dip-721-nft-container/src/Main.mo - stable var transactionId: Types.TransactionId = 0; - stable var nfts = List.nil(); - stable var custodians = List.make(custodian); - stable var logo : Types.LogoResult = init.logo; - stable var name : Text = init.name; - stable var symbol : Text = init.symbol; - stable var maxLimit : Nat16 = init.maxLimit; - - // https://forum.dfinity.org/t/is-there-any-address-0-equivalent-at-dfinity-motoko/5445/3 - let null_address : Principal = Principal.fromText("aaaaa-aa"); - - public query func balanceOfDip721(user: Principal) : async Nat64 { - return Nat64.fromNat( - List.size( - List.filter(nfts, func(token: Types.Nft) : Bool { token.owner == user }) - ) - ); - }; - - public query func ownerOfDip721(token_id: Types.TokenId) : async Types.OwnerResult { - let item = List.get(nfts, Nat64.toNat(token_id)); - switch (item) { - case (null) { - return #Err(#InvalidTokenId); - }; - case (?token) { - return #Ok(token.owner); - }; - }; - }; - - public shared({ caller }) func safeTransferFromDip721(from: Principal, to: Principal, token_id: Types.TokenId) : async Types.TxReceipt { - if (to == null_address) { - return #Err(#ZeroAddress); - } else { - return transferFrom(from, to, token_id, caller); - }; - }; - - public shared({ caller }) func transferFromDip721(from: Principal, to: Principal, token_id: Types.TokenId) : async Types.TxReceipt { - return transferFrom(from, to, token_id, caller); - }; - - func transferFrom(from: Principal, to: Principal, token_id: Types.TokenId, caller: Principal) : Types.TxReceipt { - let item = List.get(nfts, Nat64.toNat(token_id)); - switch (item) { - case null { - return #Err(#InvalidTokenId); - }; - case (?token) { - if ( - caller != token.owner and - not List.some(custodians, func (custodian : Principal) : Bool { custodian == caller }) - ) { - return #Err(#Unauthorized); - } else if (Principal.notEqual(from, token.owner)) { - return #Err(#Unauthorized); - } else { - nfts := List.map(nfts, func (item : Types.Nft) : Types.Nft { - if (item.id == token.id) { - let update : Types.Nft = { - owner = to; - id = item.id; - metadata = token.metadata; - }; - return update; - } else { - return item; - }; - }); - transactionId += 1; - return #Ok(transactionId); - }; - }; - }; - }; - - public query func supportedInterfacesDip721() : async [Types.InterfaceId] { - return [#TransferNotification, #Burn, #Mint]; - }; - - public query func logoDip721() : async Types.LogoResult { - return logo; - }; - - public query func nameDip721() : async Text { - return name; - }; - - public query func symbolDip721() : async Text { - return symbol; - }; - - public query func totalSupplyDip721() : async Nat64 { - return Nat64.fromNat( - List.size(nfts) - ); - }; - - public query func getMetadataDip721(token_id: Types.TokenId) : async Types.MetadataResult { - let item = List.get(nfts, Nat64.toNat(token_id)); - switch (item) { - case null { - return #Err(#InvalidTokenId); - }; - case (?token) { - return #Ok(token.metadata); - } - }; - }; - - public query func getMaxLimitDip721() : async Nat16 { - return maxLimit; - }; - - public func getMetadataForUserDip721(user: Principal) : async Types.ExtendedMetadataResult { - let item = List.find(nfts, func(token: Types.Nft) : Bool { token.owner == user }); - switch (item) { - case null { - return #Err(#Other("No token found for this user")); - }; - case (?token) { - return #Ok({ - metadata_desc = token.metadata; - token_id = token.id; - }); - } - }; - }; - - public query func getTokenIdsForUserDip721(user: Principal) : async [Types.TokenId] { - let items = List.filter(nfts, func(token: Types.Nft) : Bool { token.owner == user }); - let tokenIds = List.map(items, func (item : Types.Nft) : Types.TokenId { item.id }); - return List.toArray(tokenIds); - }; - - public shared query ({caller}) func check_user_has_nft() : async Bool { - let user = caller; - let items = List.filter(nfts, func(token: Types.Nft) : Bool { token.owner == user }); - let tokenIds = List.map(items, func (item : Types.Nft) : Types.TokenId { item.id }); - let userTokenIds = List.toArray(tokenIds); - if (userTokenIds.size() == 0) { - return false; - } else { - return true; - } - }; - - public shared({ caller }) func mintDip721(to: Principal, metadata: Types.MetadataDesc) : async Types.MintReceipt { - if (not List.some(custodians, func (custodian : Principal) : Bool { custodian == caller })) { - return #Err(#Unauthorized); - }; - - let newId = Nat64.fromNat(List.size(nfts)); - let nft : Types.Nft = { - owner = to; - id = newId; - metadata = metadata; - }; - - var tempList = List.nil(); - tempList := List.push(nft, tempList); - nfts := List.append(nfts, tempList); - - transactionId += 1; - - return #Ok({ - token_id = newId; - id = transactionId; - }); - }; - - // Helper functions - func textToNat(txt : Text) : Nat { - assert(txt.size() > 0); - let chars = txt.chars(); - - var num : Nat = 0; - for (v in chars){ - let charToNum = Nat32.toNat(Char.toNat32(v)-48); - assert(charToNum >= 0 and charToNum <= 9); - num := num * 10 + charToNum; - }; - - num; - }; - - func textToNat64(txt : Text) : Nat64 { - assert(txt.size() > 0); - let chars = txt.chars(); - - var num : Nat = 0; - for (v in chars){ - let charToNum = Nat32.toNat(Char.toNat32(v)-48); - assert(charToNum >= 0 and charToNum <= 9); - num := num * 10 + charToNum; - }; - - Nat64.fromNat(num); - }; - -// Project-specific functions - // ##################### NFT Details ################# - // defined according to NFT in Types - /* - Types.MetadataDesc for this project looks like: - [ - { - purpose: #Rendered ; - data: spaceAsHtmlTextBlob // Text.encodeUtf8(spaceAsHtmlText) to get Blob from Text (probably change to spaceAsJsonFormattedTextBlob later) - key_val_data: [ - { - key = "ownerName"; - val = #TextContent ownerName; - }, - { - key = "ownerContactInfo"; - val = #TextContent ownerContactInfo; - }, - { - key = "aboutDescription"; - val = #TextContent aboutDescription; - }, - { - key = "spaceDescription"; - val = #TextContent spaceDescription; - }, - { - key = "spaceName"; - val = #TextContent spaceName; - }, - { - key = "creator"; - val: #PrincipalContent caller; - }, - { - key = "creationTime"; - val = #Nat64Content generatedTimestamp; - }, - { - key = "protocolEntityId"; - val = #TextContent protocolEntityId; - }, - ]; - } - ] - */ - - public shared({ caller }) func createSpace(spaceHtml : Text) : async Types.NftResult { - // don't allow anonymous Principal - if (Principal.isAnonymous(caller)) { - return #Err(#Unauthorized); - }; - - let newId = Nat64.fromNat(List.size(nfts)); - - // create space for caller - let textArrayContent : [Text] = []; - let keyValData : [Types.MetadataKeyVal] = [ - { - key = "ownerName"; - val = #TextContent ""; - }, - { - key = "ownerContactInfo"; - val = #TextContent ""; - }, - { - key = "aboutDescription"; - val = #TextContent "This is my flaming hot Personal Web Space. Enjoy!"; - }, - { - key = "spaceDescription"; - val = #TextContent "My virtual home - heeyah"; - }, - { - key = "spaceName"; - val = #TextContent "My Flaming Hot Personal Web Space"; - }, - { - key = "creator"; - val = #PrincipalContent caller; - }, - { - key = "creationTime"; - val = #Nat64Content (Nat64.fromNat(Int.abs(Time.now()))); - }, - { - key = "protocolEntityId"; - val = #TextContent ""; // not initialized yet, needs to be updated by the frontend after creating the Entity - } - ]; - let nftData = Text.encodeUtf8(spaceHtml); - - let metadataPart : Types.MetadataPart = { - purpose = #Rendered; - key_val_data = keyValData; - data = nftData; //provided space HTML - }; - let metadata : Types.MetadataDesc = [metadataPart]; - let nft : Types.Nft = { - owner = caller; - id = newId; - metadata = metadata; - }; - - var tempList = List.nil(); - tempList := List.push(nft, tempList); - nfts := List.append(nfts, tempList); - - transactionId += 1; - - return #Ok(nft); - }; - - public shared query ({caller}) func getCallerSpaces() : async [Types.Nft] { - let spaces = List.filter(nfts, func(token: Types.Nft) : Bool { token.owner == caller }); - return List.toArray(spaces); - }; - - public shared query ({caller}) func getSpace(spaceId : Types.TokenId) : async Types.NftResult { - let item = List.get(nfts, Nat64.toNat(spaceId)); - switch (item) { - case (null) { - return #Err(#InvalidTokenId); - }; - case (?token) { - return #Ok(token); - }; - }; - }; - - public func getRandomSpace() : async Types.NftResult { - let numberOfSpaces = List.size(nfts); - if (numberOfSpaces > 0) { - let random = Random.Finite(await Random.blob()); - var p : Nat8 = 16; - - if (numberOfSpaces < 256) { - p := 8; - } else if (numberOfSpaces < 2049) { - p := 11; - } else if (numberOfSpaces < 8193) { - p := 13; - }; - switch (random.range(p)) { - case (null) { - return #Err(#Other("Error retrieving a random space")); - }; - case (?randomNumber) { - let spaceId = randomNumber % numberOfSpaces; - let item = List.get(nfts, spaceId); - switch (item) { - case (null) { - return #Err(#InvalidTokenId); - }; - case (?token) { - return #Ok(token); - }; - }; - }; - }; - } else { - return #Err(#Other("No space available")); - }; - }; - - // Update the Space's Entity id (should only be necessary after creating the Entity) - public shared({ caller }) func updateSpaceEntityId(spaceId : Types.TokenId, entityId : Text) : async Types.NftResult { - switch (List.get(nfts, Nat64.toNat(spaceId))) { - case (null) { - return #Err(#InvalidTokenId); - }; - case (?token) { - // only owner may update - if (token.owner != caller) { - return #Err(#Unauthorized); - }; - // assemble updated space data, then update nfts list - // create placeholder objects... - var aboutDescriptionObject = { - key = "aboutDescription"; - val: Types.MetadataVal = #TextContent "This is my flaming hot Personal Web Space. Enjoy!"; - }; - var creatorObject = { - key = "creator"; - val: Types.MetadataVal = #PrincipalContent caller; - }; - var creationTimeObject = { - key = "creationTime"; - val: Types.MetadataVal = #Nat64Content (Nat64.fromNat(0)); - }; - var protocolEntityIdObject = { - key = "protocolEntityId"; - val: Types.MetadataVal = #TextContent entityId; - }; - var ownerNameObject = { - key = "ownerName"; - val: Types.MetadataVal = #TextContent ""; - }; - var ownerContactInfoObject = { - key = "ownerContactInfo"; - val: Types.MetadataVal = #TextContent ""; - }; - var spaceDescriptionObject = { - key = "spaceDescription"; - val: Types.MetadataVal = #TextContent ""; - }; - var spaceNameObject = { - key = "spaceName"; - val: Types.MetadataVal = #TextContent ""; - }; - // ... and fill them with space's current data - for (i in token.metadata[0].key_val_data.keys()) { - if (token.metadata[0].key_val_data[i].key == "aboutDescription") { - aboutDescriptionObject := token.metadata[0].key_val_data[i]; // currently not used, thus remains unchanged - } else if (token.metadata[0].key_val_data[i].key == "creator") { - creatorObject := token.metadata[0].key_val_data[i]; // should remain unchanged - } else if (token.metadata[0].key_val_data[i].key == "creationTime") { - creationTimeObject := token.metadata[0].key_val_data[i]; // should remain unchanged - } else if (token.metadata[0].key_val_data[i].key == "ownerName") { - ownerNameObject := token.metadata[0].key_val_data[i]; // should remain unchanged - } else if (token.metadata[0].key_val_data[i].key == "ownerContactInfo") { - ownerContactInfoObject := token.metadata[0].key_val_data[i]; // should remain unchanged - } else if (token.metadata[0].key_val_data[i].key == "spaceDescription") { - spaceDescriptionObject := token.metadata[0].key_val_data[i]; // should remain unchanged - } else if (token.metadata[0].key_val_data[i].key == "spaceName") { - spaceNameObject := token.metadata[0].key_val_data[i]; // should remain unchanged - }; - }; - - let updatedKeyValData: [Types.MetadataKeyVal] = [ - ownerNameObject, - ownerContactInfoObject, - aboutDescriptionObject, - spaceDescriptionObject, - spaceNameObject, - creatorObject, - creationTimeObject, - protocolEntityIdObject - ]; - - let spaceData = token.metadata[0].data; // should remain unchanged - - let updatedMetadataPart : Types.MetadataPart = { - purpose = #Rendered; - key_val_data = updatedKeyValData; - data = spaceData; - }; - let updatedMetadata : Types.MetadataDesc = [updatedMetadataPart]; - let updatedNft : Types.Nft = { - owner = token.owner; - id = token.id; - metadata = updatedMetadata; - }; - - // add updated space to list of NFTs - nfts := List.map(nfts, func (item : Types.Nft) : Types.Nft { - if (item.id == token.id) { - return updatedNft; - } else { - return item; - }; - }); - transactionId += 1; - switch (List.get(nfts, Nat64.toNat(spaceId))) { - case (null) { - return #Err(#InvalidTokenId); - }; - case (?updatedSpace) { - return #Ok(updatedSpace); - } - }; - }; - }; - }; - - // Update a Space's metadata fields including the Space's data which is displayed (if updatedSpaceData is provided) - public shared({ caller }) func updateUserSpace(updatedUserSpaceData: Types.UpdateMetadataValuesInput) : async Types.NftResult { - switch (List.get(nfts, Nat64.toNat(updatedUserSpaceData.id))) { - case (null) { - return #Err(#InvalidTokenId); - }; - case (?token) { - // only owner may update - if (token.owner != caller) { - return #Err(#Unauthorized); - }; - // assemble updated space data, then update nfts list - // create placeholder objects... - var creatorObject = { - key = "creator"; - val: Types.MetadataVal = #PrincipalContent caller; - }; - var creationTimeObject = { - key = "creationTime"; - val: Types.MetadataVal = #Nat64Content (Nat64.fromNat(0)); - }; - var protocolEntityIdObject = { - key = "protocolEntityId"; - val: Types.MetadataVal = #TextContent ""; - }; - // ... and fill them with space's current data - for (i in token.metadata[0].key_val_data.keys()) { - if (token.metadata[0].key_val_data[i].key == "creator") { - creatorObject := token.metadata[0].key_val_data[i]; // should always remain unchanged - } else if (token.metadata[0].key_val_data[i].key == "creationTime") { - creationTimeObject := token.metadata[0].key_val_data[i]; // should always remain unchanged - } else if (token.metadata[0].key_val_data[i].key == "protocolEntityId") { - protocolEntityIdObject := token.metadata[0].key_val_data[i]; // should always remain unchanged - }; - }; - - let updatedKeyValData: [Types.MetadataKeyVal] = [ - { - key = "ownerName"; - val = #TextContent (updatedUserSpaceData.updatedOwnerName); - }, - { - key = "ownerContactInfo"; - val = #TextContent (updatedUserSpaceData.updatedOwnerContactInfo); - }, - { - key = "aboutDescription"; - val = #TextContent (updatedUserSpaceData.updatedAboutDescription); - }, - { - key = "spaceDescription"; - val = #TextContent (updatedUserSpaceData.updatedSpaceDescription); - }, - { - key = "spaceName"; - val = #TextContent (updatedUserSpaceData.updatedSpaceName); - }, - creatorObject, - creationTimeObject, - protocolEntityIdObject - ]; - // updatedSpaceData is an optional attribute; only use it to update the Space if it was provided - let spaceData = switch(updatedUserSpaceData.updatedSpaceData) { - case (null) {token.metadata[0].data}; - case (?"") {token.metadata[0].data}; - case (?updatedSpaceData) {Text.encodeUtf8(updatedSpaceData)} //TODO: probably check provided HTML - }; - let updatedMetadataPart : Types.MetadataPart = { - purpose = #Rendered; - key_val_data = updatedKeyValData; - data = spaceData; - }; - let updatedMetadata : Types.MetadataDesc = [updatedMetadataPart]; - let updatedNft : Types.Nft = { - owner = token.owner; - id = token.id; - metadata = updatedMetadata; - }; - - // add updated space to list of NFTs - nfts := List.map(nfts, func (item : Types.Nft) : Types.Nft { - if (item.id == token.id) { - return updatedNft; - } else { - return item; - }; - }); - transactionId += 1; - switch (List.get(nfts, Nat64.toNat(updatedUserSpaceData.id))) { - case (null) { - return #Err(#InvalidTokenId); - }; - case (?updatedSpace) { - return #Ok(updatedSpace); - } - }; - }; - }; - }; - -// HTTP interface - public query func http_request(request : HTTP.Request) : async HTTP.Response { - //Debug.print(debug_show("http_request test")); - //Debug.print(debug_show(request)); - if (Text.contains(request.url, #text("tokenid"))) { // endpoint for Stoic Wallet/Entrepot - let tokenId = Iter.toArray(Text.tokens(request.url, #text("tokenid=")))[1]; - let { index } = Stoic.decodeToken(tokenId); - let item = List.get(nfts, Nat32.toNat(index)); - switch (item) { - case (null) { - let response = { - body = Text.encodeUtf8("Invalid tokenid"); - headers = []; - status_code = 404 : Nat16; - streaming_strategy = null; - upgrade = false; - }; - return(response); - }; - case (?token) { - let body = token.metadata[0].data; - let response = { - body = body; - headers = [("Content-Type", "text/html"), ("Content-Length", Nat.toText(body.size()))]; - status_code = 200 : Nat16; - streaming_strategy = null; - upgrade = false; - }; - return(response); - }; - }; - } else if (Text.contains(request.url, #text("spaceId"))) { - let spaceId = Iter.toArray(Text.tokens(request.url, #text("spaceId=")))[1]; - let item = List.get(nfts, textToNat(spaceId)); - switch (item) { - case (null) { - let response = { - body = Text.encodeUtf8("Invalid spaceId"); - headers = []; - status_code = 404 : Nat16; - streaming_strategy = null; - upgrade = false; - }; - return(response); - }; - case (?token) { - let body = token.metadata[0].data; - let response = { - body = body; - headers = [("Content-Type", "text/html"), ("Content-Length", Nat.toText(body.size()))]; - status_code = 200 : Nat16; - streaming_strategy = null; - upgrade = false; - }; - return(response); - }; - }; - } else if (Text.contains(request.url, #text("/file/"))) { - if (Text.contains(request.url, #text("fileId"))) { - var fileId = Iter.toArray(Text.tokens(request.url, #text("fileId=")))[1]; - if (Text.contains(fileId, #text("canisterId"))) { - // for local retrievals during development - fileId := Iter.toArray(Text.tokens(fileId, #text("?canisterId")))[0]; - }; - let item = fileDatabase.get(fileId); - switch (item) { - case (null) { - let response = { - body = Text.encodeUtf8("Invalid fileId " # fileId); - headers = []; - status_code = 404 : Nat16; - streaming_strategy = null; - upgrade = false; - }; - return(response); - }; - case (?file) { - let body = file.file_content; - let response = { - body = body; - headers = [("Content-Disposition", "inline; filename=\""#file.file_name#"\""), ("Content-Type", "model/gltf-binary"), ("Content-Length", Nat.toText(body.size())), ("Access-Control-Allow-Origin", "*"), ("X-Frame-Options", "ALLOWALL")]; - status_code = 200 : Nat16; - streaming_strategy = null; - upgrade = false; - }; - return(response); - }; - }; - } else { - let response = { - body = Text.encodeUtf8("Not implemented"); - headers = []; - status_code = 404 : Nat16; - streaming_strategy = null; - upgrade = false; - }; - return(response); - }; - } else { - return { - upgrade = false; // ← If this is set to true, the request will be sent to http_request_update() - status_code = 200; - headers = [ ("content-type", "text/plain") ]; - body = "It does not work"; - streaming_strategy = null; - }; - }; - }; - - -/* - * - * - * - * - * Code for uploading files - * - * - * -*/ -// 1 MB is the max size for a single file -let oneMB : Nat = 1048576; // 1 MB -private let maxFileSize : Nat = oneMB; -private let maxTotalSize : Nat = 10 * oneMB; -private let maxFiles : Nat = 10; - -// A simple file storage database which stores a unique file ID in the form of a 128 bit (16 byte) UUID as -// defined by RFC 4122 -// Files should be synced with the UserRecord associated with it to keep the user/data scheme in sync -private var fileDatabase : HashMap.HashMap = HashMap.HashMap(0, Text.equal, Text.hash); -// Stable version of the file database for cansiter upgrades -stable var fileDatabaseStable : [(Text, FileTypes.FileInfo)] = []; - -// Variable stores reference of a user with all the files they have uploaded to their account. -// The user record stores reference to all the UUIDs for the files they have stored -private var userFileRecords : HashMap.HashMap = HashMap.HashMap(0, Text.equal, Text.hash); -// Stable version of the userFileRecords for canister upgrades -stable var userFileRecordsStable : [(Text, FileTypes.UserRecord)] = []; - -/* - * Function retrieves the total size of the files uploaded to their account - * - * @params user: The user id associated with the account, i.e a text representation of the principal - * @return The total size of files uploaded to their account -*/ -private func getUserFilesTotalSize(user: FileTypes.FileUserId) : Nat { - switch (userFileRecords.get(Principal.toText(user))) { - case (null) { return 0; }; - case (?userRecord) { return userRecord.totalSize; }; - }; -}; - -/* - * Function all the file ids associated with the user account - * @params user: The user id associated with the account, i.e a text representation of the principal - * @return All the File Ids associated with the user account. The file Ids can be used to retrieve the files - * stored within the fileDatabase -*/ -private func getUserFileIds(user: FileTypes.FileUserId) : [Text] { - switch (userFileRecords.get(Principal.toText(user))) { - case (null) { return []; }; - case (?userRecord) { - return userRecord.file_ids; - }; - }; -}; - -/* - * Function retrives all the FileInfo (i.e files) associated with the user account - * @params user: The user id associated with the account, i.e a text representation of the principal - * @return All the FileInfo structs for the user account which contain the file and other relevant information -*/ -private func getUserFiles(user: FileTypes.FileUserId) : Buffer.Buffer { - switch (userFileRecords.get(Principal.toText(user))) { - case (null) { return Buffer.Buffer(0); }; - case (?userRecord) { - var userFileInfo = Buffer.Buffer(userRecord.file_ids.size()); - for (file_id in userRecord.file_ids.vals()) - { - let retrievedFileInfo : ?FileTypes.FileInfo = fileDatabase.get(file_id); - switch (retrievedFileInfo) { - case(null) {}; - case(?checkedFileInfo) { - userFileInfo.add(checkedFileInfo); - } - }; - - }; - return userFileInfo; - }; - }; -}; - -/* - * Function which checks the file extension and ensures that it is within the supported formats - * - * @params fileName: The file name to check to see if it is valid - * @return Whether the file name is a valid type - * - * @note: Checking if a file is valid via the file extension is generally dumb since it is easy to change. - * In the future we want to add the ability to inspect the file and ensure it is actually the file - * it claims to be. -*/ -private func isValidFileExtension(fileName : Text) : Bool { - let validExtensions : [Text] = ["glb", "gltf", "jpg", "jpeg", "png", "gif", "svg", "mp4", "mov"]; - var extensionMatched : Bool = false; - for (extension in validExtensions.vals()) - { - if (Text.endsWith(fileName, #text extension)) - { - extensionMatched := true; - return extensionMatched; - }; - }; - - return extensionMatched; -}; - -/* - * Public Function which enables a logged in user to upload a file to their account if they have enough space available - * @params fileName: The file name that the uploaded file should be called - * @params content: The file to be uploaded - * @return A text of the results of the uploading status -*/ -public shared(msg) func uploadUserFile(fileName : Text, content : FileTypes.File) : async FileTypes.FileResult { - - let user = msg.caller; - - if (Principal.isAnonymous(user)) - { - return #Err(#Unauthorized); - }; - - // Ensure that the file extension is supported - let validExtension : Bool = isValidFileExtension(fileName); - if (validExtension == false) { - return #Err(#Other("File Extension not valid")); - }; - - // Make sure the new file isn't above the limit - let fileSize = content.size(); - if (fileSize > maxFileSize) { - return #Err(#Other("Error: File size exceeds the limit.")); - }; - - // Ensure that the user isn't uploading an empty file - if (fileSize <= 0) { - return #Err(#Other("Error: File Empty")); - }; - - // Check to make sure a file with that name isn't already uploaded - let userFiles = getUserFiles(user); - var fileNameAlreadyExists : Bool = false; - for (fileInfo in userFiles.vals()) - { - if (fileInfo.file_name == fileName) - { - fileNameAlreadyExists := true; - }; - }; - if (fileNameAlreadyExists) - { - return #Err(#Other("Error: File Name Already Exists")); - }; - - // Retrieve the total amount of data stored by the user - let userTotalSize = getUserFilesTotalSize(user); - if (userTotalSize + fileSize > maxTotalSize) { - return #Err(#Other("Error: Total size limit reached.")); - }; - - // Retrieve all the file ids used by the current user - let userFilesIds = getUserFileIds(user); - if (userFilesIds.size() >= maxFiles) { - return #Err(#Other("Error: File limit reached.")); - }; - - var found_unique_file_id : Bool = false; - var counter : Nat = 0; - var newFileId : Text = ""; - - // Keep searching for a unique name until one is found, the chances of collisions are really low - // but in case it happens keep looping until a file id is not found - while(not found_unique_file_id) - { - // 100 is chosen arbitarily to ensure that in case of something weird happening - // there is a timeout and it errors rather then looking forever - if (counter > 100) - { - return #Err(#Other("Error: Failed to upload file due to not finding a unique identifier, please contact support")); - }; - - // Technically there is a race condition here... lets see if we can make this an atomic - // operation. For now since the chance of a collision is realllly low, the chance that two names within - // the time the UUID is checked and then aquired 1 line later happens to be the same is small - // we can leave this for now. When we have higher usage we probably should integrate to a more robust - // database system with atomic operations anyways. - // The only risk is if the randomness in the names isn't that random? We will have to see how robust the Random module is. - // Checking for race conditions in the uploading will need to be checked in the future - newFileId := await Utils.newRandomUniqueId(); - if (fileDatabase.get(newFileId) == null) - { - // Claim the id by putting an empty record into it - fileDatabase.put(newFileId, { file_name = "blank"; file_content = ""; owner_principal = "blank"}); - found_unique_file_id := true; - }; - - counter := counter + 1; - }; - - // Add the new file to the file database - let file_info = { file_name = fileName; file_content = content; owner_principal = Principal.toText(user) }; - fileDatabase.put(newFileId, file_info); - - // Add the new file id to the user record - let newFilesId = Array.append(userFilesIds,[newFileId]); - let newUserRecord = {file_ids = newFilesId; totalSize = userTotalSize + fileSize }; - userFileRecords.put(Principal.toText(user), newUserRecord); - - return #Ok(#FileId(newFileId)); -}; - -/* - * Public Function which displays all the file names that the user has uploaded to their account - * @return An array of text that contain all the file names uploaded to the current users account -*/ -public shared(msg) func listUserFileNames() : async FileTypes.FileResult { - let user = msg.caller; - let userFiles = getUserFiles(user); - return #Ok(#FileNames(Array.map(userFiles.toArray(), func fileInfo = fileInfo.file_name))); -}; - -/* - * Public Function which displays all the file ids that the user has uploaded to their account - * @return An array of text that contain all the file ids uploaded to the current users account -*/ -public shared(msg) func listUserFileIds() : async FileTypes.FileResult { - let user = msg.caller; - let userFileIds = getUserFileIds(user); - return #Ok(#FileIds(userFileIds)); -}; - -/* - * Public Function which retrieves a file info by file id - * Currently there are no visability constraints on files, but once visability is built it can be added here - * - * @return The file info associated with the file id -*/ -public query func getFile(fileId: Text) : async FileTypes.FileResult { - let retrievedFile = fileDatabase.get(fileId); - switch (retrievedFile) - { - case(null) {return #Err(#Other("Error getting file"));}; - case(?file) { - return #Ok(#File(file)); - }; - }; -}; - -/* - * Public Function which retrieves the logged in users userRecord - * - * @return The user record associated with the logged in users -*/ -public shared(msg) func getUserRecord() : async FileTypes.FileResult { - let user = msg.caller; - let retrievedUserRecord = userFileRecords.get(Principal.toText(user)); - switch(retrievedUserRecord) { - case(null) {#Err(#Other("Error getting user record"));}; - case(?userRecord) {#Ok(#UserRecord(userRecord));}; - }; -}; - -/* - * Public Function which deletes the file_id that is passed in - * The file must be owned by the current logged in user to allow deleting the file - * - * @return The file info associated with the file id -*/ -public shared(msg) func deleteFile(fileId: Text) : async FileTypes.FileResult { - let user = msg.caller; - - if (Principal.isAnonymous(user)) - { - return #Err(#Unauthorized); - }; - - // Check to make sure that the user owns the file attempting to be deleted - let userFileIds = getUserFileIds(user); - let fileIdOwnedByUser : Bool = Array.find(userFileIds, func x = fileId == x) != null; - if (fileIdOwnedByUser == false) - { - return #Err(#Other("Error deleting file")); - }; - - // Figure out the size of the file attempting to be deleted - let fileInfo : ?FileTypes.FileInfo = fileDatabase.get(fileId); - var fileSize = 0; - switch (fileInfo) { - case (null) { fileSize := 0;}; - case (?value) { fileSize := value.file_content.size(); }; - }; - - // // Attempt to retrieve the user record and then delete the file and then update - // the user record to reflect the file being deleted - let optionalUserRecord : ?FileTypes.UserRecord = userFileRecords.get(Principal.toText(user)); - switch (optionalUserRecord) { - case (null) { - return #Err(#Other("Error deleting file")); - }; - case (?userRecord) { - - // Delete the file - let deleteFileResult = fileDatabase.remove(fileId); - - // Delete the file from the user record and reduce the file size - let updatedFileIds : [Text] = Array.filter(userFileIds, func x = x != fileId); - let newUserRecord : FileTypes.UserRecord = {file_ids = updatedFileIds; totalSize = userRecord.totalSize - fileSize; }; - userFileRecords.put(Principal.toText(user), newUserRecord); - }; - }; - - return #Ok(#Success); - }; - -// Email Signups from Website - stable var emailSubscribersStorageStable : [(Text, Types.EmailSubscriber)] = []; - var emailSubscribersStorage : HashMap.HashMap = HashMap.HashMap(0, Text.equal, Text.hash); - - // Add a user as new email subscriber - private func putEmailSubscriber(emailSubscriber : Types.EmailSubscriber) : Text { - emailSubscribersStorage.put(emailSubscriber.emailAddress, emailSubscriber); - return emailSubscriber.emailAddress; - }; - - // Retrieve an email subscriber by email address - private func getEmailSubscriber(emailAddress : Text) : ?Types.EmailSubscriber { - let result = emailSubscribersStorage.get(emailAddress); - return result; - }; - - // User can submit a form to sign up for email updates - // For now, we only capture the email address provided by the user and on which page they submitted the form - public func submitSignUpForm(submittedSignUpForm : Types.SignUpFormInput) : async Text { - switch(getEmailSubscriber(submittedSignUpForm.emailAddress)) { - case null { - // New subscriber - let emailSubscriber : Types.EmailSubscriber = { - emailAddress: Text = submittedSignUpForm.emailAddress; - pageSubmittedFrom: Text = submittedSignUpForm.pageSubmittedFrom; - subscribedAt: Nat64 = Nat64.fromNat(Int.abs(Time.now())); - }; - let result = putEmailSubscriber(emailSubscriber); - if (result != emailSubscriber.emailAddress) { - return "There was an error signing up. Please try again."; - }; - return "Successfully signed up!"; - }; - case _ { return "Already signed up!"; }; - }; - }; - - // Function for custodian to get all email subscribers - public shared({ caller }) func getEmailSubscribers() : async [(Text, Types.EmailSubscriber)] { - // Only Principals registered as custodians can access this function - if (List.some(custodians, func (custodian : Principal) : Bool { custodian == caller })) { - return Iter.toArray(emailSubscribersStorage.entries()); - }; - return []; - }; - - // Function for custodian to delete an email subscriber - public shared({ caller }) func deleteEmailSubscriber(emailAddress : Text) : async Bool { - // Only Principals registered as custodians can access this function - if (List.some(custodians, func (custodian : Principal) : Bool { custodian == caller })) { - emailSubscribersStorage.delete(emailAddress); - return true; - }; - return false; - }; - -// Upgrade Hooks - system func preupgrade() { - fileDatabaseStable := Iter.toArray(fileDatabase.entries()); - userFileRecordsStable := Iter.toArray(userFileRecords.entries()); - emailSubscribersStorageStable := Iter.toArray(emailSubscribersStorage.entries()); - }; - - system func postupgrade() { - fileDatabase := HashMap.fromIter(Iter.fromArray(fileDatabaseStable), fileDatabaseStable.size(), Text.equal, Text.hash); - fileDatabaseStable := []; - userFileRecords := HashMap.fromIter(Iter.fromArray(userFileRecordsStable), userFileRecordsStable.size(), Text.equal, Text.hash); - userFileRecordsStable := []; - emailSubscribersStorage := HashMap.fromIter(Iter.fromArray(emailSubscribersStorageStable), emailSubscribersStorageStable.size(), Text.equal, Text.hash); - emailSubscribersStorageStable := []; - }; -}; +import List "mo:base/List"; +import Principal "mo:base/Principal"; +import Text "mo:base/Text"; +import Iter "mo:base/Iter"; +import Nat "mo:base/Nat"; +import Nat16 "mo:base/Nat16"; +import Nat32 "mo:base/Nat32"; +import Nat64 "mo:base/Nat64"; +import Time "mo:base/Time"; +import Int "mo:base/Int"; +import Char "mo:base/Char"; +import AssocList "mo:base/AssocList"; +import Buffer "mo:base/Buffer"; +import Random "mo:base/Random"; +import RBTree "mo:base/RBTree"; +import HashMap "mo:base/HashMap"; +import Array "mo:base/Array"; + +import FileTypes "./types/FileStorageTypes"; +import Utils "./Utils"; + +import Types "./Types"; +import HTTP "./Http"; + +import Stoic "./EXT/Stoic"; + +import Protocol "./Protocol"; +import Testable "mo:matchers/Testable"; +import Blob "mo:base/Blob"; + + + +shared actor class PersonalWebSpace(custodian: Principal, init : Types.Dip721NonFungibleToken) = Self { +// TODO: instead add functions to manage cycles balance and gather stats + public func greet(name : Text) : async Text { + return "Hello, " # name # "!"; + }; + + // DIP721 standard: https://github.com/dfinity/examples/blob/master/motoko/dip-721-nft-container/src/Main.mo + stable var transactionId: Types.TransactionId = 0; + stable var nfts = List.nil(); + stable var custodians = List.make(custodian); + stable var logo : Types.LogoResult = init.logo; + stable var name : Text = init.name; + stable var symbol : Text = init.symbol; + stable var maxLimit : Nat16 = init.maxLimit; + + // https://forum.dfinity.org/t/is-there-any-address-0-equivalent-at-dfinity-motoko/5445/3 + let null_address : Principal = Principal.fromText("aaaaa-aa"); + + public query func balanceOfDip721(user: Principal) : async Nat64 { + return Nat64.fromNat( + List.size( + List.filter(nfts, func(token: Types.Nft) : Bool { token.owner == user }) + ) + ); + }; + + public query func ownerOfDip721(token_id: Types.TokenId) : async Types.OwnerResult { + let item = List.get(nfts, Nat64.toNat(token_id)); + switch (item) { + case (null) { + return #Err(#InvalidTokenId); + }; + case (?token) { + return #Ok(token.owner); + }; + }; + }; + + public shared({ caller }) func safeTransferFromDip721(from: Principal, to: Principal, token_id: Types.TokenId) : async Types.TxReceipt { + if (to == null_address) { + return #Err(#ZeroAddress); + } else { + return transferFrom(from, to, token_id, caller); + }; + }; + + public shared({ caller }) func transferFromDip721(from: Principal, to: Principal, token_id: Types.TokenId) : async Types.TxReceipt { + return transferFrom(from, to, token_id, caller); + }; + + func transferFrom(from: Principal, to: Principal, token_id: Types.TokenId, caller: Principal) : Types.TxReceipt { + let item = List.get(nfts, Nat64.toNat(token_id)); + switch (item) { + case null { + return #Err(#InvalidTokenId); + }; + case (?token) { + if ( + caller != token.owner and + not List.some(custodians, func (custodian : Principal) : Bool { custodian == caller }) + ) { + return #Err(#Unauthorized); + } else if (Principal.notEqual(from, token.owner)) { + return #Err(#Unauthorized); + } else { + nfts := List.map(nfts, func (item : Types.Nft) : Types.Nft { + if (item.id == token.id) { + let update : Types.Nft = { + owner = to; + id = item.id; + metadata = token.metadata; + }; + return update; + } else { + return item; + }; + }); + transactionId += 1; + return #Ok(transactionId); + }; + }; + }; + }; + + public query func supportedInterfacesDip721() : async [Types.InterfaceId] { + return [#TransferNotification, #Burn, #Mint]; + }; + + public query func logoDip721() : async Types.LogoResult { + return logo; + }; + + public query func nameDip721() : async Text { + return name; + }; + + public query func symbolDip721() : async Text { + return symbol; + }; + + public query func totalSupplyDip721() : async Nat64 { + return Nat64.fromNat( + List.size(nfts) + ); + }; + + public query func getMetadataDip721(token_id: Types.TokenId) : async Types.MetadataResult { + let item = List.get(nfts, Nat64.toNat(token_id)); + switch (item) { + case null { + return #Err(#InvalidTokenId); + }; + case (?token) { + return #Ok(token.metadata); + } + }; + }; + + public query func getMaxLimitDip721() : async Nat16 { + return maxLimit; + }; + + public func getMetadataForUserDip721(user: Principal) : async Types.ExtendedMetadataResult { + let item = List.find(nfts, func(token: Types.Nft) : Bool { token.owner == user }); + switch (item) { + case null { + return #Err(#Other("No token found for this user")); + }; + case (?token) { + return #Ok({ + metadata_desc = token.metadata; + token_id = token.id; + }); + } + }; + }; + + public query func getTokenIdsForUserDip721(user: Principal) : async [Types.TokenId] { + let items = List.filter(nfts, func(token: Types.Nft) : Bool { token.owner == user }); + let tokenIds = List.map(items, func (item : Types.Nft) : Types.TokenId { item.id }); + return List.toArray(tokenIds); + }; + + public shared query ({caller}) func check_user_has_nft() : async Bool { + let user = caller; + let items = List.filter(nfts, func(token: Types.Nft) : Bool { token.owner == user }); + let tokenIds = List.map(items, func (item : Types.Nft) : Types.TokenId { item.id }); + let userTokenIds = List.toArray(tokenIds); + if (userTokenIds.size() == 0) { + return false; + } else { + return true; + } + }; + + public shared({ caller }) func mintDip721(to: Principal, metadata: Types.MetadataDesc) : async Types.MintReceipt { + if (not List.some(custodians, func (custodian : Principal) : Bool { custodian == caller })) { + return #Err(#Unauthorized); + }; + + let newId = Nat64.fromNat(List.size(nfts)); + let nft : Types.Nft = { + owner = to; + id = newId; + metadata = metadata; + }; + + var tempList = List.nil(); + tempList := List.push(nft, tempList); + nfts := List.append(nfts, tempList); + + transactionId += 1; + + return #Ok({ + token_id = newId; + id = transactionId; + }); + }; + + // Helper functions + func textToNat(txt : Text) : Nat { + assert(txt.size() > 0); + let chars = txt.chars(); + + var num : Nat = 0; + for (v in chars){ + let charToNum = Nat32.toNat(Char.toNat32(v)-48); + assert(charToNum >= 0 and charToNum <= 9); + num := num * 10 + charToNum; + }; + + num; + }; + + func textToNat64(txt : Text) : Nat64 { + assert(txt.size() > 0); + let chars = txt.chars(); + + var num : Nat = 0; + for (v in chars){ + let charToNum = Nat32.toNat(Char.toNat32(v)-48); + assert(charToNum >= 0 and charToNum <= 9); + num := num * 10 + charToNum; + }; + + Nat64.fromNat(num); + }; + +// Project-specific functions + // ##################### NFT Details ################# + // defined according to NFT in Types + /* + Types.MetadataDesc for this project looks like: + [ + { + purpose: #Rendered ; + data: spaceAsHtmlTextBlob // Text.encodeUtf8(spaceAsHtmlText) to get Blob from Text (probably change to spaceAsJsonFormattedTextBlob later) + key_val_data: [ + { + key = "ownerName"; + val = #TextContent ownerName; + }, + { + key = "ownerContactInfo"; + val = #TextContent ownerContactInfo; + }, + { + key = "aboutDescription"; + val = #TextContent aboutDescription; + }, + { + key = "spaceDescription"; + val = #TextContent spaceDescription; + }, + { + key = "spaceName"; + val = #TextContent spaceName; + }, + { + key = "creator"; + val: #PrincipalContent caller; + }, + { + key = "creationTime"; + val = #Nat64Content generatedTimestamp; + }, + { + key = "protocolEntityId"; + val = #TextContent protocolEntityId; + }, + ]; + } + ] + */ + + public shared({ caller }) func createSpace(spaceHtml : Text) : async Types.NftResult { + // don't allow anonymous Principal + if (Principal.isAnonymous(caller)) { + return #Err(#Unauthorized); + }; + + let newId = Nat64.fromNat(List.size(nfts)); + + // create space for caller + let textArrayContent : [Text] = []; + let keyValData : [Types.MetadataKeyVal] = [ + { + key = "ownerName"; + val = #TextContent ""; + }, + { + key = "ownerContactInfo"; + val = #TextContent ""; + }, + { + key = "aboutDescription"; + val = #TextContent "This is my flaming hot Personal Web Space. Enjoy!"; + }, + { + key = "spaceDescription"; + val = #TextContent "My virtual home - heeyah"; + }, + { + key = "spaceName"; + val = #TextContent "My Flaming Hot Personal Web Space"; + }, + { + key = "creator"; + val = #PrincipalContent caller; + }, + { + key = "creationTime"; + val = #Nat64Content (Nat64.fromNat(Int.abs(Time.now()))); + }, + { + key = "protocolEntityId"; + val = #TextContent ""; // not initialized yet, needs to be updated by the frontend after creating the Entity + } + ]; + let nftData = Text.encodeUtf8(spaceHtml); + + let metadataPart : Types.MetadataPart = { + purpose = #Rendered; + key_val_data = keyValData; + data = nftData; //provided space HTML + }; + let metadata : Types.MetadataDesc = [metadataPart]; + let nft : Types.Nft = { + owner = caller; + id = newId; + metadata = metadata; + }; + + var tempList = List.nil(); + tempList := List.push(nft, tempList); + nfts := List.append(nfts, tempList); + + transactionId += 1; + + return #Ok(nft); + }; + + public shared query ({caller}) func getCallerSpaces() : async [Types.Nft] { + let spaces = List.filter(nfts, func(token: Types.Nft) : Bool { token.owner == caller }); + return List.toArray(spaces); + }; + + public shared query ({caller}) func getSpace(spaceId : Types.TokenId) : async Types.NftResult { + let item = List.get(nfts, Nat64.toNat(spaceId)); + switch (item) { + case (null) { + return #Err(#InvalidTokenId); + }; + case (?token) { + return #Ok(token); + }; + }; + }; + + public func getRandomSpace() : async Types.NftResult { + let numberOfSpaces = List.size(nfts); + if (numberOfSpaces > 0) { + let random = Random.Finite(await Random.blob()); + var p : Nat8 = 16; + + if (numberOfSpaces < 256) { + p := 8; + } else if (numberOfSpaces < 2049) { + p := 11; + } else if (numberOfSpaces < 8193) { + p := 13; + }; + switch (random.range(p)) { + case (null) { + return #Err(#Other("Error retrieving a random space")); + }; + case (?randomNumber) { + let spaceId = randomNumber % numberOfSpaces; + let item = List.get(nfts, spaceId); + switch (item) { + case (null) { + return #Err(#InvalidTokenId); + }; + case (?token) { + return #Ok(token); + }; + }; + }; + }; + } else { + return #Err(#Other("No space available")); + }; + }; + + // Update the Space's Entity id (should only be necessary after creating the Entity) + public shared({ caller }) func updateSpaceEntityId(spaceId : Types.TokenId, entityId : Text) : async Types.NftResult { + switch (List.get(nfts, Nat64.toNat(spaceId))) { + case (null) { + return #Err(#InvalidTokenId); + }; + case (?token) { + // only owner may update + if (token.owner != caller) { + return #Err(#Unauthorized); + }; + // assemble updated space data, then update nfts list + // create placeholder objects... + var aboutDescriptionObject = { + key = "aboutDescription"; + val: Types.MetadataVal = #TextContent "This is my flaming hot Personal Web Space. Enjoy!"; + }; + var creatorObject = { + key = "creator"; + val: Types.MetadataVal = #PrincipalContent caller; + }; + var creationTimeObject = { + key = "creationTime"; + val: Types.MetadataVal = #Nat64Content (Nat64.fromNat(0)); + }; + var protocolEntityIdObject = { + key = "protocolEntityId"; + val: Types.MetadataVal = #TextContent entityId; + }; + var ownerNameObject = { + key = "ownerName"; + val: Types.MetadataVal = #TextContent ""; + }; + var ownerContactInfoObject = { + key = "ownerContactInfo"; + val: Types.MetadataVal = #TextContent ""; + }; + var spaceDescriptionObject = { + key = "spaceDescription"; + val: Types.MetadataVal = #TextContent ""; + }; + var spaceNameObject = { + key = "spaceName"; + val: Types.MetadataVal = #TextContent ""; + }; + // ... and fill them with space's current data + for (i in token.metadata[0].key_val_data.keys()) { + if (token.metadata[0].key_val_data[i].key == "aboutDescription") { + aboutDescriptionObject := token.metadata[0].key_val_data[i]; // currently not used, thus remains unchanged + } else if (token.metadata[0].key_val_data[i].key == "creator") { + creatorObject := token.metadata[0].key_val_data[i]; // should remain unchanged + } else if (token.metadata[0].key_val_data[i].key == "creationTime") { + creationTimeObject := token.metadata[0].key_val_data[i]; // should remain unchanged + } else if (token.metadata[0].key_val_data[i].key == "ownerName") { + ownerNameObject := token.metadata[0].key_val_data[i]; // should remain unchanged + } else if (token.metadata[0].key_val_data[i].key == "ownerContactInfo") { + ownerContactInfoObject := token.metadata[0].key_val_data[i]; // should remain unchanged + } else if (token.metadata[0].key_val_data[i].key == "spaceDescription") { + spaceDescriptionObject := token.metadata[0].key_val_data[i]; // should remain unchanged + } else if (token.metadata[0].key_val_data[i].key == "spaceName") { + spaceNameObject := token.metadata[0].key_val_data[i]; // should remain unchanged + }; + }; + + let updatedKeyValData: [Types.MetadataKeyVal] = [ + ownerNameObject, + ownerContactInfoObject, + aboutDescriptionObject, + spaceDescriptionObject, + spaceNameObject, + creatorObject, + creationTimeObject, + protocolEntityIdObject + ]; + + let spaceData = token.metadata[0].data; // should remain unchanged + + let updatedMetadataPart : Types.MetadataPart = { + purpose = #Rendered; + key_val_data = updatedKeyValData; + data = spaceData; + }; + let updatedMetadata : Types.MetadataDesc = [updatedMetadataPart]; + let updatedNft : Types.Nft = { + owner = token.owner; + id = token.id; + metadata = updatedMetadata; + }; + + // add updated space to list of NFTs + nfts := List.map(nfts, func (item : Types.Nft) : Types.Nft { + if (item.id == token.id) { + return updatedNft; + } else { + return item; + }; + }); + transactionId += 1; + switch (List.get(nfts, Nat64.toNat(spaceId))) { + case (null) { + return #Err(#InvalidTokenId); + }; + case (?updatedSpace) { + return #Ok(updatedSpace); + } + }; + }; + }; + }; + + // Update a Space's metadata fields including the Space's data which is displayed (if updatedSpaceData is provided) + public shared({ caller }) func updateUserSpace(updatedUserSpaceData: Types.UpdateMetadataValuesInput) : async Types.NftResult { + switch (List.get(nfts, Nat64.toNat(updatedUserSpaceData.id))) { + case (null) { + return #Err(#InvalidTokenId); + }; + case (?token) { + // only owner may update + if (token.owner != caller) { + return #Err(#Unauthorized); + }; + // assemble updated space data, then update nfts list + // create placeholder objects... + var creatorObject = { + key = "creator"; + val: Types.MetadataVal = #PrincipalContent caller; + }; + var creationTimeObject = { + key = "creationTime"; + val: Types.MetadataVal = #Nat64Content (Nat64.fromNat(0)); + }; + var protocolEntityIdObject = { + key = "protocolEntityId"; + val: Types.MetadataVal = #TextContent ""; + }; + // ... and fill them with space's current data + for (i in token.metadata[0].key_val_data.keys()) { + if (token.metadata[0].key_val_data[i].key == "creator") { + creatorObject := token.metadata[0].key_val_data[i]; // should always remain unchanged + } else if (token.metadata[0].key_val_data[i].key == "creationTime") { + creationTimeObject := token.metadata[0].key_val_data[i]; // should always remain unchanged + } else if (token.metadata[0].key_val_data[i].key == "protocolEntityId") { + protocolEntityIdObject := token.metadata[0].key_val_data[i]; // should always remain unchanged + }; + }; + + let updatedKeyValData: [Types.MetadataKeyVal] = [ + { + key = "ownerName"; + val = #TextContent (updatedUserSpaceData.updatedOwnerName); + }, + { + key = "ownerContactInfo"; + val = #TextContent (updatedUserSpaceData.updatedOwnerContactInfo); + }, + { + key = "aboutDescription"; + val = #TextContent (updatedUserSpaceData.updatedAboutDescription); + }, + { + key = "spaceDescription"; + val = #TextContent (updatedUserSpaceData.updatedSpaceDescription); + }, + { + key = "spaceName"; + val = #TextContent (updatedUserSpaceData.updatedSpaceName); + }, + creatorObject, + creationTimeObject, + protocolEntityIdObject + ]; + // updatedSpaceData is an optional attribute; only use it to update the Space if it was provided + let spaceData = switch(updatedUserSpaceData.updatedSpaceData) { + case (null) {token.metadata[0].data}; + case (?"") {token.metadata[0].data}; + case (?updatedSpaceData) {Text.encodeUtf8(updatedSpaceData)} //TODO: probably check provided HTML + }; + let updatedMetadataPart : Types.MetadataPart = { + purpose = #Rendered; + key_val_data = updatedKeyValData; + data = spaceData; + }; + let updatedMetadata : Types.MetadataDesc = [updatedMetadataPart]; + let updatedNft : Types.Nft = { + owner = token.owner; + id = token.id; + metadata = updatedMetadata; + }; + + // add updated space to list of NFTs + nfts := List.map(nfts, func (item : Types.Nft) : Types.Nft { + if (item.id == token.id) { + return updatedNft; + } else { + return item; + }; + }); + transactionId += 1; + switch (List.get(nfts, Nat64.toNat(updatedUserSpaceData.id))) { + case (null) { + return #Err(#InvalidTokenId); + }; + case (?updatedSpace) { + return #Ok(updatedSpace); + } + }; + }; + }; + }; + +// HTTP interface + public query func http_request(request : HTTP.Request) : async HTTP.Response { + //Debug.print(debug_show("http_request test")); + //Debug.print(debug_show(request)); + if (Text.contains(request.url, #text("tokenid"))) { // endpoint for Stoic Wallet/Entrepot + let tokenId = Iter.toArray(Text.tokens(request.url, #text("tokenid=")))[1]; + let { index } = Stoic.decodeToken(tokenId); + let item = List.get(nfts, Nat32.toNat(index)); + switch (item) { + case (null) { + let response = { + body = Text.encodeUtf8("Invalid tokenid"); + headers = []; + status_code = 404 : Nat16; + streaming_strategy = null; + upgrade = false; + }; + return(response); + }; + case (?token) { + let body = token.metadata[0].data; + let response = { + body = body; + headers = [("Content-Type", "text/html"), ("Content-Length", Nat.toText(body.size()))]; + status_code = 200 : Nat16; + streaming_strategy = null; + upgrade = false; + }; + return(response); + }; + }; + } else if (Text.contains(request.url, #text("spaceId"))) { + let spaceId = Iter.toArray(Text.tokens(request.url, #text("spaceId=")))[1]; + let item = List.get(nfts, textToNat(spaceId)); + switch (item) { + case (null) { + let response = { + body = Text.encodeUtf8("Invalid spaceId"); + headers = []; + status_code = 404 : Nat16; + streaming_strategy = null; + upgrade = false; + }; + return(response); + }; + case (?token) { + let body = token.metadata[0].data; + let response = { + body = body; + headers = [("Content-Type", "text/html"), ("Content-Length", Nat.toText(body.size()))]; + status_code = 200 : Nat16; + streaming_strategy = null; + upgrade = false; + }; + return(response); + }; + }; + } else if (Text.contains(request.url, #text("/file/"))) { + if (Text.contains(request.url, #text("fileId"))) { + var fileId = Iter.toArray(Text.tokens(request.url, #text("fileId=")))[1]; + if (Text.contains(fileId, #text("canisterId"))) { + // for local retrievals during development + fileId := Iter.toArray(Text.tokens(fileId, #text("?canisterId")))[0]; + }; + let item = fileDatabase.get(fileId); + switch (item) { + case (null) { + let response = { + body = Text.encodeUtf8("Invalid fileId " # fileId); + headers = []; + status_code = 404 : Nat16; + streaming_strategy = null; + upgrade = false; + }; + return(response); + }; + case (?file) { + let body = file.file_content; + let response = { + body = body; + headers = [("Content-Disposition", "inline; filename=\""#file.file_name#"\""), ("Content-Type", "model/gltf-binary"), ("Content-Length", Nat.toText(body.size())), ("Access-Control-Allow-Origin", "*"), ("X-Frame-Options", "ALLOWALL")]; + status_code = 200 : Nat16; + streaming_strategy = null; + upgrade = false; + }; + return(response); + }; + }; + } else { + let response = { + body = Text.encodeUtf8("Not implemented"); + headers = []; + status_code = 404 : Nat16; + streaming_strategy = null; + upgrade = false; + }; + return(response); + }; + } else { + return { + upgrade = false; // ← If this is set to true, the request will be sent to http_request_update() + status_code = 200; + headers = [ ("content-type", "text/plain") ]; + body = "It does not work"; + streaming_strategy = null; + }; + }; + }; + + +/* + * + * + * + * + * Code for uploading files + * + * + * +*/ +// 1 MB is the max size for a single file +let oneMB : Nat = 1048576; // 1 MB +private let maxFileSize : Nat = oneMB; +private let maxTotalSize : Nat = 10 * oneMB; +private let maxFiles : Nat = 10; + +// A simple file storage database which stores a unique file ID in the form of a 128 bit (16 byte) UUID as +// defined by RFC 4122 +// Files should be synced with the UserRecord associated with it to keep the user/data scheme in sync +private var fileDatabase : HashMap.HashMap = HashMap.HashMap(0, Text.equal, Text.hash); +// Stable version of the file database for cansiter upgrades +stable var fileDatabaseStable : [(Text, FileTypes.FileInfo)] = []; + +// Variable stores reference of a user with all the files they have uploaded to their account. +// The user record stores reference to all the UUIDs for the files they have stored +private var userFileRecords : HashMap.HashMap = HashMap.HashMap(0, Text.equal, Text.hash); +// Stable version of the userFileRecords for canister upgrades +stable var userFileRecordsStable : [(Text, FileTypes.UserRecord)] = []; + +/* + * Function retrieves the total size of the files uploaded to their account + * + * @params user: The user id associated with the account, i.e a text representation of the principal + * @return The total size of files uploaded to their account +*/ +private func getUserFilesTotalSize(user: FileTypes.FileUserId) : Nat { + switch (userFileRecords.get(Principal.toText(user))) { + case (null) { return 0; }; + case (?userRecord) { return userRecord.totalSize; }; + }; +}; + +/* + * Function all the file ids associated with the user account + * @params user: The user id associated with the account, i.e a text representation of the principal + * @return All the File Ids associated with the user account. The file Ids can be used to retrieve the files + * stored within the fileDatabase +*/ +private func getUserFileIds(user: FileTypes.FileUserId) : [Text] { + switch (userFileRecords.get(Principal.toText(user))) { + case (null) { return []; }; + case (?userRecord) { + return userRecord.file_ids; + }; + }; +}; + +/* + * Function retrives all the FileInfo (i.e files) associated with the user account + * @params user: The user id associated with the account, i.e a text representation of the principal + * @return All the FileInfo structs for the user account which contain the file and other relevant information +*/ +private func getUserFiles(user: FileTypes.FileUserId) : Buffer.Buffer { + switch (userFileRecords.get(Principal.toText(user))) { + case (null) { return Buffer.Buffer(0); }; + case (?userRecord) { + var userFileInfo = Buffer.Buffer(userRecord.file_ids.size()); + for (file_id in userRecord.file_ids.vals()) + { + let retrievedFileInfo : ?FileTypes.FileInfo = fileDatabase.get(file_id); + switch (retrievedFileInfo) { + case(null) {}; + case(?checkedFileInfo) { + userFileInfo.add(checkedFileInfo); + } + }; + + }; + return userFileInfo; + }; + }; +}; + +/* + * Function which checks the file extension and ensures that it is within the supported formats + * + * @params fileName: The file name to check to see if it is valid + * @return Whether the file name is a valid type + * + * @note: Checking if a file is valid via the file extension is generally dumb since it is easy to change. + * In the future we want to add the ability to inspect the file and ensure it is actually the file + * it claims to be. +*/ +private func isValidFileExtension(fileName : Text) : Bool { + let validExtensions : [Text] = ["glb", "gltf", "jpg", "jpeg", "png", "gif", "svg", "mp4", "mov"]; + var extensionMatched : Bool = false; + for (extension in validExtensions.vals()) + { + if (Text.endsWith(fileName, #text extension)) + { + extensionMatched := true; + return extensionMatched; + }; + }; + + return extensionMatched; +}; + +/* + * Public Function which enables a logged in user to upload a file to their account if they have enough space available + * @params fileName: The file name that the uploaded file should be called + * @params content: The file to be uploaded + * @return A text of the results of the uploading status +*/ +public shared(msg) func uploadUserFile(fileName : Text, content : FileTypes.File) : async FileTypes.FileResult { + + let user = msg.caller; + + if (Principal.isAnonymous(user)) + { + return #Err(#Unauthorized); + }; + + // Ensure that the file extension is supported + let validExtension : Bool = isValidFileExtension(fileName); + if (validExtension == false) { + return #Err(#Other("File Extension not valid")); + }; + + // Make sure the new file isn't above the limit + let fileSize = content.size(); + if (fileSize > maxFileSize) { + return #Err(#Other("Error: File size exceeds the limit.")); + }; + + // Ensure that the user isn't uploading an empty file + if (fileSize <= 0) { + return #Err(#Other("Error: File Empty")); + }; + + // Check to make sure a file with that name isn't already uploaded + let userFiles = getUserFiles(user); + var fileNameAlreadyExists : Bool = false; + for (fileInfo in userFiles.vals()) + { + if (fileInfo.file_name == fileName) + { + fileNameAlreadyExists := true; + }; + }; + if (fileNameAlreadyExists) + { + return #Err(#Other("Error: File Name Already Exists")); + }; + + // Retrieve the total amount of data stored by the user + let userTotalSize = getUserFilesTotalSize(user); + if (userTotalSize + fileSize > maxTotalSize) { + return #Err(#Other("Error: Total size limit reached.")); + }; + + // Retrieve all the file ids used by the current user + let userFilesIds = getUserFileIds(user); + if (userFilesIds.size() >= maxFiles) { + return #Err(#Other("Error: File limit reached.")); + }; + + var found_unique_file_id : Bool = false; + var counter : Nat = 0; + var newFileId : Text = ""; + + // Keep searching for a unique name until one is found, the chances of collisions are really low + // but in case it happens keep looping until a file id is not found + while(not found_unique_file_id) + { + // 100 is chosen arbitarily to ensure that in case of something weird happening + // there is a timeout and it errors rather then looking forever + if (counter > 100) + { + return #Err(#Other("Error: Failed to upload file due to not finding a unique identifier, please contact support")); + }; + + // Technically there is a race condition here... lets see if we can make this an atomic + // operation. For now since the chance of a collision is realllly low, the chance that two names within + // the time the UUID is checked and then aquired 1 line later happens to be the same is small + // we can leave this for now. When we have higher usage we probably should integrate to a more robust + // database system with atomic operations anyways. + // The only risk is if the randomness in the names isn't that random? We will have to see how robust the Random module is. + // Checking for race conditions in the uploading will need to be checked in the future + newFileId := await Utils.newRandomUniqueId(); + if (fileDatabase.get(newFileId) == null) + { + // Claim the id by putting an empty record into it + fileDatabase.put(newFileId, { file_name = "blank"; file_content = ""; owner_principal = "blank"}); + found_unique_file_id := true; + }; + + counter := counter + 1; + }; + + // Add the new file to the file database + let file_info = { file_name = fileName; file_content = content; owner_principal = Principal.toText(user) }; + fileDatabase.put(newFileId, file_info); + + // Add the new file id to the user record + let newFilesId = Array.append(userFilesIds,[newFileId]); + let newUserRecord = {file_ids = newFilesId; totalSize = userTotalSize + fileSize }; + userFileRecords.put(Principal.toText(user), newUserRecord); + + return #Ok(#FileId(newFileId)); +}; + +/* + * Public Function which displays all the file names that the user has uploaded to their account + * @return An array of text that contain all the file names uploaded to the current users account +*/ +public shared(msg) func listUserFileNames() : async FileTypes.FileResult { + let user = msg.caller; + let userFiles = getUserFiles(user); + return #Ok(#FileNames(Array.map(userFiles.toArray(), func fileInfo = fileInfo.file_name))); +}; + +/* + * Public Function which displays all the file ids that the user has uploaded to their account + * @return An array of text that contain all the file ids uploaded to the current users account +*/ +public shared(msg) func listUserFileIds() : async FileTypes.FileResult { + let user = msg.caller; + let userFileIds = getUserFileIds(user); + return #Ok(#FileIds(userFileIds)); +}; + +/* + * Public Function which retrieves a file info by file id + * Currently there are no visability constraints on files, but once visability is built it can be added here + * + * @return The file info associated with the file id +*/ +public query func getFile(fileId: Text) : async FileTypes.FileResult { + let retrievedFile = fileDatabase.get(fileId); + switch (retrievedFile) + { + case(null) {return #Err(#Other("Error getting file"));}; + case(?file) { + return #Ok(#File(file)); + }; + }; +}; + +/* + * Public Function which retrieves the logged in users userRecord + * + * @return The user record associated with the logged in users +*/ +public shared(msg) func getUserRecord() : async FileTypes.FileResult { + let user = msg.caller; + let retrievedUserRecord = userFileRecords.get(Principal.toText(user)); + switch(retrievedUserRecord) { + case(null) {#Err(#Other("Error getting user record"));}; + case(?userRecord) {#Ok(#UserRecord(userRecord));}; + }; +}; + +/* + * Public Function which deletes the file_id that is passed in + * The file must be owned by the current logged in user to allow deleting the file + * + * @return The file info associated with the file id +*/ +public shared(msg) func deleteFile(fileId: Text) : async FileTypes.FileResult { + let user = msg.caller; + + if (Principal.isAnonymous(user)) + { + return #Err(#Unauthorized); + }; + + // Check to make sure that the user owns the file attempting to be deleted + let userFileIds = getUserFileIds(user); + let fileIdOwnedByUser : Bool = Array.find(userFileIds, func x = fileId == x) != null; + if (fileIdOwnedByUser == false) + { + return #Err(#Other("Error deleting file")); + }; + + // Figure out the size of the file attempting to be deleted + let fileInfo : ?FileTypes.FileInfo = fileDatabase.get(fileId); + var fileSize = 0; + switch (fileInfo) { + case (null) { fileSize := 0;}; + case (?value) { fileSize := value.file_content.size(); }; + }; + + // // Attempt to retrieve the user record and then delete the file and then update + // the user record to reflect the file being deleted + let optionalUserRecord : ?FileTypes.UserRecord = userFileRecords.get(Principal.toText(user)); + switch (optionalUserRecord) { + case (null) { + return #Err(#Other("Error deleting file")); + }; + case (?userRecord) { + + // Delete the file + let deleteFileResult = fileDatabase.remove(fileId); + + // Delete the file from the user record and reduce the file size + let updatedFileIds : [Text] = Array.filter(userFileIds, func x = x != fileId); + let newUserRecord : FileTypes.UserRecord = {file_ids = updatedFileIds; totalSize = userRecord.totalSize - fileSize; }; + userFileRecords.put(Principal.toText(user), newUserRecord); + }; + }; + + return #Ok(#Success); + }; + +// Email Signups from Website + stable var emailSubscribersStorageStable : [(Text, Types.EmailSubscriber)] = []; + var emailSubscribersStorage : HashMap.HashMap = HashMap.HashMap(0, Text.equal, Text.hash); + + // Add a user as new email subscriber + private func putEmailSubscriber(emailSubscriber : Types.EmailSubscriber) : Text { + emailSubscribersStorage.put(emailSubscriber.emailAddress, emailSubscriber); + return emailSubscriber.emailAddress; + }; + + // Retrieve an email subscriber by email address + private func getEmailSubscriber(emailAddress : Text) : ?Types.EmailSubscriber { + let result = emailSubscribersStorage.get(emailAddress); + return result; + }; + + // User can submit a form to sign up for email updates + // For now, we only capture the email address provided by the user and on which page they submitted the form + public func submitSignUpForm(submittedSignUpForm : Types.SignUpFormInput) : async Text { + switch(getEmailSubscriber(submittedSignUpForm.emailAddress)) { + case null { + // New subscriber + let emailSubscriber : Types.EmailSubscriber = { + emailAddress: Text = submittedSignUpForm.emailAddress; + pageSubmittedFrom: Text = submittedSignUpForm.pageSubmittedFrom; + subscribedAt: Nat64 = Nat64.fromNat(Int.abs(Time.now())); + }; + let result = putEmailSubscriber(emailSubscriber); + if (result != emailSubscriber.emailAddress) { + return "There was an error signing up. Please try again."; + }; + return "Successfully signed up!"; + }; + case _ { return "Already signed up!"; }; + }; + }; + + // Function for custodian to get all email subscribers + public shared({ caller }) func getEmailSubscribers() : async [(Text, Types.EmailSubscriber)] { + // Only Principals registered as custodians can access this function + if (List.some(custodians, func (custodian : Principal) : Bool { custodian == caller })) { + return Iter.toArray(emailSubscribersStorage.entries()); + }; + return []; + }; + + // Function for custodian to delete an email subscriber + public shared({ caller }) func deleteEmailSubscriber(emailAddress : Text) : async Bool { + // Only Principals registered as custodians can access this function + if (List.some(custodians, func (custodian : Principal) : Bool { custodian == caller })) { + emailSubscribersStorage.delete(emailAddress); + return true; + }; + return false; + }; + +// Upgrade Hooks + system func preupgrade() { + fileDatabaseStable := Iter.toArray(fileDatabase.entries()); + userFileRecordsStable := Iter.toArray(userFileRecords.entries()); + emailSubscribersStorageStable := Iter.toArray(emailSubscribersStorage.entries()); + }; + + system func postupgrade() { + fileDatabase := HashMap.fromIter(Iter.fromArray(fileDatabaseStable), fileDatabaseStable.size(), Text.equal, Text.hash); + fileDatabaseStable := []; + userFileRecords := HashMap.fromIter(Iter.fromArray(userFileRecordsStable), userFileRecordsStable.size(), Text.equal, Text.hash); + userFileRecordsStable := []; + emailSubscribersStorage := HashMap.fromIter(Iter.fromArray(emailSubscribersStorageStable), emailSubscribersStorageStable.size(), Text.equal, Text.hash); + emailSubscribersStorageStable := []; + }; +}; diff --git a/src/PersonalWebSpace_frontend/components/BitfinityButton.svelte b/src/PersonalWebSpace_frontend/components/BitfinityButton.svelte index 183faaf..2d4d6b0 100644 --- a/src/PersonalWebSpace_frontend/components/BitfinityButton.svelte +++ b/src/PersonalWebSpace_frontend/components/BitfinityButton.svelte @@ -1,37 +1,37 @@ - - - + + + diff --git a/src/PersonalWebSpace_frontend/components/LoginModal.svelte b/src/PersonalWebSpace_frontend/components/LoginModal.svelte index 8703d3d..8ce58ab 100644 --- a/src/PersonalWebSpace_frontend/components/LoginModal.svelte +++ b/src/PersonalWebSpace_frontend/components/LoginModal.svelte @@ -1,20 +1,20 @@ - - - -
- - - - -
-
+ + + +
+ + + + +
+
diff --git a/src/PersonalWebSpace_frontend/components/NfidButton.svelte b/src/PersonalWebSpace_frontend/components/NfidButton.svelte index 1dd4bba..0ed85df 100644 --- a/src/PersonalWebSpace_frontend/components/NfidButton.svelte +++ b/src/PersonalWebSpace_frontend/components/NfidButton.svelte @@ -1,39 +1,39 @@ - - - + + + diff --git a/src/PersonalWebSpace_frontend/components/PlugButton.svelte b/src/PersonalWebSpace_frontend/components/PlugButton.svelte index ec60075..bb2b176 100644 --- a/src/PersonalWebSpace_frontend/components/PlugButton.svelte +++ b/src/PersonalWebSpace_frontend/components/PlugButton.svelte @@ -1,37 +1,37 @@ - - - + + + diff --git a/src/PersonalWebSpace_frontend/components/ProtocolEntity.svelte b/src/PersonalWebSpace_frontend/components/ProtocolEntity.svelte index 8dbd0e5..69d36bb 100644 --- a/src/PersonalWebSpace_frontend/components/ProtocolEntity.svelte +++ b/src/PersonalWebSpace_frontend/components/ProtocolEntity.svelte @@ -1,84 +1,84 @@ - - -{#if entityHasValidUrl()} -
- - - - - {#if viewerIsSpaceOwner} - {#if linkDeletionInProgress} - - {:else} - {#if successfullyDeletedLink} - - {:else} - - {#if errorDeletingLink} -

Unlucky, the deletion didn't work. Please give it another try.

- {/if} - {/if} - {/if} - {/if} - -
-

Address: {entity.entitySpecificFields}

-

Owner: {entity.owner}

-
-
-{/if} - - + + +{#if entityHasValidUrl()} +
+ + + + + {#if viewerIsSpaceOwner} + {#if linkDeletionInProgress} + + {:else} + {#if successfullyDeletedLink} + + {:else} + + {#if errorDeletingLink} +

Unlucky, the deletion didn't work. Please give it another try.

+ {/if} + {/if} + {/if} + {/if} + +
+

Address: {entity.entitySpecificFields}

+

Owner: {entity.owner}

+
+
+{/if} + + diff --git a/src/PersonalWebSpace_frontend/components/SpaceInfo.svelte b/src/PersonalWebSpace_frontend/components/SpaceInfo.svelte index 1974544..c2e61f4 100644 --- a/src/PersonalWebSpace_frontend/components/SpaceInfo.svelte +++ b/src/PersonalWebSpace_frontend/components/SpaceInfo.svelte @@ -1,122 +1,122 @@ - - -
- {#if isViewerSpaceOwner()} - submitUpdateSpaceInfoForm()}> -

Space Name:

- -

Space Description:

- -

Owner Name:

- -

About Owner:

- -

Owner Contact Info:

- - -

Space Creation Time: {spaceMetadata.creationTime}

-

Owner Principal: {spaceMetadata.spaceOwnerPrincipal}

- - {#if spaceInfoUpdateInProgress} - - loading animation - {:else} - - {/if} - - {:else} -

Space Name: {updatedSpaceName}

-

Space Description: {updatedSpaceDescription}

-

Space Creation Time: {spaceMetadata.creationTime}

-

Owner Principal: {spaceMetadata.spaceOwnerPrincipal}

-

Owner Name: {updatedOwnerName}

-

About Owner: {updatedAboutDescription}

-

Owner Contact Info: {updatedOwnerContactInfo}

- {/if} -
- - + + +
+ {#if isViewerSpaceOwner()} +
submitUpdateSpaceInfoForm()}> +

Space Name:

+ +

Space Description:

+ +

Owner Name:

+ +

About Owner:

+ +

Owner Contact Info:

+ + +

Space Creation Time: {spaceMetadata.creationTime}

+

Owner Principal: {spaceMetadata.spaceOwnerPrincipal}

+ + {#if spaceInfoUpdateInProgress} + + loading animation + {:else} + + {/if} +
+ {:else} +

Space Name: {updatedSpaceName}

+

Space Description: {updatedSpaceDescription}

+

Space Creation Time: {spaceMetadata.creationTime}

+

Owner Principal: {spaceMetadata.spaceOwnerPrincipal}

+

Owner Name: {updatedOwnerName}

+

About Owner: {updatedAboutDescription}

+

Owner Contact Info: {updatedOwnerContactInfo}

+ {/if} +
+ + diff --git a/src/PersonalWebSpace_frontend/components/SpaceNeighbors.svelte b/src/PersonalWebSpace_frontend/components/SpaceNeighbors.svelte index 1936908..9b8ef71 100644 --- a/src/PersonalWebSpace_frontend/components/SpaceNeighbors.svelte +++ b/src/PersonalWebSpace_frontend/components/SpaceNeighbors.svelte @@ -1,376 +1,376 @@ - - -

Get to Know the Virtual Neighborhood!

-{#if loadingInProgress} -

Looking for the Neighbors...

-{:else if neighborsLoadingError} -

There was an error loading the Neighbors. Please try again.

-{:else if neighborsLoaded} - {#if spaceHasNeighbors()} -

These are the Space's Neighbors:

- {:else} -

This Space doesn't have any Neighbors yet. If you are the owner, why not set up your Virtual Neighborhood now?

- {/if} - {#if isViewerSpaceOwner()} -
- {#if addNeighborButtonActive} - - {:else} - - {/if} - {#if newNeighborFormActive} -
submitAddNeighborForm()}> - - {#if newNeighborUrl !== ""} - {#if neighborUrlInputHandler(newNeighborUrl)} - - - - {#if neighborCreationInProgress} - loading animation - {:else} - - {/if} - {:else} - - {/if} - {/if} -
- {#if !neighborUrlIsValid} -

Please provide a valid URL for the new Neighbor.

- {/if} - {/if} - {#if successfullyAddedNeighbor} -

Success: You've got a new Virtual Neighbor in the Open Internet Metaverse!

- {:else if errorAddingNeighbor} -

Unlucky, this didn't work. Please give it another shot.

- {/if} -
- {:else if $store.isAuthed} -
- - {#if showVisitorSpaces} - {#if loadingVisitorSpaces} -

Loading Your Spaces...

- {:else} - {#if numberOfSpacesVisitorOwns > 0} -

These are Your Spaces. Please select which one to link to this Space:

- - {:else} -

You currently don't own any Spaces. Please create Your first Open Internet Metaverse Space:

- -

- Create My First Space -

- {/if} - {/if} - {/if} -
- {/if} -
- {#each neighborEntities as neighborEntity} - - {/each} -
-{/if} - - + + +

Get to Know the Virtual Neighborhood!

+{#if loadingInProgress} +

Looking for the Neighbors...

+{:else if neighborsLoadingError} +

There was an error loading the Neighbors. Please try again.

+{:else if neighborsLoaded} + {#if spaceHasNeighbors()} +

These are the Space's Neighbors:

+ {:else} +

This Space doesn't have any Neighbors yet. If you are the owner, why not set up your Virtual Neighborhood now?

+ {/if} + {#if isViewerSpaceOwner()} +
+ {#if addNeighborButtonActive} + + {:else} + + {/if} + {#if newNeighborFormActive} +
submitAddNeighborForm()}> + + {#if newNeighborUrl !== ""} + {#if neighborUrlInputHandler(newNeighborUrl)} + + + + {#if neighborCreationInProgress} + loading animation + {:else} + + {/if} + {:else} + + {/if} + {/if} +
+ {#if !neighborUrlIsValid} +

Please provide a valid URL for the new Neighbor.

+ {/if} + {/if} + {#if successfullyAddedNeighbor} +

Success: You've got a new Virtual Neighbor in the Open Internet Metaverse!

+ {:else if errorAddingNeighbor} +

Unlucky, this didn't work. Please give it another shot.

+ {/if} +
+ {:else if $store.isAuthed} +
+ + {#if showVisitorSpaces} + {#if loadingVisitorSpaces} +

Loading Your Spaces...

+ {:else} + {#if numberOfSpacesVisitorOwns > 0} +

These are Your Spaces. Please select which one to link to this Space:

+ + {:else} +

You currently don't own any Spaces. Please create Your first Open Internet Metaverse Space:

+ +

+ Create My First Space +

+ {/if} + {/if} + {/if} +
+ {/if} +
+ {#each neighborEntities as neighborEntity} + + {/each} +
+{/if} + + \ No newline at end of file diff --git a/src/PersonalWebSpace_frontend/components/StoicButton.svelte b/src/PersonalWebSpace_frontend/components/StoicButton.svelte index c9c26e9..e29ce36 100644 --- a/src/PersonalWebSpace_frontend/components/StoicButton.svelte +++ b/src/PersonalWebSpace_frontend/components/StoicButton.svelte @@ -1,39 +1,39 @@ - - - + + + diff --git a/src/PersonalWebSpace_frontend/components/UserSpace.svelte b/src/PersonalWebSpace_frontend/components/UserSpace.svelte index 2ba6de2..3e5e5ba 100644 --- a/src/PersonalWebSpace_frontend/components/UserSpace.svelte +++ b/src/PersonalWebSpace_frontend/components/UserSpace.svelte @@ -1,133 +1,133 @@ - - -
-
- - - - {#if isViewerSpaceOwner() && entityIdToLinkTo !== ""} - {#if linkCreationInProgress} - - {:else} - {#if successfullyCreatedLink} - - {:else} - - {#if errorCreatingLink} -

Unlucky, the linking didn't work. Please give it another try.

- {/if} - {/if} - {/if} - {/if} - - -
-

Owner: {space.owner}

-

Owner Name: {ownerName}

-

Owner Contact Info: {ownerContactInfo}

-

Space Name: {spaceName}

-

Space Description: {spaceDescription}

-

Creation Time: {creationTime}

-
-
-
+ + +
+
+ + + + {#if isViewerSpaceOwner() && entityIdToLinkTo !== ""} + {#if linkCreationInProgress} + + {:else} + {#if successfullyCreatedLink} + + {:else} + + {#if errorCreatingLink} +

Unlucky, the linking didn't work. Please give it another try.

+ {/if} + {/if} + {/if} + {/if} + + +
+

Owner: {space.owner}

+

Owner Name: {ownerName}

+

Owner Contact Info: {ownerContactInfo}

+

Space Name: {spaceName}

+

Space Description: {spaceDescription}

+

Creation Time: {creationTime}

+
+
+
diff --git a/src/PersonalWebSpace_frontend/pages/CreateSpace.svelte b/src/PersonalWebSpace_frontend/pages/CreateSpace.svelte index 52bbda8..882bcf9 100644 --- a/src/PersonalWebSpace_frontend/pages/CreateSpace.svelte +++ b/src/PersonalWebSpace_frontend/pages/CreateSpace.svelte @@ -1,406 +1,406 @@ - - - - -
-

Create Your Personal Web Space

- {#if !$store.isAuthed} -

Log in to generate a 3D room (Your Space, Your Realm, Your Virtual Home) which you can edit afterwards. Fun fact: The Space is an NFT itself and will be sent to your wallet. This way you know it's truly yours!

- - {:else} -

You're Logged In

- - {/if} -

Create a new Space

- -

Spaces Ready For You:

- - -

Your Web Space Station

- - {#if !$store.isAuthed} - -

{loginSubtext}

- {:else} - {#if isSpaceCreationInProgress} - - {#if spaceToCreate === "defaultspace/0"} -

{inProgressSubtext}

- {/if} - {:else if wasSpaceCreatedSuccessfully} - - {#if spaceToCreate === "defaultspace/0"} -

{createdSubtext}

- {:else} -

{clickDefaultSubtext}

- {/if} - {:else} - -

{clickDefaultSubtext}

- {/if} - {/if} - -

Your Nature Retreat

- - {#if !$store.isAuthed} - -

{loginSubtext}

- {:else} - {#if isSpaceCreationInProgress} - - {#if spaceToCreate === "defaultspace/1"} -

{inProgressSubtext}

- {/if} - {:else if wasSpaceCreatedSuccessfully} - - {#if spaceToCreate === "defaultspace/1"} -

{createdSubtext}

- {:else} -

{clickDefaultSubtext}

- {/if} - {:else} - -

{clickDefaultSubtext}

- {/if} - {/if} - -

Your Internet Island

- - {#if !$store.isAuthed} - -

{loginSubtext}

- {:else} - {#if isSpaceCreationInProgress} - - {#if spaceToCreate === "defaultspace/2"} -

{inProgressSubtext}

- {/if} - {:else if wasSpaceCreatedSuccessfully} - - {#if spaceToCreate === "defaultspace/2"} -

{createdSubtext}

- {:else} -

{clickDefaultSubtext}

- {/if} - {:else} - -

{clickDefaultSubtext}

- {/if} - {/if} - -

Create Your Space From an Existing Model:

- -

Upload a GLB Model File

-
createNewUserSpaceFromModel("UserUploadedGlbModel")}> - - - {#if files} - {#key files} - - {#if userFileInputHandler(files)} - {#if !$store.isAuthed} - -

{loginSubtext}

- {:else} - {#if isSpaceCreationInProgress} - - {#if spaceToCreate === "UserUploadedGlbModel"} -

{inProgressSubtext}

- {/if} - {:else if wasSpaceCreatedSuccessfully} - - {#if spaceToCreate === "UserUploadedGlbModel"} -

{createdSubtext}

- {:else} -

{clickFromModelSubtext}

- {/if} - {:else} - {#if fileSizeToUpload <= fileSizeUploadLimit} - -

{clickFromModelSubtext}

- {:else} - -

{fileTooBigText}

- {/if} - {/if} - {/if} - {:else} - -

Please provide a valid GLB Model File.

- {/if} - {/key} - {/if} - - -

GLB Model Hosted on the Web

-
createNewUserSpaceFromModel("WebHostedGlbModel")}> - - {#if webHostedGlbModelUrl !== ""} - {#if urlInputHandler(webHostedGlbModelUrl)} - {#key webHostedGlbModelUrl} - - {/key} - {#if !$store.isAuthed} - -

{loginSubtext}

- {:else} - {#if isSpaceCreationInProgress} - - {#if spaceToCreate === "WebHostedGlbModel"} -

{inProgressSubtext}

- {/if} - {:else if wasSpaceCreatedSuccessfully} - - {#if spaceToCreate === "WebHostedGlbModel"} -

{createdSubtext}

- {:else} -

{clickFromModelSubtext}

- {/if} - {:else} - -

{clickFromModelSubtext}

- {/if} - {/if} - {:else} - -

Please provide a valid URL for the GLB Model.

- {/if} - {/if} - -
- -
- -